Package Management for PowerShell Modules with PowerShellGet
The following post was written PowerShell MVP Kirk Munro
Windows PowerShell has developed a great reputation for itself, not only from the capabilities of the product, but from the strength of the community that has grown around the product. As a PowerShell MVP and long-time member of that community, one of my favorite ways to give back to that community is to share the results of my PowerShell work with them in a format that they can use in their own environment. For me, the format of choice for that is PowerShell modules, but up until recently there hasn’t been a Microsoft-supported, sanctioned way to share PowerShell modules privately inside of organizations or publically across the internet. Fortunately, that is all about to change when sharing, discovery, and consumption of PowerShell modules gets a whole lot easier with my favorite new feature in the upcoming release of Windows Management Framework 5.0 (WMF5), PowerShellGet.
What is PowerShellGet?
PowerShellGet is a package manager for Windows PowerShell. More specifically, it is a wrapper around a new Windows component called OneGet, and it enables simplified package management of PowerShell modules. That may confuse you, so let me try to explain. In the next version of WMF5 and Windows, Microsoft is including a component called OneGet. OneGet is a unified package management component that allows you to perform software discovery, installation and inventory for any type of software package that it supports through its extensible provider interface. PowerShellGet is a module that defines an extension for OneGet (a provider called PSModule) that allows OneGet to manage PowerShell modules as software packages. PowerShellGet also defines PowerShell commands that wrap the native OneGet PowerShell commands to provide a focused interface for PowerShell-centric package management. Still missing some of the picture? Here’s a diagram that should help you out
This diagram illustrates how PowerShellGet fits into the framework provided by OneGet. PowerShellGet is comprised of the following two core components that interact with OneGet, both of which are defined within the PowerShellGet module:
1. The set of commands that you see at the top of the diagram, which internally call into the OneGet commands that you see in the second rectangle from the top.
2. A PSModule provider that plugs into the OneGet Core provider API, to allow OneGet to manage PowerShell modules as packages.
This architecture of course means you could opt to use the OneGet commands to manage your PowerShell module packages, but that would be making more work for yourself than is necessary since PowerShellGet already comes with commands that are more appropriate for the job.
PowerShellGet Repositories
Each of the providers that plug into OneGet provide access to one or more repositories (also referred to as galleries). These repositories may be public or private, accessible via the internet or only accessible on an Intranet. They may be created and supported by Microsoft or created by individuals or organizations. For PowerShellGet, by default the PSModule provider connects OneGet to the PowerShell Resource Gallery (a Microsoft-supported, public PowerShellGet repository, currently in preview). Internally the PSModule provider is using OneGet itself to talk to the repository, and PowerShell modules are managed as packages through that provider. That’s a little more complicated than we need to go into here though.
Here is a screenshot showing you what the PowerShell Resource Gallery looks like:
While some tasks for managing PowerShell modules as packages are available through the gallery user interface, not all tasks are available and really, since this is about PowerShell, unless you want to look at the statistical information on the site you’re much better off using the commands that ship with PowerShellGet to manage these packages.
If you want to create additional repositories for PowerShellGet to connect to, you have a few options. All PowerShellGet repositories are NuGet galleries behind the scenes (NuGet is a package manager for the Microsoft development platform). Given this is the case, you can either create your own NuGet gallery by following the commands in the NuGetGallery readme, or you can pay for a 3rd party company that offers hosted NuGet galleries for a fee.
PowerShellGet Commands
Now that you have a better understanding of what PowerShellGet is all about, let’s dig into how you can use PowerShellGet with the PowerShell commands that it comes with. PowerShellGet includes the following commands:
Get-PSRepository |
List all PowerShellGet repositories that have been registered for use by PowerShellGet on the local system. |
Set-PSRepository |
Modify the properties on a PowerShellGet repository that has been registered for use by PowerShellGet on the local system. |
Register-PSRepository |
Registers a PowerShellGet repository for use by PowerShellGet on the local system. |
Unregister-PSRepository |
Unregisters a PowerShellGet repository that is currently registered for use by PowerShellGet on the local system. |
Find-Module |
Finds one or more modules on a PowerShellGet repository that match the specified search criteria. |
Install-Module |
Downloads or more modules from a PowerShellGet repository and installs them on the local system. |
Update-Module |
Downloads and installs the latest version of one or more modules from the PowerShellGet repository from which they were originally installed. |
Publish-Module |
Publishes a module into a PowerShellGet repository. This can be a new module that has never been published to a PowerShellGet repository or a module that you want to republish because you have updated it to a newer version. |
Here’s a brief demonstration showing some of those commands in action:
# Get a list of all registered PowerShellGet repositories
Get-PSRepository | Format-List *
# SAMPLE OUTPUT
# Name : PSGallery
# SourceLocation : https://msconfiggallery.cloudapp.net/api/v2/
# Trusted : False
# Registered : True
# InstallationPolicy : Untrusted
# OneGetProvider : NuGet
# PublishLocation : https://go.microsoft.com/fwlink/?LinkID=397527\&clcid=0x409
# ProviderOptions : {}
#
# Name : MSPSGallery
# SourceLocation : https://www.microsoft.com/
# Trusted : True
# Registered : True
# InstallationPolicy : Trusted
# OneGetProvider : NuGet
# PublishLocation : https://go.microsoft.com/fwlink/?LinkID=397635\&clcid=0x409
# ProviderOptions : {}
# Register a PowerShellGet repository for use on the local system
# (note, this repository does not really exist; it's just an example)
Register-PSRepository -Name Private -SourceLocation https://poshoholic.com
# Change a property on a PowerShellGet repository
Set-PSRepository -Name Private -InstallationPolicy Trusted
# Unregister a PowerShellGet repository
Unregister-PSRepository -Name Private
# Find all modules that are available in all PowerShellGet repositories
Find-Module -Name *
# SAMPLE OUTPUT
# Repository Version Name Description
# ---------- ------- ---- -----------
# PSGallery 1.0.0.0 AppDomainConfig Manipulate AppDomain configu...
# PSGallery 1.0.0.1 CimInventory Module that should help read...
# PSGallery 1.0.0.1 DebugPx The DebugPx module provides ...
# PSGallery 1.0.0.1 DoPx The DoPx module provides a r...
# ...
# <snip>
# ...
# PSGallery 1.0.0.12 PSReadline Great command line editing i...
# PSGallery 1.0.0.2 SnippetPx The SnippetPx module enhance...
# PSGallery 2.0.0.6 TypePx The TypePx module adds prope...
# PSGallery 1.3.1 xWebAdministration The xWebAdministration modul...
# PSGallery 1.0 xWindowsUpdate Module with DSC Resources fo...
# PSGallery 0.0.0.1 xWinEventLog Configure Windows Event Logs...
# PSGallery 1.0.0.0 xWordPress This module contains the xWo...
# Find a specific module that is available in a specific PowerShellGet repository
# (note, DebugPx is an actual module in the gallery)
Find-Module -Name DebugPx -Repository PSGallery | Format-List *
# SAMPLE OUTPUT
# Name : DebugPx
# Version : 1.0.0.1
# Description : The DebugPx module provides a set of commands that
# make it easier to debug PowerShell scripts,
# functions and modules. These commands leverage the
# native debugging capabilities in PowerShell (the
# callstack, breakpoints, error output and the -Debug
# common parameter) and provide additional
# functionality that these features do not provide,
# enabling a richer debugging experience.
# Author : Kirk Munro
# CompanyName :
# Copyright : (c) 2014 Kirk Munro
# PublishedDate :
# LicenseUri :
# ProjectUri :
# IconUri :
# Tags : breakpoint debugger write-debug set-psbreakpoint
# ReleaseNotes :
# RequiredModules :
# RepositorySourceLocation : https://msconfiggallery.cloudapp.net/api/v2/
# Repository : PSGallery
# OneGetProvider : NuGet
# Install a module, along with required modules, for all users
# (note, in the CTP, required modules must be explicitly installed)
# (also note, installing for all users requires elevation)
Install-Module -Name DebugPx,SnippetPx
# Update all modules that you installed using PowerShellGet
Update-Module
# Publish a module that you created to PowerShellGet
# (note, this is not a valid NuGet API key, and this assumes you have a
# module called MyGreatModule with a module manifest in a discoverable
# location)
$nugetApiKey = [System.Guid]::NewGuid().ToString()
Publish-Module -Name MyGreatModule -NuGetApiKey $nugetApiKey
There are several important things that should be called out about the commands listed above:
1. The only command that will not work in that demonstration is the last command. That is because it uses an auto-generated NuGet API key that is not valid, and it is dependent on you having a module called MyGreatModule that is discoverable via one of the paths in your PSModulePath environment variable. If you do have a module that you want to share in a PowerShellGet repository, it must have a manifest with a version number defined within it, and you must have the API key for the PowerShellGet repository where you want to share your module. You can find your API key for the PowerShell Resource Gallery by logging in with your Microsoft account and browsing to your account information page.
2. When publishing an update to a module, you must increase the version number in the manifest of the module you are publishing. Otherwise, PowerShellGet will not allow you to publish the modified module to a PowerShellGet repository.
3. If you invoke Register-PSRepository and you pass it a URI that is valid but that does not resolve to a NuGet gallery, the repository will be registered however you will see several warning messages and probably one error message as well. For this article, I was merely testing the Register-PSRepository command without setting up a private repository myself first. I will do that myself later, and can share the details about that as well, if not here then on my personal blog at poshoholic.com
4. The PowerShell Resource Gallery repository already contains a lot of very useful modules. In fact, while researching this article I uploaded a module that I personally use more than any other non-core PowerShell module. It’s called DebugPx, and you can install it yourself using the Install-Module command as shown in the commands listed above. Watch for more information about DebugPx on my blog as well.
Food for Thought
One interesting fact about PowerShellGet that makes it stand out from other modules that ship in WMF5 is that it is a script module, and the commands that it defines are PowerShell functions. That means that you can open those files in your favorite text editor and read the internal PowerShell code to see how those commands work. There are a few interesting nuggets of information that can be gleaned from reviewing those script files. One item in particular that grabbed my attention, was that the PowerShellGet manifest lists the minimum required PowerShell version as 3.0. Could that be a typo, or a sign of things to come? Only time will tell for that one, but regardless, it is well worth taking a look to see what is there – you just might learn a thing or two!
Wrap-up
I think that about covers PowerShellGet, at least for this article. There is definitely more that could be discussed, such a detailed guide on setting up a NuGet gallery for use with PowerShellGet, or recommendations on how to create and publish your first module to PowerShellGet. That information will have to wait for another article for now though. With all of this information, I hope that you see how this is a truly fantastic feature that is definitely going to have an impact on the PowerShell community, and personally, I can’t wait to see what new modules come out of it! Thanks for reading!
About the author
Kirk Munro is a Technical Product Manager at Provance Technologies, where he is helping build the next generation of Provance's flagship IT Asset Management product. He is also a 7-time recipient of the Microsoft Most Valued Professional (MVP) award for his involvement in the PowerShell community. For the past 8 years, Kirk has focused almost all of his time on PowerShell and PowerShell solutions, including managing popular products such as PowerGUI, PowerWF and PowerSE. It is through this work he became known as the world's first self-proclaimed Poshoholic. Outside of work these days Kirk is returning to his software developer roots, learning mobile technologies like Xamarin and Ruby on Rails, and taking courses on Coursera or edX whenever he can make the time to do so. Follow Kirk on Twitter
About MVP Mondays
The MVP Monday Series is created by Melissa Travers. In this series we work to provide readers with a guest post from an MVP every Monday. Melissa is a Community Program Manager, formerly known as MVP Lead, for Messaging and Collaboration (Exchange, Lync, Office 365 and SharePoint) and Microsoft Dynamics in the US. She began her career at Microsoft as an Exchange Support Engineer and has been working with the technical community in some capacity for almost a decade. In her spare time she enjoys going to the gym, shopping for handbags, watching period and fantasy dramas, and spending time with her children and miniature Dachshund. Melissa lives in North Carolina and works out of the Microsoft Charlotte office.
*PowerShell MVPs Claus Nielsen and Aleksandar Nikolic also contributed to this article as technical reviewers. Thank you Kirk, Claus and Aleksandar!
Comments
Anonymous
October 06, 2014
Excelent i work with chocolatey and oneget is very nice blogs.itpro.es/.../que-es-oneget-su-instalacion-en-windows-8-1-y-el-despliegue-de-software blogs.itpro.es/.../integrando-chocolatey-a-mdt-2013-e-instalando-aplicaciones-de-forma-desatendida-en-windows-8-1Anonymous
October 06, 2014
Link to oneget appears to be broken. Points to blogs.msdn.com/.../oneget.orgAnonymous
October 06, 2014
Thanks so much for this write-up, so many things about PowerShellGet have not been explained anywhere, like the way it relates to OneGet. Of course this is because it's still early technology, but it felt like MS said 'here's some cool stuff, YOU figure out how it works'Anonymous
October 06, 2014
I think you're missing the http:// from your oneget.org link, the link currently takes me to the MSDN blog backendAnonymous
February 12, 2015
And where do I go to download PowershellGet?Anonymous
February 17, 2016
Just tried this out and it works wonderfully!!! It's so easy to publish, share, update packages. Thanks!!Anonymous
October 31, 2017
There's definately a lot to learn about this issue. I really like all the points you have made.Anonymous
November 08, 2017
It appears thatOneGet
has been renamed asPackageManagement
. If so, it would be a good thing to update this article or provide a link to newer information. Thanks.