Le guide complet : Comment mettre à jour PowerShell vers PowerShell 5.1

Points à retenir

  • Mise à jour automatisée de PowerShell: Le script automatise la mise à jour vers PowerShell  5.1 sur des versions spécifiques de Windows.
  • Efficacité pour les professionnels de l’informatique: Idéal pour les entreprises MSP et les professionnels de l’informatique qui gèrent plusieurs systèmes, ce qui permet d’assurer l’uniformité et de gagner du temps.
  • Vérifications de la compatibilité: Vérifie automatiquement la compatibilité du système et empêche l’exécution sur les systèmes où Exchange Server est installé.
  • Gestion performante des erreurs: Comprend la gestion et la journalisation des erreurs pour permettre des mises à jour fiables et traçables.
  • Gestion des conditions préalablement nécessaires: Identifie et installe les prérequis nécessaires tels que les mises à jour de .NET Framework avant de mettre à jour PowerShell.
  • Personnalisable et évolutif: Peut être modifié pour des environnements spécifiques et peut être étendu à plusieurs systèmes.
  • Mesures de sécurité: Il est recommandé de le tester dans des environnements contrôlés et d’assurer des sauvegardes avant le déploiement.
  • Améliorée par des outils de gestion: A utiliser avec des outils tels que NinjaOne pour une gestion et une surveillance complètes du système.
  • Mise à jour par script VS. manuelle: Offre un processus de mise à jour plus fiable et plus efficace que les méthodes manuelles traditionnelles.

Contexte

PowerShell est un outil essentiel dans les environnements informatiques modernes, offrant une plateforme polyvalente pour l’automatisation des tâches et la gestion des systèmes. La mise à jour de PowerShell est essentielle pour la sécurité, la compatibilité et l’accès aux nouvelles fonctionnalités. Cet article se penche sur un script PowerShell spécialement conçu pour mettre à jour PowerShell vers la version 5.1, une tâche qui concerne de nombreux professionnels de l’informatique et fournisseurs de services gérés (MSP). 

Le script en question automatise la mise à niveau de PowerShell vers la version 5.1 sur Windows Server 2012 R2 et Windows 8.1. Il s’agit d’un grand atout, car les mises à jour manuelles peuvent prendre beaucoup de temps et être source d’erreurs. Pour les professionnels de l’informatique et les MSP qui gèrent plusieurs systèmes, un tel script garantit la consistance et l’efficacité de la maintenance de leur infrastructure.

Le script :

#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/fr/conditions-dutilisation
    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 {
    
    
    
}

 

Accédez à plus de 700 scripts dans le Dojo NinjaOne

Obtenir l’accès

Description détaillée

Le script opère en plusieurs étapes :

  • Préparation et vérification: Il commence par définir les préférences en matière de traitement des erreurs et vérifie la présence de Microsoft Exchange Server, qui nécessite une approche différente en matière de mise à jour.
  • Journalisation initiale: Il initialise ensuite la journalisation pour suivre la progression du script, ce qui est particulièrement utile dans les environnements où les tâches automatisées s’exécutent fréquemment.
  • Vérification de la version de PowerShell: Le script vérifie la version actuelle de PowerShell. S’il s’agit déjà de la version 5.1, le script s’arrête car aucune mise à jour n’est nécessaire.
  • Vérification du système d’exploitation et de l’architecture: Il identifie le système d’exploitation et l’architecture (x64 ou x86) pour déterminer le bon paquet de mise à jour.
  • Détermination de l’action: Le script décide s’il faut mettre à jour .NET Framework avant PowerShell, ce qui est indispensable pour PowerShell 5.1.
  • Téléchargement et installation des mises à jour: Il télécharge et installe ensuite les paquets nécessaires, en gérant les redémarrages si nécessaire.
  • Option de redémarrage forcé: Un paramètre permet un redémarrage forcé si nécessaire, garantissant que les mises à jour sont entièrement appliquées.

Cas d’utilisation potentiels

Prenons l’exemple d’une entreprise MSP chargée de la maintenance de plusieurs environnements de clients. Ils peuvent déployer ce script sur plusieurs systèmes, en veillant à ce que tous soient mis à jour avec la même version de PowerShell. Cette uniformité simplifie la gestion et réduit les problèmes de compatibilité.

Comparaisons

Traditionnellement, les mises à jour PowerShell peuvent être effectuées manuellement ou par le biais d’un script batch. Ce script PowerShell offre une approche plus sophistiquée avec la gestion des erreurs, la journalisation et les vérifications au niveau de l’environnement, réduisant ainsi le risque d’interruption ou de défaillance.

