# 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