이 샘플 스크립트를 복사하여 붙여넣고 환경에 필요한 대로 수정합니다.

<# . 시놉시스     보안 부팅 롤아웃 오케스트레이터를 Windows 예약 작업으로 배포합니다.

.DESCRIPTION     백그라운드에서 지속적으로 오케스트레이터를 실행하는 예약된 작업을 만듭니다.작업은 무시 실행 정책을 사용하여 실행되므로 보안 프롬프트가 표시되지 않습니다.     오케스트레이터는 다음을 수행합니다.     - 지정된 간격에 대한 디바이스 업데이트 폴링     - 자동으로 웨이브 생성 및 GPO 배포     - 적격 디바이스가 모두 업데이트될 때까지 계속합니다     .     다음을 사용하여 진행률 모니터링: Get-SecureBootRolloutStatus.ps1

.PARAMETER AggregationInputPath     JSON 디바이스 데이터에 대한 UNC 경로(검색 GPO에서)

.PARAMETER ReportBasePath     보고서 및 상태 파일의 로컬 경로

.PARAMETER TargetOU     GPO를 연결하는 OU(선택 사항 - 기본값: 도메인 루트)

.PARAMETER PollIntervalMinutes     상태 확인 사이의 분입니다. 기본값: 30

.PARAMETER UseWinCS     AvailableUpdatesPolicy GPO 대신 WinCS(Windows 구성 시스템)를 사용합니다.사용하도록 설정하면 WinCsFlags.exe 예약된 작업을 레지스트리 GPO 대신 엔드포인트에 배포합니다.

.PARAMETER WinCSKey     보안 부팅 구성에 대한 WinCS 키입니다. 기본값: F33E0C8E002

.PARAMETER ServiceAccount     작업을 실행할 계정입니다. 기본값: SYSTEM     도메인 작업의 경우 도메인 관리 서비스 계정을 사용합니다.

.PARAMETER ScriptPath     오케스트레이터 스크립트의 경로입니다. 기본값: 이 스크립트와 동일한 폴더입니다.

.PARAMETER Uninstall     예약된 작업 제거

.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     # AvailableUpdatesPolicy 대신 WinCS 메서드를 사용하여 배포     .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports" -UseWinCS

.EXAMPLE     .\Deploy-OrchestratorTask.ps1 -제거 #>

