Get-Ryan

[Powershell] Update-UserInstalledModules

Sep 6th, 2022 (edited)
1,479
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PowerShell 5.87 KB | Source Code | 0 0
  1. [cmdletbinding()]
  2. param(
  3.     [Switch]
  4.     $UninstallOldVersions
  5. )
  6.  
  7. # Load required modules
  8. $requiredModules = @(
  9.     'PowerShellGet'
  10. )
  11. $modCheckFail = $false
  12. foreach ($modName in $requiredModules) {
  13.     if (!(Get-Module -Name $modName)) {
  14.         if (!(Get-Module -Name $modName -ListAvailable)) {
  15.             Write-Warning "'$modName' module required. Please install prior to running"
  16.             $modCheckFail = $true
  17.         }
  18.         else {
  19.             Import-Module -Name $modName
  20.         }
  21.     }
  22. }
  23. if ($modCheckFail) { Return }
  24.  
  25. # Validate required commands (failure may indicate too old a version of required modules)
  26. $requiredCommands = @(
  27.     'Find-Module',
  28.     'Get-InstalledModule',
  29.     'Install-Module',
  30.     'Uninstall-Module'
  31. )
  32. $cmdCheckFail = $false
  33. foreach ($cmdName in $requiredCommands) {
  34.     if (!(Get-Command -Name $cmdName -ErrorAction Ignore)) {
  35.         Write-Warning "Required command '$cmdName' not found after loading required modules"
  36.         $cmdCheckFail = $true
  37.     }
  38. }
  39. if ($cmdCheckFail) {
  40.     Write-Warning "Check you have the latest versions of all required modules"
  41.     foreach ($modName in $requiredModules) {
  42.         Write-Warning "$modName"
  43.     }
  44.     Return
  45. }
  46.  
  47. # Dependent functions
  48. function Test-VersionString {
  49.     [cmdletbinding()]
  50.     param(
  51.         [parameter(Mandatory = $true)]
  52.         [ValidateNotNullOrEmpty()]
  53.         [String]
  54.         $VersionString
  55.     )
  56.  
  57.     if ($VersionString -match '^[\d]+\.[\d]+\.[\d]+$') { $true }
  58.     if ($VersionString -match '^[\d]+\.[\d]+\.[\d]+\.[\d]+$') { $true }
  59.     else { $false }
  60. }
  61.  
  62. function Test-ModuleVersionPresent {
  63.     [cmdletbinding()]
  64.     param(
  65.         [parameter(Mandatory = $true)]
  66.         [ValidateNotNullOrEmpty()]
  67.         [String]
  68.         $ModuleName,
  69.  
  70.         [parameter(Mandatory = $true)]
  71.         [ValidateNotNullOrEmpty()]
  72.         [String]
  73.         $Version
  74.     )
  75.  
  76.     $list = [System.Collections.Generic.List[String]]::new()
  77.  
  78.     $moduleList = Get-Module -Name $ModuleName -ListAvailable
  79.  
  80.     foreach ($module in $moduleList) {
  81.         $list.Add($module.Version.ToString())
  82.     }
  83.  
  84.     if ($Version -in $list) { $true }
  85.     else { $false }
  86. }
  87.  
  88. # MAIN
  89. $installedModules = Get-InstalledModule
  90.  
  91. $x = 1
  92. foreach ($installedModule in $installedModules) {
  93.     Write-Progress -Activity 'Processing modules' -Status "($x/$($installedModules.Count)) - '$($installedModule.Name)'" -PercentComplete ($x/$installedModules.Count*100)
  94.  
  95.     $latestModule = Find-Module -Name $installedModule.Name -Repository $installedModule.Repository
  96.     if (!$latestModule) {
  97.         Write-Warning "Unable to find latest module '$($installedModule.Name)' at repository '$($installedModule.Repository)'. Skipping module."
  98.         Continue
  99.     }
  100.  
  101.     if (!(Test-VersionString -VersionString $installedModule.Version) -or !(Test-VersionString -VersionString $latestModule.Version)) {
  102.         Write-Warning "Unhandled version string syntax in source or latest module. Version must 4 segments of digits only. Skipping module."
  103.         Write-Warning "Source: '$($installedModule.Name)' - '$($installedModule.Version)' -- Latest: '$($latestModule.Name)' - '$($latestModule.Version)'"
  104.         Continue
  105.     }
  106.     else {
  107.         if ([System.Version]$installedModule.Version -lt [System.Version]$latestModule.Version) {
  108.             Write-Output "'$($installedModule.Name)' - Higher version '$($latestModule.Version)' found (local version '$($installedModule.Version)'). Installing."
  109.  
  110.             Install-Module -Name $installedModule.Name -Repository $installedModule.Repository -RequiredVersion $latestModule.Version -Scope CurrentUser -Force
  111.             if (!(Test-ModuleVersionPresent -ModuleName $installedModule.Name -Version $latestModule.Version)) {
  112.                 Write-Warning "'$($installedModule.Name)' - Latest version not found after installation attempt."
  113.                 if ($UninstallOldVersions) { Write-Warning "Uninstall of old versions will not proceed" }
  114.                 Continue
  115.             }
  116.             else {
  117.                 if ($UninstallOldVersions) {
  118.                     Write-Output "'$($installedModule.Name)' - Uninstalling old versions"
  119.  
  120.                     $installedModuleMatches = Get-Module -Name $installedModule.Name -ListAvailable
  121.  
  122.                     foreach ($moduleMatch in $installedModuleMatches) {
  123.                         if ($moduleMatch.Version.ToString() -eq $latestModule.Version) { Continue }
  124.                         else {
  125.                             Uninstall-Module -Name $moduleMatch.Name -RequiredVersion $moduleMatch.Version -Force
  126.                         }
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.         elseif ([System.Version]$installedModule.Version -eq [System.Version]$latestModule.Version) {
  132.             Write-Output "'$($installedModule.Name)' - Same version '$($latestModule.Version)' found (local version '$($installedModule.Version)'). Skipping install."
  133.            
  134.             if ($UninstallOldVersions) {
  135.                 Write-Output "'$($installedModule.Name)' - Uninstalling old versions"
  136.  
  137.                 $installedModuleMatches = Get-Module -Name $installedModule.Name -ListAvailable
  138.  
  139.                 foreach ($moduleMatch in $installedModuleMatches) {
  140.                     if ($moduleMatch.Version.ToString() -eq $latestModule.Version) { Continue }
  141.                     else {
  142.                         Uninstall-Module -Name $moduleMatch.Name -RequiredVersion $moduleMatch.Version -Force
  143.                     }
  144.                 }
  145.             }
  146.         }
  147.         elseif ([System.Version]$installedModule.Version -gt [System.Version]$latestModule.Version) {
  148.             Write-Warning "'$($installedModule.Name)' - Local version '$($installedModule.Version)' found as higher (repository version '$($latestModule.Version)'). No action taken due to anomaly."
  149.             Continue
  150.         }
  151.     }
  152.  
  153.     $x++
  154. }
Advertisement
Add Comment
Please, Sign In to add comment