memstechtips/Winhance · error · InvalidOperationException
In-memory PowerShell script failed (exit code {exitCode}): {
Error message
In-memory PowerShell script failed (exit code {exitCode}):
{errors} What it means
InvalidOperationException thrown by PowerShellRunner's in-memory script path (the -EncodedCommand route) when the launched powershell.exe returned a non-zero exit code AND produced stderr output. The script bytes are Base64-encoded and passed via -EncodedCommand to bypass execution policy; if PowerShell errors, the combined errors string is folded into the message.
Source
Thrown at src/Winhance.Infrastructure/Features/Common/Utilities/PowerShellRunner.cs:91
if (string.IsNullOrEmpty(script))
throw new ArgumentException("Script cannot be null or empty.", nameof(script));
var scriptBytes = Encoding.Unicode.GetBytes(script);
if (scriptBytes.Length > MaxEncodedScriptBytes)
{
throw new ArgumentException(
$"Script is {scriptBytes.Length} bytes (UTF-16); -EncodedCommand path supports up to {MaxEncodedScriptBytes}. Use RunScriptAsync for larger scripts.",
nameof(script));
}
var encoded = Convert.ToBase64String(scriptBytes);
var args = $"-ExecutionPolicy Bypass -NoProfile -EncodedCommand {encoded}";
var (output, errors, exitCode) = await LaunchPowerShellAsync(args, progress, ct).ConfigureAwait(false);
if (exitCode != 0 && errors.Length > 0)
{
throw new InvalidOperationException(
$"In-memory PowerShell script failed (exit code {exitCode}):\n{errors}");
}
return output.ToString();
}
/// <summary>
/// Executes a PowerShell script file via Windows PowerShell 5.1 (powershell.exe).
/// Stdout is captured line-by-line for progress reporting (Write-Host output).
/// If execution policy blocks the script, retries with -EncodedCommand.
/// </summary>
public async Task<string> RunScriptFileAsync(
string scriptPath,
string arguments = "",
IProgress<TaskProgressDetail>? progress = null,
CancellationToken ct = default)
{
if (string.IsNullOrEmpty(scriptPath))
View on GitHub (pinned to f23d554eb2)
Solutions
- Read the {errors} portion of the message — it contains PowerShell's own error record (usually the most direct clue).
- Run the same script from a file via RunScriptFileAsync, or paste it into a powershell.exe window, to reproduce interactively.
- If Constrained Language Mode is active, relax the AppLocker/WDAC policy for the script path or run from a trusted location.
- Ensure any modules/cmdlets the script uses are installed (Install-Module) for the same user/edition running powershell.exe (5.1, not pwsh).
- Add explicit `try/catch` and `$ErrorActionPreference` handling inside the script so it reports a clean exit instead of surfacing as stderr.
Example fix
// before: throw only when exitCode != 0 AND errors present — a failing-but-silent script slips through
if (exitCode != 0 && errors.Length > 0)
throw new InvalidOperationException($"In-memory PowerShell script failed (exit code {exitCode}):\n{errors}");
// after: treat any non-zero exit as failure and always include available output
if (exitCode != 0)
throw new InvalidOperationException($"In-memory PowerShell script failed (exit code {exitCode}). Errors: {errors}. Output: {output}"); Defensive patterns
Strategy: try-catch
Validate before calling
// Optional pre-flight: ensure the script has no obvious syntax issue and required modules exist. // At minimum, gate EncodedCommand use on script size. bool ShouldUseEncodedCommand(byte[] scriptBytes) => scriptBytes.Length <= MaxEncodedScriptBytes;
Try / catch
catch (InvalidOperationException ex) when (ex.Message.Contains("In-memory PowerShell script failed"))
{
// The {errors} substring carries PowerShell's own error record — surface it verbatim to the user.
// Fall back to RunScriptFileAsync (writes the script to disk) if Constrained Language Mode blocked the encoded form.
} Prevention
- Read the {errors} portion of the message first — it usually names the failing cmdlet/line.
- For complex scripts, prefer RunScriptFileAsync over the EncodedCommand path.
- Ensure referenced modules are installed for Windows PowerShell 5.1 (not pwsh).
- Add try/catch and explicit $ErrorActionPreference inside scripts to avoid stderr-driven failures.
When it happens
Trigger: RunScript via the EncodedCommand path: scriptBytes (UTF-16) are under the MaxEncodedScriptBytes cap, encoded, and powershell.exe runs with -ExecutionPolicy Bypass -NoProfile -EncodedCommand <base64>. Non-zero exit + non-empty errors triggers the throw. Causes: the script itself errors (bad cmdlet, missing module, syntax), a terminating exception inside the script, or PowerShell's Constrained Language Mode blocking the script.
Common situations: The script references a module/cmdlet not present on the machine. Constrained Language Mode (AppLocker/WDAC policy) blocks the encoded script even with -ExecutionPolicy Bypass. The script reads a registry key/path that does not exist and uses -ErrorAction Stop. A different PowerShell edition (Core vs 5.1) is implied but powershell.exe (5.1) is what runs.
Related errors
- oscdimg.exe failed with exit code: {exitCode}
- ADK installation failed with exit code: {exitCode}
- winget install failed with exit code: {exitCode}
- winget install Microsoft.OSCDIMG failed with exit code: {exi
- DISM Export-Driver failed with exit code: {exitCode}
AI-assisted analysis of memstechtips/Winhance@f23d554eb2 (2026-08-13).
Data as JSON: /api/errors/8c23b2b05273b0c9.
Report an issue: GitHub.