| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Launching a process with the DETACHED_PROCESS flag of the WinAPI CreateProcess() function by design does so without a console, even for console-subsystem applications.
However, pwsh.exe assumes the presence of a console and quietly aborts if it cannot find one: exit code 0 is reported, and no WER (Windows Error Reporting) event is recorded in the Windows Application event log.
Note:
SCM, the Windows Service Control Manager, is an example of a component that starts (service) executables with DETACHED_PROCESS; while using pwsh.exe as a service executable is not a common use case, it is possible to implement a service via a .ps1 script passed to pwsh.exe -File - see this Stack Overflow post.
There are two ways to fix this problem:
Report a nonzero exit code and log a WER event with a specific error message - this is what the repro below assumes.
Alternatively, allow PowerShell to run without a console: infer non-interactive mode in the absence of a console and prevent attempts to access console-specific features in a controlled manner (note that the -noninteractive CLI option does not currently do that).
The following repro code requires .NET 11+ / at least a PowerShell 7.7 preview version, due to use of the new .StartDetached property of ProcessStartInfo.
using namespace System.Diagnostics
$startTime = [System.DateTime]::Now
# Start PowerShell without a console (DETACHED_PROCESS)
# Note: Requires .NET 11+
[Process]::Start(
[ProcessStartInfo] @{
FileName = 'pwsh.exe'
Arguments = '-c "Start-Sleep 5"'
StartDetached = $true
}
) | Wait-Process -PassThru | Select-Object *Exit*
"Ran for $('{0:N1}' -f ([datetime]::Now - $startTime).TotalSeconds) secs." | Out-Host
# # As a crosscheck, use the following to provoke a crash that DOES create a WER event.
# $ps = Start-Process -PassThru conhost.exe (Get-Process -Id $PID).Path; Start-Sleep 2; $ps | Stop-Process
"Sleeping a little, to give a WER event time to show up" | Out-Host
1..5 | ForEach-Object { Write-Host -NoNewline .; Start-Sleep 1 }
Write-Host
# Report the resulting WER event, if any.
Get-WinEvent -FilterHashTable @{
ProviderName = 'Windows Error Reporting'
Id = 1001
Data = 'pwsh.exe' # matches the <Data Name="P1"> sub-element of <EventData>
StartTime = $startTime # events written since this [datetime] instance; supplemnt with `EndTime`, if needed
} | Format-ListThe offending parts of the source code:
PowerShell/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs
Lines 548 to 571 in 2725d6a
| private static readonly Lazy<ConsoleHandle> _outputHandle = new Lazy<SafeFileHandle>(() => | |
| { | |
| // We use CreateFile here instead of GetStdWin32Handle, as GetStdWin32Handle will return redirected handles | |
| var handle = NativeMethods.CreateFile( | |
| "CONOUT$", | |
| (UInt32)(NativeMethods.AccessQualifiers.GenericRead | NativeMethods.AccessQualifiers.GenericWrite), | |
| (UInt32)NativeMethods.ShareModes.ShareWrite, | |
| (IntPtr)0, | |
| (UInt32)NativeMethods.CreationDisposition.OpenExisting, | |
| 0, | |
| (IntPtr)0); | |
| if (handle == NativeMethods.INVALID_HANDLE_VALUE) | |
| { | |
| int err = Marshal.GetLastWin32Error(); | |
| HostException e = CreateHostException(err, "RetreiveActiveScreenBufferConsoleHandle", | |
| ErrorCategory.ResourceUnavailable, ConsoleControlStrings.GetActiveScreenBufferHandleExceptionTemplate); | |
| throw e; | |
| } | |
| return new ConsoleHandle(handle, true); | |
| } | |
| ); |
PowerShell/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs
Lines 105 to 111 in 2725d6a
| // These exceptions are caused by killing conhost.exe | |
| // 1236, network connection aborted by local system | |
| // 0x6, invalid console handle | |
| if (win32e.NativeErrorCode == 0x6 || win32e.NativeErrorCode == 1236) | |
| { | |
| return exitCode; | |
| } |
Ran for 10.0 secs.
.....
ExitCode HasExited ExitTime
-------- --------- --------
1 True <timestamp>
<tabular display of a WER event-log entry with a specific error message>Ran for 0.3 secs.
.....
ExitCode HasExited ExitTime
-------- --------- --------
0 True <timestamp>
Get-WinEvent: foo.ps1:25
Line |
25 | Get-WinEvent -FilterHashTable @{
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| No events were found that match the specified selection criteria.That is:
PowerShell Core v7.7.0-preview.5 on WindowsNo response
| Back | FazBrowse Home | New Git URL |
Activity
iSazonov commented on Nov 10, 2026
Apparently you need to run the detached process in Server Mode.
jessehouwing commented on Nov 10, 2026
Server mode doesn't allow you to pass the start-up script as an argument from what I can tell.
mklement0 commented on Nov 10, 2026
Good point, Jesse Houwing (@jessehouwing) - a run-given-code-then-exit CLI call is fundamentally different from putting pwsh.exe into a server mode.
Apart from that, Ilya (@iSazonov): Among the various server modes: