Automatically updating the version number in a PowerShell Module – How I do regex

I am presenting Continuous Delivery for your PowerShell Module to the PowerShell Gallery at PSDayUK in London. Go and register if you will be close to London on Friday 22nd September.

In 45 minutes we will

– Use Plaster to create our module framework
– Use GitHub for Version Control
– Use Pester to develop our module with TDD
– Use VSTS to Build, Test (with Pester) and Release our changes to the PowerShell Gallery

45 minutes will not give me much time to dive deep into what is done but I will release all of my code on GitHub.

One of the things I needed to accomplish was to update the version number in the module manifest file. I did this with some regex and this is how I achieved it.

I went to regex101.com and pasted in the contents of a module file into the test string box and start to work out what I need. I need the value after ModuleVersion = ‘ so I started like this

01 - regex101.png

Under the quick reference it has some explanations which will help you. Keep going until you have the correct value in the match information. In the image below you can see that it has a Group 1 in green which matches the value I want (0.9.13). There is also an explanation of how it has got there. This is what I shall use in the PowerShell script

01 - regex.png

Now we can go to PowerShell. First get the contents of the file

# get the contents of the module manifest file
try {
    $file = (Get-Content .\BeardAnalysis.psd1)
}
catch {
    Write-Error "Failed to Get-Content"
}

Then we use [regex]::matches() to get our value as shown below. I always like to write in the comments what the regex is doing so that I (or others) know what was intended. We also set the value to a type of Version. I reference the group 1 value that I saw in the website.

# Use RegEx to get the Version Number and set it as a version datatype
# \s* - between 0 and many whitespace
# ModuleVersion - literal
# \s - 1 whitespace
# = - literal
# \s - 1 whitespace
# ' - literal
# () - capture Group
# \d* - between 0 and many digits
# ' - literal
# \s* between 0 and many whitespace

[version]$Version = [regex]::matches($file, "\s*ModuleVersion\s=\s'(\d*.\d*.\d*)'\s*").groups[1].value

Next we need to add one to the version number

# Add one to the build of the version number
[version]$NewVersion = "{0}.{1}.{2}" -f $Version.Major, $Version.Minor, ($Version.Build + 1)

and then replace the value in the file, notice the Get-Content has braces around it

# Replace Old Version Number with New Version number in the file
try {
    (Get-Content .\BeardAnalysis.psd1) -replace $version, $NewVersion | Out-File .\BeardAnalysis.psd1
    Write-Output "Updated Module Version from $Version to $NewVersion"
}
catch {
$_
    Write-Error "failed to set file"
}

That’s how I do it and the process I use when I need regex!

Here is the full script

# get the contents of the module manifest file
try {
    $file = (Get-Content .\BeardAnalysis.psd1)
}
catch {
    Write-Error "Failed to Get-Content"
}

# Use RegEx to get the Version Number and set it as a version datatype
# \s* - between 0 and many whitespace
# ModuleVersion - literal
# \s - 1 whitespace
# = - literal
# \s - 1 whitespace
# ' - literal
# () - capture Group
# \d* - between 0 and many digits
# ' - literal
# \s* between 0 and many whitespace

[version]$Version = [regex]::matches($file, "\s*ModuleVersion\s=\s'(\d*.\d*.\d*)'\s*").groups[1].value
Write-Output "Old Version - $Version"

# Add one to the build of the version number
[version]$NewVersion = "{0}.{1}.{2}" -f $Version.Major, $Version.Minor, ($Version.Build + 1)
Write-Output "New Version - $NewVersion"

# Replace Old Version Number with New Version number in the file
try {
    (Get-Content .\BeardAnalysis.psd1) -replace $version, $NewVersion | Out-File .\BeardAnalysis.psd1
    Write-Output "Updated Module Version from $Version to $NewVersion"
}
catch {
$_
    Write-Error "failed to set file"
}

 

An easier way

My fabulous friend and MVP Ravikanth Chaganti has told me of a better way using Import-PowerShellDataFile

This command is available on PowerShell v5 and above. There is no need to use regex now 🙂 You can just get the manifest as an object and then use the Update-ModuleManifest to update the file

$manifest = Import-PowerShellDataFile .\BeardAnalysis.psd1 
[version]$version = $Manifest.ModuleVersion
# Add one to the build of the version number
[version]$NewVersion = "{0}.{1}.{2}" -f $Version.Major, $Version.Minor, ($Version.Build + 1) 
# Update the manifest file
Update-ModuleManifest -Path .\BeardAnalysis.psd1 -ModuleVersion $NewVersion