Copiare e incollare questo script di esempio e modificarlo in base alle esigenze dell'ambiente:
<# . SINOSSI Abilita l'attività pianificata Aggiornamento di avvio protetto.
.DESCRIPTION Questo script assicura l'attività pianificata Windows Secure Boot Update (\Microsoft\Windows\PI\Secure-Boot-Update) è abilitato. Se disabilitata, lo consente. Se l'attività è stata eliminata, può ricrearla.
.PARAMETER Action Azione da eseguire. Valori validi: controlla, abilita, crea - controllare: controllare solo lo stato dell'attività - abilita: (impostazione predefinita) Abilita l'attività se disabilitata. Se l'attività non è presente, viene richiesto di crearla.- crea: crea l'attività se non esiste
.PARAMETER ComputerName Opzionale. Matrice di nomi di computer in cui controllare/abilitare l'attività.Se non è specificato, viene eseguito nel computer locale.
.PARAMETER Credential Opzionale. Credenziali per l'accesso remoto al computer.
.PARAMETER Quiet Elimina le richieste e risponde automaticamente Sì. Utile per l'automazione.
.EXAMPLE \Enable-SecureBootTask.ps1 # Abilita lo stato dell'attività nel computer locale
.EXAMPLE abilita .\Check-SecureBootScheduledTask.ps1 # Abilita l'attività se disabilitata. Prompt per creare, se mancante.
.EXAMPLE \Check-SecureBootScheduledTask.ps1 creare # Crea l'attività se è stata eliminata, quindi ne controlla lo stato
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 selezionare -ComputerName "PC1", "PC2" # Controlla l'attività nei computer remoti
.NOTES Richiede privilegi di amministratore per abilitare o creare l'attività.Percorso attività: \Microsoft\Windows\PI\Secure-Boot-Update L'attività viene eseguita taskhostw.exe ogni 12 ore con privilegi elevati.#>
[CmdletBinding(SupportsShouldProcess)] param( [Parameter(Position=0)] [ValidateSet('check', 'enable', 'create', '')] [string]$Action = 'enable',
[Parameter()] [string[]]$ComputerName,
[Parameter()] [PSCredential]$Credential,
[Parameter()] [Alias('Forza', 'Silenzioso')] [opzione]$Quiet )
# Convert Action to switches for backward compatibility $Enable = $Action -eq 'enable' $Create = $Action -eq 'create'
# Download URL: https://aka.ms/getsecureboot -> "Deployment and Monitoring Samples" # Nota: questo script viene eseguito sugli endpoint per abilitare l'attività Aggiornamento di avvio protetto.
$TaskPath = "\Microsoft\Windows\PI\" $TaskName = "Secure-Boot-Update"
function Get-SecureBootTaskStatus { [CmdletBinding()] param( [stringa]$Computer = $env:NOMECOMPUTER )
$result = [PSCustomObject]@{ ComputerName = $Computer TaskExists = $false TaskState = $null IsEnabled = $false LastRunTime = $null NextRunTime = $null Errore = $null }
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { # Usare schtasks.exe per un rilevamento delle attività più affidabile $schtasksOutput = schtasks.exe /Query /TN "$TaskPath$TaskName" /FO CSV 2>&1 if ($LASTEXITCODE -ne 0) { # L'attività non trovata non è un errore, significa semplicemente che l'attività non esiste $result. TaskExists = $false restituire $result } # Analizza output CSV $taskData = $schtasksOutput | ConvertFrom-Csv if ($taskData) { $result. TaskExists = $true $result. TaskState = $taskData.Status $result. IsEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running') # Prova a ottenere la prossima fase di esecuzione dai dati if ($taskData.'Next Run Time' -and $taskData.'Next Run Time' -ne 'N/D') { prova { $result. NextRunTime = [DateTime]::P arse($taskData.'Next Run Time') } cattura { } } } } else { # Computer remoto - usare Invoke-Command con schtasks $remoteResult = Invoke-Command -ComputerName $Computer -ScriptBlock { param($fullTaskName) $output = schtasks.exe /Query /TN $fullTaskName /FO CSV 2>&1 @{ ExitCode = $LASTEXITCODE Output = $output } } -ArgumentList "$TaskPath$TaskName" -ErrorAction Stop
if ($remoteResult.ExitCode -ne 0) { # L'attività non trovata non è un errore, significa semplicemente che l'attività non esiste $result. TaskExists = $false $result reso }
$taskData = $remoteResult.Output | ConvertFrom-Csv if ($taskData) { $result. TaskExists = $true $result. TaskState = $taskData.Status $result. IsEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running') } } } catch { $result. Errore = $_. Exception.Message }
return $result }
function New-SecureBootTask { [CmdletBinding(SupportsShouldProcess)] param( [stringa]$Computer = $env:NOMECOMPUTER )
$success = $false $errorMsg = $null
# Task definition - matches the original Windows Secure Boot Update task # Usa ComHandler con la classe SBServicing, eseguita come LocalSystem $taskXml = @" <?xml version="1.0" encoding="UTF-16"?> <Task version="1.6" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> >RegistrationInfo < <data>2012-02-07T16:39:20</Date> <SecurityDescriptor>O:BAG:BAD:P(A;; FA;;; BA)(A;; FA;;; SY)(A;; FRFX;;; LS)<>/SecurityDescriptor <>di origine '$(@%SystemRoot%\system32\TpmTasks.dll,-601)</Source> <author>'$(@%SystemRoot%\system32\TpmTasks.dll,-600)</Author> descrizione <>'$(@%SystemRoot%\system32\TpmTasks.dll,-604)</Description> <> URI\Microsoft\Windows\PI\Secure-Boot-Update</URI> ></RegistrationInfo ><Principals <Principal id="LocalSystem"> <userid><<S-1-5-18 /UserId> <> /Principal ></Principals >Impostazioni < <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> ><0 StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> ><4 ExecutionTimeLimit><PT1H /ExecutionTimeLimit> ><8 MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <StartWhenAvailable>true</StartWhenAvailable> ><IdleSettings <>True StopOnIdleEnd</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> </Settings> >trigger < >Boot Trigger di < <ritardo></Delay di PT5M> >ripetizione < <intervallo></Interval>PT12H /Interval> </>Ripetizione >/BootBoot < >/Trigger < <Actions Context="LocalSystem"> >ComHandler < <> ClassId{5014B7C8-934E-4262-9816-887FA745A6C4}</ClassId> <>< dati. [CDATA[SBServicing]]></Data> >/ComHandler < </Actions> </> attività " @
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { if ($PSCmdlet.ShouldProcess("$TaskPath$TaskName", "Create scheduled task")) { # Save XML to temp file and import $tempFile = [System.IO.Path]::GetTempFileName() $taskXml | Out-File -FilePath $tempFile -Encoding Unicode -Force $output = schtasks.exe /Create /TN "$TaskPath$TaskName" /XML $tempFile /F 2>&1 Remove-Item $tempFile -Force -ErrorAction SilentlyContinue if ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join " " } } } else { if ($PSCmdlet.ShouldProcess("$Computer\$TaskPath$TaskName", "Crea attività programmata")) { $result = Invoke-Command -ComputerName $Computer -ScriptBlock { param($taskPath; $taskName; $xml) $tempFile = [System.IO.Path]::GetTempFileName() $xml | Out-File -FilePath $tempFile -Encoding Unicode -Force $output = schtasks.exe /Create /TN "$taskPath$taskName" /XML $tempFile /F 2>&1 Remove-Item $tempFile -Force -ErrorAction SilentlyContinue @{ ExitCode = $LASTEXITCODE; Output = $output } } -ArgumentList $TaskPath, $TaskName, $taskXml -ErrorAction Stop se ($result. ExitCode -eq 0) { $success = $true } else { $errorMsg = $result. Output -join " " } } } } catch { $errorMsg = $_. Exception.Message }
return @{ Success = $success Errore = $errorMsg } }
function Enable-SecureBootTask { [CmdletBinding(SupportsShouldProcess)] param( [stringa]$Computer = $env:NOMECOMPUTER )
$success = $false $errorMsg = $null
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { if ($PSCmdlet.ShouldProcess("$TaskPath$TaskName", "Enable scheduled task")) { $output = schtasks.exe /Change /TN "$TaskPath$TaskName" /ENABLE 2>&1 if ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join " " } } } else { if ($PSCmdlet.ShouldProcess("$Computer\$TaskPath$TaskName", "Enable scheduled task")) { $result = Invoke-Command -ComputerName $Computer -ScriptBlock { param($fullTaskName) $output = schtasks.exe /Change /TN $fullTaskName /ENABLE 2>&1 @{ ExitCode = $LASTEXITCODE; Output = $output } } -ArgumentList "$TaskPath$TaskName" -ErrorAction Stop se ($result. ExitCode -eq 0) { $success = $true } else { $errorMsg = $result. Output -join " " } } } } catch { $errorMsg = $_. Exception.Message }
return @{ Success = $success Errore = $errorMsg } }
# Main execution Write-Host "" Write-Host "========================================" -ForegroundColor Ciano Write-Host " Secure Boot Update Task Enabler" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Ciano Write-Host "" Write-Host "Attività: $TaskPath$TaskName" -ForegroundColor gray Write-Host ""
# Determine target computers $targets = if ($ComputerName) { $ComputerName } else { @($env:COMPUTERNAME) }
$results = @()
foreach ($computer in $targets) { Write-Host "Controllo: $computer" -ForegroundColor yellow $status = Get-SecureBootTaskStatus -$computer computer se ($status. Errore) { Write-Host " Errore: $($status. Errore)" -Primo pianoColore rosso } elseif (-non $status. TaskExists) { Write-Host " Attività non esiste in questo sistema" -ForegroundColor Red # Crea se richiesto o chiedi conferma se è stato specificato Enable $shouldCreate = $Create if (-not $shouldCreate -and $Enable) { Write-Host "" Write-Host " L'attività potrebbe essere stata eliminata". -ForegroundColor Yellow if ($Quiet) { Write-Host " Creazione automatica attività (modalità non interattiva)" -ForegroundColor Ciano $shouldCreate = $true } else { $confirm = Read-Host " Ricreare l'attività? (Y/N)" if ($confirm -eq 'Y' -o $confirm -eq 'y') { $shouldCreate = $true } } } if ($shouldCreate) { Write-Host " Creazione attività..." -Primo pianoColore giallo $createResult = New-SecureBootTask -$computer computer if ($createResult.Success) { Write-Host " Attività creata correttamente" -ForegroundColor Green # Ricontrollare lo stato $status = $computer computer Get-SecureBootTaskStatus se ($status. TaskExists) { $stateColor = if ($status. IsEnabled) { "Green" } else { "Red" } Write-Host " Stato: $($status. TaskState)" -ForegroundColor $stateColor } } else { Write-Host " Impossibile creare: $($createResult.Error)" -ForegroundColor Red } } } else { $stateColor = if ($status. IsEnabled) { "Green" } else { "Red" } Write-Host " State: $($status. TaskState)" -ForegroundColor $stateColor se ($status. LastRunTime - e $status. LastRunTime -ne [DateTime]::MinValue) { Write-Host " Ultima esecuzione: $($status. LastRunTime)" -ForegroundColor gray } se ($status. NextRunTime - e $status. NextRunTime -ne [DateTime]::MinValue) { Write-Host " Prossima esecuzione: $($status. NextRunTime)" -ForegroundColor gray }
# Enable if requested and currently disabled se ($Enable e -non $status. IsEnabled) { Write-Host " Abilitazione attività..." -Primo pianoColore giallo $enableResult = Enable-SecureBootTask -Computer $computer if ($enableResult.Success) { Write-Host "Attività abilitata correttamente" -ForegroundColor Green # Ricontrollare lo stato $status = Get-SecureBootTaskStatus -Computer $computer } else { Write-Host " Impossibile abilitare: $($enableResult.Error)" -ForegroundColor Red } } elseif ($Enable -and $status. IsEnabled) { Write-Host " Attività già abilitata" -ForegroundColor Green } } $results += $status Write-Host "" }
# Summary Write-Host "========================================" -ForegroundColor Ciano Write-Host " Riepilogo" -ForegroundColor Ciano Write-Host "========================================" -ForegroundColor Ciano
$enabled = ($results | Where-Object { $_.IsEnabled }).Count $disabled = ($results | Where-Object { $_. TaskExists -and -not $_. IsEnabled }). Conteggio $notFound = ($results | Where-Object { -not $_. TaskExists }). Conteggio $errors = ($results | Where-Object { $_. Errore }). Conteggio
Write-Host "Total Checked: $($results.Count)" Write-Host "Abilitato: $enabled" -ForegroundColor green if ($disabled -gt 0) { Write-Host "Disabilitato: $disabled" -ForegroundColor Rosso } if ($notFound -gt 0) { Write-Host "Non trovato: $notFound" -Primo pianoColore giallo } if ($errors -gt 0) { Write-Host "Errori: $errors" -Primo pianoColore rosso }
# Return results for pipeline $results