Copiare e incollare questo script di esempio e modificarlo in base alle esigenze dell'ambiente:
<# . SINOSSI Distribuisce l'agente di orchestrazione di secure boot rollout come attività pianificata di Windows.
.DESCRIPTION Crea un'attività pianificata che esegue l'agente di orchestrazione continuamente in background.L'attività viene eseguita con criteri di esecuzione ignorati, quindi non vengono visualizzati messaggi di sicurezza. L'agente di orchestrazione: - Poll for device updates on the specified interval - Genera automaticamente onde e distribuisci oggetti Criteri di gruppo - Continua fino a quando tutti i dispositivi idonei non vengono aggiornati Monitorare lo stato di avanzamento usando: Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath Percorso UNC ai dati del dispositivo JSON (dall'oggetto Criteri di gruppo di rilevamento)
.PARAMETER ReportBasePath Percorso locale per report e file di stato
.PARAMETER TargetOU Ou to link GPO (optional - defaults to domain root)
.PARAMETER PollIntervalMinutes Minuti tra i controlli di stato. Impostazione predefinita: 30
.PARAMETER UseWinCS Usa WinCS (Windows Configuration System) invece di AvailableUpdatesPolicy GPO.Se abilitata, distribuisce WinCsFlags.exe'attività pianificata agli endpoint anziché all'oggetto Criteri di gruppo del Registro di sistema.
.PARAMETER WinCSKey Chiave WinCS per la configurazione di avvio protetto. Impostazione predefinita: F33E0C8E002
.PARAMETER ServiceAccount Account per eseguire l'attività. Impostazione predefinita: SISTEMA Per le operazioni di dominio, usare un account del servizio di amministrazione del dominio.
.PARAMETER ScriptPath Percorso dello script dell'agente di orchestrazione. Impostazione predefinita: stessa cartella di questo script.
.PARAMETER Uninstall Rimuovere l'attività programmata
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -ServiceAccount "DOMAIN\svc_secureboot"
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"
.EXAMPLE # Deploy using WinCS method instead of AvailableUpdatesPolicy .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -Uninstall #>
[CmdletBinding()] param( [Parametro(Obbligatorio = $false)] [stringa]$AggregationInputPath, [Parametro(Obbligatorio = $false)] [stringa]$ReportBasePath, [Parametro(Obbligatorio = $false)] [stringa]$TargetOU, [Parametro(Obbligatorio = $false)] [int]$PollIntervalMinutes = 30, [Parametro(Obbligatorio = $false)] [opzione]$UseWinCS, [Parametro(Obbligatorio = $false)] [stringa]$WinCSKey = "F33E0C8E002", [Parametro(Obbligatorio = $false)] [string]$ServiceAccount = "SYSTEM", [Parametro(Obbligatorio = $false)] [stringa]$ScriptPath, [Parametro(Obbligatorio = $false)] [opzione]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = "SecureBoot-Rollout-Orchestrator" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Esempi di distribuzione e monitoraggio"
# ============================================================================ # CONVALIDA DIPENDENZA # ============================================================================
function Test-ScriptDependencies { <# . SINOSSI Verifica che siano presenti tutti gli script necessari.. DESCRIZIONE Controlla le dipendenze degli script necessarie e fornisce istruzioni per il download, se mancanti.#> param( [Parametro(Obbligatorio = $true)] [stringa]$ScriptDirectory, [Parametro(Obbligatorio = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script in $RequiredScripts) { $scriptPath = Join-Path $ScriptDirectory $script if (-not (Test-Path $scriptPath)) { $missingScripts += $script } } if ($missingScripts.Count -gt 0) { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Red Write-Host "DIPENDENZE MANCANTI" -ForegroundColor red Write-Host ("=" * 70) -ForegroundColor Red Write-Host "" Write-Host "Non sono stati trovati gli script obbligatori seguenti:" -ForegroundColor Yellow foreach ($script in $missingScripts) { Write-Host " - $script" -ForegroundColor white } Write-Host "" Write-Host "Scarica gli script più recenti da:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor white Write-Host " Passa a: '$DownloadSubPage'" -Primo pianoColore bianco Write-Host "" Write-Host "Estrai tutti gli script nella stessa directory ed esegui di nuovo". -ForegroundColor Yellow Write-Host "" restituire $false } restituire $true }
# Required scripts for orchestrator deployment $requiredScripts = @( "Start-SecureBootRolloutOrchestrator.ps1", "Aggregate-SecureBootData.ps1", "Deploy-GPO-SecureBootCollection.ps1", "Detect-SecureBootCertUpdateStatus.ps1", "Get-SecureBootRolloutStatus.ps1", "Enable-SecureBootUpdateTask.ps1" )
if (-not (Test-ScriptDependencies -ScriptDirectory $PSScriptRoot -RequiredScripts $requiredScripts)) { uscita 1 }
# ============================================================================ # DISINSTALLA # ============================================================================
if ($Uninstall) { Write-Host "" Write-Host "Rimozione dell'attività programmata: $TaskName" -ForegroundColor yellow $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false Write-Host "Attività rimossa correttamente". -Primo pianoColore verde } else { Write-Host "Attività non trovata". -ForegroundColor gray } uscita 0 }
# ============================================================================ # CONVALIDA # ============================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host "ERROR: -AggregationInputPath and -ReportBasePath are required." -ForegroundColor Red Write-Host "" Write-Host "Esempio:" -Primo pianoColore giallo Write-Host ' .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"' uscita 1 }
# Find orchestrator script if (-$ScriptPath) { $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }
if (-not (Test-Path $ScriptPath)) { Write-Host "ERRORE: script dell'agente di orchestrazione non trovato: $ScriptPath" -ForegroundColor red uscita 1 }
# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot "Aggregate-SecureBootData.ps1" if (-not (Test-Path $aggregateScript)) { Write-Host "AVVISO: Aggregate-SecureBootData.ps1 non trovato nella directory di script" -ForegroundColor Yellow Write-Host " L'agente di orchestrazione potrebbe non riuscire se non riesce a trovare questo script". -ForegroundColor Yellow }
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Ciano Write-Host " Secure Boot Rollout Orchestrator - Distribuzione attività" -ForegroundColor Cyan Write-Host ("=" * 70) -ForegroundColor Ciano Write-Host ""
# For display, show relative paths (script names only) $displayScriptPath = Split-Path $ScriptPath -Leaf
Write-Host "Configuration:" -ForegroundColor Yellow Write-Host " Nome attività: $TaskName" Write-Host " Orchestratore: $displayScriptPath" Write-Host " Percorso di input: $AggregationInputPath" Write-Host " Percorso report: $ReportBasePath" Write-Host " OU di destinazione: $(if ($TargetOU) { $TargetOU } else { '(radice del dominio)' })" Write-Host " Intervallo sondaggio: $PollIntervalMinutes minuti" Write-Host " Account del servizio: $ServiceAccount" Write-Host " Metodo di distribuzione: $(if ($UseWinCS) { "WinCS (WinCsFlags.exe)" } else { "AvailableUpdatesPolicy (GPO)" })" if ($UseWinCS) { Write-Host "Tasto WinCS: $WinCSKey" } Write-Host ""
# ============================================================================ # RILEVAMENTO OGGETTO CRITERI DI GRUPPO - DISTRIBUZIONE AUTOMATICA, SE MANCANTE # ============================================================================
$CollectionGPOName = "SecureBoot-EventCollection" $deployGpoScript = Join-Path $PSScriptRoot "Deploy-GPO-SecureBootCollection.ps1"
# Check if GroupPolicy module is available if (Get-Module -ListAvailable -Name GroupPolicy) { Import-Module GroupPolicy -ErrorAction SilentlyContinue Write-Host "Controllo dell'oggetto Criteri di gruppo rilevamento..." -ForegroundColor yellow prova { # Ottenere il dominio da AggregationInputPath (ad esempio, \\domain\share) $domainFromPath = if ($AggregationInputPath -match '^\\\\([^\\]+)\\') { $matches[1] } else { $env:USERDNSDOMAIN } # Controlla se esiste un oggetto Criteri di gruppo $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue if ($existingGpo) { Write-Host " Oggetto Criteri di gruppo rilevamento trovato: $CollectionGPOName" -ForegroundColor green } else { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Yellow Write-Host " OGGETTO CRITERI DI RILEVAMENTO NON TROVATO" -ForegroundColor yellow Write-Host ("=" * 70) -ForegroundColor Yellow Write-Host "" Write-Host "L'oggetto Criteri di gruppo di rilevamento '$CollectionGPOName' non è stato trovato". -ForegroundColor yellow Write-Host "Questo oggetto Criteri di gruppo è necessario per raccogliere i dati sullo stato del dispositivo". -ForegroundColor Yellow Write-Host "" # Chiedi all'utente se vuole distribuire subito l'oggetto Criteri di gruppo Write-Host "Vuoi distribuire ora l'oggetto Criteri di gruppo Rilevamento? (Y/N)" -ForegroundColor Ciano $response = Read-Host if ($response -match '^[Yy]') { Write-Host "" Write-Host "Avvio della distribuzione dell'oggetto Criteri di gruppo..." -ForegroundColor Ciano Write-Host "" # Parametri di compilazione per la distribuzione dell'oggetto Criteri di gruppo $gpoParams = @{ NomeDominio = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1" } if ($TargetOU) { $gpoParams.OUPath = $TargetOU } else { # Usa Il rilevamento automatico DIU per consentire all'utente di selezionare $gpoParams.AutoDetectOU = $true } # Esegui lo script di distribuzione dell'oggetto Criteri di gruppo & $deployGpoScript @gpoParams if ($LASTEXITCODE -ne 0) { Write-Host "Potrebbero essersi verificati problemi nella distribuzione dell'oggetto Criteri di gruppo. Rivedi l'output precedente". -Primo pianoColore giallo Write-Host "Puoi continuare con la distribuzione dell'agente di orchestrazione o premere CTRL+C per interrompere". -Primo pianoColore giallo Write-Host "" Read-Host "Premere INVIO per continuare" } else { Write-Host "" Write-Host "Oggetto Criteri di gruppo rilevamento distribuito correttamente!" -ForegroundColor Green Write-Host "" } } else { Write-Host "" Write-Host "Ignorare la distribuzione dell'oggetto Criteri di gruppo. L'agente di orchestrazione non riceverà i dati del dispositivo" -ForegroundColor Yellow Write-Host "finché l'oggetto Criteri di gruppo rilevamento non viene distribuito manualmente". -Primo pianoColore giallo Write-Host "" Write-Host "Per distribuire l'oggetto Criteri di gruppo rilevamento in seguito, eseguire:" -ForegroundColor Ciano Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath'" -AutoDetectOU" -ForegroundColor white Write-Host "" } } } catch { Write-Host " Impossibile controllare l'oggetto Criteri di gruppo: $($_. Exception.Message)" -ForegroundColor yellow Write-Host " Continuando con la distribuzione dell'agente di orchestrazione..." -ForegroundColor Gray } } else { Write-Host " Modulo GroupPolicy non disponibile - saltando il controllo oggetto Criteri di gruppo" -ForegroundColor Gray Write-Host " Verifica che l'oggetto Criteri di gruppo rilevamento sia distribuito separatamente". -ForegroundColor Gray }
Write-Host ""
# ============================================================================ # ARGOMENTI BUILD # ============================================================================
$arguments = @( "-NoProfile" "-ExecutionPolicy Bypass" "-File '"$ScriptPath'"" "-AggregationInputPath '"$AggregationInputPath'"" "-ReportBasePath '"$ReportBasePath'"" "-PollIntervalMinutes $PollIntervalMinutes" )
if ($TargetOU) { $arguments += "-TargetOU '"$TargetOU'"" }
if ($UseWinCS) { $arguments += "-UseWinCS" $arguments += "-WinCSKey '"$WinCSKey'"" }
$argumentString = $arguments -join " "
# Don't display raw arguments with full paths - it's confusing for published scripts # L'attività userà il percorso completo internamente
# ============================================================================ # CREA ATTIVITÀ PIANIFICATA # ============================================================================
# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Write-Host "L'attività esiste già. Aggiornamento..." -ForegroundColor yellow Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false }
# Create task action $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $argumentString -WorkingDirectory $PSScriptRoot
# Create trigger - run once, immediately (orchestrator loops internally) $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date). AddMinutes(1)
# Create principal if ($ServiceAccount -eq "SYSTEM") { $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest } else { # Richiesta della password per l'account di dominio Write-Host "Immetti la password per $ServiceAccount" -ForegroundColor yellow $cred = Get-Credential -UserName $ServiceAccount -Message "Service account credentials for scheduled task" $principal = New-ScheduledTaskPrincipal -UserId $ServiceAccount -LogonType Password -RunLevel Highest }
# Task settings $settings = New-ScheduledTaskSettingsSet ' -AllowStartIfOnBatteries ' -DontStopIfGoingOnBatteries ' -StartWhenAvailable ' -RunOnlyIfNetworkAvailable ' -RestartCount 3 ' -RestartInterval (New-TimeSpan -Minutes 5) ' -ExecutionTimeLimit (New-TimeSpan -Days 30) # Consenti long-running
# Register task prova { if ($ServiceAccount -eq "SYSTEM") { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Secure Boot Certificate Rollout - Automated GPO deployment" } else { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Secure Boot Certificate Rollout - Automated GpO deployment" -User $ServiceAccount -Password $cred. GetNetworkCredential(). Password } Write-Host "Attività pianificata creata correttamente!" -ForegroundColor green } catch { Write-Host "Impossibile creare un'attività programmata: $($_. Exception.Message)" -ForegroundColor red uscita 1 }
# ============================================================================ # CREA COLLEGAMENTO STATO # ============================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (Test-Path $statusScript) { Write-Host "" Write-Host "Per controllare lo stato dell'implementazione, esegui:" -ForegroundColor Yellow Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'"" -ForegroundColor Ciano }
# ============================================================================ # OUTPUT # ============================================================================
Write-Host "" Write-Host ("=" * 70) -ForegroundColor green Write-Host " DISTRIBUZIONE COMPLETATA" - Primo pianoColore verde Write-Host ("=" * 70) -ForegroundColor green Write-Host "" Write-Host "L'orchestratore inizierà tra circa 1 minuto". -Primo pianoColore bianco Write-Host "" Write-Host "MONITORAGGIO:" -Primo pianoColore giallo Write-Host " Visualizza stato attività: Get-ScheduledTask -TaskName '$TaskName' | Seleziona stato" Write-Host " Visualizza log attività: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyyMMdd').log' -Tail 50" Write-Host " Visualizza stato implementazione: Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json" Write-Host " Visualizza dashboard: Start '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html'" Write-Host " Stato rapido: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "GESTIONE:" -ForegroundColor yellow Write-Host " Start manually: Start-ScheduledTask -TaskName '$TaskName'" Write-Host " Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host " Remove: .\Deploy-OrchestratorTask.ps1 -Uninstall" Write-Host ""