Скопируйте и вставьте этот пример скрипта и измените его при необходимости для своей среды:
<# . ОБЗОР Включает запланированную задачу безопасного обновления загрузки.
.DESCRIPTION Этот скрипт обеспечивает выполнение запланированной задачи безопасного обновления Windows (\Microsoft\Windows\PI\Secure-Boot-Update) включен. Если этот параметр отключен, он включает его. Если задача была удалена, она может воссоздать ее.
.PARAMETER Action Выполняемая действие. Допустимые значения: проверка, включить, создать — проверка: только проверка состояние задачи — включить: (по умолчанию) Включите задачу, если она отключена. Если задача отсутствует, выводится запрос на создание.— create: создайте задачу, если она не существует.
.PARAMETER ComputerName Дополнительные. Массив имен компьютеров для проверка или включения задачи.Если не указано, выполняется на локальном компьютере.
.PARAMETER Credential Дополнительные. Учетные данные для доступа к удаленному компьютеру.
.PARAMETER Quiet Подавляет запросы и автоматически отвечает "Да". Полезно для автоматизации.
.EXAMPLE .\Enable-SecureBootTask.ps1 # Включает состояние задачи на локальном компьютере
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 enable # Включает задачу, если она отключена. Запросы для создания, если отсутствует.
.EXAMPLE Создание \Check-SecureBootScheduledTask.ps1 # Создает задачу, если она была удалена, а затем проверяет ее состояние
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 проверка -ComputerName "PC1", "PC2" # Проверка задачи на удаленных компьютерах
.NOTES Для включения или создания задачи требуются права администратора.Путь к задаче: \Microsoft\Windows\PI\Secure-Boot-Update Задача выполняется taskhostw.exe каждые 12 часов с повышенными привилегиями.#>
[CmdletBinding(SupportsShouldProcess)] param( [Parameter(Position=0)] [ValidateSet('проверка', 'enable', 'create', '')] [string]$Action = 'enable',
[Parameter()] [string[]]$ComputerName,
[Parameter()] [PSCredential]$Credential,
[Parameter()] [Alias('Force', 'Silent']] [switch]$Quiet )
# Convert Action to switches for backward compatibility $Enable = $Action -eq 'enable' $Create = $Action -eq 'create'
# Download URL: https://aka.ms/getsecureboot -> "Deployment and Monitoring Samples" # Примечание. Этот скрипт выполняется на конечных точках для включения задачи "Обновление безопасной загрузки".
$TaskPath = "\Microsoft\Windows\PI\" $TaskName = "Secure-Boot-Update"
function Get-SecureBootTaskStatus { [КомандлетBinding()] param( [string]$Computer = $env:COMPUTERNAME )
$result = [PSCustomObject]@{ ComputerName = $Computer TaskExists = $false TaskState = $null IsEnabled = $false LastRunTime = $null NextRunTime = $null Ошибка = $null }
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { # Использование schtasks.exe для более надежного обнаружения задач $schtasksOutput = schtasks.exe /Query /TN "$TaskPath$TaskName" /FO CSV 2>&1 if ($LASTEXITCODE -ne 0) { # Задача не найдена не является ошибкой — просто означает, что задача не существует $result. TaskExists = $false $result возврата } # Анализ выходных данных CSV $taskData = $schtasksOutput | ConvertFrom-Csv if ($taskData) { $result. TaskExists = $true $result. TaskState = $taskData.Status $result. IsEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running') # Попробуйте получить время следующего выполнения из данных if ($taskData.'Next Run Time' -and $taskData.'Next Run Time' -ne 'N/A') { try { $result. NextRunTime = [DateTime]::P arse($taskData.'Next Run Time') } catch { } } } } else { # Удаленный компьютер — использование Invoke-Command с schtasks $remoteResult = Invoke-Command -ComputerName $Computer -ScriptBlock { param($fullTaskName) $output = schtasks.exe /Query /TN $fullTaskName /FO CSV 2>&1 @{ ExitCode = $LASTEXITCODE Выходные данные = $output } } -ArgumentList "$TaskPath$TaskName" -ErrorAction Stop
if ($remoteResult.ExitCode -ne 0) { # Задача не найдена не является ошибкой — просто означает, что задача не существует $result. TaskExists = $false $result возврата }
$taskData = $remoteResult.Output | ConvertFrom-Csv if ($taskData) { $result. TaskExists = $true $result. TaskState = $taskData.Status $result. IsEnabled = ($taskData.Status -eq 'Ready' -or $taskData.Status -eq 'Running') } } } catch { $result. Ошибка = $_. Exception.Message }
return $result }
function New-SecureBootTask { [КомандлетBinding(SupportsShouldProcess)] param( [string]$Computer = $env:COMPUTERNAME )
$success = $false $errorMsg = $null
# Task definition - matches the original Windows Secure Boot Update task # Использует ComHandler с классом SBServicing, выполняется как LocalSystem $taskXml = @" <?xml version="1.0" encoding="UTF-16"?> <Task version="1.6" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Дата>2012-02-07T16:39:20</Date> <SecurityDescriptor>O:BAG:BAD:P(A;; FA;;; BA)(A;; FA;;; SY)(A;; FRFX;; LS)</SecurityDescriptor> <источник>'$(@%SystemRoot%\system32\TpmTasks.dll,-601)</Source> <Author>'$(@%SystemRoot%\system32\TpmTasks.dll,-600)</Author> описание <>'$(@%SystemRoot%\system32\TpmTasks.dll,-604)</Description> <URI>\Microsoft\Windows\PI\Secure-Boot-Update</URI> </RegistrationInfo> > субъектов < <Principal id="LocalSystem"> <UserId>S-1-5-18</UserId> </Principal> ></Principals > параметров < <запретитьStartIfOnBatteries>false</DisallowStartIfOnBatteries> ><0 StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> ><4 ExecutionTimeLimit>PT1H</ExecutionTimeLimit> ><8 MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <StartWhenAvailable>true</StartWhenAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> </Settings> триггеры <> >BootTrigger < <задержка>PT5M</Delay> > повторения < интервал <>PT12H</Interval> ></Повторение </BootTrigger> </Triggers> <Actions Context="LocalSystem"> <ComHandler> <ClassId>{5014B7C8-934E-4262-9816-887FA745A6C4}</ClassId> <>< данных! [CDATA[SBServicing]]></Data> </ComHandler> </Actions> </Task> " @
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { if ($PSCmdlet.ShouldProcess("$TaskPath$TaskName", "Create scheduled task")) { # Сохранение XML в временный файл и импорт $tempFile = [System.IO.Path]::GetTempFileName() $taskXml | Out-File -FilePath $tempFile -Encoding Юникод -Force $output = schtasks.exe /Create /TN "$TaskPath$TaskName" /XML $tempFile /F 2>&1 Remove-Item $tempFile -Force -ErrorAction SilentlyContinue if ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join " " } } } else { if ($PSCmdlet.ShouldProcess("$Computer\$TaskPath$TaskName", "Create scheduled task")) { $result = Invoke-Command -ComputerName $Computer -ScriptBlock { param($taskPath, $taskName, $xml) $tempFile = [System.IO.Path]::GetTempFileName() $xml | Out-File -FilePath $tempFile -Encoding Юникод -Force $output = schtasks.exe /Create /TN "$taskPath$taskName" /XML $tempFile /F 2>&1 Remove-Item $tempFile -Force -ErrorAction SilentlyContinue @{ ExitCode = $LASTEXITCODE; Output = $output } } -ArgumentList $TaskPath, $TaskName, $taskXml -ErrorAction Stop if ($result. ExitCode -eq 0) { $success = $true } else { $errorMsg = $result. Output -join " " } } } } catch { $errorMsg = $_. Exception.Message }
return @{ Успех = $success Ошибка = $errorMsg } }
function Enable-SecureBootTask { [КомандлетBinding(SupportsShouldProcess)] param( [string]$Computer = $env:COMPUTERNAME )
$success = $false $errorMsg = $null
try { if ($Computer -eq $env:COMPUTERNAME -or $Computer -eq "localhost" -or $Computer -eq ".") { if ($PSCmdlet.ShouldProcess("$TaskPath$TaskName", "Включить запланированную задачу")) { $output = schtasks.exe /Change /TN "$TaskPath$TaskName" /ENABLE 2>&1 if ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join " } } } else { if ($PSCmdlet.ShouldProcess("$Computer\$TaskPath$TaskName", "Включить запланированную задачу")) { $result = Invoke-Command -ComputerName $Computer -ScriptBlock { param($fullTaskName) $output = schtasks.exe /Change /TN $fullTaskName /ENABLE 2>&1 @{ ExitCode = $LASTEXITCODE; Output = $output } } -ArgumentList "$TaskPath$TaskName" -ErrorAction Stop if ($result. ExitCode -eq 0) { $success = $true } else { $errorMsg = $result. Output -join " " } } } } catch { $errorMsg = $_. Exception.Message }
return @{ Успех = $success Ошибка = $errorMsg } }
# Main execution Write-Host "" Write-Host "========================================" -ForegroundColor Cyan Write-Host "Включение задач обновления безопасной загрузки" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "Задача: $TaskPath$Имя_задачи" -ForegroundColor Gray Write-Host ""
# Determine target computers $targets = if ($ComputerName) { $ComputerName } else { @($env:COMPUTERNAME) }
$results = @()
foreach ($computer in $targets) { Write-Host "Проверка: $computer" -ForegroundColor Yellow $status = Get-SecureBootTaskStatus -Computer $computer if ($status. Ошибка) { Write-Host "Ошибка: $($status. Ошибка)" - ForegroundColor Red } elseif (не $status. TaskExists) { Write-Host "Задача не существует в этой системе" -ForegroundColor Red # Создание при запросе или запрос, если параметр Enable был указан $shouldCreate = $Create if (-not $shouldCreate -and $Enable) { Write-Host "" Write-Host "Возможно, задача была удалена". -ForegroundColor Yellow if ($Quiet) { Write-Host "Автоматическое создание задачи (тихий режим)" -ForegroundColor Cyan $shouldCreate = $true } else { $confirm = Read-Host "Вы хотите воссоздать задачу? (Г/Н)" if ($confirm -eq 'Y' -or $confirm -eq 'y') { $shouldCreate = $true } } } if ($shouldCreate) { Write-Host "Создание задачи..." -ForegroundColor Yellow $createResult = New-SecureBootTask -Computer $computer if ($createResult.Success) { Write-Host "Задача создана успешно" -ForegroundColor Green # Состояние повторного проверка $status = Get-SecureBootTaskStatus -Computer $computer if ($status. TaskExists) { $stateColor = if ($status. IsEnabled) { "Green" } else { "Red" } Write-Host "State: $($status. TaskState)" -ForegroundColor $stateColor } } else { Write-Host "Не удалось создать: $($createResult.Error)" -ForegroundColor Red } } } else { $stateColor = if ($status. IsEnabled) { "Green" } else { "Red" } Write-Host "State: $($status. TaskState)" -ForegroundColor $stateColor if ($status. LastRunTime — и $status. LastRunTime -ne [DateTime]::MinValue) { Write-Host "Последний запуск: $($status. LastRunTime)" -ForegroundColor Gray } if ($status. NextRunTime и $status. NextRunTime -ne [DateTime]::MinValue) { Write-Host "Следующий запуск: $($status. NextRunTime)" -ForegroundColor Gray }
# Enable if requested and currently disabled if ($Enable -and -not $status. IsEnabled) { Write-Host "Включение задачи..." -ForegroundColor Yellow $enableResult = Enable-SecureBootTask -Computer $computer if ($enableResult.Success) { Write-Host "Задача включена успешно" -ForegroundColor Green # Состояние повторного проверка $status = Get-SecureBootTaskStatus -Computer $computer } else { Write-Host "Не удалось включить: $($enableResult.Error)" -ForegroundColor Red } } elseif ($Enable -and $status. IsEnabled) { Write-Host "Задача уже включена" -ForegroundColor Green } } $results += $status Write-Host "" }
# Summary Write-Host "========================================" -ForegroundColor Cyan Write-Host "Сводка" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
$enabled = ($results | Where-Object { $_.IsEnabled }).Count $disabled = ($results | Where-Object { $_. TaskExists -and -not $_. IsEnabled }). Рассчитывать $notFound = ($results | Where-Object { -not $_. TaskExists }). Рассчитывать $errors = ($results | Where-Object { $_. Ошибка }). Рассчитывать
Write-Host "Total Checked: $($results.Count)" Write-Host "Включено: $enabled" -ForegroundColor Green if ($disabled -gt 0) { Write-Host "Disabled: $disabled" -ForegroundColor Red } if ($notFound -gt 0) { Write-Host "Не найдено: $notFound" -ForegroundColor Yellow } if ($errors -gt 0) { Write-Host "Errors: $errors" -ForegroundColor Red }
# Return results for pipeline $results