Copie e cole este script de exemplo e modifique conforme necessário para seu ambiente:
<# . SINOPSE Implanta o Orquestrador de Distribuição de Inicialização Segura como uma tarefa agendada pelo 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 bypass para que não sejam exibidas solicitações de segurança. O orquestrador fará: – Sondagem para atualizações de dispositivo no intervalo especificado – Gerar ondas automaticamente e implantar GPOs – Continue até que todos os dispositivos qualificados sejam atualizados Monitorar o progresso usando: Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath Caminho UNC para dados de dispositivo JSON (do GPO de detecção)
.PARAMETER ReportBasePath Caminho local para relatórios e arquivos de estado
.PARAMETER TargetOU OU para vincular GPOs (opcional – padrões à raiz do domínio)
.PARAMETER PollIntervalMinutes Minutos entre verificações de status. Padrão: 30
.PARAMETER UseWinCS Use WinCS (Sistema de Configuração do Windows) em vez de GPO AvailableUpdatesPolicy.Quando habilitado, implanta WinCsFlags.exe tarefa agendada em pontos de extremidade em vez de GPO do registro.
.PARAMETER WinCSKey A chave WinCS para configuração de Inicialização Segura. Padrão: F33E0C8E002
.PARAMETER ServiceAccount Conta para executar a tarefa. Padrão: SYSTEM Para operações de domínio, use uma conta de serviço de administrador de domínio.
.PARAMETER ScriptPath Caminho para o script do orquestrador. Padrã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 # Implantar usando o método WinCS em vez de AvailableUpdatesPolicy .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -Desinstalar #>
[CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$AggregationInputPath, [Parameter(Mandatory = $false)] [string]$ReportBasePath, [Parameter(Mandatory = $false)] [string]$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)] [string]$ScriptPath, [Parameter(Mandatory = $false)] [alternar]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = "SecureBoot-Rollout-Orchestrator" $DownloadUrl = "https://aka.ms/getsecureboot" $DownloadSubPage = "Exemplos de implantação e monitoramento"
# ============================================================================ # VALIDAÇÃO DE DEPENDÊNCIA # ============================================================================
function Test-ScriptDependencies { <# . SINOPSE 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 download se estiver ausente.#> param( [Parameter(Mandatory = $true)] [string]$ScriptDirectory, [Parameter(Mandatory = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script no $RequiredScripts) { $scriptPath = Join-Path $ScriptDirectory $script if (-not (test-path $scriptPath)) { $missingScripts += $script } } se ($missingScripts.Count -gt 0) { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Red Write-Host " DEPENDÊNCIAS AUSENTES" -ForegroundColor Red Write-Host ("=" * 70) -ForegroundColor Red Write-Host "" Write-Host "Os seguintes scripts necessários não foram encontrados:" -ForegroundColor Yellow foreach ($script no $missingScripts) { Write-Host " - $script" -ForegroundColor White } Write-Host "" Write-Host "Baixe os scripts mais recentes de:" -ForegroundColor Cyan Write-Host " URL: $DownloadUrl" -ForegroundColor White Write-Host " Navegar até: '$DownloadSubPage'" -ForegroundColor White Write-Host "" Write-Host "Extrair todos os scripts para o mesmo diretório e executar novamente." -ForegroundColor Yellow Write-Host "" retornar $false } retornar $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)) { saída 1 }
# ============================================================================ # UNINSTALL # ============================================================================
if ($Uninstall) { Write-Host "" Write-Host "Removendo a tarefa agendada: $TaskName" -ForegroundColor Yellow $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." -ForegroundColor Green } else { Write-Host "Tarefa não encontrada". -ForegroundColor Gray } saída 0 }
# ============================================================================ # VALIDAÇÃO # ============================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host "ERROR: -AggregationInputPath e -ReportBasePath são necessários." -ForegroundColor Red Write-Host "" Write-Host "Example:" -ForegroundColor Yellow Write-Host ' .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"' saída 1 }
# Find orchestrator script if (-not $ScriptPath) { $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }
if (-not (Test-Path $ScriptPath)) { Write-Host "ERROR: script do orquestrador não encontrado: $ScriptPath" -ForegroundColor Red saída 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 script" -ForegroundColor Yellow Write-Host " O Orquestrador pode falhar se não conseguir encontrar este script." -ForegroundColor Yellow }
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host " Orquestrador de Distribuição de Inicialização Segura – Implantação de Tarefas" -Cyan ForegroundColor 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 " TARGET OU: $(if ($TargetOU) { $TargetOU } else { '(raiz de domínio)' })" Write-Host " Intervalo de Votação: $PollIntervalMinutes minutos" Write-Host " Conta de Serviço: $ServiceAccount" Write-Host " Método de Implantação: $(if ($UseWinCS) { "WinCS (WinCsFlags.exe)" } else { "AvailableUpdatesPolicy (GPO)" })" se ($UseWinCS) { Write-Host " WinCS Key: $WinCSKey" } Write-Host ""
# ============================================================================ # DETECÇÃO DE GPO – IMPLANTAÇÃO AUTOMÁTICA SE ESTIVER AUSENTE # ============================================================================
$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 "Verificando o GPO de Detecção..." -ForegroundColor Yellow try { # Obter o domínio do AggregationInputPath (por exemplo, \\domain\share) $domainFromPath = se ($AggregationInputPath -match '^\\\\([^\\]+)\\') { { $matches[1] } else { $env:USERDNSDOMAIN } # Verificar se o GPO existe $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue se ($existingGpo) { Write-Host " GPO de detecção encontrado: $CollectionGPOName" -ForegroundColor Green } else { Write-Host "" Write-Host ("=" * 70) -ForegroundColor Yellow Write-Host " DETECTION GPO NOT FOUND" -ForegroundColor Yellow Write-Host ("=" * 70) -ForegroundColor Yellow Write-Host "" Write-Host "O GPO de detecção '$CollectionGPOName' não foi encontrado." -ForegroundColor Yellow Write-Host "Esse GPO é necessário para coletar dados do dispositivo status." -ForegroundColor Yellow Write-Host "" # Pergunte ao usuário se ele deseja implantar o GPO agora Write-Host "Você gostaria de implantar o GPO de Detecção agora? (Y/N)" -Cyan ForegroundColor $response = Host de Leitura se ($response -match '^[Yy]') { Write-Host "" Write-Host "Iniciando a implantação de GPO..." -ForegroundColor Cyan Write-Host "" # Compilar parâmetros para implantação de GPO $gpoParams = @{ DomainName = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1" } se ($TargetOU) { $gpoParams.OUPath = $TargetOU } else { # Usar AutoDetectOU para permitir que o usuário selecione $gpoParams.AutoDetectOU = $true } # Executar o script de implantação de GPO & $deployGpoScript @gpoParams se ($LASTEXITCODE -ne 0) { Write-Host "A implantação de GPO pode ter encontrado problemas. Examine a saída acima." -ForegroundColor Yellow Write-Host "Você pode continuar com a implantação do orquestrador ou pressionar Ctrl+C para abortar." -ForegroundColor Yellow Write-Host "" Read-Host "Pressione Enter para continuar" } else { Write-Host "" Write-Host "GPO de detecção implantado com êxito!" -ForegroundColor Green Write-Host "" } } else { Write-Host "" Write-Host "Ignorar a implantação de GPO. O orquestrador não receberá dados do dispositivo" -ForegroundColor Yellow Write-Host "até que o GPO de Detecção seja implantado manualmente." -ForegroundColor Yellow Write-Host "" Write-Host "Para implantar o GPO de Detecção mais tarde, execute:" -ForegroundColor Cyan Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath'" -AutoDetectOU" -ForegroundColor White Write-Host "" } } } catch { Write-Host " Não é possível marcar para GPO: $($_. Exception.Message)" -ForegroundColor Yellow Write-Host " Continuando com a implantação do orquestrador..." -ForegroundColor Gray } } else { Write-Host " Módulo GroupPolicy não disponível - ignorando gpo marcar" -ForegroundColor Gray Write-Host " Garantir que o GPO de Detecção seja implantado separadamente." -ForegroundColor Gray }
Write-Host ""
# ============================================================================ # ARGUMENTOS BUILD # ============================================================================
$arguments = @( "-NoProfile" "-ExecutionPolicy Bypass" "-Arquivo '"$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 usará 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. Atualizando..." -ForegroundColor Yellow Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false }
# Create task action $action = New-ScheduledTaskAction -Executar "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 se ($ServiceAccount -eq "SYSTEM") { $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest } else { # Solicitar senha para a conta de domínio Write-Host "Inserir senha para $ServiceAccount" -ForegroundColor Yellow $cred = Get-Credential -UserName $ServiceAccount -Mensagem "Credenciais da conta de serviço para 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 longa
# Register task try { se ($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(). Senha } Write-Host "Tarefa agendada criada com êxito!" -ForegroundColor Green } catch { Write-Host "Falha ao criar uma tarefa agendada: $($_. Exception.Message)" -ForegroundColor Red saída 1 }
# ============================================================================ # CRIAR ATALHO DE STATUS # ============================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" se ($statusScript de caminho de teste) { Write-Host "" Write-Host "Para marcar status de distribuição, execute:" -ForegroundColor Yellow Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'"" -ForegroundColor Cyan }
# ============================================================================ # SAÍDA # ============================================================================
Write-Host "" Write-Host ("=" * 70) -ForegroundColor Green Write-Host " DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host ("=" * 70) -ForegroundColor Green Write-Host "" Write-Host "O orquestrador começará em aproximadamente 1 minuto." -ForegroundColor White Write-Host "" Write-Host "MONITORING:" -ForegroundColor Yellow Write-Host " Exibir status de tarefas: Get-ScheduledTask -TaskName '$TaskName' | Selecionar Estado" Write-Host " Exibir log de tarefas: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyyMMdd').log' -Tail 50" Write-Host " Exibir estado de distribuição: Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json" Write-Host " Exibir dashboard: iniciar '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html'" Write-Host " status rápido: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "MANAGEMENT:" -ForegroundColor Yellow Write-Host " Iniciar manualmente: Start-ScheduledTask -TaskName '$TaskName'" Write-Host " Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host " Remover: .\Deploy-OrchestratorTask.ps1 -Desinstalar" Write-Host ""