Publish a PowerShell module to MyGet in 5 Minutes
I've been trying to sell my colleagues on the benefits of PowerShell. Need to interact with Git, do it from PowerShell. Got some repetitive task to perform? PowerShell. I'd like a cup of coffee... seriously write a script to contact your IOT enabled coffee machine and have it ready for you when you get there.
A buddy was doing some QA testing of a GeoIP lookup service we've built. We store IPs as unsigned ints (for speedy Azure table storage row-key lookup) and he needed a quick way to go from integer to 4-octet (1.2.3.4) and back. So we knocked up some PowerShell functions. And then a train of thought took over.
Everyone should hopefully be in the mindset of automating and scripting common tasks. But the benefit is even more powerful if you can share and distribute these things among your friends and colleagues. Maybe you do already. Maybe you paste scripts into Slack. Maybe you have a Github repo that people can grab them from and add import statements to their PSProfile. Here, we're going to look at bundling our module into a package and deploying it to MyGet so it can be shared and installed by the masses.
Seems like a good idea... right?
Create a PowerShell module
First, I created a new module in my github repo of powershell scripts, creatively named EoinCModule.
The Module directory contains 2 files, the module itself, and a manifest file.
- EoinCModule
- EoinCModule.psm1
- EoinCModule.psd1
A PowerShell module, is a PSM1 file which contains your functions and commandlets. It's a pretty straight forward PowerShell script file with parameters, comments etc...
The manifest file contains meta-data about the module to describe it during the publish process. To create a template manifest file, you can run the following command in your module directory.
New-ModuleManifest -Path EoinCModule.psd1
The manifest file contains the meta data about your module. At a minimum you'll need to update it to include
- Author
- Description
- ModuleVersion
- RootModule (your PSM1 file)
- FunctionsToExport
Signup to MyGet
Next you'll need somewhere to publish your package to. MyGet is a public package management site that's free to sign up for.
I signed up with my gmail account, created a public feed and that's it.
Publish your Packages
PowerShell 5.0 has integrated publish support to allow you to publish direct to MyGet.
In MyGet, navigate to your profile page and grab your Publisher API key.
Once you have your API Key, run the following commands from your PowerShell prompt to publish your module. (Don't forget to replace your feed name & api key)
Import-Module PowerShellGet
$PSGalleryPublishUri = 'https://www.myget.org/F/YOUR-FEED-NAME/api/v2/package'
$PSGallerySourceUri = 'https://www.myget.org/F/YOUR-FEED-NAME/api/v2'
$APIKey = 'YOUR-API-KEY'
Register-PSRepository -Name MyGetFeed -SourceLocation $PSGallerySourceUri -PublishLocation $PSGalleryPublishUri
Publish-Module -Path .\YOUR-MODULE-DIRECTORY -NuGetApiKey $APIKey -Repository MyGetFeed -Verbose
That's it. Your package is published.
Importing your package
Once your package is published you (or anyone else) can import it using the following command.
Install-Module -Name "MODULE-NAME" -RequiredVersion "VERSION" -Repository "REPO-NAME"
Other Bits & Pieces
The process outlined above is pretty trivial, and if you have some module scripts already, getting them published shouldn't take any longer than 5-10 minutes. I did run into a couple of little issues though. When you generate your manifest, the default template will contain a version number with only a Major.Minor component. In order to publish, the version number must contain at BUILD component as well.
In order to publish you'll notice a command above to register a PSRepository
. This will persist across PowerShell sessions once created. In the above example, I named my repository "MyGetFeed".
To install my module for example, you would run
Install-Module -Name "EoinCModule" -RequiredVersion "1.0.0" -Repository "MyGetFeed"
To install my module on a different machine, you would first need to register the repository on that machine. e.g.
Import-Module PowerShellGet
Register-PSRepository -Name "eoinc" -SourceLocation "https://www.myget.org/F/eoinc/api/v2"
Install-Module -Name "EoinCModule" -RequiredVersion "1.0.0" -Repository "eoinc"
~Eoin Campbell