Copiez et collez cet exemple de script et modifiez-le si nécessaire pour votre environnement :
<# . SYNOPSIS Déploie l’orchestrateur de déploiement de démarrage sécurisé en tant que tâche planifiée Windows.
.DESCRIPTION Crée une tâche planifiée qui exécute l’orchestrateur en continu en arrière-plan.La tâche s’exécute avec une stratégie d’exécution de contournement afin qu’aucune invite de sécurité ne s’affiche. L’orchestrateur : - Interroger les mises à jour des appareils à l’intervalle spécifié - Générer automatiquement des vagues et déployer des objets de stratégie de groupe - Continuer jusqu’à ce que tous les appareils éligibles soient mis à jour Surveiller la progression à l’aide de : Get-SecureBootRolloutStatus.ps1
.PARAMETER AggregationInputPath Chemin d’accès UNC aux données d’appareil JSON (à partir de l’objet de stratégie de groupe de détection)
.PARAMETER ReportBasePath Chemin d’accès local pour les rapports et les fichiers d’état
.PARAMETER TargetOU Unité d’organisation pour lier des objets de stratégie de groupe (facultatif - la valeur par défaut est la racine du domaine)
.PARAMETER PollIntervalMinutes Minutes entre vérifications d’état. Valeur par défaut : 30
.PARAMETER UseWinCS Utilisez WinCS (Système de configuration Windows) au lieu de l’objet de stratégie de groupe AvailableUpdatesPolicy.Lorsqu’il est activé, déploie WinCsFlags.exe tâche planifiée sur des points de terminaison au lieu d’un objet de stratégie de groupe du Registre.
.PARAMETER WinCSKey Clé WinCS pour la configuration du démarrage sécurisé. Valeur par défaut : F33E0C8E002
.PARAMETER ServiceAccount Compte pour exécuter la tâche. Par défaut : SYSTEM Pour les opérations de domaine, utilisez un compte de service d’administration de domaine.
.PARAMETER ScriptPath Chemin d’accès au script d’orchestrateur. Par défaut : même dossier que ce script.
.PARAMETER Uninstall Supprimer la tâche planifiée
.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 # Déployer à l’aide de la méthode WinCS au lieu de AvailableUpdatesPolicy .\Deploy-OrchestratorTask.ps1 -AggregationInputPath « \\server\SecureBootData$ » -ReportBasePath « C :\SecureBootReports » -UseWinCS
.EXAMPLE .\Deploy-OrchestratorTask.ps1 -Uninstall #>
[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)] [switch]$Uninstall )
$ErrorActionPreference = "Stop" $TaskName = « SecureBoot-Rollout-Orchestrator » $DownloadUrl = « https://aka.ms/getsecureboot » $DownloadSubPage = « Exemples de déploiement et de surveillance »
# ============================================================================ # VALIDATION DES DÉPENDANCES # ============================================================================
function Test-ScriptDependencies { <# . SYNOPSIS Vérifie que tous les scripts requis sont présents.. DESCRIPTION Recherche les dépendances de script requises et fournit des instructions de téléchargement si elles sont manquantes.#> param( [Parameter(Mandatory = $true)] [string]$ScriptDirectory, [Parameter(Mandatory = $true)] [string[]]$RequiredScripts ) $missingScripts = @() foreach ($script dans $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 « DÉPENDANCES MANQUANTES » -ForegroundColor Red Write-Host (« = » * 70) -ForegroundColor Red Write-Host « » Write-Host « Les scripts requis suivants sont introuvables » -ForegroundColor Yellow foreach ($script dans $missingScripts) { Write-Host " - $script » -ForegroundColor White } Write-Host « » Write-Host « Veuillez télécharger les derniers scripts à partir de : » -ForegroundColor Cyan Write-Host " URL : $DownloadUrl » -ForegroundColor White Write-Host « Accéder à : '$DownloadSubPage' » -ForegroundColor White Write-Host « » Write-Host « Extraire tous les scripts dans le même répertoire et réexécuter ». -ForegroundColor Yellow Write-Host « » $false de retour } $true de retour }
# 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)) { sortie 1 }
# ============================================================================ # UNINSTALL # ============================================================================
if ($Uninstall) { Write-Host « » Write-Host « Suppression de la tâche planifiée : $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 « Tâche supprimée avec succès ». -ForegroundColor Vert } else { Write-Host « Tâche introuvable ». -ForegroundColor Gray } sortie 0 }
# ============================================================================ # VALIDATION # ============================================================================
if (-not $AggregationInputPath -or -not $ReportBasePath) { Write-Host « ERROR : -AggregationInputPath et -ReportBasePath are required. » -ForegroundColor Red Write-Host « » Write-Host « Example : » -ForegroundColor Yellow Write-Host '.\Deploy-OrchestratorTask.ps1 -AggregationInputPath « \\server\SecureBootData$ » -ReportBasePath « C :\SecureBootReports"' sortie 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 sortie 1 }
# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot « Aggregate-SecureBootData.ps1 » if (-not (Test-Path $aggregateScript)) { Write-Host « AVERTISSEMENT : Aggregate-SecureBootData.ps1 introuvable dans le répertoire de script » -ForegroundColor Yellow Write-Host « Orchestrator peut échouer s’il ne trouve pas ce script ». -ForegroundColor Yellow }
Write-Host "" Write-Host (« = » * 70) -ForegroundColor Cyan Write-Host « Secure Boot Rollout 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 « Nom de la tâche : $TaskName » Write-Host « Orchestrator : $displayScriptPath » Write-Host « Chemin d’entrée : $AggregationInputPath » Write-Host « Chemin d’accès du rapport : $ReportBasePath » Write-Host « Unité d’organisation cible : $(if ($TargetOU) { $TargetOU } else { '(domain root)' }) » » Write-Host « Intervalle d’interrogation : $PollIntervalMinutes minutes » Write-Host « Compte de service : $ServiceAccount » Write-Host « Deployment Method : $(if ($UseWinCS) { « WinCS (WinCsFlags.exe) » } else { « AvailableUpdatesPolicy (GPO) » }) " » if ($UseWinCS) { Write-Host « Clé WinCS : $WinCSKey » } Write-Host « »
# ============================================================================ # DÉTECTION D’OBJETS DE STRATÉGIE DE GROUPE - DÉPLOIEMENT AUTOMATIQUE S’IL EST MANQUANT # ============================================================================
$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 « Vérification de l’objet de stratégie de groupe de détection... » -ForegroundColor Yellow try { # Obtenir le domaine à partir de AggregationInputPath (par exemple, \\domaine\share) $domainFromPath = if ($AggregationInputPath -match '^\\\\([^\]+)\\') { $matches[1] } else { $env :USERDNSDOMAIN } # Vérifier si l’objet de stratégie de groupe existe $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue if ($existingGpo) { Write-Host « Objet de stratégie de groupe de détection trouvé : $CollectionGPOName » -ForegroundColor Vert } 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 « L’objet de stratégie de groupe de détection '$CollectionGPOName' est introuvable. » -ForegroundColor Yellow Write-Host « Cet objet de stratégie de groupe est requis pour collecter des données de status d’appareil ». -ForegroundColor Yellow Write-Host « » # Demander à l’utilisateur s’il souhaite déployer l’objet de stratégie de groupe maintenant Write-Host « Voulez-vous déployer l’objet de stratégie de groupe détection maintenant ? (Y/N)" -ForegroundColor Cyan $response = Hôte en lecture if ($response -match '^[Yy]') { Write-Host « » Write-Host « Lancement du déploiement d’objets de stratégie de groupe... » -ForegroundColor Cyan Write-Host « » # Paramètres de build pour le déploiement d’objets de stratégie de groupe $gpoParams = @{ DomainName = $domainFromPath CollectionSharePath = $AggregationInputPath ScriptSourcePath = Join-Path $PSScriptRoot « Detect-SecureBootCertUpdateStatus.ps1 » } if ($TargetOU) { $gpoParams.OUPath = $TargetOU } else { # Utiliser AutoDetectOU pour permettre à l’utilisateur de sélectionner $gpoParams.AutoDetectOU = $true } # Exécuter le script de déploiement de l’objet de stratégie de groupe & $deployGpoScript @gpoParams if ($LASTEXITCODE -ne 0) { Write-Host « Le déploiement d’objet de stratégie de groupe a peut-être rencontré des problèmes. Passez en revue la sortie ci-dessus." -ForegroundColor Yellow Write-Host « Vous pouvez poursuivre le déploiement de l’orchestrateur ou appuyer sur Ctrl+C pour abandonner . » -ForegroundColor Yellow Write-Host « » Read-Host « Appuyez sur Entrée pour continuer » } else { Write-Host « » Write-Host « Objet de stratégie de groupe de détection déployé avec succès ! » -ForegroundColor Vert Write-Host « » } } else { Write-Host « » Write-Host « Ignorer le déploiement des objets de stratégie de groupe. L’orchestrateur ne recevra pas les données de l’appareil » -ForegroundColor Yellow Write-Host « jusqu’à ce que l’objet de stratégie de groupe Détection soit déployé manuellement ». -ForegroundColor Yellow Write-Host « » Write-Host « Pour déployer l’objet de stratégie de groupe détection ultérieurement, exécutez : » -ForegroundColor Cyan Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath' » -AutoDetectOU » -ForegroundColor White Write-Host « » } } } catch { Write-Host « Impossible de case activée pour l’objet de stratégie de groupe : $($_. Exception.Message)" -ForegroundColor Yellow Write-Host « Poursuite du déploiement de l’orchestrateur... » -ForegroundColor Gray } } else { Write-Host « Module GroupPolicy non disponible - ignorer l’case activée d’objet de stratégie de groupe » -ForegroundColor Gray Write-Host « Vérifier que l’objet de stratégie de groupe de détection est déployé séparément ». -ForegroundColor Gray }
Write-Host ""
# ============================================================================ # ARGUMENTS DE 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 # La tâche utilise le chemin d’accès complet en interne
# ============================================================================ # CREATE SCHEDULED TASK # ============================================================================
# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) { Write-Host « La tâche existe déjà. Mise à jour..." -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 { # Invite de mot de passe pour le compte de domaine Write-Host « Entrer le mot de passe pour $ServiceAccount » -ForegroundColor Yellow $cred = Get-Credential -UserName $ServiceAccount -Message « Informations d’identification du compte de service pour la tâche planifiée » $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) # Autoriser l’exécution longue
# Register task try { 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(). Mot de passe } Write-Host « Tâche planifiée créée avec succès ! » -ForegroundColor Vert } catch { Write-Host « Impossible de créer la tâche planifiée : $($_. Exception.Message)" -ForegroundColor Red sortie 1 }
# ============================================================================ # CRÉER UN RACCOURCI D’ÉTAT # ============================================================================
$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (Test-Path $statusScript) { Write-Host « » Write-Host « Pour case activée déploiement status, exécutez : » -ForegroundColor Yellow Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'" » -ForegroundColor Cyan }
# ============================================================================ # SORTIE # ============================================================================
Write-Host "" Write-Host (« = » * 70) -ForegroundColor Vert Write-Host « DEPLOYMENT COMPLETE » -ForegroundColor Vert Write-Host (« = » * 70) -ForegroundColor Vert Write-Host « » Write-Host « L’orchestrateur démarre dans environ 1 minute ». -ForegroundColor White Write-Host « » Write-Host « MONITORING : » -ForegroundColor Yellow Write-Host " Afficher les status de tâches : Get-ScheduledTask -TaskName '$TaskName' | Sélectionner l’état » Write-Host " Afficher le journal des tâches : Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyyyMMdd').log' -Tail 50 » Write-Host " Afficher l’état de déploiement : Get-Content '$ReportBasePath\RolloutState\RolloutState.json' | ConvertFrom-Json » Write-Host « Afficher le tableau de bord : Démarrer '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html' » Write-Host « Quick status : .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath' » Write-Host « » Write-Host « MANAGEMENT : » -ForegroundColor Yellow Write-Host « Démarrer manuellement : Start-ScheduledTask -TaskName '$TaskName' » Write-Host « Arrêter : Stop-ScheduledTask -TaskName '$TaskName' » Write-Host « Supprimer : .\Deploy-OrchestratorTask.ps1 -Uninstall » Write-Host « »