[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 '托管计划、单实例、重启次数、无执行时限、分钟触发及脚本语法检查通过;未注册或启动任何任务。'