Una guida completa: Come aggiornare PowerShell alla versione 5.1

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

Ottieni l’accesso

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.

Passi successivi

La creazione di un team IT efficiente ed efficace richiede una soluzione centralizzata che funga da principale strumento per la fornitura di servizi. NinjaOne consente ai team IT di monitorare, gestire, proteggere e supportare tutti i dispositivi, ovunque essi si trovino, senza la necessità di una complessa infrastruttura locale.

Per saperne di più sulla distribuzione remota di script con NinjaOne, fai un tour dal vivo, o inizia la tua prova gratuita della piattaforma NinjaOne.

Categorie:

Ti potrebbe interessare anche

×

Guarda NinjaOne in azione!

Inviando questo modulo, accetto La politica sulla privacy di NinjaOne.

Termini e condizioni NinjaOne

Cliccando sul pulsante “Accetto” qui sotto, dichiari di accettare i seguenti termini legali e le nostre condizioni d’uso:

  • Diritti di proprietà: NinjaOne possiede e continuerà a possedere tutti i diritti, i titoli e gli interessi relativi allo script (compreso il copyright). NinjaOne ti concede una licenza limitata per l’utilizzo dello script in conformità con i presenti termini legali.
  • Limitazione d’uso: Puoi utilizzare lo script solo per legittimi scopi personali o aziendali interni e non puoi condividere lo script con altri soggetti.
  • Divieto di ripubblicazione: In nessun caso ti è consentito ripubblicare lo script in una libreria di script appartenente o sotto il controllo di un altro fornitore di software.
  • Esclusione di garanzia: Lo script viene fornito “così com’è” e “come disponibile”, senza garanzie di alcun tipo. NinjaOne non promette né garantisce che lo script sia privo di difetti o che soddisfi le tue esigenze o aspettative specifiche.
  • Assunzione del rischio: L’uso che farai dello script è da intendersi a tuo rischio. Riconosci che l’utilizzo dello script comporta alcuni rischi intrinseci, che comprendi e sei pronto ad assumerti.
  • Rinuncia e liberatoria: Non riterrai NinjaOne responsabile di eventuali conseguenze negative o indesiderate derivanti dall’uso dello script e rinuncerai a qualsiasi diritto legale o di equità e a qualsiasi rivalsa nei confronti di NinjaOne in relazione all’uso dello script.
  • EULA: Se sei un cliente NinjaOne, l’uso dello script è soggetto al Contratto di licenza con l’utente finale (EULA) applicabile.