FAQ

Q : Ce script fonctionnera-t-il sur n’importe quel système d’exploitation Windows ?
R : Non, il est conçu pour Windows Server 2012 R2 et Windows 8.1.

Q : Que se passe-t-il si Microsoft Exchange Server est installé ?
R : Le script ne procédera pas à la mise à jour, car Exchange Server nécessite un processus de mise à jour différent.

Q : Puis-je utiliser ce script pour une mise à jour vers des versions autres que 5.1 ?
R : Le script actuel est spécialement conçu pour la mise à jour vers PowerShell 5.1. Des modifications seraient nécessaires pour les autres versions.

Implications

L’utilisation de ce script peut grandement améliorer l’efficacité informatique, mais nécessite une attention particulière. Une mise à jour incorrecte peut entraîner une instabilité du système. Testez toujours les scripts dans un environnement contrôlé avant de procéder à un déploiement à grande échelle.

Recommandations

  • D’abord tester: Exécutez toujours le script dans un environnement de test avant de le déployer à grande échelle.
  • Systèmes de sauvegarde: Assurez-vous que les sauvegardes du système sont à jour en cas de défaillance.
  • Personnaliser selon les besoins: Modifiez le script pour des environnements spécifiques si nécessaire.
  • Contrôler les journaux: Vérifiez régulièrement les journaux générés pour détecter tout problème ou anomalie.

Dernières réflexions

Dans le cadre d’une gestion informatique rationalisée, des outils comme NinjaOne peuvent compléter ces scripts en offrant un contrôle et une surveillance centralisés. Les capacités de NinjaOne en matière de gestion des mises à jour et de surveillance de la santé du système peuvent fonctionner en tandem avec de tels scripts, améliorant ainsi l’efficacité et la fiabilité globales de l’informatique. La combinaison de l’automatisation par le biais de scripts et d’un outil de gestion performante comme NinjaOne garantit que les environnements informatiques sont non seulement mis à jour, mais aussi surveillés et gérés de façon constante pour permettre des performances optimales.

Pour aller plus loin

Pour créer une équipe informatique efficace et performante, il est essentiel d'avoir une solution centralisée qui joue le rôle de nœud principal pour vos services. NinjaOne permet aux équipes informatiques de surveiller, gérer, sécuriser et prendre en charge tous les appareils, où qu'ils soient, sans avoir besoin d'une infrastructure complexe sur site. Pour en savoir plus sur NinjaOne Endpoint Management, participez à une visite guidée, ou profitez d'un essai gratuit de la plateforme NinjaOne.

Catégories :

Vous pourriez aussi aimer

×

Voir NinjaOne en action !

En soumettant ce formulaire, j'accepte la politique de confidentialité de NinjaOne.

Termes et conditions NinjaOne

En cliquant sur le bouton “J’accepte” ci-dessous, vous indiquez que vous acceptez les termes juridiques suivants ainsi que nos conditions d’utilisation:

  • Droits de propriété: NinjaOne possède et continuera de posséder tous les droits, titres et intérêts relatifs au script (y compris les droits d’auteur). NinjaOne vous accorde une licence limitée pour l’utilisation du script conformément à ces conditions légales.
  • Limitation de l’utilisation: Les scripts ne peuvent être utilisés qu’à des fins personnelles ou professionnelles internes légitimes et ne peuvent être partagés avec d’autres entités.
  • Interdiction de publication: Vous n’êtes en aucun cas autorisé à publier le script dans une bibliothèque de scripts appartenant à, ou sous le contrôle d’un autre fournisseur de logiciels.
  • Clause de non-responsabilité: Le texte est fourni “tel quel” et “tel que disponible”, sans garantie d’aucune sorte. NinjaOne ne promet ni ne garantit que le script sera exempt de défauts ou qu’il répondra à vos besoins ou attentes particulières.
  • Acceptation des risques: L’utilisation du script est sous votre propre responsabilité. Vous reconnaissez qu’il existe certains risques inhérents à l’utilisation du script, et vous comprenez et assumez chacun de ces risques.
  • Renonciation et exonération de responsabilité: Vous ne tiendrez pas NinjaOne pour responsable des conséquences négatives ou involontaires résultant de votre utilisation du script, et vous renoncez à tout droit ou recours légal ou équitable que vous pourriez avoir contre NinjaOne en rapport avec votre utilisation du script.
  • EULA: Si vous êtes un client de NinjaOne, votre utilisation du script est soumise au contrat de licence d’utilisateur final qui vous est applicable (End User License Agreement (EULA)).