Punti chiave
- Aggiornare PowerShell automaticamente: Lo script automatizza l’aggiornamento di PowerShell alla versione 5.1 su versioni specifiche di Windows.
- Efficienza per i professionisti IT: Ideale per MSP e professionisti IT che gestiscono più sistemi, perché garantisce uniformità e risparmio di tempo.
- Controlli di compatibilità: Verifica automaticamente la compatibilità del sistema e impedisce l’esecuzione sui sistemi in cui è installato Exchange Server.
- Solida gestione degli errori: Lo script per aggiornare PowerShell include la gestione e il logging degli errori per aggiornamenti affidabili e tracciabili.
- Gestione dei prerequisiti: Identifica e installa i prerequisiti necessari, come gli aggiornamenti di .NET Framework, prima di aggiornare PowerShell.
- Personalizzabile e scalabile: Lo script per aggiornare PowerShell può essere modificato per ambienti specifici e scalabile su più sistemi.
- Misure di sicurezza: Si raccomanda di eseguire test in ambienti controllati e di assicurarsi di avere un backup disponibile prima della distribuzione dello script per aggiornare PowerShell.
- Potenziato con strumenti di gestione: Utilizza lo script per aggiornare PowerShell insieme a strumenti come NinjaOne per una gestione e un monitoraggio completi del sistema.
- Aggiornamento manuale e tramite script: Offre un processo di aggiornamento più affidabile ed efficiente rispetto ai metodi manuali tradizionali.
Background
PowerShell è uno strumento fondamentale nei moderni ambienti IT, in quanto offre una piattaforma versatile per automatizzare le attività e gestire i sistemi. Mantenere PowerShell aggiornato è essenziale per la sicurezza, la compatibilità e l’accesso a nuove funzionalità. In questo articolo analizzeremo uno script PowerShell specificamente progettato per aggiornare PowerShell alla versione 5.1, un’attività rilevante per molti professionisti IT e Managed Service Provider (MSP).
Lo script in questione permette di aggiornare PowerShell alla versione 5.1, automaticamente, su Windows Server 2012 R2 e Windows 8.1. Si tratta di un vantaggio significativo perché gli aggiornamenti manuali possono richiedere molto tempo e sono soggetti a errori. Per i professionisti IT e gli MSP che gestiscono più sistemi, uno script di questo tipo garantisce coerenza ed efficienza nella manutenzione dell’infrastruttura.
Lo script per aggiornare PowerShell alla versione 5.1:
#Requires -Version 2 <# .SYNOPSIS Upgrades PowerShell to version 5.1. .DESCRIPTION NOTICE - Multiple reboots may be required to continue with the install in the case where 3.0 is installed. This requires the user to log back in manually after the reboot before continuing. The script will upgrade powershell to 5.1 on the following OS' Windows Server 2012 R2 Windows 8.1 This script WILL NOT run if Exchange Server is installed! A log of this process is created in $env:Temp\upgrade_powershell.log This log can used to see how the script faired after an automatic reboot. .EXAMPLE -Restart PARAMETER: -Restart Restart even if a restart isn't required. .EXAMPLE # upgrade to 5.1 with defaults and manual login and reboots (No Parameters) .OUTPUTS None .NOTES Minium Supported OS: Windows 8.1, Server 2012 R2 Release Notes: Renamed script and added Script Variable support By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/it/condizioni-utilizzo/ Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA). #> [CmdletBinding()] Param( [string]$Version = "5.1", [switch]$ForceRestart = [System.Convert]::ToBoolean($env:ForceRestart) ) begin { # Modified version from: https://github.com/jborean93/ansible-windows/tree/master/scripts # # LICENSE: https://github.com/jborean93/ansible-windows/blob/master/LICENSE # MIT License # # Copyright (c) 2017 Jordan Borean # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. $ErrorActionPreference = 'Stop' if ([System.Management.Automation.ActionPreference]::SilentlyContinue -ne $VerbosePreference) { $VerbosePreference = "Continue" } if ([System.Convert]::ToBoolean($env:Verbose)) { $Verbose = $true } # Don't upgrade PowerShell if Exchange is installed, this needs manual intervention to not cause problems. if ($(Get-Service -Name MSExchangeServiceHost -ErrorAction SilentlyContinue) -or $(Get-Command Exsetup.exe -ErrorAction SilentlyContinue | ForEach-Object { $_.FileVersionInfo })) { Write-Host "Exchange looks to be installed. Aborting PowerShell upgrade." exit 1 } [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } $tmp_dir = $env:temp if (-not (Test-Path -Path $tmp_dir)) { New-Item -Path $tmp_dir -ItemType Directory > $null } Function Write-Log($message, $level = "INFO") { # Poor man's implementation of Log4Net $date_stamp = Get-Date -Format s $log_entry = "$date_stamp - $level - $message" $log_file = "$tmp_dir\upgrade_powershell.log" Write-Host -Message $log_entry Add-Content -Path $log_file -Value $log_entry } Function Invoke-Reboot { Write-Log -message "need to reboot server to continue powershell upgrade" shutdown.exe /r /t 30 } Function Invoke-RunProcess($executable, $arguments) { $process = New-Object -TypeName System.Diagnostics.Process $psi = $process.StartInfo $psi.FileName = $executable $psi.Arguments = $arguments Write-Log -message "starting new process '$executable $arguments'" $process.Start() | Out-Null $process.WaitForExit() | Out-Null $exit_code = $process.ExitCode Write-Log -message "process completed with exit code '$exit_code'" return $exit_code } Function Invoke-DownloadFile($url, $path) { Write-Log -message "downloading url '$url' to '$path'" $client = New-Object -TypeName System.Net.WebClient $client.DownloadFile($url, $path) } Write-Log -message "starting script" # on PS v1.0, upgrade to 2.0 and then run the script again if ($PSVersionTable -eq $null) { Write-Log -message "upgrading powershell v1.0 to v2.0" $architecture = $env:PROCESSOR_ARCHITECTURE if ($architecture -eq "AMD64") { $url = "https://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu" } else { $url = "https://download.microsoft.com/download/F/9/E/F9EF6ACB-2BA8-4845-9C10-85FC4A69B207/Windows6.0-KB968930-x86.msu" } $filename = $url.Split("/")[-1] $file = "$tmp_dir\$filename" Invoke-DownloadFile -url $url -path $file $exit_code = Invoke-RunProcess -executable $file -arguments "/quiet /norestart" if ($exit_code -ne 0 -and $exit_code -ne 3010) { $error_msg = "failed to update Powershell from 1.0 to 2.0: exit code $exit_code" Write-Log -message $error_msg -level "ERROR" throw $error_msg } Invoke-Reboot } # exit if the target version is the same as the actual version $current_ps_version = [version]"$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" if ($current_ps_version -eq [version]$Version) { Write-Log -message "current and target PS version are the same, no action is required" exit 0 } $os_version = [Version](Get-Item -Path "$env:SystemRoot\System32\kernel32.dll").VersionInfo.ProductVersion $architecture = $env:PROCESSOR_ARCHITECTURE if ($architecture -eq "AMD64") { $architecture = "x64" } else { $architecture = "x86" } } process { $actions = @() switch ($Version) { "5.1" { if ($os_version -lt [version]"6.3") { $error_msg = "cannot upgrade Server 2008 to Powershell v5.1, v3 is the latest supported" Write-Log -message $error_msg -level "ERROR" throw $error_msg } # check if WMF 3 is installed, need to be uninstalled before 5.1 if ($os_version.Minor -lt 2) { $wmf3_installed = Get-HotFix -Id "KB2506143" -ErrorAction SilentlyContinue if ($wmf3_installed) { $error_msg = "cannot upgrade to Powershell v5.1, this needs manual intervention." Write-Log -message $error_msg -level "ERROR" throw $error_msg } } $actions += "5.1" break } default { $error_msg = "version '$Version' is not supported in this upgrade script" Write-Log -message $error_msg -level "ERROR" throw $error_msg } } # detect if .NET 4.5.2 is not installed and add to the actions $dotnet_path = "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" if (-not $(Test-Path -Path $dotnet_path -ErrorAction SilentlyContinue)) { $dotnet_upgrade_needed = $true } else { $dotnet_version = Get-ItemProperty -Path $dotnet_path -Name Release -ErrorAction SilentlyContinue if ($dotnet_version) { # 379893 == 4.5.2 if ($dotnet_version.Release -lt 379893) { $dotnet_upgrade_needed = $true } } else { $dotnet_upgrade_needed = $true } } if ($dotnet_upgrade_needed) { $actions = @("dotnet") + $actions } Write-Log -message "The following actions will be performed: $($actions -join ", ")" foreach ($action in $actions) { $url = $null $file = $null $arguments = "/quiet /norestart" switch ($action) { "dotnet" { Write-Log -message "running .NET update to 4.5.2" $url = "https://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe" $error_msg = "failed to update .NET to 4.5.2" $arguments = "/q /norestart" break } "5.1" { Write-Log -message "running powershell update to version 5.1" if ($os_version.Minor -eq 2) { # Server 2012 $url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/W2K12-KB3191565-x64.msu" } else { # Server 2012 R2 and Windows 8.1 if ($architecture -eq "x64") { $url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1AndW2K12R2-KB3191564-x64.msu" } else { $url = "http://download.microsoft.com/download/6/F/5/6F5FF66C-6775-42B0-86C4-47D41F2DA187/Win8.1-KB3191564-x86.msu" } } break } default { $error_msg = "unknown action '$action'" Write-Log -message $error_msg -level "ERROR" } } if ($null -eq $file) { $filename = $url.Split("/")[-1] $file = "$tmp_dir\$filename" } if ($null -ne $url) { Invoke-DownloadFile -url $url -path $file } $exit_code = Invoke-RunProcess -executable $file -arguments $arguments if ($exit_code -ne 0 -and $exit_code -ne 3010) { $log_msg = "$($error_msg): exit code $exit_code" Write-Log -message $log_msg -level "ERROR" throw $log_msg } if ($exit_code -eq 3010) { $log_msg = "Reboot is required!" Write-Log -message $log_msg -level "WARN" break } } if ($ForceRestart) { Invoke-Reboot } } end { }
Accedi a oltre 700 script nel Dojo NinjaOne
Analisi dettagliata
Lo script per aggiornare PowerShell opera in diverse fasi:
- Preparazione e verifica: Inizia impostando le preferenze di gestione degli errori e verificando la presenza di Microsoft Exchange Server, poiché la sua presenza richiede un approccio di aggiornamento diverso.
- Logging iniziale: Quindi inizializza il logging per seguire i progressi dello script, particolarmente utile in ambienti in cui le attività automatiche vengono eseguite frequentemente.
- Verifica della versione di PowerShell: Lo script per aggiornare PowerShell controlla la versione corrente di PowerShell. Se è già 5.1, lo script esce perché non è necessario alcun aggiornamento.
- Controllo del sistema operativo e dell’architettura: Identifica il sistema operativo e l’architettura (x64 o x86) per determinare il pacchetto di aggiornamento corretto.
- Determinazione dell’azione: Lo script decide se aggiornare .NET Framework prima di aggiornare PowerShell, un prerequisito per la versione 5.1 di PowerShell.
- Scaricare e installare gli aggiornamenti: Quindi scarica e installa i pacchetti necessari, gestendo i riavvii se necessario.
- Opzione di riavvio forzato: Un parametro consente un riavvio forzato, se necessario, per garantire l’applicazione completa degli aggiornamenti.
Casi d’uso potenziali
Immagina un MSP responsabile della manutenzione di più ambienti di clienti. Potrebbe distribuire questo script per aggiornare PowerShell su vari sistemi, assicurandosi che tutti siano aggiornati alla stessa versione di PowerShell. Questa uniformità semplifica la gestione e riduce i problemi di compatibilità.
Confronti
Tradizionalmente, gli aggiornamenti di PowerShell possono essere eseguiti manualmente o tramite uno script batch. Questo script per aggiornare PowerShell offre un approccio più sofisticato con gestione degli errori, registrazione e controlli ambientali, riducendo il rischio di interruzioni o guasti.
Domande frequenti
D: Questo script per aggiornare PowerShell funziona su qualsiasi sistema operativo Windows?
R: No, è progettato per Windows Server 2012 R2 e Windows 8.1.
D: Cosa succede se è installato Microsoft Exchange Server?
R: Lo script non procederà con l’aggiornamento, poiché Exchange Server richiede un processo di aggiornamento diverso.
D: Posso usare questo script per aggiornare PowerShell a versioni diverse dalla 5.1?
R: Lo script è progettato in modo specifico per aggiornare PowerShell alla versione 5.1. Per le altre versioni sarebbero necessarie delle modifiche.
Implicazioni
L’uso di questo script per aggiornare PowerShell può migliorare notevolmente l’ efficienza IT, ma richiede un approccio attento. Un aggiornamento non corretto può causare l’instabilità del sistema. Esegui sempre dei test in un ambiente controllato prima di un’ampia diffusione.
Raccomandazioni
- Prima di tutto, effettua dei test: Esegui sempre lo script per aggiornare PowerShell in un ambiente di prova prima di distribuirlo su larga scala.
- Sistemi di backup: Assicurati che i backup del sistema siano aggiornati, per poterli usare in caso di guasto.
- Personalizza secondo le necessità: Se necessario, modifica lo script per aggiornare PowerShell in ambienti specifici.
- Monitora i log: Controlla regolarmente i log generati per individuare eventuali problemi o anomalie.
Considerazioni finali
Nel contesto della gestione semplificata dell’IT, strumenti come NinjaOne possono integrare script come quello per aggiornare PowerShell offrendo un controllo e un monitoraggio centralizzati. Le funzionalità di NinjaOne per la gestione degli aggiornamenti e il monitoraggio dell’integrità del sistema possono lavorare insieme agli script, migliorando l’efficienza e l’affidabilità IT complessiva. La combinazione di automazione tramite script e di un solido strumento di gestione come NinjaOne assicura che gli ambienti IT non solo siano aggiornati, ma anche costantemente monitorati e gestiti per ottenere le massime prestazioni.