Execution
5.2.1
Common execution helpers, self-elevation and stub-script wrapper for PowerShell.
Minimum PowerShell version
5.1
Installation Options
Owners
Copyright
(c) 2026 mtb.me. All rights reserved.
Package Details
Author(s)
- Manuel
Tags
Execution Self-Elevation Stub PowerShell Windows
Functions
Clear-TempDirectories ConvertTo-SplatHashtable Exit-AndWaitOnUI Format-SplatHashtable Get-QuotedPath Invoke-NativeCommand Invoke-StubScript Invoke-WhenFileChanged Remove-ItemSafe Remove-NativeProgressNoise Restart-SelfElevated Set-PSScriptID
PSEditions
Dependencies
This module has no dependencies.
Release Notes
Execution v5.2.1+sha.6347929
## [v5.2.1] - 2026-05-06
### Changed
- User-facing string formatting: identifier interpolations
(paths, names, refs, hashes) are now consistently wrapped in
single quotes inside `Write-Verbose` / `Write-Host` / `Write-Debug`
messages, matching the convention used by built-in PowerShell
cmdlets. Pure formatting change; no logic, parameter, or behaviour
impact.
- `Get-ScriptIsCalledFromUI`: matcher rewritten to walk the parent
chain shape-aware rather than slot-aware. Console-host noise
(`conhost.exe`, `OpenConsole.exe`) is filtered out of the
meaningful chain regardless of the depth at which Windows inserts
it, and the function recognises both classic .cmd-stub
double-clicks (`pwsh.exe|powershell.exe` -> `cmd.exe` ->
`explorer.exe`) and direct .ps1 file-association /
drag-onto-pwsh-icon launches (`pwsh.exe|powershell.exe` ->
`explorer.exe`). Run-from-open-cmd (extra `cmd.exe` between the
stub's `cmd.exe` and `explorer.exe`) and run-from-open-pwsh shapes
continue to return `$false`. Adds an internal `-ProcessId` test
seam; the only production caller (`Exit-AndWaitOnUI`) still
invokes the function with no arguments and is unaffected.
### Fixed
- `Get-ScriptIsCalledFromUI`: hang on PID-reuse cycles in the
`Win32_Process.ParentProcessId` chain. Symptom: a `.cmd` stub
double-click would loop forever emitting verbose
`Query CimInstances ... ProcessId = N` lines for a small set of
system PIDs (typically a 3-PID services / wininit / lsass-class
cycle). Root cause: the parent-chain walk only terminated when
CIM returned no record, so any cycle in `ParentProcessId`
produced an infinite loop. Walk now tracks visited PIDs in a
`HashSet[int]` and terminates on the first repeat, plus has a
hard depth cap of 32 as defense-in-depth. Self-loops, 2-cycles
and arbitrarily deep linear chains all terminate cleanly.
Function is now covered by Pester tests under
`tests/Private/Get-ScriptIsCalledFromUI.Tests.ps1`, including a
Stopwatch-based regression check that asserts the cycle case
returns in well under a second.
### Fixed
- `Invoke-NativeCommand -Encoding Unicode|BigEndianUnicode|UTF8BOM`:
no longer leaks a leading U+FEFF (the Byte Order Mark) into the
first captured stdout / stderr line. Native tools that emit a BOM
(sfc.exe is the prominent Windows example, but any program that
writes UTF-16 LE / BE or UTF-8-with-BOM is affected) used to
surface that BOM as an invisible first character in `Stdout[0]` /
`Output[0]` and live `-Stream` output -- visible in
`Start-Transcript` logs and any byte-level consumer. Root cause:
.NET's `BeginOutputReadLine` routes through the internal
`AsyncStreamReader`, which calls `encoding.GetDecoder()` directly
and therefore skips the BOM detection that the regular
`StreamReader(stream, encoding)` constructor performs by default
(`detectEncodingFromByteOrderMarks: true`). The raw BOM bytes
decode to U+FEFF and prefix the first `OutputDataReceived` event.
`Read-NativeEventBatch` now delegates to a new private
`Remove-LeadingBom` helper that strips a single leading U+FEFF from
the first non-empty data event of each stream (state tracked
per-stream via `[ref]` flags so the strip persists across the
many polling-loop drain calls under `-Stream`). Mid-stream U+FEFF
is left untouched -- BOM is only semantically valid at stream
start, so there are no false positives. Default-on, no new
parameter; nobody wants the BOM in their captured output.
FileList
- Execution.nuspec
- Execution.psd1
- Execution.psm1
Version History
| Version | Downloads | Last updated |
|---|---|---|
| 5.3.2 | 20 | 5/11/2026 |
| 5.3.1 | 135 | 5/8/2026 |
| 5.3.0 | 103 | 5/7/2026 |
| 5.2.1 (current version) | 48 | 5/6/2026 |
| 5.2.0 | 85 | 5/6/2026 |
| 5.1.0 | 105 | 5/5/2026 |
| 5.0.0 | 7 | 5/5/2026 |
| 4.0.0 | 70 | 5/4/2026 |
| 3.0.1 | 497 | 4/16/2026 |
| 3.0.0 | 7 | 4/16/2026 |
| 2.1.1 | 1,663 | 12/29/2025 |
| 2.1.0 | 6 | 12/29/2025 |
| 2.0.2 | 75,833 | 4/28/2024 |
| 2.0.1 | 328 | 4/27/2024 |
| 2.0.0 | 11 | 4/26/2024 |
| 1.7.0 | 23,958 | 3/9/2020 |
| 1.6.2 | 447 | 2/5/2020 |
| 1.6.1 | 86 | 2/3/2020 |
| 1.6.0 | 42 | 2/3/2020 |
| 1.5.1 | 2,278 | 4/24/2019 |
| 1.5.0 | 201 | 4/1/2019 |
| 1.4.4 | 51 | 3/31/2019 |
| 1.4.3 | 43 | 3/31/2019 |
| 1.4.2 | 45 | 3/31/2019 |
| 1.4.1 | 43 | 3/30/2019 |
| 1.4.0 | 42 | 3/30/2019 |
| 1.3.0 | 43 | 3/30/2019 |
| 1.2.2 | 43 | 3/29/2019 |
| 1.2.1 | 42 | 3/29/2019 |
| 1.2.0 | 67 | 3/28/2019 |
| 1.1.0 | 48 | 3/27/2019 |
| 1.0.2 | 46 | 3/26/2019 |
| 1.0.1 | 104 | 3/17/2019 |
| 1.0.0 | 68 | 3/17/2019 |