Files
ycode/scripts/ops/dev-processes.ps1
T

35 lines
2.2 KiB
PowerShell

# Read-only snapshot or identity-checked termination. Input is JSON over stdin;
# repository paths/commands are never evaluated as PowerShell source.
$ErrorActionPreference = 'Stop'
$request = [Console]::In.ReadToEnd() | ConvertFrom-Json
function Identity($p) {
[PSCustomObject]@{ pid = [int]$p.ProcessId; parentPid = [int]$p.ParentProcessId; name = $p.Name; commandLine = [string]$p.CommandLine; created = $(if ($null -ne $p.CreationDate) { $p.CreationDate.ToUniversalTime().ToString('o') } else { '' }) }
}
if ($request.action -eq 'stop') {
$stopped = @()
foreach ($expected in $request.processes) {
$p = Get-CimInstance Win32_Process -Filter ('ProcessId = ' + [int]$expected.pid)
if ($null -eq $p) { continue }
$actual = Identity $p
if (-not $expected.created -or -not $expected.commandLine -or $actual.created -ne $expected.created -or $actual.commandLine -cne $expected.commandLine) { throw ('PROCESS_IDENTITY_CHANGED:' + $expected.pid) }
# Open a handle before the final identity check so termination cannot select a reused PID.
$handle = [System.Diagnostics.Process]::GetProcessById([int]$expected.pid)
$null = $handle.Handle
$again = Get-CimInstance Win32_Process -Filter ('ProcessId = ' + [int]$expected.pid)
if ($null -eq $again) { $handle.Dispose(); continue }
$identity = Identity $again
if ($identity.created -ne $expected.created -or $identity.commandLine -cne $expected.commandLine) { $handle.Dispose(); throw ('PROCESS_IDENTITY_CHANGED:' + $expected.pid) }
$handle.Kill()
$handle.Dispose()
$stopped += [int]$expected.pid
}
@{ stopped = $stopped } | ConvertTo-Json -Compress
exit
}
$processes = @(Get-CimInstance Win32_Process | ForEach-Object { Identity $_ })
$windows = @(Get-Process electron -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowHandle -ne 0 } | ForEach-Object {
@{ pid = $_.Id; title = $_.MainWindowTitle; responding = $_.Responding }
})
$listeners = @(Get-NetTCPConnection -State Listen -ErrorAction Stop | ForEach-Object { @{ pid = $_.OwningProcess; port = $_.LocalPort; address = $_.LocalAddress } })
@{ processes = $processes; windows = $windows; listeners = $listeners } | ConvertTo-Json -Depth 5 -Compress