Created
January 1, 2025 21:25
-
-
Save jorgeasaurus/e902a70bfa260176bba8b0d86b81299c to your computer and use it in GitHub Desktop.
Update PowerShell modules to their latest versions using PowerShell 7 parallel processing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 7.0 | |
<# | |
.SYNOPSIS | |
Updates PowerShell modules to their latest versions. | |
.DESCRIPTION | |
Updates all or specified PowerShell modules to their latest versions, with options for | |
prerelease versions and parallel processing. Automatically removes older versions after update. | |
.PARAMETER AllowPrerelease | |
If specified, allows updating to prerelease versions. | |
.PARAMETER Name | |
Specifies the names of modules to update. Defaults to '*' for all modules. | |
.PARAMETER WhatIf | |
Shows what would happen if the function runs without actually performing updates. | |
.PARAMETER ThrottleLimit | |
Maximum number of concurrent operations. Defaults to 5. | |
.EXAMPLE | |
Update-Modules | |
Updates all installed modules to their latest stable versions. | |
.EXAMPLE | |
Update-Modules -Name "Az" -AllowPrerelease | |
Updates the Az module to its latest version, including prereleases. | |
#> | |
function Update-Modules { | |
param ( | |
[switch]$AllowPrerelease, # Include prerelease versions in updates | |
[string]$Name = '*', # Module name filter, '*' for all modules | |
[switch]$WhatIf, # Preview changes without applying them | |
[int]$ThrottleLimit = 5 # Control parallel execution limit | |
) | |
# Initialize by getting all installed modules matching the name filter | |
Write-Host ("Retrieving all installed modules ...") -ForegroundColor Green | |
[array]$CurrentModules = Get-InstalledModule -Name $Name -ErrorAction SilentlyContinue | | |
Select-Object Name, Version, Repository | | |
Sort-Object Name | |
# Exit if no modules are found | |
if (-not $CurrentModules) { | |
Write-Host ("No modules found.") -ForegroundColor Gray | |
return | |
} | |
# Display initial status | |
Write-Host ("{0} modules found." -f $CurrentModules.Count) -ForegroundColor Gray | |
Write-Host ("Updating installed modules to the latest {0} version ..." -f $(if ($AllowPrerelease) { "PreRelease" } else { "Production" })) -ForegroundColor Green | |
# Store original versions for comparison in summary | |
$script:OldVersions = @{} | |
foreach ($Module in $CurrentModules) { | |
$script:OldVersions[$Module.Name] = $Module.Version | |
} | |
# Process updates in parallel for better performance | |
$CurrentModules | ForEach-Object -Parallel { | |
$Module = $_ | |
$AllowPrerelease = $using:AllowPrerelease | |
$WhatIf = $using:WhatIf | |
try { | |
# Find the latest available version | |
$findParams = @{ | |
Name = $Module.Name | |
AllowPrerelease = $AllowPrerelease | |
ErrorAction = 'Stop' | |
} | |
$latest = Find-Module @findParams | Select-Object -First 1 | |
# Update only if a newer version is available | |
if ($latest.Version -and $Module.Version -and ([version]$latest.Version -gt [version]$Module.Version)) { | |
$updateParams = @{ | |
Name = $Module.Name | |
AllowPrerelease = $AllowPrerelease | |
AcceptLicense = $true | |
Force = $true | |
WhatIf = $WhatIf | |
ErrorAction = 'Stop' | |
} | |
Update-Module @updateParams | |
Write-Host ("Updated {0} from version {1} to {2}" -f $Module.Name, $Module.Version, $latest.Version) -ForegroundColor Yellow | |
# Remove older versions to save disk space | |
if (-not $WhatIf) { | |
$AllVersions = Get-InstalledModule -Name $Module.Name -AllVersions | Sort-Object PublishedDate -Descending | |
foreach ($Version in $AllVersions | Select-Object -Skip 1) { | |
try { | |
Uninstall-Module -Name $Module.Name -RequiredVersion $Version.Version -Force -ErrorAction Stop | |
Write-Host ("Uninstalled older version {0} of {1}" -f $Version.Version, $Module.Name) -ForegroundColor Gray | |
} catch { | |
Write-Warning ("Failed to uninstall version {0} of {1}: {2}" -f $Version.Version, $Module.Name, $_.Exception.Message) | |
} | |
} | |
} | |
} else { | |
Write-Host ("{0} is up to date (version {1})" -f $Module.Name, $Module.Version) -ForegroundColor Cyan | |
} | |
} catch { | |
Write-Warning ("{0}: {1}" -f $Module.Name, $_.Exception.Message) | |
} | |
} -ThrottleLimit $ThrottleLimit | |
# Generate summary report of all updates | |
if (-not $WhatIf) { | |
$NewModules = Get-InstalledModule -Name $Name -ErrorAction SilentlyContinue | | |
Select-Object Name, Version | | |
Sort-Object Name | |
# Compare new versions with original versions | |
$UpdatedModules = $NewModules | Where-Object { | |
$script:OldVersions[$_.Name] -ne $_.Version | |
} | |
# Display summary of changes | |
if ($UpdatedModules) { | |
Write-Host "`nUpdated modules:" -ForegroundColor Green | |
foreach ($Module in $UpdatedModules) { | |
Write-Host ("- {0}: {1} -> {2}" -f $Module.Name, $script:OldVersions[$Module.Name], $Module.Version) -ForegroundColor Green | |
} | |
} else { | |
Write-Host "`nNo modules were updated." -ForegroundColor Gray | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment