#requires -version 5.0 # https://gist.github.com/jdhitsolutions/7217ed9293f18e8d454e3f88ecb38b67 Function Compare-Module { <# .Synopsis Compare module versions. .Description Use this command to compare module versions between what is installed against an online repository like the PSGallery. Results will be automatically sorted by module name. .Parameter Name The name of a module to check. Wildcards are permitted. .Notes Version: 1.2 Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/ .Example PS C:\> Compare-Module | Where-objject {$_.UpdateNeeded} Name : Azure OnlineVersion : 1.5.1 InstalledVersion : 1.0.4 PublishedDate : 6/27/2016 6:50:11 PM UpdateNeeded : True Name : Azure.Storage OnlineVersion : 1.1.4 InstalledVersion : 1.0.4 PublishedDate : 6/27/2016 6:48:07 PM UpdateNeeded : True Name : AzureRM OnlineVersion : 1.5.1 InstalledVersion : 1.2.0 PublishedDate : 6/27/2016 7:08:50 PM UpdateNeeded : True ... .Example PS C:\> Compare-Module | Where UpdateNeeded | Out-Gridview -title "Select modules to update" -outputMode multiple | Foreach { Update-Module $_.name } Compare modules and send results to Out-Gridview. Use Out-Gridview as an object picker to decide what modules to update. .Example PS C:\> compare-module -name xWindows* | format-table Name OnlineVersion InstalledVersion PublishedDate UpdateNeeded ---- ------------- ---------------- ------------- ------------ xWindowsEventForwarding 1.0.0.0 1.0.0.0 6/17/2015 9:46:32 PM False xWindowsRestore 1.0.0 1.0.0 12/18/2014 4:22:42 AM False xWindowsUpdate 2.5.0.0 2.3.0.0 5/18/2016 11:02:47 PM True Compare all modules that start with xWindows and display results in a table format. .Example PS C:\> get-dscresource cAD* | Select moduleName -Unique | compare-module Name : cActiveDirectory OnlineVersion : 1.1.1 InstalledVersion : 1.0.1 PublishedDate : 6/23/2015 9:24:55 PM UpdateNeeded : True Get all DSC Resources that start with cAD and select the corresponding module name. Since the module name will be listed for every resource, get a unique list and pipe that to Compare-Module. .Link Find-Module .Link Get-Module .Link Update-Module .Inputs [string] .Outputs [PSCustomObject] #> [cmdletbinding()] [alias("cmo")] Param ( [Parameter( Position = 0, ValueFromPipelineByPropertyName )] [ValidateNotNullorEmpty()] [Alias("modulename")] [string]$Name, [ValidateNotNullorEmpty()] [string]$Gallery = "PSGallery" ) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" $progParam = @{ Activity = $MyInvocation.MyCommand Status = "Getting installed modules" CurrentOperation = "Get-Module -ListAvailable" PercentComplete = 25 } Write-Progress @progParam } #begin Process { $gmoParams = @{ ListAvailable = $True } if ($Name) { $gmoParams.Add("Name", $Name) } $installed = Get-Module @gmoParams if ($installed) { $progParam.Status = "Getting online modules" $progParam.CurrentOperation = "Find-Module -repository $Gallery" $progParam.PercentComplete = 50 Write-Progress @progParam $fmoParams = @{ Repository = $Gallery ErrorAction = "Stop" } if ($Name) { $fmoParams.Add("Name", $Name) } Try { $online = Find-Module @fmoParams } Catch { Write-Warning "Failed to find online module(s). $($_.Exception.message)" } $progParam.status = "Comparing $($installed.count) installed modules to $($online.count) online modules." $progParam.percentComplete = 80 Write-Progress @progParam $data = $online | Where-Object {$installed.name -contains $_.name} | Select-Object -property Name, @{Name = "OnlineVersion"; Expression = {$_.Version}}, @{Name = "InstalledVersion"; Expression = { #save the name from the incoming online object $name = $_.Name $installed.Where( {$_.name -eq $name}).Version -join ","} }, PublishedDate, @{Name = "UpdateNeeded"; Expression = { $name = $_.Name #there could me multiple versions installed $installedVersions = $installed.Where( {$_.name -eq $name}).Version | Sort-Object foreach ($item in $installedVersions) { If ([version]$_.Version -gt [version]$item) { $result = $True } else { $result = $False } } $result } } | Sort-Object -Property Name $progParam.PercentComplete = 100 $progParam.Completed = $True Write-Progress @progparam #write the results to the pipeline $data } else { Write-Warning "No local module or modules found" } } #Progress End { Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end } #close function