PayrollManagementSystem/scripts/windows/Test-PayrollTaskPlan.ps1

52 lines
3.6 KiB
PowerShell
Raw Normal View History

[CmdletBinding()]
param([Parameter(Mandatory=$true)][string]$ProjectRoot, [Parameter(Mandatory=$true)][string]$PythonPath,
[Parameter(Mandatory=$true)][string]$ConnectionFile, [Parameter(Mandatory=$true)][string]$RuntimeDirectory)
. (Join-Path $PSScriptRoot 'TaskHost.Common.ps1')
foreach ($value in @('C:\', '\\server\share\', 'C:\path with spaces\', 'C:\ordinary')) {
$quoted = Quote-TaskArgument $value
$tail = [regex]::Match($value, '\\+$').Value
if ($quoted -ne ('"' + $value + $tail + '"')) { throw '尾反斜线必须保留并加倍。' }
}
$trustedSid = 'S-1-5-18'
$publicSid = 'S-1-5-32-545'
function New-TestRule([string]$Sid, [Security.AccessControl.FileSystemRights]$Rights) {
return [Security.AccessControl.FileSystemAccessRule]::new(
[Security.Principal.SecurityIdentifier]::new($Sid), $Rights, [Security.AccessControl.AccessControlType]::Allow)
}
Assert-PayrollAccessRules -Rules @(New-TestRule $trustedSid FullControl) -TrustedSids @($trustedSid) -PrivateFile $true
Assert-PayrollAccessRules -Rules @(New-TestRule $publicSid ReadAndExecute) -TrustedSids @($trustedSid)
foreach ($case in @(@{Rights='Modify'; Private=$false}, @{Rights='Read'; Private=$true})) {
$rejected = $false
try { Assert-PayrollAccessRules -Rules @(New-TestRule $publicSid $case.Rights) -TrustedSids @($trustedSid) -PrivateFile $case.Private }
catch { $rejected = $true }
if (-not $rejected) { throw '必须拒绝公共主体写程序或读取连接配置。' }
}
$account = [Security.Principal.WindowsIdentity]::GetCurrent().Name
$expectedPrincipal = [pscustomobject]@{ServiceSid=(Resolve-PayrollAccountSid $account); LogonType='Interactive'}
Assert-PayrollTaskPrincipal -Actual ([pscustomobject]@{UserId=$account; LogonType='Interactive'; RunLevel='Limited'}) -Expected $expectedPrincipal
$rejected = $false
try { Assert-PayrollTaskPrincipal -Actual ([pscustomobject]@{UserId=$account; LogonType='Interactive'; RunLevel='Highest'}) -Expected $expectedPrincipal }
catch { $rejected = $true }
if (-not $rejected) { throw '必须拒绝运行身份提权漂移。' }
$plan = Get-PayrollTaskPlan -ProjectRoot $ProjectRoot -PythonPath $PythonPath -ConnectionFile $ConnectionFile `
-RuntimeDirectory $RuntimeDirectory -TaskPath '\PayrollManagementSystem-Test-1234abcd\'
if ($plan.Tasks.Count -ne 3 -or $plan.EnabledOnInstall) { throw '任务数量或默认启用状态错误。' }
foreach ($task in $plan.Tasks) {
if ($task.Arguments -match '(-Command|password=|--password)') { throw '动作不得包含动态命令或密码。' }
if (-not $task.Arguments.Contains('-File "')) { throw '动作须通过明确脚本入口启动。' }
if ($task.Arguments.Contains('--reload')) { throw '托管后端不能使用开发重载。' }
}
$settings = Get-PayrollTaskSettings
if ($settings.MultipleInstances -ne 'IgnoreNew' -or $settings.RestartCount -ne 3 -or
$settings.RestartInterval -ne 'PT1M' -or $settings.ExecutionTimeLimit -ne 'PT0S' -or $settings.Enabled) {
throw '重启、单实例或长任务设置不符合约定。'
}
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes 1)
if ($trigger.Repetition.Interval -ne 'PT1M') { throw '周期检查应每分钟触发。' }
foreach ($file in Get-ChildItem -LiteralPath $PSScriptRoot -Filter '*.ps1') {
$tokens = $null; $errors = $null
[Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$errors) | Out-Null
if ($errors.Count) { throw ('脚本语法错误:' + $file.Name) }
}
Write-Output '托管计划、单实例、重启次数、无执行时限、分钟触发及脚本语法检查通过;未注册或启动任何任务。'