param(
[Parameter(Mandatory)][int]$TargetProcessId,
[Parameter(Mandatory)][ValidateSet('describe','read','health.read','session.status')][string]$Operation,
[ValidateSet('Navigation','Interaction')][string]$Service = 'Navigation',
[string]$OutputPath
)
$ErrorActionPreference = 'Stop'
if ($TargetProcessId -le 0) { throw 'A selected process ID is required.' }
if ($OutputPath -and (Test-Path -LiteralPath $OutputPath)) { throw 'Use a new evidence path.' }
$stream = [IO.Pipes.NamedPipeClientStream]::new('.', "XFEEDToolBox.$Service.$TargetProcessId", [IO.Pipes.PipeDirection]::InOut, [IO.Pipes.PipeOptions]::Asynchronous)
try {
$stream.Connect(2000)
$writer = [IO.StreamWriter]::new($stream, [Text.UTF8Encoding]::new($false), 1024, $true)
$reader = [IO.StreamReader]::new($stream, [Text.UTF8Encoding]::new($false, $true), $false, 65536, $true)
try {
$writer.AutoFlush = $true
$writer.WriteLine((@{ op = $Operation } | ConvertTo-Json -Compress))
$reply = $reader.ReadLineAsync().WaitAsync([TimeSpan]::FromSeconds(2)).GetAwaiter().GetResult()
if (!$reply -or $reply.Length -ge 65536) { throw 'Empty or oversized observer response.' }
$decoded = $reply | ConvertFrom-Json
if (!$decoded.ok) { throw $decoded.error }
$result = $decoded.result | ConvertTo-Json -Depth 30
if ($OutputPath) { [IO.File]::WriteAllText([IO.Path]::GetFullPath($OutputPath), $result) }
$result
} finally { $reader.Dispose(); $writer.Dispose() }
} finally { $stream.Dispose() }
param(
[Parameter(Mandatory)][int]$TargetProcessId,
[Parameter(Mandatory)][ValidateSet('describe','read','health.read','session.status')][string]$Operation,
[ValidateSet('Navigation','Interaction')][string]$Service = 'Navigation',
[string]$OutputPath
)
$ErrorActionPreference = 'Stop'
if ($TargetProcessId -le 0) { throw 'A selected process ID is required.' }
if ($OutputPath -and (Test-Path -LiteralPath $OutputPath)) { throw 'Use a new evidence path.' }
$stream = [IO.Pipes.NamedPipeClientStream]::new('.', "XFEEDToolBox.$Service.$TargetProcessId", [IO.Pipes.PipeDirection]::InOut, [IO.Pipes.PipeOptions]::Asynchronous)
try {
$stream.Connect(2000)
$writer = [IO.StreamWriter]::new($stream, [Text.UTF8Encoding]::new($false), 1024, $true)
$reader = [IO.StreamReader]::new($stream, [Text.UTF8Encoding]::new($false, $true), $false, 65536, $true)
try {
$writer.AutoFlush = $true
$writer.WriteLine((@{ op = $Operation } | ConvertTo-Json -Compress))
$reply = $reader.ReadLineAsync().WaitAsync([TimeSpan]::FromSeconds(2)).GetAwaiter().GetResult()
if (!$reply -or $reply.Length -ge 65536) { throw 'Empty or oversized observer response.' }
$decoded = $reply | ConvertFrom-Json
if (!$decoded.ok) { throw $decoded.error }
$result = $decoded.result | ConvertTo-Json -Depth 30
if ($OutputPath) { [IO.File]::WriteAllText([IO.Path]::GetFullPath($OutputPath), $result) }
$result
} finally { $reader.Dispose(); $writer.Dispose() }
} finally { $stream.Dispose() }