Fix Windows TrustedInstaller session errors

- Fix errors (stderr stream) not being logged.
- Use `schtasks /delete` instead of `Unregister-ScheduledTask` as
  PowerShell command sometimes fail for existing tasks.
- Refactor to use `-TaskName` to explicit describe parameter, and use
  linebreaks for `Register-ScheduledTask` call with many parameters.
This commit is contained in:
undergroundwires
2021-11-09 00:14:56 +01:00
parent a40f83d6b6
commit 20a0071c0d

View File

@@ -6100,31 +6100,46 @@ functions:
call: call:
function: RunPowerShell function: RunPowerShell
parameters: parameters:
# schtasks.exe
# PowerShell commands (Unregister-ScheduledTask and Get-ScheduledTask) sometimes fail to find existing tasks.
# They are seen to throw different exceptions:
# - `ObjectNotFound: (MSFT_ScheduledTask:Root/Microsoft/...T_ScheduledTask)` with `HRESULT 0x80070002`
# - `No MSFT_ScheduledTask objects found with property 'TaskName'`
# - `The system cannot find the file specified`
# So schtasks.exe is used instead of those:
# > `schtasks.exe /delete /tn "$taskName" /f 2>&1 | Out-Null`
# Replaces `Unregister-ScheduledTask $taskName -Confirm:$false`
# > `"$(schtasks.exe /query /tn "$taskName" 2>$null)".Contains('Running')`
# Replaces `Get-ScheduledTask -TaskName $taskName).State -eq 'Running'`
code: |- code: |-
$command = '{{ $code }}'
$trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464') $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464')
$trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]) $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount])
$command = '{{ $code }}' $streamOutFile = New-TemporaryFile
$stdOutFile = New-TemporaryFile
$batchFile = New-TemporaryFile $batchFile = New-TemporaryFile
$powerShellFile = New-TemporaryFile $powerShellFile = New-TemporaryFile
try { try {
$batchFile = Rename-Item $batchFile "$($batchFile.BaseName).bat" -PassThru $batchFile = Rename-Item $batchFile "$($batchFile.BaseName).bat" -PassThru
"@echo off`r`n$command`r`nexit 0" | Out-File $batchFile -Encoding ASCII "@echo off`r`n$command`r`nexit 0" | Out-File $batchFile -Encoding ASCII
$taskName = 'privacy.sexy invoke' $taskName = 'privacy.sexy invoke'
if(Get-ScheduledTask $taskName -ErrorAction Ignore) { # Something may have gone wrong before schtasks.exe /delete /tn "$taskName" /f 2>&1 | Out-Null # Clean if something went wrong before
Unregister-ScheduledTask $taskName -Confirm:$false
}
$taskAction = New-ScheduledTaskAction ` $taskAction = New-ScheduledTaskAction `
-Execute 'cmd.exe' ` -Execute 'cmd.exe' `
-Argument "cmd /c `"$batchFile`" > $stdOutFile" -Argument "cmd /c `"$batchFile`" > $streamOutFile 2>&1"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null Register-ScheduledTask `
-TaskName $taskName `
-Action $taskAction `
-Settings $settings `
-Force `
-ErrorAction Stop `
| Out-Null
try { try {
($scheduleService = New-Object -ComObject Schedule.Service).Connect() ($scheduleService = New-Object -ComObject Schedule.Service).Connect()
$scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null
$timeOutLimit = (Get-Date).AddMinutes(5) $timeOutLimit = (Get-Date).AddMinutes(5)
Write-Host "Running as $trustedInstallerName" Write-Host "Running as $trustedInstallerName"
while((Get-ScheduledTask $taskName).State -eq 'Running') { while("$(schtasks.exe /query /tn "$taskName" 2>$null)".Contains('Running')) {
Start-Sleep -Milliseconds 200 Start-Sleep -Milliseconds 200
if((Get-Date) -gt $timeOutLimit) { if((Get-Date) -gt $timeOutLimit) {
Write-Warning "Skipping results, it took so long to execute script." Write-Warning "Skipping results, it took so long to execute script."
@@ -6135,36 +6150,41 @@ functions:
Write-Error "Failed to execute with exit code: $result." Write-Error "Failed to execute with exit code: $result."
} }
} finally { } finally {
Unregister-ScheduledTask $taskName -Confirm:$false schtasks.exe /delete /tn "$taskName" /f | Out-Null # Outputs only errors
} }
Get-Content $stdOutFile Get-Content $streamOutFile
} finally { } finally {
Remove-Item $stdOutFile, $batchFile # Remove-Item $streamOutFile, $batchFile
} }
revertCode: |- # Duplicated until custom pipes are implemented revertCode: |- # Duplicated until custom pipes are implemented
$command = '{{ $revertCode }}'
$trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464') $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464')
$trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]) $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount])
$command = '{{ $revertCode }}' $streamOutFile = New-TemporaryFile
$stdOutFile = New-TemporaryFile
$batchFile = New-TemporaryFile $batchFile = New-TemporaryFile
$powerShellFile = New-TemporaryFile
try { try {
$batchFile = Rename-Item $batchFile "$($batchFile.BaseName).bat" -PassThru $batchFile = Rename-Item $batchFile "$($batchFile.BaseName).bat" -PassThru
"@echo off`r`n$command`r`nexit 0" | Out-File $batchFile -Encoding ASCII "@echo off`r`n$command`r`nexit 0" | Out-File $batchFile -Encoding ASCII
$taskName = 'privacy.sexy invoke' $taskName = 'privacy.sexy invoke'
if(Get-ScheduledTask $taskName -ErrorAction Ignore) { # Something may have gone wrong before schtasks.exe /delete /tn "$taskName" /f 2>&1 | Out-Null # Clean if something went wrong before
Unregister-ScheduledTask $taskName -Confirm:$false
}
$taskAction = New-ScheduledTaskAction ` $taskAction = New-ScheduledTaskAction `
-Execute 'cmd.exe' ` -Execute 'cmd.exe' `
-Argument "cmd /c `"$batchFile`" > $stdOutFile" -Argument "cmd /c `"$batchFile`" > $streamOutFile 2>&1"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null Register-ScheduledTask `
-TaskName $taskName `
-Action $taskAction `
-Settings $settings `
-Force `
-ErrorAction Stop `
| Out-Null
try { try {
($scheduleService = New-Object -ComObject Schedule.Service).Connect() ($scheduleService = New-Object -ComObject Schedule.Service).Connect()
$scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null
$timeOutLimit = (Get-Date).AddMinutes(5) $timeOutLimit = (Get-Date).AddMinutes(5)
Write-Host "Running as $trustedInstallerName" Write-Host "Running as $trustedInstallerName"
while((Get-ScheduledTask $taskName).State -eq 'Running') { while("$(schtasks.exe /query /tn "$taskName" 2>$null)".Contains('Running')) {
Start-Sleep -Milliseconds 200 Start-Sleep -Milliseconds 200
if((Get-Date) -gt $timeOutLimit) { if((Get-Date) -gt $timeOutLimit) {
Write-Warning "Skipping results, it took so long to execute script." Write-Warning "Skipping results, it took so long to execute script."
@@ -6175,11 +6195,11 @@ functions:
Write-Error "Failed to execute with exit code: $result." Write-Error "Failed to execute with exit code: $result."
} }
} finally { } finally {
Unregister-ScheduledTask $taskName -Confirm:$false schtasks.exe /delete /tn "$taskName" /f | Out-Null # Outputs only errors
} }
Get-Content $stdOutFile Get-Content $streamOutFile
} finally { } finally {
Remove-Item $stdOutFile, $batchFile Remove-Item $streamOutFile, $batchFile
} }
- -
name: DisableServiceInRegistry name: DisableServiceInRegistry