复制并粘贴此示例脚本,并根据需要针对环境进行修改:
<# .简介 启用安全启动更新计划任务。
.DESCRIPTION 此脚本可确保 Windows 安全启动更新计划任务 已启用 (\Microsoft\Windows\PI\Secure-Boot-Update) 。 如果禁用, 它启用它。 如果删除了任务,它可以重新创建它。
.PARAMETER Action 要执行的操作。 有效值:检查、启用、创建 - 检查:仅检查任务状态 - enable: (默认) 启用任务(如果禁用)。 如果缺少任务,系统会提示创建。- create:创建任务(如果不存在)
.PARAMETER ComputerName 选。 要检查/启用任务的计算机名称数组。如果未指定,则在本地计算机上运行。
.PARAMETER Credential 选。 用于远程计算机访问的凭据。
.PARAMETER Quiet 取消提示并自动回答“是”。 适用于自动化。
.EXAMPLE .\Enable-SecureBootTask.ps1 # 在本地计算机上启用任务状态
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 enable # 如果禁用,则启用任务。 如果缺少创建提示。
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 create # 创建任务(如果已删除),然后检查其状态
.EXAMPLE .\Check-SecureBootScheduledTask.ps1 检查 -ComputerName“PC1”、“PC2” # 检查远程计算机上的任务
.NOTES 需要管理员权限才能启用或创建任务。任务路径:\Microsoft\Windows\PI\Secure-Boot-Update 任务每 12 小时以提升的权限运行 taskhostw.exe。#>
[CmdletBinding(SupportsShouldProcess)] param ( [参数 (Position=0) ] [ValidateSet ('检查', 'enable', 'create', ') ] [string]$Action = 'enable',
[Parameter()] [string[]]$ComputerName,
[Parameter()] [PSCredential]$Credential,
[Parameter()] [别名 ('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 { [CmdletBinding () ] param ( [string]$Computer = $env:COMPUTERNAME )
$result = [PSCustomObject]@{ ComputerName = $Computer TaskExists = $false TaskState = $null IsEnabled = $false LastRunTime = $null NextRunTime = $null 错误 = $null }
try { 如果 ($Computer -eq $env:COMPUTERNAME -或 $Computer -eq “localhost” -或 $Computer -eq “”。) { # 使用 schtasks.exe 进行更可靠的任务检测 $schtasksOutput = schtasks.exe /Query /TN “$TaskPath$TaskName” /FO CSV 2>&1 如果 ($LASTEXITCODE -ne 0) { # 找不到任务不是错误 - 只是表示任务不存在 $result。TaskExists = $false 返回$result } # 分析 CSV 输出 $taskData = $schtasksOutput |ConvertFrom-Csv 如果 ($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 如果 ($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 { [CmdletBinding (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;;发;;;BA) (A;;发;;;SY) (A;;FRFX;;;LS) </SecurityDescriptor> <Source>'$ (@%SystemRoot%\system32\TpmTasks.dll,-601) </Source> <Author>'$ (@%SystemRoot%\system32\TpmTasks.dll,-600) </Author> <description>'$ (@%SystemRoot%\system32\TpmTasks.dll,-604) </Description> <URI>\Microsoft\Windows\PI\Secure-Boot-Update</URI> </RegistrationInfo> <主体> <主体 id=“LocalSystem”> <UserId>S-1-5-18</UserId> </Principal> </Principals> <设置> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> ><0 StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> ><4 ExecutionTimeLimit>PT1H</ExecutionTimeLimit> ><8 MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <StartWhenAvailable>true</StartWhenAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> (2 RestartOnIdle>false</RestartOnIdle> (6 /IdleSettings> (8 UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine> </设置> <触发器> <BootTrigger> <延迟>PT5M</延迟> (2 重复> (4 间隔>PT12H</Interval> (8 /Repetition> </BootTrigger> </Triggers> <Actions Context=“LocalSystem”> <ComHandler> <ClassId>{5014B7C8-934E-4262-9816-887FA745A6C4}</ClassId> <数据><![CDATA[SBServicing]]></Data> </ComHandler> </Actions> </Task> "@
try { 如果 ($Computer -eq $env:COMPUTERNAME -或 $Computer -eq “localhost” -或 $Computer -eq “”。) { if ($PSCmdlet.ShouldProcess (“$TaskPath$TaskName”、“Create scheduled task”) ) { # 将 XML 保存到临时文件并导入 $tempFile = [System.IO.Path]::GetTempFileName () $taskXml |Out-File -FilePath $tempFile -Encoding Unicode -Force $output = schtasks.exe /Create /TN “$TaskPath$TaskName” /XML $tempFile /F 2>&1 Remove-Item $tempFile -Force -ErrorAction SilentlyContinue 如果 ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join ” } } } else { 如果 ($PSCmdlet.ShouldProcess (“$Computer\$TaskPath$TaskName”、“创建计划任务”) ) { $result = Invoke-Command -ComputerName $Computer -ScriptBlock { param ($taskPath、$taskName、$xml) $tempFile = [System.IO.Path]::GetTempFileName () $xml |Out-File -FilePath $tempFile -Encoding Unicode -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 如果为 ($result,则为 。ExitCode -eq 0) { $success = $true } else { $errorMsg = $result。Output -join ” } } } } catch { $errorMsg = $_。Exception.Message }
return @{ Success = $success 错误 = $errorMsg } }
function Enable-SecureBootTask { [CmdletBinding (SupportsShouldProcess) ] param ( [string]$Computer = $env:COMPUTERNAME )
$success = $false $errorMsg = $null
try { 如果 ($Computer -eq $env:COMPUTERNAME -或 $Computer -eq “localhost” -或 $Computer -eq “”。) { 如果 ($PSCmdlet.ShouldProcess (“$TaskPath$TaskName”、“启用计划任务”) ) { $output = schtasks.exe /Change /TN “$TaskPath$TaskName” /ENABLE 2>&1 如果 ($LASTEXITCODE -eq 0) { $success = $true } else { $errorMsg = $output -join ” } } } else { 如果 ($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 如果 ($result,则为 。ExitCode -eq 0) { $success = $true } else { $errorMsg = $result。Output -join ” } } } } catch { $errorMsg = $_。Exception.Message }
return @{ Success = $success 错误 = $errorMsg } }
# Main execution Write-Host“” Write-Host “========================================” -ForegroundColor Cyan Write-Host“安全启动更新任务启用程序”-ForegroundColor Cyan Write-Host “========================================” -ForegroundColor Cyan Write-Host“” Write-Host“任务:$TaskPath$TaskName”-ForegroundColor Gray Write-Host“”
# Determine target computers $targets = if ($ComputerName) { $ComputerName } else { @ ($env:COMPUTERNAME) }
$results = @()
foreach ($computer in $targets) { Write-Host“正在检查: $computer”-ForegroundColor 黄色 $status = Get-SecureBootTaskStatus -Computer $computer 如果为 ($status,则为 。错误) { Write-Host“ 错误: $ ($status。错误) “ -ForegroundColor Red } elseif (-not $status。TaskExists) { Write-Host“此系统上不存在任务”-ForegroundColor 红色 # 如果请求创建,则提示;如果指定了 Enable,则提示 $shouldCreate = $Create 如果 (-not $shouldCreate -and $Enable) { Write-Host“” Write-Host“任务可能已删除”。-ForegroundColor Yellow 如果 ($Quiet) { Write-Host“自动创建任务 (安静模式) ”-ForegroundColor Cyan $shouldCreate = $true } else { $confirm = Read-Host“是否重新创建任务? (Y/N) ” 如果 ($confirm -eq 'Y' -或 $confirm -eq 'y') { $shouldCreate = $true } } } 如果 ($shouldCreate) { Write-Host“正在创建任务...” -ForegroundColor Yellow $createResult = New-SecureBootTask -Computer $computer if ($createResult.Success) { Write-Host“已成功创建任务”-ForegroundColor Green # 重新检查状态 $status = Get-SecureBootTaskStatus -Computer $computer 如果为 ($status,则为 。TaskExists) { $stateColor = 如果 ($status。IsEnabled) { “Green” } else { “Red” } Write-Host“状态:$ ($status。TaskState) “ -ForegroundColor $stateColor } } else { Write-Host“无法创建: $ ($createResult.错误) ” -ForegroundColor Red } } } else { $stateColor = 如果 ($status。IsEnabled) { “Green” } else { “Red” } Write-Host“状态:$ ($status。TaskState) “ -ForegroundColor $stateColor 如果 ($status。LastRunTime -and $status。LastRunTime -ne [DateTime]::MinValue) { Write-Host“上次运行:$ ($status。LastRunTime) “ -ForegroundColor Gray } 如果 ($status,则为 。NextRunTime -and $status。NextRunTime -ne [DateTime]::MinValue) { Write-Host“下次运行:$ ($status。NextRunTime) “ -ForegroundColor Gray }
# Enable if requested and currently disabled 如果 ($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.错误) ” -ForegroundColor Red } } elseif ($Enable -and $status。IsEnabled) { Write-Host“任务已启用”-ForegroundColor Green } } $results += $status Write-Host“” }
# Summary Write-Host “========================================” -ForegroundColor Cyan Write-Host “Summary” -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 } 如果 ($notFound -gt 0) { Write-Host“未找到: $notFound” -ForegroundColor Yellow } if ($errors -gt 0) { Write-Host “Errors: $errors” -ForegroundColor Red }
# Return results for pipeline $results