Table of Contents
So you have become quite experienced in writing Powershell scripts and modules. You are ready to share your code with the rest of the world, or perhaps you have created a script that you want to be able to download from the internet, on any computer running Powershell. Well, then you might want to look into publishing your code on The PowerShell Gallery.
The PowerShell Gallery is Powershell Repository hosted on the internet, with Powershell content available for everybody to download and use. The content provided on the PowerShell Gallery might be authored by Microsoft but it might also be somebody who just wants to share his code.
The PowerShell Gallery is registered as the default Repository when you install Powershell 7, or on any Windows PC running Windows Powershell. To see this you can easily open your Powershell terminal and run the following command:
Name InstallationPolicy SourceLocation ---- ------------------ -------------- PSGallery Untrusted https://www.powershellgallery.com/api/v2
Here you can see the URL of the PowerShell Gallery and you can see that it is listed as an Untrusted Repository.
Why is it ‘Untrusted?’
Well since anybody can publish code on the PowerShell Gallery, you cannot be 100% sure that the code is secure. With that said, the Powershell Team at Microsoft has done a lot of enhancements and taken security measures to make sure that every module put onto the Gallery is getting scanned and checked by various PSSCriptAnalyzer Rules. Besides Microsoft’s effort to securing the Gallery, since everybody can download the code everyone can read through the code and check if everything is secure.
If you want to read more on how the Powershell Team at Microsoft is securing the PowerShell Gallery, you can read the blog post here: https://devblogs.microsoft.com/powershell/powershell-gallery-new-security-scan/
Get a login to the PowerShell Gallery
Now to get started publishing to the Powershell gallery, you will need to head over to their website: https://www.powershellgallery.com/. Here you can search for Powershell scripts and modules. For example, if you search for New-ModuleProject, you should see the Powershell Script I have created for starting up a new Module Project.
To get a login to the PowerShell Gallery, click on the ‘Sign in’ button in the top right corner. Click on Sign in with Microsoft. Now if you don’t have a Microsoft account you will need to go ahead and create it.
Once you have signed in or created a new Microsoft account, and then signed in, you will need to get an API Key to be able to publish modules to the Repository.
Creating an API Key to the PowerShell Gallery
The API Key is your personal secret which is used to authenticate yourself when publishing a package to the PowerShell Gallery. It is very important that you keep this API Key to yourself since anybody with this key will be able to publish code to the Repository as if it was you.
Now to Create a new API Key click on your profile name in the top right corner and click on ‘API Keys’
Now you can click on the ‘+ Create’ button to create your new API Key.
Once the API Key is generated I highly recommend you to save the key in some sort of secure password manager.
Now in case you lose your API Key, or it somehow gets compromised you can always either delete your key or generate a new one.
Creating and publishing your first script to the PowerShell Gallery
Now if you want to learn how to get a good start with a new Module I strongly recommend you read my post https://scriptingchris.tech/2021/05/07/how-to-write-a-powershell-module/
But for now, we are just going to create a simple .ps1 script and publish it to the PowerShell Gallery.
So When publishing to the Powershell gallery your script or module needs to have some specific metadata applied to it, for the Gallery to know how to handle your script.
Basically, for a PowerShell module, you will need to use the cmdlet New-ModuleManist, to generate a .psd1 file that will contain all the metadata for your Powershell module.
And for a Powershell script, you can use the cmdlet New-ScriptFileInfo.
In both cases the most important elements to fill in the metadata files generated from these cmdlets are:
– Script or Module Name – Those are drawn from the names of the .PS1 for a script, or the .PSD1 for a module
– Version – this is a required primary key, the format should follow SemVer guidelines. See Best Practices for details.
– Author – this is a required primary key, and contains the name to be associated with the item. See Authors and Owners below.
– Description – this is a required primary key, used to briefly explain what this item does and any requirements for using it
– ProjectURI – this is a strongly recommended URI field in PSData that provides a link to a Github repo or similar location where you do development on the item
Now if you want to read more about Creating and Publishing packages, you can read about it on the Microsoft Docs: https://docs.microsoft.com/en-gb/powershell/scripting/gallery/how-to/publishing-packages/publishing-a-package?view=powershell-7.1
Creating the new script
So to create the script to publish on the PowerShell Gallery I will run the following command:
New-ScriptFileInfo -Path ./New-TestScript.ps1 -Description "This is just my test script"
Now the first time you open the file it should look something similar to this:
<#PSScriptInfo .VERSION 1.0 .GUID ef52a095-71a6-4748-8886-601a3149242b .AUTHOR Chris .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION This is just my test script #> Param()
So for the author, the script will automatically enter the username, which you are logged in to your computer with. The description was also filled from when calling the cmdlet.
You can go ahead and fill in the metadata you need. In my case I will fill in the following:
.VERSION 1.0.0 .AUTHOR Chris .COMPANYNAME ScriptingCHris .COPYRIGHT Copyright (c) 2021 ScriptingChris .RELEASENOTES My First Release <# .DESCRIPTION This is just my test script #>
Make a note of the Version. Because you are actually publishing a NuGet package you will need to provide the version in the format of x.x.x instead of x.x.
Now for the actual script, I will enter the following:
Param( [Parameter(Mandatory=$true)] [String]$Name ) Write-Output "Hello $($Name)"
Be sure to test your code before publishing anything!
./New-TestScript.ps1 -Name Chris
Publishing the script to the PowerShell Gallery
So to publish the script to the PowerShell Gallery is as simple as running the following command:
Publish-Script -Path ./New-TestScript.ps1 -NuGetApiKey $PSGalleryApiKey
Where I have stored my PowerShell Gallery API Key in the Variable $PSGalleryApiKey
Now if you experience an error similar to below:
Failed to publish script 'New-TestScript': 'The underlying connection was closed: An unexpected error occurred on a send.
There might be one of two possible problems.
The first problem might be that your system runs Tls11 instead of Tls12, to fix this run the following command:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
The second problem might be that your PowerShellGet Module is not up to date. To fix this you can run the following command and restart your Powershell terminal.
Install-Module PowerShellGet -Force -AllowClobber
Checking that everything worked
To make sure that everything worked go to the website https://www.powershellgallery.com/ and log in with your Microsoft account. If you click on your Username in the top right corner and the ‘Manage Packages’, then click on ‘Published Packages’ here you should see the Script you just uploaded.
The last way we can check that it worked is through Powershell. To do this open a Powershell terminal and run the following command:
Find-Script New-TestScript | Select Name, Version, Description, Author | ft
Name Version Description Author ---- ------- ----------- ------ New-TestScript 1.0.0 This is just my test script Chris