feat(process): add Start-InfisicalProcess with event-based capture and friendly TimeSpan logging

- New cmdlet Start-InfisicalProcess: launches a child process with InfisicalSecret
  objects decrypted directly into ProcessStartInfo.Environment (optional -Prefix),
  additional -EnvironmentVariables, stdout/stderr capture, -AcceptableExitCodeList,
  -ParsingExpression regex parsing, -ExecutionTimeout / -ExecutionTimeoutInterval,
  -NoWait, -WindowStyle / -CreateNoWindow parameter sets, -Priority,
  -StandardInputObjectList, -SecureArgumentList, -LogOutput, -ContinueOnError, and
  ShouldProcess support. Secret plaintext is never written to user or machine scope.
- Stream capture uses event-based OutputDataReceived/ErrorDataReceived with
  BeginOutputReadLine/BeginErrorReadLine (no Task / ReadToEndAsync /
  GetAwaiter().GetResult()) to avoid PowerShell SynchronizationContext deadlocks.
- Restored the do { log; sleep } while (!HasExited) polling pattern using
  Thread.Sleep(pollInterval) so verbose "has been running for X" / "Checking again
  in Y" messages fire at the configured cadence even when no -ExecutionTimeout is
  supplied.
- TimeSpan values in verbose logs and on the result now use a friendly format
  ("7 seconds, and 364 milliseconds", "1 minute, and 30 seconds", "N/A" when zero)
  matching the legacy Start-ProcessWithOutput GetTimeSpanMessage scriptblock.
- Added DurationFriendly property to InfisicalProcessResult and a "The command
  execution took X" verbose line at completion.
- build.ps1 CmdletsToExport and Test-ModuleImports expected list contain 42 cmdlets.
- Added 9 xUnit tests covering FormatFriendly singular/plural, multi-unit joining,
  zero, sub-millisecond, and skip-zero-components behavior.
This commit is contained in:
GraceSolutions
2026-06-06 18:29:30 -04:00
parent d3c7b83da7
commit 207e7429e4
11 changed files with 780 additions and 10 deletions
+42
View File
@@ -1491,6 +1491,48 @@ No warnings should be emitted.
---
# 16.6 Start-InfisicalProcess
Signature:
```text
Start-InfisicalProcess
-FilePath <string>
[-WorkingDirectory <DirectoryInfo>]
[-ArgumentList <string[]>]
[-AcceptableExitCodeList <string[]>]
[-WindowStyle <Normal|Hidden|Minimized|Maximized>]
[-CreateNoWindow]
[-NoWait]
[-Priority <AboveNormal|BelowNormal|High|Idle|Normal|RealTime>]
[-ExecutionTimeout <TimeSpan>]
[-ExecutionTimeoutInterval <TimeSpan>]
[-StandardInputObjectList <object[]>]
[-EnvironmentVariables <IDictionary>]
[-ParsingExpression <Regex>]
[-SecureArgumentList]
[-LogOutput]
[-ContinueOnError]
[-Secret <InfisicalSecret[]>]
[-Prefix <string>]
```
Behavior:
```text
Buffer pipeline InfisicalSecret objects in ProcessRecord.
Decrypt secrets only into ProcessStartInfo.Environment.
Apply -Prefix to each secret name before injection.
Never write secret plaintext to user or machine environment scope.
Honor -WhatIf / -Confirm.
Default -AcceptableExitCodeList = @('0','3010').
Throw a terminating error on unacceptable exit code unless -ContinueOnError is set.
```
Output: `InfisicalProcessResult` with `ExitCode`, `ExitCodeAsHex`, `ExitCodeAsInteger`, `ExitCodeAsDecimal`, `StandardOutput`, `StandardError`, `StandardOutputObject`, `StandardErrorObject`, `StartTime`, `ExitTime`, `Duration`, `DurationFriendly`, `ProcessId`, `TimedOut`, `Succeeded`, `SecretCount`.
---
# 17. SecureString Utility
Required utility: