Automating the world one-liner at a time…
At TechEd, we announced and released an early version of PowerShellGet: a package manager for PowerShell modules. The response was positive, and many people asked the same type of question:
“Can I set up my own internal repository for PowerShellGet?”
Many enterprise-oriented houses want the ability to create private module repositories (without sharing them with the world). Many security minded folks want to curate their own module collections.
The short answer to this question is: yes! All you need to do is create your own NuGet Server and redefine a couple of PowerShellGet variables. Detailed instructions are below.
You might be asking yourself: “Why does PowerShellGet work against NuGet Feeds?” When designing PowerShellGet, we didn’t want to reinvent the wheel. Making a good package manager from scratch can be hard. Fortunately, Microsoft already has a pretty awesome package management solution in NuGet (http://www.nuget.org/). So, we decided to build PowerShellGet on top of NuGet.
This way, we can craft a PowerShell specific package management experience without needing to develop stuff like the protocol from scratch.
This means that PowerShellGet can work against any NuGet repository out of the box. Note: Do not publish PowerShell modules to NuGet.org.
The only things you need to do to make this happen are:
There are many ways to set up a working NuGet repository. Here are a couple of options:
For the purposes of this blog, I’m going to use MyGet to create a NuGet feed. I ended up with a feed at this URL: https://www.myget.org/F/powershellgetdemo/.
For this release, PowerShellGet uses two variables to determine which gallery to work against: $PSGallerySourceUri and $PSGalleryPublishUri. Here’s what you need to do to generate these variables for your feed:
To make PowerShellGet work against these variables, you need to first import the PSGet module, and then override the values before using PSGet commands.
Here’s an example:
C:\Windows\System32\WindowsPowerShell\v1.0> Import-Module PowerShellGet
C:\Windows\System32\WindowsPowerShell\v1.0> $PSGalleryPublishUri = 'https://www.myget.org/F/powershellgetdemo/api/v2/package'
C:\Windows\System32\WindowsPowerShell\v1.0> $PSGallerySourceUri = 'https://www.myget.org/F/powershellgetdemo/api/v2'
You can successfully publish and install modules from your new NuGet gallery.
C:\Windows\System32\WindowsPowerShell\v1.0> Publish-Module -Name xDscResourceDesigner -NuGetApiKey wouldnt-you-like-to-know…
C:\Windows\System32\WindowsPowerShell\v1.0> Find-Module xDscResourceDesigner
Version Name DateUpdated Description
------- ---- ----------- -----------
1.1.1 xDSCResourceDesigner 5/15/2014 12:51:24 AM The xDscResour...
As always, if you have feedback about PowerShellGet or any other PowerShell feature, please let us know: http://connect.microsoft.com/PowerShell.
Should a module package have some conventional structure? Should the module directory be one of the root directories, like /ModuleName in the package, or should its file be in /Tools or in /Tools/ModuleName?
The Publish-Module Cmdlet should take care of all of that for you. Just point it at the NuGet repository you want to use, and you're good to go.
I am disapointed of this Post. I think you have made this post yourself to comfortable.
1. To use MyGet.org for a security driven enterprise is not alternative.
2. You dont show how to setup a Myget Service (because it is very challenging for Admins?)
3. The link "Setting Up a Local Gallery" is depcrated. Here is the right Link: github.com/.../NuGetGallery
There you see that the prerequisites are to challenging for an IT Admin.
With DSC you have a Rescource to Setup a DSC Repository WebService.
So for PowerShellGet I hope we get an easier way to setup a Nuget Gallery and not this awkward Visual Studio compiling stuff...
Greets Peter Kriegel
Founder member of the European, German speaking, Windows PowerShell Community
Thanks for the feedback Peter,
Absolutely -- this process can and should be improved, and we're optimistic that either we or the community will be able to improve it over time. This blog post is meant as the starting point for that process. Using DSC to set up a PowerShellGet repository is a good idea for how to make things easier.
@John Slack, I see, Publish-Module takes care of this. The thing is that for the moment I cannot use these new features. But I still can provide a couple of modules for others (actually, they are already on NuGet.org but I am not sure they are ready to play this game). Q: How do I compose a package on my own so that it is recognized by PowerShellGet as a PS module package?
I believe that the contents of the module are put in the root directory. You'll also need to make sure that they are modules with module manifests for them to be installed normally.
On the Nuget Document Page there is a very good description How to create Packages.
So the PowerShell Team should tell us if there are some difference's to package a normal Nuget Package or a "special" PowerShell Module package or a PowerShell Snapin package.
PowerShell Snapins are mostly Microsoft Installer .msi files. So there should be the same Nuget Install Process like other nuget packaged .msi Software files.
In case of a Module Install, I think the main point here is to set the Installation destination correct inside the Nuget package Metadatas.
You can use the $env:PSModulePath variable to set an valid Module destination path.
Nuget Packages are able to start an PowerShell Script which lives inside the package automatically, so there you can do the real Module install process.
See here the Section: Automatically Running PowerShell Scripts During Package Installation and Removal
Intressing Links about that:
Writing a NuGet Package That Adds A Command (Module) To The PowerShell Console
What should a PowerShell module package look like?
PowerShell Module distribution using NuGet.
Good points about creating traditional NuGet packages with PowerShell content -- the process of packing a folder remains the same (there's nothing special about a PowerShellGet package). PowerShellGet has gone a slightly different route than the NuGet client, so some of the other guidance you posted doesn't apply. I'll try to dive into how we're using NuGet, as that will help clarify things.
When PowerShellGet publishes a module, it wraps it into a NuGet package. It generates the .nuspec from the Module Manifest (and additional Publish-Module parameters), and packs the folder without doing anything like putting the module's contents into a subfolder (e.g. tools). As you pointed out, anyone can do the same thing by following NuGet's guidance: docs.nuget.org/.../creating-and-publishing-a-package
When PowerShellGet installs a module, it uses NuGet to download and unpack the module (without running any install.ps1 scripts), makes sure it is a valid module, and then copies it to either program files or the users documents folder (based on the -Scope parameter used by the caller).
NuGet has lots of guidance for creating packages that will be consumed by the NuGet client in Visual Studio. The NuGet Client understands the tools folder, the install.ps1, and other NuGet specific data. That client and behavior has been designed explicitly with Visual Studio in mind. Even when it deals with PowerShell content, the focus is on installing it to the Visual Studio specific Package Manager Console.
We aren't doing many of the things that the VS Client does, so a lot of NuGet's guidance on creating packages doesn't apply to PowerShellGet. That's why we made a point to abstract the .nuspec, .nupkg, and other NuGet infrastructure away from the user -- we felt exposing NuGet would only confuse the usage of PowerShellGet.
Does that make sense? I'd love to chat with you more about this.
Thanks for the information! That's really helpful.
I see that connect.microsoft.com/PowerShell is the standard location for work item tracking and management with PowerShell. But, because the source code of this module ships with it; would that make it an "open source" project? And, potentially GitHub could be used for development? I figure this question is pretty off-topic, so no worries if its more appropriate in another forum.
I am very pleased that you will chat with me, I will try my best to chat with you ;-)
I am very busy to do ma daily work, to coordinate the German PowerShell Community, produce German PowerShell videos for my YouTube channel and to do Forum Support on TechNet.
Even I do Twitter, Facebook Google+ all with PowerShell Stuff.
So it is very hard for me to coordinate and doing additional conversations on so many different Places.
So please bear with me if I miss a Post.
Event it is hard for me to chat in English, English Post take me long time :-(
I think the most conversation is already done in the community.
The First Time I saw the discussion about the need of a PowerShell module manager I was very excited about the idea because I agreed with the fact that a PowerShell module manager is needed!
If you look to psget the boys Mike Chaliy, Jason Stangroome, Mark Robert Johnson and others has done a very very good Job.
So I think these guys are the right ones to talk to. I am only a consumer of this topic no producer ;-)
Jason Sangroom has Presented his: Requirements for a PowerShell module manager
Folow the discussion there.
So I have adopted and extended the ideas of Jansons and started to plan my own Project. Please see my vision there:
(Unfortunately I never started this Project)
I have rapt attention how the story will go with PowerShellGet as a Module manger ;-)
I missed to thank you for the description and the insides how to produce PowerShellGet Packages.
I hope you will do a brain-dead Step by Step tutorial ;-)
I will investigate myself into this Process and plan to do a blog Post in German language.
@Peter - It's kinda funny that you asked for a "brain-dead Step-by-Step tutorial". The PowerShell snippets in the post are all the steps that are necessary. It just looks soo simple, that it's hard to believe that's all there is to it.
1) If you want to publish to a private repository (myget, etc), change the $PSGalleryPublishUri and $PSGallerySourceUri paths.
2) Use Publish-Module.
Publish-Module will find the module on disk, package it up for you, and push it up to the repository. I guess the key thing is to have a .psd1 file in your module. You can get a sample .psd1 file from the PowerShellGet module at (C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerShellGet\PowerShellGet.psd1). Make sure to set your version number in the .psd1 file.
Have you tried using the New-ModuleManifest cmdlet for creating the .psd1? I use it to create the blank template, and then edit it in the ISE.
@John - I hadn't. Thanks for pointing it out! I just tried it out and I like that it creates a new Guid for the file and fills in some $env:USERNAME information.
I know there's a lot of documentation on how to create a .psd1 file. But ... I found using PowerShellGet.psd1 as an example useful for me because it was a quick guide to know what values were appropriate for the different variables. (But, I should definitely read more documentation)
I have missed that Boe Prox has done a very good Blog post :
Setting Up a NuGet Feed For Use with ....
But you need Visual Studio and compiling voodo ...