Copie e cole este script de exemplo e modifique conforme necessário para o seu ambiente:
<# . SYNOPSIS Implementa o Orquestrador de Implementação de Arranque Seguro como uma Tarefa Agendada do Windows.
.DESCRIPTION Cria uma tarefa agendada que executa o orquestrador continuamente em segundo plano.A tarefa é executada com a política de execução de ignorar para que não sejam apresentados pedidos de segurança. O orquestrador irá: - Consultar as atualizações do dispositivo no intervalo especificado - Gerar automaticamente ondas e implementar GPOs - Continue até que todos os dispositivos elegíveis sejam atualizados Monitorizar o progresso com: Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath Caminho UNC para os dados do dispositivo JSON (do GPO de deteção)
.PARAMETER ReportBasePath Caminho local para relatórios e ficheiros de estado
.PARAMETER TargetOU UO para ligar GPOs (opcional - predefinições para raiz de domínio)
.PARAMETER PollIntervalMinutes Minutos entre verificações de estado. Predefinição: 30
.PARAMETER UseWinCS Utilize o WinCS (Sistema de Configuração do Windows) em vez do GPO AvailableUpdatesPolicy.Quando ativada, implementa WinCsFlags.exe tarefa agendada em pontos finais em vez do GPO de registo.
.PARAMETER WinCSKey A chave WinCS para a configuração de Arranque Seguro. Predefinição: F33E0C8E002
.PARAMETER ServiceAccount Conta para executar a tarefa. Predefinição: SYSTEM Para operações de domínio, utilize uma conta de serviço de administração de domínio.
.PARAMETER ScriptPath Caminho para o script do orquestrador. Predefinição: a mesma pasta que este script.
.PARAMETER Uninstall Remover a tarefa agendada
.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 # Implementar com o método WinCS em vez de AvailableUpdatesPolicy .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -Desinstalar #>
[CmdletBinding()] parâmetro( [Parameter(Mandatory = $false)] [cadeia]$AggregationInputPath, [Parameter(Mandatory = $false)] [cadeia]$ReportBasePath, [Parameter(Mandatory = $false)] [cadeia]$TargetOU, [Parameter(Mandatory = $false)] [int]$PollIntervalMinutes = 30, [Parameter(Mandatory = $false)] [switch]$UseWinCS, [Parameter(Mandatory = $false)] [string]$WinCSKey = "F33E0C8E002", [Parameter(Mandatory = $false)] [string]$ServiceAccount = "SYSTEM", [Parameter(Mandatory = $false)] [cadeia]$ScriptPath, [Parameter(Mandatory = $false)] [switch]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = "SecureBoot-Rollout-Orchestrator" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Exemplos de Implementação e Monitorização"
# ============================================================================ # VALIDAÇÃO DE DEPENDÊNCIA # ============================================================================
function Test-ScriptDependencies { <# . SYNOPSIS Valida que todos os scripts necessários estão presentes.. DESCRIÇÃO Verifica as dependências de script necessárias e fornece instruções de transferência se estiverem em falta.#> parâmetro( [Parameter(Mandatory = $true)] [cadeia]$ScriptDirectory, [Parameter(Mandatory = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script em $RequiredScripts) { $scriptPath = Join-Path $ScriptDirectory $script if (-not (Test-Path $scriptPath)) { $missingScripts += $script } } if ($missingScripts.Count -gt 0) { Write-Host "" Write-Host ("=" * 70) -Primeiro PlanoColor Vermelho Write-Host " DEPENDÊNCIAS EM FALTA" -ForegroundColor Vermelho Write-Host ("=" * 70) -Primeiro PlanoColor Vermelho Write-Host "" Write-Host "Os seguintes scripts necessários não foram encontrados:" -ForegroundColor Amarelo foreach ($script no $missingScripts) { Write-Host " - $script" -ForegroundColor White } Write-Host "" Write-Host "Transfira os scripts mais recentes de:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor White Write-Host " Navegue para: '$DownloadSubPage'" -ForegroundColor White Write-Host "" Write-Host "Extrair todos os scripts para o mesmo diretório e executar novamente". -ForegroundColor Amarelo Write-Host "" devolver $false } devolver $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)) { sair 1 }
# ============================================================================ # DESINSTALAR # ============================================================================
if ($Uninstall) { Write-Host "" Write-Host "Remover tarefa agendada: $TaskName" -Primeiro PlanoColor Amarelo $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue se ($existingTask) { Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false Write-Host "Tarefa removida com êxito". -Primeiro PlanoColor Verde } senão { Write-Host "Tarefa não encontrada". -Primeiro PlanoColor Cinzento } sair 0 }
# ============================================================================ # VALIDAÇÃO # ============================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host "ERROR: -AggregationInputPath and -ReportBasePath are required." -ForegroundColor Red Write-Host "" Write-Host "Example:" -ForegroundColor Yellow Write-Host " .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"" sair 1 }
# Find orchestrator script if (-not $ScriptPath) { $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }
if (-not (Test-Path $ScriptPath)) { Write-Host "ERROR: Orchestrator script not found: $ScriptPath" -ForegroundColor Red sair 1 }
# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot "Aggregate-SecureBootData.ps1" if (-not (Test-Path $aggregateScript)) { Write-Host "AVISO: Aggregate-SecureBootData.ps1 não encontrado no diretório de scripts" -ForegroundColor Amarelo Write-Host " O Orchestrator poderá falhar se não conseguir encontrar este script." -ForegroundColor Yellow }
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host " Secure Boot Deployment Orchestrator - Task Deployment" -ForegroundColor Cyan Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host ""
# For display, show relative paths (script names only) $displayScriptPath = Split-Path $ScriptPath -Leaf
Write-Host "Configuration:" -ForegroundColor Yellow Write-Host " Nome da Tarefa: $TaskName" Write-Host " Orchestrator: $displayScriptPath" Write-Host " Caminho de Entrada: $AggregationInputPath" Write-Host " Caminho do Relatório: $ReportBasePath" Write-Host " UO de Destino: $(se ($TargetOU) { $TargetOU } senão { '(raiz do domínio)' })" Write-Host " Intervalo de Consulta: $PollIntervalMinutes minutos" Write-Host " Conta de Serviço: $ServiceAccount" Write-Host " Método de Implementação: $(se ($UseWinCS) { "WinCS (WinCsFlags.exe)" } senão { "AvailableUpdatesPolicy (GPO)" })" se ($UseWinCS) { Write-Host " Chave WinCS: $WinCSKey" } Write-Host ""
# ============================================================================ # GPO DETECTION - AUTO-DEPLOY IF MISSING # ============================================================================
$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 "A verificar se há GPO de Deteção..." -Primeiro PlanoColor Amarelo experimente { # Obtenha o domínio a partir de AggregationInputPath (por exemplo, \\domain\share) $domainFromPath = se ($AggregationInputPath -corresponder '^\\\\([^\\]+)\\') { $matches[1] } senão { $env:USERDNSDOMAIN } # Verificar se o GPO existe $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue se ($existingGpo) { Write-Host " GPO de deteção encontrado: $CollectionGPOName" -ForegroundColor Green } senão { Write-Host "" Write-Host ("=" * 70) -Primeiro PlanoColor Amarelo Write-Host " DETECTION GPO NOT FOUND" -ForegroundColor Yellow Write-Host ("=" * 70) -Primeiro PlanoColor Amarelo Write-Host "" Write-Host "O GPO de deteção '$CollectionGPOName' não foi encontrado." -ForegroundColor Yellow Write-Host "Este GPO é necessário para recolher dados de estado do dispositivo." -ForegroundColor Amarelo Write-Host "" # Pergunte ao utilizador se pretende implementar o GPO agora Write-Host "Pretende implementar o GPO de Deteção agora? (Y/N)" -ForegroundColor Cyan $response = Read-Host if ($response -match '^[Yy]') { Write-Host "" Write-Host "Launching GPO Deployment..." -ForegroundColor Cyan Write-Host "" # Criar parâmetros para implementação de GPO $gpoParams = @{ DomainName = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1" } se ($TargetOU) { $gpoParams.OUPath = $TargetOU } senão { # Utilize AutoDetectOU para permitir que o utilizador selecione $gpoParams.AutoDetectOU = $true } # Execute o script de implementação de GPO & $deployGpoScript @gpoParams se ($LASTEXITCODE -ne 0) { Write-Host "A implementação do GPO pode ter encontrado problemas. Reveja o resultado acima." -ForegroundColor Amarelo Write-Host "Pode continuar com a implementação do orquestrador ou premir Ctrl+C para abortar". -Primeiro PlanoColor Amarelo Write-Host "" Read-Host "Prima Enter para continuar" } senão { Write-Host "" Write-Host "GPO de deteção implementado com êxito!" -ForegroundColor Green Write-Host "" } } senão { Write-Host "" Write-Host "A ignorar a implementação do GPO. O orquestrador não receberá dados do dispositivo" -ForegroundColor Yellow Write-Host "até que o GPO de Deteção seja implementado manualmente". -ForegroundColor Amarelo Write-Host "" Write-Host "Para implementar o GPO de Deteção mais tarde, execute:" -ForegroundColor Cyan Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath"" -AutoDetectOU" -ForegroundColor White Write-Host "" } } } captura { Write-Host " Não é possível verificar o GPO: $($_. Exception.Message)" -ForegroundColor Yellow Write-Host " Continuação com a implementação do orquestrador..." -ForegroundColor Gray } } senão { Write-Host " GroupPolicy module not available - skipping GPO check" -ForegroundColor Gray Write-Host " Garantir que o GPO de Deteção é implementado separadamente." -ForegroundColor Gray }
Write-Host ""
# ============================================================================ # CRIAR ARGUMENTOS # ============================================================================
$arguments = @( "-NoProfile" "-ExecutionPolicy Bypass" "-Ficheiro '"$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 # A tarefa utilizará o caminho completo internamente
# ============================================================================ # CRIAR TAREFA AGENDADA # ============================================================================
# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue se ($existingTask) { Write-Host "A tarefa já existe. A atualizar..." -ForegroundColor Amarelo 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 } senão { # Pedir palavra-passe para a conta de domínio Write-Host "Introduzir palavra-passe para $ServiceAccount" -Primeiro PlanoColor Amarelo $cred = Get-Credential -UserName $ServiceAccount -Message "Credenciais da conta de serviço para a tarefa agendada" $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) # Permitir execução prolongada
# Register task experimente { if ($ServiceAccount -eq "SYSTEM") { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Secure Boot Certificate Deployment - Automated GPO deployment" } senão { Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description "Secure Boot Certificate Deployment - Automated GPO deployment" -User $ServiceAccount -Password $cred. GetNetworkCredential(). Palavra-passe } Write-Host "Tarefa agendada criada com êxito!" -Primeiro PlanoColor Verde } captura { Write-Host "Falha ao criar a tarefa agendada: $($_. Exception.Message)" -ForegroundColor Red sair 1 }
# ============================================================================ # CRIAR ATALHO DE ESTADO # ============================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (Test-Path $statusScript) { Write-Host "" Write-Host "Para verificar o estado da implementação, execute:" -ForegroundColor Amarelo Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath""" -ForegroundColor Cyan }
# ============================================================================ # SAÍDA # ============================================================================
Write-Host "" Write-Host ("=" * 70) -Primeiro PlanoColor Verde Write-Host " DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host ("=" * 70) -Primeiro PlanoColor Verde Write-Host "" Write-Host "O orquestrador começará em aproximadamente 1 minuto." -ForegroundColor White Write-Host "" Write-Host "MONITORIZAÇÃO:" -Primeiro PlanoColor Amarelo Write-Host " Ver estado da tarefa: Get-ScheduledTask -TaskName '$TaskName' | Selecionar Estado" Write-Host " Ver registo de tarefas: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyMMdd').log' -Tail 50" Write-Host " Ver estado de implementação: Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json" Write-Host " Ver dashboard: Iniciar '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html'" Write-Host " Estado rápido: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "GESTÃO:" -Primeiro PlanoColor Amarelo Write-Host " Iniciar manualmente: Start-ScheduledTask -TaskName '$TaskName'" Write-Host " Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host " Remove: .\Deploy-OrchestratorTask.ps1 -Uninstall" Write-Host ""