Проверка наличия обновлений для модулей PowerShell
Почему вообще важно обновлять модули?
Ответ достаточно очевидный. В IT области в целом быстро происходят изменения (буквально каждые несколько минут), и PowerShell в частности это тоже касается. Так что ваши модули PowerShell регулярно пополняются новыми функциями, опциями или просто исправлениями ошибок (новыми багами они само собой тоже пополняются). В модулях Microsoft 365/Entra/Graph в процессе обновлений например часто существенно меняются способы подключения и возможности командлетов.
В этом посте хотелось бы оставить небольшой скрипт, который поможет автоматизировать рутиную задачу по обновлению модулей.
Скрипт собирает список всех установленных модулей PowerShell в вашей системе (установленных из репозитория с помощью Install-Module) и проверяет, доступна ли более новая версия. Он извлекает информацию о 63 обновлениях одновременно, пока все модули не будут проверены на наличие более свежих версий. (Ограничение поиска PSGallery с использованием Find-Module). Если да, он добавит его в список и отобразит в конце скрипта.
Вы можете использовать параметр -NameFilter для поиска только определенных модулей. (Если вы отфильтруете то, чего не существует, появится предупреждение.)
Например, команда ниже будет искать только все модули Graph
Graph: PS C:\Scripts> .\Find-ModuleUpdates.ps1 -NameFilter *Graph*
Примечание. Это может занять некоторое время, если у вас установлено много модулей!
Запуск скрипта
В примере ниже, запускаем скрипт Find-ModuleUpdates.ps1 из c:\scripts:
PS C:\Scripts> .\Find-ModuleUpdates.ps1

В процессе поиска обновлений скрипт демонстрирует информативный прогресс-бар, и дальше если обновления обнаружены, покажет информацию о них.
Например здесь нам доступны обновления для семи модулей.
А вот так выглядит результат работы, в котором доступные обновления не найдены:

Скрипт
# Parameter for filtering modules for specific pattern, e.g. *Graph*
param (
[Parameter(Mandatory = $false)][string]$NameFilter = '*'
)
#Retrieve all installed modules
Write-Host ("Retrieving installed PowerShell modules") -ForegroundColor Green
$InstalledModules = Get-InstalledModule -Name $NameFilter -ErrorAction SilentlyContinue
#Retrieve current versions of modules (63 at a time because of PSGallery limit) if $InstalledModules is greater than 0
if ($InstalledModules.Count -gt 0) {
$startnumber = 0
$endnumber = 62
$onlineversions = $null
while ($InstalledModules.Count -gt $onlineversions.Count) {
Write-Host ("Checking online versions for installed modules [{0}..{1}/{2}]" -f $startnumber, $endnumber, $InstalledModules.Count) -ForegroundColor Green
$currentversions = Find-Module -Name $InstalledModules.name[$startnumber..$endnumber]
$startnumber = $startnumber + 63
$endnumber = $endnumber + 63
$onlineversions = $onlineversions + $currentversions
}
}
else {
Write-Warning ("No modules were found to check for updates, please check your NameFilter. Exiting...")
return
}
#Loop through all modules and check for newer versions and add those to $total
$number = 1
Write-Host ("Checking for updated versions") -ForegroundColor Green
$total = foreach ($module in $InstalledModules) {
Write-Progress ("[{0}/{1} Checking module {2}" -f $number, $InstalledModules.count, $module.name)
try {
$PsgalleryModule = $onlineversions | Where-Object name -eq $module.Name
if ([version]$module.version -lt [version]$PsgalleryModule.version) {
[PSCustomObject]@{
Repository = $module.Repository
'Module name' = $module.Name
'Installed version' = $module.Version
'Latest version' = $PsgalleryModule.version
'Published on' = $PsgalleryModule.PublishedDate
}
}
}
catch {
Write-Warning ("Could not find module {0}" -f $module.Name)
}
$number++
}
#Output $total to display updates for installed modules if any
if ($total.Count -gt 0) {
Write-Host ("Found {0} updated modules" -f $total.Count) -ForegroundColor Green
$total | Format-Table -AutoSize
}
else {
Write-Host ("No updated modules were found")
}