[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 = "배포 및 모니터링 샘플"

# ============================================================================ # 종속성 유효성 검사 # ============================================================================

function Test-ScriptDependencies {     <#     . 시놉시스         필요한 모든 스크립트가 있는지 확인합니다.. 설명         필요한 스크립트 종속성을 확인하고 누락된 경우 다운로드 지침을 제공합니다.#>     param(         [Parameter(Mandatory = $true)]         [string]$ScriptDirectory,                  [Parameter(Mandatory = $true)]         [string[]]$RequiredScripts     )          $missingScripts = @()          foreach($RequiredScripts $script) {         $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 "누락된 종속성" -ForegroundColor Red         Write-Host ("=" * 70) -ForegroundColor Red         Write-Host ""         Write-Host "다음 필수 스크립트를 찾을 수 없습니다." -ForegroundColor 노란색         foreach($missingScripts $script) {             Write-Host " - $script" -ForegroundColor White         }         Write-Host ""         Write-Host "에서 최신 스크립트를 다운로드하세요:" -ForegroundColor Cyan         Write-Host " URL: $DownloadUrl" -ForegroundColor White         Write-Host "탐색: '$DownloadSubPage'" -ForegroundColor White         Write-Host ""         Write-Host "모든 스크립트를 동일한 디렉터리에 추출하고 다시 실행합니다." -ForegroundColor Yellow         Write-Host ""         return $false     }          return $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)) {     종료 1 }

# ============================================================================ # 제거 # ============================================================================

if ($Uninstall) {     Write-Host ""     Write-Host "예약된 작업 제거: $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 "작업이 성공적으로 제거되었습니다." -ForegroundColor 녹색     } else {         Write-Host "작업을 찾을 수 없습니다." -ForegroundColor 회색     }     종료 0 }     

# ============================================================================ # 유효성 검사 # ============================================================================

if (-not $AggregationInputPath -or -not $ReportBasePath) {     Write-Host "ERROR: -AggregationInputPath 및 -ReportBasePath가 필요합니다." -ForegroundColor Red     Write-Host ""     Write-Host "Example:" -ForegroundColor Yellow     Write-Host ' .\Deploy-OrchestratorTask.ps1 -AggregationInputPath "\\server\SecureBootData$" -ReportBasePath "C:\SecureBootReports"'     종료 1 }

# Find orchestrator script if (-not $ScriptPath) {     $ScriptPath = Join-Path $PSScriptRoot "Start-SecureBootRolloutOrchestrator.ps1" }

if (-not (Test-Path $ScriptPath)) {     Write-Host "ERROR: Orchestrator 스크립트를 찾을 수 없음: $ScriptPath" -ForegroundColor Red     종료 1 }

# Find aggregation script (needed by orchestrator) $aggregateScript = Join-Path $PSScriptRoot "Aggregate-SecureBootData.ps1" if (-not (Test-Path $aggregateScript)) {     Write-Host "경고: 스크립트 디렉터리에서 Aggregate-SecureBootData.ps1 찾을 수 없음" -ForegroundColor 노란색     Write-Host "이 스크립트를 찾을 수 없으면 오케스트레이터가 실패할 수 있습니다." -ForegroundColor Yellow }

Write-Host "" Write-Host ("=" * 70) -ForegroundColor Cyan Write-Host "보안 부팅 롤아웃 오케스트레이터 - 작업 배포" -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 " 작업 이름: $TaskName" Write-Host " Orchestrator: $displayScriptPath" Write-Host " 입력 경로: $AggregationInputPath" Write-Host " 보고서 경로: $ReportBasePath" Write-Host " 대상 OU: $(if ($TargetOU) { $TargetOU } else { '(domain root)' })" Write-Host "폴링 간격: $PollIntervalMinutes 분" Write-Host " 서비스 계정: $ServiceAccount" Write-Host " 배포 방법: $(if ($UseWinCS) { "WinCS (WinCsFlags.exe)" } else { "AvailableUpdatesPolicy (GPO)" })" if ($UseWinCS) {     Write-Host " WinCS 키: $WinCSKey" } Write-Host ""

# ============================================================================ # GPO 검색 - 누락된 경우 자동 배포 # ============================================================================

$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 "검색 GPO 확인..." -ForegroundColor 노란색     try {         # AggregationInputPath에서 도메인 가져오기(예: \\domain\share)         $domainFromPath = if ($AggregationInputPath -match '^\\\\([^\\]+)\\') {             $matches[1]         } else {             $env:USERDNSDOMAIN         }         # GPO가 있는지 확인         $existingGpo = Get-GPO -Name $CollectionGPOName -ErrorAction SilentlyContinue         if ($existingGpo) {             Write-Host " 검색 GPO 발견: $CollectionGPOName" -ForegroundColor 녹색         } else {             Write-Host ""             Write-Host ("=" * 70) -ForegroundColor Yellow             Write-Host "검색 GPO를 찾을 수 없음" -ForegroundColor 노란색             Write-Host ("=" * 70) -ForegroundColor Yellow             Write-Host ""             Write-Host "검색 GPO '$CollectionGPOName'을(를) 찾을 수 없습니다." -ForegroundColor Yellow             Write-Host "이 GPO는 디바이스 상태 데이터를 수집하는 데 필요합니다." -ForegroundColor Yellow             Write-Host ""             # 사용자에게 지금 GPO를 배포할 것인지 물어봅니다.             Write-Host "지금 검색 GPO를 배포하시겠습니까?                                          (Y/N)" -ForegroundColor Cyan             $response = 읽기 호스트                          if ($response -match '^[Yy]') {                 Write-Host ""                 Write-Host "GPO 배포 시작..." -ForegroundColor Cyan                 Write-Host ""                                  # GPO 배포를 위한 빌드 매개 변수                 $gpoParams = @{                     DomainName = $domainFromPath                     CollectionSharePath = $AggregationInputPath                     ScriptSourcePath = Join-Path $PSScriptRoot "Detect-SecureBootCertUpdateStatus.ps1"                 }                                  if ($TargetOU) {                     $gpoParams.OUPath = $TargetOU                 } else {                     # AutoDetectOU를 사용하여 사용자가 선택할 수 있도록 허용                     $gpoParams.AutoDetectOU = $true                 }                                  # GPO 배포 스크립트 실행                                 & $deployGpoScript @gpoParams                 if ($LASTEXITCODE -ne 0) {                     Write-Host "GPO 배포에 문제가 있을 수 있습니다. 위의 출력을 검토합니다." -ForegroundColor Yellow                     Write-Host "오케스트레이터 배포를 계속하거나 Ctrl+C를 눌러 중단할 수 있습니다." -ForegroundColor Yellow                     Write-Host ""                     Read-Host "계속하려면 Enter 키를 누릅니다."                 } else {                     Write-Host ""                     Write-Host "GPO 검색이 성공적으로 배포되었습니다!" -ForegroundColor Green                     Write-Host ""                 }             } else {                 Write-Host ""                 Write-Host "GPO 배포 건너뛰기. 오케스트레이터가 디바이스 데이터를 수신하지 않습니다." -ForegroundColor Yellow                 "검색 GPO가 수동으로 배포될 때까지" Write-Host. -ForegroundColor Yellow                 Write-Host ""                 Write-Host "나중에 검색 GPO를 배포하려면 run:" -ForegroundColor Cyan                 Write-Host " .\Deploy-GPO-SecureBootCollection.ps1 -DomainName '"$domainFromPath'" -AutoDetectOU" -ForegroundColor White                 Write-Host ""             }         }     } catch {         Write-Host " GPO에 대해 검사 수 없습니다. $($_) Exception.Message)" -ForegroundColor Yellow         Write-Host "오케스트레이터 배포 계속..." -ForegroundColor Gray     } } else {     Write-Host " GroupPolicy 모듈을 사용할 수 없음 - GPO 검사 건너뛰기" -ForegroundColor Gray     Write-Host "검색 GPO가 별도로 배포되었는지 확인합니다." -ForegroundColor Gray }

Write-Host ""

# ============================================================================ # BUILD 인수 # ============================================================================

$arguments = @(     "-NoProfile"     "-ExecutionPolicy 바이패스"     "-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 # 태스크는 내부적으로 전체 경로를 사용합니다.

# ============================================================================ # 예약된 작업 만들기 # ============================================================================

# Check for existing task $existingTask = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue if ($existingTask) {     Write-Host "작업이 이미 있습니다. 업데이트 중..." -ForegroundColor 노란색     Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue     Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false }

# Create task action $action = New-ScheduledTaskAction -"powershell.exe" 실행 -argument $argumentString -WorkingDirectory $PSScriptRoot

# Create trigger - run once, immediately (orchestrator loops internally) $trigger = New-ScheduledTaskTrigger -한 번 -At(Get-Date). AddMinutes(1)

# Create principal if ($ServiceAccount -eq "SYSTEM") {     $principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest } else {     # 도메인 계정에 대한 암호 프롬프트     Write-Host "$ServiceAccount 암호 입력" -ForegroundColor Yellow     $cred = Get-Credential -UserName $ServiceAccount -메시지 "예약된 작업에 대한 서비스 계정 자격 증명"     $principal = New-ScheduledTaskPrincipal -UserId $ServiceAccount -LogonType 암호 -RunLevel Highest }

# Task settings $settings = New-ScheduledTaskSettingsSet '     -AllowStartIfOnBatteries '     -DontStopIfGoingOnBatteries '     -StartWhenAvailable '     -RunOnlyIfNetworkAvailable '     -RestartCount 3 '     -RestartInterval(New-TimeSpan -Minutes 5) '     -ExecutionTimeLimit(New-TimeSpan -Days 30) # 장기 실행 허용

# Register task try {     if ($ServiceAccount -eq "SYSTEM") {         Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -description "보안 부팅 인증서 롤아웃 - 자동화된 GPO 배포"     } 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(). 암호     }     Write-Host "예약된 작업이 성공적으로 생성되었습니다!" -ForegroundColor Green } catch {     Write-Host "예약된 작업을 만들지 못했습니다. $($_) Exception.Message)" -ForegroundColor Red     종료 1 }

# ============================================================================ # 만들기 상태 바로 가기 # ============================================================================

$statusScript = Join-Path $PSScriptRoot "Get-SecureBootRolloutStatus.ps1" if (Test-Path $statusScript) {     Write-Host ""     Write-Host "롤아웃 상태 검사 실행:" -ForegroundColor Yellow     Write-Host " .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '"$ReportBasePath'" -ForegroundColor Cyan }

# ============================================================================ # OUTPUT # ============================================================================

Write-Host "" Write-Host ("=" * 70) -ForegroundColor Green Write-Host "DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host ("=" * 70) -ForegroundColor Green Write-Host "" Write-Host "오케스트레이터는 약 1분 후에 시작됩니다." -ForegroundColor White Write-Host "" Write-Host "MONITORING:" -ForegroundColor Yellow Write-Host " 작업 상태 보기: Get-ScheduledTask -TaskName '$TaskName' | 상태 선택" Write-Host " 작업 로그 보기: Get-Content '$ReportBasePath\RolloutState\Orchestrator_$(Get-Date -Format 'yyyyMMdd').log' -Tail 50" Write-Host " 출시 상태 보기: '$ReportBasePath\RolloutState\RolloutState.json' Get-Content | ConvertFrom-Json" Write-Host "dashboard 보기: '$ReportBasePath\Aggregation_*\SecureBoot_Dashboard*.html' 시작" Write-Host "빠른 상태: .\Get-SecureBootRolloutStatus.ps1 -ReportBasePath '$ReportBasePath'" Write-Host "" Write-Host "MANAGEMENT:" -ForegroundColor Yellow Write-Host "수동으로 시작: Start-ScheduledTask -TaskName '$TaskName'" Write-Host "중지: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host "제거: .\Deploy-OrchestratorTask.ps1 -제거" Write-Host ""  

도움이 더 필요하세요?

더 많은 옵션을 원하세요?

구독 혜택을 살펴보고, 교육 과정을 찾아보고, 디바이스를 보호하는 방법 등을 알아봅니다.