PowerShell Package Management - Repository vs Provider vs Source PowerShell Package Management - Repository vs Provider vs Source powershell powershell

PowerShell Package Management - Repository vs Provider vs Source


Update August 2021

PowerShellGet 3.0 will be fundamentally different from previous versions of the module. It will no longer be dependent on PackageManagment, uses the NuGet APIs and libraries directly (as opposed to nuget.exe) and has new syntax. You can learn more about the ongoing development of PowerShellGet 3.0 from the DevBlogs Article and on GitHub.

The question and answer on this page are therefore relevant only to PowerShellGet 2.0.


The best way to think of this is as two spheres; the PackageManagement one and the PowerShellGet one.

PackageManagement

PackageManagement (formerly OneGet) is the outer sphere, and is a framework for package delivery in Windows. It is administered through PowerShell, but applies to the whole operating system or user profile. It provides two main classes:

  • A PackageProvider is the equivalent of a package manager; think APT/dpkg, pacman, Homebrew, Chocolatey/NuGet, or winget. These utilise the framework to manage software on Windows using the concept of packages.
  • A PackageSource serves a single PackageProvider and is where the provider gets its packages from.

PowerShellGet

PowerShellGet is the inner sphere, and is a PowerShell module that uses the PackageManagement framework to deliver packages specifically for PowerShell. It is registered as a PackageProvider, and uses the associated PackageSources to deliver modules and scripts from the PowerShell Gallery, or additional sources. It introduces a new class, called a PSRepository. You can think of this as a virtual wrapper for a PackageSource that only exists in the PowerShellGet sphere.

When you register a new PSRepository with Register-PSRepository, you'll notice that if you run Get-PackageSource, a new source has been automatically added with the same name and URI, for the PowerShellGet provider. The PSRepository has a few specific functions:

  • To limit changes made to within the PowerShell universe; none of the PowerShellGet Cmdlets modify operating system components or software.
  • To differentiate between module packages and script packages, and to install them in the correct locations.
  • To permit manual updating of the above with the Update-* Cmdlets.
  • To permit publishing of packages back to the PSRepository source.

For (un)installing/updating modules and scripts, PowerShellGet uses the PackageManagement Cmdlets. For publishing scripts and modules, it uses the .NET CLI command dotnet nuget push after wrapping them in a nupkg archive.

Summary

In light of the above, we can now answer the four points in the question:

  1. The PSRepository is a custom object and wrapper for a PackageSource; it stores a string property called PackageManagementProvider which can be used with Get-PackageProvider to access the PackageProvider object.
  2. PSRepository objects have custom properties that allow for different URIs for modules, scripts, retrieving and publishing.These are SourceLocation and PublishLocation for modules, and ScriptSourceLocation and ScriptPublishLocation for scripts.
  3. PowerShellGet uses the PackageManagement framework in the background, so every PSRepository has a matching PackageSource used in backend operations.
  4. The PowerShellGet module registers itself as a PackageProvider in its manifest, in order to interact with the framework and provide the customised functionality that it does. It also interacts with the NuGet PackageProvider.

In short, when you're dealing with software packages outside of PowerShell, you work directly with the PackageManagement framework. When you're dealing with modules and scripts for PowerShell, you work with PowerShellGet, which gives you abstracted access to the framework and NuGet.

Sources: