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     : http://www.microsoft.com/

# Trusted            : True

# Registered         : True

# InstallationPolicy : Trusted

# OneGetProvider     : NuGet

# PublishLocation    : http://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 http://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 (8)

  1. alastair says:

    Link to oneget appears to be broken. Points to blogs.msdn.com/…/oneget.org

  2. Mike says:

    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'

  3. Phill says:

    I think you're missing the http:// from your oneget.org link, the link currently takes me to the MSDN blog backend

  4. Wes says:

    And where do I go to download PowershellGet?

  5. Nmk says:

    Just tried this out and it works wonderfully!!! It’s so easy to publish, share, update packages. Thanks!!

  6. There’s definately a lot to learn about this issue. I really like all the points you have made.

  7. Paul says:

    It appears that `OneGet` has been renamed as `PackageManagement`. If so, it would be a good thing to update this article or provide a link to newer information. Thanks.

Skip to main content