Using Azure DevOps for Your Company’s Private PowerShell Library
Full Disclosure: This article is based off a project I was assigned at work and is the collection of a lot of research through the process. This article serves as a single document to collect my solution, their solutions and many trials and tribulations.
This article assumes that you have two things:
- The NuGet CLI — https://docs.microsoft.com/en-us/nuget/tools/nuget-exe-cli-reference
- A VSTS account — https://visualstudio.microsoft.com/team-services/
The Problem:
Systems Administrators and Developers (some would say the line is shrinking) develop PowerShell Modules and Scripts to automate processes within their multiple environments. Some groups will work with a single, monolithic, run book (.psm1). Others will work with a folder full of individual script files(.ps1). Either way, what good are these tools if they are not shared with other developers and administrators throughout the company to be able to work and be more efficient.
The Start:
VSTS is a powerful tool that offers the ability for enterprises to host their private projects within a single teams-based environment. Through VSTS, developers have access to not only version control, but also the ability to create an entire development pipeline within the same domain for every project. Developers also enjoy the wide range of third party tools to configure the multiple environments and central dashboards to display curucial project information (build history, bug count, links to the multiple environments, branch history, etc.).
What some may not know is that VSTS also allows for subscribers to create their own PRIVATE NuGet package repository right within VSTS. This service is called Package Manger and it will be the solution to the problem above.
Creating the Pipeline:
This tutorial assumes that you already have an account within VSTS.
- To begin, you will need to have command line access to VSTS. To access your security tokens, login to VSTS
- At the top right corner of the browser, click on your initials. In the dropdown menu click on “Security”
- Within the new security page, there is a modal in the middle of the page. This will show all of the keys that you have to get to VSTS. Click on the “ADD” icon in the middle of the page.
- The add icon brings you to a configuration page
- Description — The name of the set of keys you are going to create.
- You can leave the expiration and the accounts portion
- Click “Create Token” at the bottom of the page
If done correctly, the key value will be stored in the middle of the page. This value is only shown once. Copy and paste this value into a separate document. You will only need the keys value, so you can store the value in what ever file type you want.
Creating the Feed
Before we continue to the magical side of VSTS, we have to make sure that we have Package Manager access.
- Login to VSTS.
- Within VSTS, go to Builds and Releases. This should bring a dropdown. If you see “Packages” as an option within the dropdown, continue to “Connecting to the Powershell Repo”.
- If you do not see Packages within the dropdown you will need to install Package Management and make sure you have Package Management extensions enabled. The Package Management extension can be found here.
- With the proper permissions and the Package Management extension installed, if you go back to the Builds and Releases dropdown, “Packages” will be an option.
- We are now ready to create out first NuGet feed.
Creating the Feed
A feed is a central repository for your private NuGet packages. Each feed has many packages. We will need to create a feed such that we have a place to store our packages, which will be our Powershell Modules.
- At the top left corner of the page, click Add Feed.
- Add Feed will bring you to a creation page. This will take a title, a project and two questions regarding if you want to use external packages and who can access the new feed.
- Upon clicking “Create”, it will bring you to a modal that will show us how to connect to our new feed.
Creating and Packaging a Module
These next steps will be using a simple Get-Hello script that simply says “Hello from my VSTS Package.” If you are unfamiliar with Powershell, the below code will get you what you want. Create a folder with the name Get-Hello. Within that folder create a Get-Hello.psm1 file and within that file paste this:
Function Get-Hello{Write-Host "Hello from My VSTS Package
}
- Within the same Directory as our PowerShell Module, we need to create a module manifest. We can do this by creating a Get-Hello.psd1 file and then running.
New-ModuleManifest -Path .\Get-Hello.psd1
- This will write the manifest within the file specified.
- Within this new file, find the “Nested Modules” field. Within that field place the path to your Get-Hello.psm1 file. We can also put this within the Root-Module section of our new manifest. If we were to want to package different script files, we could add these to the FunctionsToExport section of our module.
- A KEY PART HERE: WE NEED THE VERSION NUMBER TO HAVE 3 PLACES. (EX: 0.0.1) THIS IS DUE TO NuGet AND ITS PACKAGING SPECS
2. We now have a module and its manifest and we are ready to package it and send it. Within PowerShell, run:
nuget spec Get-Hello
- The spec command will create a Get-Hello.nuspec file. This specifies the information that NuGet needs when we package our module in the next few steps.
- There are two key things we need to do to this file:
- The version number on the Module Manifest and the version number on the .nuspec file MUST BE THE SAME.
- By default, if we leave the sample dependencies, NuGet will install jQuery, we should take that out. Here is what mine looks like:
<?xml version="1.0"?>
<package >
<metadata>
<id>Get-Hello</id>
<version>0.0.2</version>
<authors>jrice1</authors>
<owners>jrice1</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>The module says hello to the user</description>
<releaseNotes>This is the newest I know of.</releaseNotes>
<copyright>Copyright 2018</copyright>
<tags>Justin Rice</tags>
<dependencies>
</dependencies>
</metadata>
</package>
3. With the module made and the spec file ready to go, we need to pack it up and ship it out. Run the following commands from PowerShell:
# Packages the module with the defined parameters within the nuspec file
nuget pack Get-Hello.nuspec#Add the VSTS repo as a source for NuGet
nuget.exe sources Add -Name "PowershellModules" -Source "https://MyOrganization.pkgs.visualstudio.com/_packaging/PowershellModules/nuget/v2"#Push the file to the NuGet Feed. Change the name of the .nupkg file
nuget.exe push -Source "PowershellModules" -ApiKey VSTS Get-Hello.nupkg
After the nuget.exe push command, PowerShell will ask you for your credentials. The first is a username which is not tied to anything. The second is the password. You can copy and paste your VSTS access key from before. Upon entering your access key, our module is now able to be installed from our feed in VSTS. Excellent!
Connecting to the Feed as a Powershell Repo
Wow cool! We now have a private repository within VSTS that we can push our Powershell Modules to and we have a module that we can install. In the, next step we will connect Powershell to our new VSTS feed so we can publish our modules and install modules published from others on our team.
- Open a Powershell session as an Administrator.
- Run the following command within Powershell:
Register-PSRepository -Name "PowershellVSTS" -SourceLocation "https://MyOrganization.pkgs.visualstudio.com/_packaging/PowershellModules/nuget/v2" -PublishLocation "https://MyOrganization.pkgs.visualstudio.com/_packaging/PowershellModules/nuget/v2" -InstallationPolicy Trusted
- You will notice above that the Publish and Source location both reference Version 2 of NuGet. At the time of writing this article, there were some discrepancies that would happen with Version 3 of NuGet.
- The script above create a new Powershell Repository named PowershellVSTS and sets the Publish and Source Location as the links to the NuGet feed. This link can also be found by clicking on “Connect to Feed” within the feeds page.
4. We can confirm that we now have a new repository by running:
Get-PSRepository
5. We now have a personal repository set up, but we will need credentials to be able to access it. It is private after all. Within Powershell, run the following:
$password = ConvertTo-SecureString 'YOUR PERSONAL ACCESS TOKEN FROM THE CREATING THE PIPELINE STEP' -AsPlainText -Force
$credsVSTS = New-Object System.Management.Automation.PSCredential 'YOUR EMAIL FOR VSTS', $password
The following script takes in your Personal access token and then uses it within a PSCredential opbject which we will use to securely access our new feed.
6. Lets see what we can install from this feed:
Find-Module * -Repository PowershellVSTS -Credential $credsVSTS
Wow, now we can see our Get-Hello module and install it!
Install-Module Get-Hello -Repository PowershellVSTS -Credential $credsVSTS
Get-Modules -ListAvailable Get-Hello
We now have a repository that pulls down NuGet packages with our Powershell Modules and scripts that we can have version control, access management and best of all, available to all our other developers!!
Sources: https://roadtoalm.com/2017/05/02/using-vsts-package-management-as-a-private-powershell-gallery/