Is there an easy way to pass version as a parameter to Get-Module
?
I have two different versions of Azure PowerShell installed:
C:\WINDOWS\system32> get-module -name azure -listavailable
Directory: C:\Program Files\WindowsPowerShell\Modules\...
ModuleType Version Name
---------- ------- ----
Manifest 1.0.4 Azure
Directory: C:\Program Files (x86)\Microsoft SDKs\Azure\...
ModuleType Version Name
---------- ------- ----
Manifest 1.0.2 Azure
And I wish to remove one of them using a command like:
Get-Module -name azure -version 1.0.2 | remove-module
Please see: get-help Remove-Module -full
-FullyQualifiedName [<String[]>]
Removes modules with names that are specified in the form of
ModuleSpecification objects (described by the Remarks section of Module
Specification Constructor (Hashtable) on MSDN). For example, the
FullyQualifiedName parameter accepts a module name that is specified in the
format @{ModuleName = "modulename"; ModuleVersion = "version_number"} or
@{ModuleName = "modulename"; ModuleVersion = "version_number"; Guid =
"GUID"}. ModuleName and ModuleVersion are required, but Guid is optional.
You cannot specify the FullyQualifiedName parameter in the same command as a
Name parameter; the two parameters are mutually exclusive.
Notice:
FullyQualifiedName parameter accepts a module name that is specified in the format @{ModuleName = "modulename"; ModuleVersion = "version_number"}
Based on that, the following should be what you are after:
Remove-Module -FullyQualifiedName @{ModuleName = "Azure"; ModuleVersion = "1.0.2"}
Improved Answer (edit)
Did more investigation on this, and there are some quirks when removing using ModuleVersion
(which can be a string
or a [version]
).
If you specify ModuleVersion
, Remove-Module
will remove all matching modules with that version and greater.
To get an explicit match, you must also pass the guid
.
Get-Module 'Azure' | where {([string]($_.Version)).StartsWith('1.0.2')} | Remove-Module
Since that is a lot to type, I suggest adding a function to your profile to make this easier.
function Remove-ModuleWithVersion
{
param (
[Parameter(Mandatory=$true)]
[string]
$Module,
[Parameter(Mandatory=$true)]
[string]
$VersionToMatch
)
Get-Module $Module | where {([string]($_.Version)).StartsWith($VersionToMatch)} | Remove-Module -Verbose
}
and call like:
Remove-ModuleWithVersion 'Azure' '1.0.2'
Testing and analysis
I might as well share how I tested this to arrive at my conclusion. I will leave some details to the reader for self-investigation...
Create two modules, and export a function from each, using different function names to make testing easier.
D:\test\modtest\v1\ModTest.psd1 with version 1.1.0.1
D:\test\modtest\v1\ModTest.psm1
function Show-Hello1
{
"Hello v1.1"
}
Export-ModuleMember -Function Show-Hello1
D:\test\modtest\v2\ModTest.psd1 with version 1.2.0.2
D:\test\modtest\v2\ModTest.psm1
function Show-Hello2
{
"Hello v1.2"
}
Export-ModuleMember -Function Show-Hello2
Create a function to load the modules, call exported functions, show modules before, remove a module using the parameters specified, show modules after.
function Invoke-LoadAndRemove($minor, $useString, $guid = $null)
{
"`n------`n$($minor), $($useString), '$($guid)'"
"`nimport modules..."
ipmo D:\test\modtest\v1\ModTest.psd1 -Force #-Verbose
ipmo D:\test\modtest\v2\ModTest.psd1 -Force #-Verbose
"call exported functions..."
Show-Hello1
Show-Hello2
"modules before..."
Get-Module *mod*
if ($useString)
{
$ver = "1.$minor.0.$minor"
}
else
{
$ver = [version]::new(1, $minor, 0, $minor)
}
"`nremoving version: $ver, -> $($ver.GetType()), useGuid=$($useGuid)"
if ($useGuid)
{
Remove-Module -FullyQualifiedName @{ModuleName = "ModTest"; ModuleVersion = $ver} -Verbose
}
else
{
Remove-Module -FullyQualifiedName @{ModuleName = "ModTest"; ModuleVersion = $ver; Guid = $guid} -Verbose
}
"modules after..."
Get-Module *mod*
"done."
}
call various ways to demonstrate how Remove-Module works...
Invoke-LoadAndRemove 2 $true
Invoke-LoadAndRemove 1 $true
Invoke-LoadAndRemove 2 $false
Invoke-LoadAndRemove 1 $false
Invoke-LoadAndRemove 1 $false 'b213dea3-4ae3-4fde-a9c6-0ac4a8d1890c'
Invoke-LoadAndRemove 2 $true '02fdc44a-2c32-4f7b-8573-b1317b03269a'
This is the part, where I leave it to the reader to analyze the output further to verify the conclusions of this article.
That said, this was what I noticed that caused me to investigate further:
modules before...
Script 1.2.0.2 ModTest Show-Hello2
Script 1.1.0.1 ModTest Show-Hello1
removing version: 1.2.0.2, -> string, useGuid=
VERBOSE: Performing the operation "Remove-Module" on target "ModTest (Path: 'D:\test\modtest\v2\ModTest.psm1')".
VERBOSE: Removing the imported "Show-Hello2" function.
modules after...
Script 1.1.0.1 ModTest Show-Hello1
done.
------
modules before...
Script 1.2.0.2 ModTest Show-Hello2
Script 1.1.0.1 ModTest Show-Hello1
removing version: 1.1.0.1, -> string, useGuid=
VERBOSE: Performing the operation "Remove-Module" on target "ModTest (Path: 'D:\test\modtest\v2\ModTest.psm1')".
VERBOSE: Performing the operation "Remove-Module" on target "ModTest (Path: 'D:\test\modtest\v1\ModTest.psm1')".
VERBOSE: Removing the imported "Show-Hello2" function.
VERBOSE: Removing the imported "Show-Hello1" function.
modules after...
done.
Notice that when removing 1.2.0.2, it works as expected. When removing 1.1.0.1, both 1.1.0.1 and 1.2.0.2 are removed!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With