{"record":{"id":"8c23b2b05273b0c9","repo":"memstechtips/Winhance","slug":"in-memory-powershell-script-failed-exit-code-exi","errorCode":null,"errorMessage":"In-memory PowerShell script failed (exit code {exitCode}):\n{errors}","messagePattern":"In-memory PowerShell script failed \\(exit code (.+?)\\):\n(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Winhance.Infrastructure/Features/Common/Utilities/PowerShellRunner.cs","lineNumber":91,"sourceCode":"        if (string.IsNullOrEmpty(script))\r\n            throw new ArgumentException(\"Script cannot be null or empty.\", nameof(script));\r\n\r\n        var scriptBytes = Encoding.Unicode.GetBytes(script);\r\n        if (scriptBytes.Length > MaxEncodedScriptBytes)\r\n        {\r\n            throw new ArgumentException(\r\n                $\"Script is {scriptBytes.Length} bytes (UTF-16); -EncodedCommand path supports up to {MaxEncodedScriptBytes}. Use RunScriptAsync for larger scripts.\",\r\n                nameof(script));\r\n        }\r\n\r\n        var encoded = Convert.ToBase64String(scriptBytes);\r\n        var args = $\"-ExecutionPolicy Bypass -NoProfile -EncodedCommand {encoded}\";\r\n\r\n        var (output, errors, exitCode) = await LaunchPowerShellAsync(args, progress, ct).ConfigureAwait(false);\r\n\r\n        if (exitCode != 0 && errors.Length > 0)\r\n        {\r\n            throw new InvalidOperationException(\r\n                $\"In-memory PowerShell script failed (exit code {exitCode}):\\n{errors}\");\r\n        }\r\n\r\n        return output.ToString();\r\n    }\r\n\r\n    /// <summary>\r\n    /// Executes a PowerShell script file via Windows PowerShell 5.1 (powershell.exe).\r\n    /// Stdout is captured line-by-line for progress reporting (Write-Host output).\r\n    /// If execution policy blocks the script, retries with -EncodedCommand.\r\n    /// </summary>\r\n    public async Task<string> RunScriptFileAsync(\r\n        string scriptPath,\r\n        string arguments = \"\",\r\n        IProgress<TaskProgressDetail>? progress = null,\r\n        CancellationToken ct = default)\r\n    {\r\n        if (string.IsNullOrEmpty(scriptPath))\r","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/memstechtips/Winhance/blob/f23d554eb2d6400b1827bcc46b91294ffa53fbc9/src/Winhance.Infrastructure/Features/Common/Utilities/PowerShellRunner.cs#L73-L109","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: throw only when exitCode != 0 AND errors present — a failing-but-silent script slips through\nif (exitCode != 0 && errors.Length > 0)\n    throw new InvalidOperationException($\"In-memory PowerShell script failed (exit code {exitCode}):\\n{errors}\");\n\n// after: treat any non-zero exit as failure and always include available output\nif (exitCode != 0)\n    throw new InvalidOperationException($\"In-memory PowerShell script failed (exit code {exitCode}). Errors: {errors}. Output: {output}\");","handlingStrategy":"try-catch","validationCode":"// Optional pre-flight: ensure the script has no obvious syntax issue and required modules exist.\n// At minimum, gate EncodedCommand use on script size.\nbool ShouldUseEncodedCommand(byte[] scriptBytes) => scriptBytes.Length <= MaxEncodedScriptBytes;","typeGuard":null,"tryCatchPattern":"catch (InvalidOperationException ex) when (ex.Message.Contains(\"In-memory PowerShell script failed\"))\n{\n    // The {errors} substring carries PowerShell's own error record — surface it verbatim to the user.\n    // Fall back to RunScriptFileAsync (writes the script to disk) if Constrained Language Mode blocked the encoded form.\n}","preventionTips":["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."],"tags":["powershell","external-process","windows","scripting","encoded-command"],"backgroundTag":null,"analyzedSha":"f23d554eb2d6400b1827bcc46b91294ffa53fbc9","analyzedAt":"2026-08-13T17:55:20.922Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}