Microsoft ha sviluppato uno script di esempio PowerShell che può aiutare a automatizzare l’aggiornamento dell’Ambiente di Ripristino di Windows (WinRE) su dispositivi già implementati per affrontare le vulnerabilità di sicurezza in CVE-2024-20666 relative al KB5034957
Script di Esempio PowerShell
Lo script di PowerShell di esempio è stato creato dal team di prodotto Microsoft per facilitare l’aggiornamento delle immagini di WinRE su dispositivi Windows 10 e Windows 11 supportati. Eseguire lo script con le credenziali di amministratore in PowerShell sui dispositivi interessati. Sono disponibili due script, e la scelta dipende dalla versione di Windows in uso. Utilizzare la versione appropriata per il proprio ambiente.
- PatchWinREScript_2004plus.ps1 (Consigliato)
- Questo script è per Windows 10, versione 2004 e versioni successive, inclusa Windows 11. Si consiglia di utilizzare questa versione dello script perché è più robusta, ma utilizza funzionalità disponibili solo su Windows 10, versione 2004 e versioni successive.
#
#
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
#
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.
#
#
Define script parameters
Param (
[Parameter(HelpMessage=”Work Directory for patch WinRE”)]
[string]$workDir = “”,
[Parameter(Mandatory=$true, HelpMessage="Path of target package")]
[string]$packagePath
)
————————————
Help functions
————————————
Log message
function LogMessage([string]$message) {
$message = “$([DateTime]::Now) – $message”
Write-Host $message
}
Check if TPM-based protector is enabled
function IsTPMBasedProtector {
$DriveLetter = $env:SystemDrive
LogMessage(“Checking BitLocker status”)
$BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$DriveLetter'"
if (-not $BitLocker) {
LogMessage("No BitLocker object")
return $False
}
$protectionEnabled = $False
switch ($BitLocker.GetProtectionStatus().protectionStatus) {
("0") { LogMessage("Unprotected"); break }
("1") { LogMessage("Protected"); $protectionEnabled = $True; break }
("2") { LogMessage("Unknown"); break }
default { LogMessage("NoReturn"); break }
}
if (!$protectionEnabled) {
LogMessage("Bitlocker isn’t enabled on the OS")
return $False
}
$ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
$return = $False
foreach ($ProtectorID
- PatchWinREScript_General.ps1
- Questo script è per Windows 10, versione 1909 e versioni precedenti, ma si esegue su tutte le versioni di Windows 10 e Windows 11.
#
#
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
#
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.
#
#
Define script parameters
Param (
[Parameter(HelpMessage=”Work Directory for patch WinRE”)]
[string]$workDir = “”,
[Parameter(Mandatory=$true, HelpMessage="Path of target package")]
[string]$packagePath
)
————————————
Help functions
————————————
Log message
function LogMessage([string]$message) {
$message = “$([DateTime]::Now) – $message”
Write-Host $message
}
Check if TPM-based protector is enabled
function IsTPMBasedProtector {
$DriveLetter = $env:SystemDrive
LogMessage(“Checking BitLocker status”)
$BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$DriveLetter'"
if (-not $BitLocker) {
LogMessage("No BitLocker object")
return $False
}
$protectionEnabled = $False
switch ($BitLocker.GetProtectionStatus().protectionStatus) {
("0") { LogMessage("Unprotected"); break }
("1") { LogMessage("Protected"); $protectionEnabled = $True; break }
("2") { LogMessage("Unknown"); break }
default { LogMessage("NoReturn"); break }
}
if (!$protectionEnabled) {
LogMessage("Bitlocker isn’t enabled on the OS")
return $False
}
$ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
$return = $False
foreach ($ProtectorID in $ProtectorIds) {
$KeyProtectorType = $BitLocker.GetKeyProtectorType($ProtectorID).KeyProtectorType
switch ($KeyProtectorType) {
"1" { LogMessage("Trusted Platform Module (TPM)"); $return = $True; break }
"4" { LogMessage("TPM And PIN"); $return = $True; break }
"5" { LogMessage("TPM And Startup Key"); $return = $True; break }
"6" { LogMessage("TPM And PIN And Startup Key"); $return = $True; break }
default { break }
}
}
if ($return) {
LogMessage("Has TPM-based protector")
} else {
LogMessage("Doesn't have TPM-based protector")
}
return $return
}
Set registry key to indicate successful execution
function SetRegistrykeyForSuccess {
reg add HKLM\SOFTWARE\Microsoft\PushButtonReset /v WinREPathScriptSucceed /d 1 /f
}
Check the version of the target file
function TargetfileVersionExam([string]$mountDir) {
# … (unchanged)
}
Patch the WinRE package
function PatchPackage([string]$mountDir, [string]$packagePath) {
# … (unchanged)
}
————————————
Execution starts
————————————
Check if the script was previously run successfully
if (Test-Path HKLM:\Software\Microsoft\PushButtonReset) {
$values = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset
if ($values -ne $null) {
if ($values.PSObject.Properties.Name -contains 'WinREPathScriptSucceed' -and $values.WinREPathScriptSucceed -eq 1) {
LogMessage("This script was previously run successfully")
exit 1
}
}
}
Use default path if no input for the mount directory is provided
if ([string]::IsNullOrEmpty($workDir)) {
LogMessage(“No input for the mount directory”)
LogMessage(“Use default path from the temporary directory”)
$workDir = [System.IO.Path]::GetTempPath()
}
LogMessage(“Working Dir: ” + $workDir)
… (unchanged)
Cleanup Mount directory in the end
LogMessage(“Delete mount directory”)
Remove-Item $mountDir -Recurse
Ulteriori Informazioni
Con il dispositivo avviato nella versione in esecuzione di Windows installata, lo script eseguirà i seguenti passaggi:
- Monta l’immagine WinRE esistente (WINRE.WIM).
- Aggiorna l’immagine WinRE con il pacchetto specificato di Safe OS Dynamic Update (Compatibilità Update) disponibile dal Windows Update Catalog. Si consiglia di utilizzare l’ultimo Safe OS Dynamic Update disponibile per la versione di Windows installata sul dispositivo.
- Smonta l’immagine WinRE.
- Se è presente il proteggitore BitLocker TPM, riconfigura WinRE per il servizio BitLocker.
Utilizzo
Lo script può accettare i seguenti parametri:
- workDir: Specifica lo spazio di lavoro utilizzato per patchare WinRE. Se non specificato, lo script utilizzerà la cartella temporanea predefinita per il dispositivo.
- packagePath: Specifica il percorso e il nome del pacchetto di aggiornamento dinamico Safe OS specifico per la versione del sistema operativo e l’architettura del processore da utilizzare per aggiornare l’immagine WinRE.
Esempio:
powershell
.\PatchWinREScript_2004plus.ps1 -packagePath "\\server\share\windows10.0-kb5021043-x64_efa19d2d431c5e782a59daaf2d.cab"