InstallLatestModule.psm1
Function Install-LatestModule { <# .SYNOPSIS This function will install and update module to latest version .DESCRIPTION The function will install and update module to latest version under system context .PARAMETER Name Specify the name of the module .PARAMETER All Will scan for all modules install under C:\Program Files\WindowsPowerShell\Modules and attempt to update them .PARAMETER Force Will reinstall modules no matter if the module is at the latest version .PARAMETER AllowImport After installation of module; it will import it for use within powershell session .EXAMPLE Install-LatestModule -All Example will update all modules installed under C:\Program Files\WindowsPowerShell\Modules .EXAMPLE Install-LatestModule -Name AzureAD Example will scan for module AzureAD and check its version. it will update if older than PSGallewries latest version .EXAMPLE Install-LatestModule -Name Az.Accounts,Az.Resources,Microsoft.Graph.Intune Example will scan for 3 modules and check its version. it will update if older than PSGallery's latest version .EXAMPLE Install-LatestModule -Name AzureAD -Force Example will scan for module AzureAD and check its version. If the version is already up-to-date; Force will reinstall it .EXAMPLE Get-Module -ListAvailable | Install-LatestModule Example will scan for all modules on device and install the latest for each if found #> [CmdletBinding(DefaultParameterSetName = 'NameParameterSet', HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=398573', SupportsShouldProcess = $true)] Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0, ParameterSetName = 'NameParameterSet')] [ValidateNotNullOrEmpty()] [string[]] $Name, [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'AllParameterSet')] [ValidateNotNullOrEmpty()] [switch] $All, [Parameter()] [switch] $Force, [Parameter()] [switch] $AllowImport ) Begin{ ## Get the name of this function [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name #build log name [string]$FileName = 'Modules_' + ${CmdletName} + '_' + (get-date -Format MM-dd-yyyy) + '.log' Start-Transcript -Path $env:TEMP\$FileName -Force -Append | Out-Null if (-not $PSBoundParameters.ContainsKey('Verbose')) { $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference') } if (-not $PSBoundParameters.ContainsKey('WhatIf')) { $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference') } [string]$ModuleName = $null $LatestModule = $null $ExistingModules = $null Write-Host ("{0} :: Checking {1} for latest installed modules [Press Ctrl+C to cancel]..." -f ${CmdletName},$UpdateFrequency) -ForegroundColor Gray #grab all version of the module installed $InstalledModules = Get-InstalledModule -ErrorAction SilentlyContinue $RefreshNeeded = $false } Process{ Try{ $psrepos = Get-PSRepository -ErrorAction Stop foreach($repo in $psrepos){ $RepoName = $repo.Name If($repo.InstallationPolicy -eq 'Untrusted'){ Set-PSRepository -Name $RepoName -InstallationPolicy Trusted } } } Catch{ $_.exception.message break } If($All){$name = $InstalledModules.name | Select -Unique} foreach ($item in $name) { #format out text Write-Host (" Searching for Module :: ") -ForegroundColor Gray -NoNewline Write-Host ("{0}" -f $item) -ForegroundColor White -NoNewline Write-Host ("...") -ForegroundColor Gray -NoNewline [string]$ModuleName = $item #$ExistingModules = $InstalledModules | Where-Object Name -eq $ModuleName $ExistingModules = Get-InstalledModule -Name $ModuleName -AllVersions -ErrorAction SilentlyContinue If($ExistingModules.count -gt 1){ Write-Host ("multiple versions found") -ForegroundColor Green -NoNewline } ElseIf($ExistingModules){ Write-Host ("[{0}] installed. " -f $ExistingModules.Version.ToString()) -ForegroundColor Green -NoNewline }Else{ Write-Host ("not found") -ForegroundColor Red } #if scheduled to check module, search for module online If($ExistingModules){ Write-Host ("Checking for the latest version...") -ForegroundColor Yellow } $LatestModule = Find-Module $ModuleName -ErrorAction SilentlyContinue #if latest module has been found online, proceed If($null -ne $LatestModule) { #ignore any versions installed, uninstall all and install latest Try { If($PSBoundParameters.ContainsKey('Force')) { Write-Host (" Uninstalling old module [{0}] and installing to latest [{1}]..." -f $ModuleName,$LatestModule.Version) -ForegroundColor Cyan -NoNewline $ExistingModules | Uninstall-Module -Force -ErrorAction Stop Install-Module $ModuleName -RequiredVersion $LatestModule.Version -Scope AllUsers -Force -SkipPublisherCheck -ErrorAction Stop -Verbose:$VerbosePreference Write-Host ("Completed") -ForegroundColor Green $RefreshNeeded = $true } Else { #if no moduels exist If($null -eq $ExistingModules) { Write-Host (" [{0}] is not installed, installing..." -f $ModuleName) -ForegroundColor Gray -NoNewline Install-Module $ModuleName -Scope AllUsers -Force -SkipPublisherCheck -AllowClobber -ErrorAction Stop -Verbose:$VerbosePreference Write-Host ("Installed") -ForegroundColor Green } #are there multiple of the same module installed? ElseIf( ($ExistingModules | Measure-Object).Count -gt 1) { If($LatestModule.Version -in $ExistingModules.Version) { Write-Host (" Latest Module found [{1}], Cleaning up older [{0}] modules..." -f $ModuleName,$LatestModule.Version.ToString()) -ForegroundColor Yellow -NoNewline #Check to see if latest module is installed already and uninstall anything older $ExistingModules | Where-Object Version -NotMatch $LatestModule.Version | Uninstall-Module -Force -ErrorAction Stop } Else { #uninstall all older Modules with that name, then install the latest Write-Host (" Uninstalling older [{0}] modules and installing the latest module version [{1}]..." -f $ModuleName,$LatestModule.Version.ToString()) -ForegroundColor Yellow -NoNewline Get-Module -FullyQualifiedName $ModuleName -ListAvailable | Uninstall-Module -Force -ErrorAction Stop Install-Module $ModuleName -RequiredVersion $LatestModule.Version -Scope AllUsers -AllowClobber -Force -SkipPublisherCheck -ErrorAction Stop -Verbose:$VerbosePreference } Write-Host ("done") -ForegroundColor Green $RefreshNeeded = $true } #if only one module exist but not the latest version ElseIf($ExistingModules.Version -ne $LatestModule.Version) { Write-Host (" Found newer version [{0}]..." -f $LatestModule.Version.ToString()) -ForegroundColor Cyan -NoNewline #Update module since it was found If($VerbosePreference){Write-Host ("Updating Module [{0}] from [{1}] to the latest version [{2}]..." -f $ModuleName,$ExistingModules.Version,$LatestModule.Version) -NoNewline -ForegroundColor Yellow} Try{ Update-Module $ModuleName -RequiredVersion $LatestModule.Version -Force -ErrorAction Stop -Verbose:$VerbosePreference } Catch{ #$_.Exception.GetType().FullName Install-Module $ModuleName -RequiredVersion $LatestModule.Version -Scope AllUsers -AllowClobber -Force -SkipPublisherCheck -ErrorAction Stop -Verbose:$VerbosePreference } Write-Host ("Updated") -ForegroundColor Green $RefreshNeeded = $true } Else { #No issue Write-Host (" Module [{0}] is at latest version [{1}]!" -f $ModuleName,$ExistingModules.Version) -ForegroundColor Green Continue } } } Catch { Write-Host (" Failed. Error: {0}" -f $_.Exception.Message) -ForegroundColor Red } Finally { If($AllowImport){ #importing module Write-Host (" Importing Module [{0}] for use..." -f $ModuleName) -ForegroundColor Green Import-Module -Name $ModuleName -Force:$force -Verbose:$VerbosePreference } } } Else{ If($VerbosePreference){Write-Host (" Module [{0}] does not exist, unable to update" -f $ModuleName) -ForegroundColor Red} } } #end of module loop } End{ If($VerbosePreference){Write-Host ("{0} :: Completed module check" -f ${CmdletName}) -ForegroundColor Gray} If($RefreshNeeded){Write-Host ("A restart of Powershell may be required to refresh module versions.") -ForegroundColor Magenta} Stop-Transcript | Out-Null } } Function Compare-LatestModule{ <# .SYNOPSIS This function will compare installed modules .DESCRIPTION The function will compare installed modules and output data .PARAMETER Name Specify the name of the module .EXAMPLE Compare-LatestModule -Name AzureAD Example will scan for module AzureAD on device in all locations and detemine if each one is at latest .EXAMPLE Compare-LatestModule -Name Az.Accounts,Az.Resources,Microsoft.Graph.Intune Example will scan for 3 modules on device in all locations and detemine if each one is at latest #> [CmdletBinding()] Param( [Parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true,Position=0)] [ValidateNotNullOrEmpty()] [string[]]$Name ) Begin{ ## Get the name of this function [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name $ModuleUpdateStatus = @() If($Name){ Write-Host ("{0} :: Retrieving modules [{1}]..." -f ${CmdletName}, ($name -join ,'')) $ExistingModules = Get-Module -Name $Name -ListAvailable } Else{ Write-Host ("{0} :: Retrieving online details for all modules, this can take a while..." -f ${CmdletName}) $ExistingModules = Get-Module -ListAvailable -All } } Process{ #TEST $Name = 'PSFramework' #TEST $Module = $ExistingModules[0] #TEST $Module = $ExistingModules[1] #TEST $Module = $ExistingModules[-1] Foreach($Module in $ExistingModules) { Write-Verbose ("{0} :: Checking status for installed module [{1}]: ..." -f ${CmdletName},$Module.Name) $ModuleDetails = '' | Select ModuleName,Location,Count,CurrentVersion,InstalledVersions,LatestRelease,UpToDate $AllModules = @() $AllModules = $ExistingModules | Where Name -eq $Name $LatestModule = Find-Module -Name $Module.Name If($Module.version -eq $LatestModule.Version){$Updated = $true}Else{$Updated = $false} $ModuleDetails.ModuleName = $Module.Name $ModuleDetails.Location = $Module.Path $ModuleDetails.Count = $AllModules.Count $ModuleDetails.CurrentVersion = $Module.Version $ModuleDetails.InstalledVersions = $AllModules.Version $ModuleDetails.LatestRelease = $LatestModule.Version $ModuleDetails.UpToDate = $Updated $ModuleUpdateStatus += $ModuleDetails } } End{ Write-Host ("{0} :: Status for {1} modules retrieved" -f ${CmdletName},$ModuleUpdateStatus.count) Return $ModuleUpdateStatus } } $exportModuleMemberParams = @{ Function = @( 'Install-LatestModule' 'Compare-LatestModule' ) } Export-ModuleMember @exportModuleMemberParams |