API Reference

New Public API

Two opt-in additions to the PowerShell hosting API. Both require an RFC before the PR can merge.

RFC required Backwards compatible
01

New Members

RFC required. Both additions below are additions to a public API surface. Per PowerShell governance, public API changes require an RFC to be filed and accepted before the PR can merge.
Member Type / Signature Default REQ Source
PSInvocationSettings.Timeout TimeSpan { get; set; } Timeout.InfiniteTimeSpan REQ-01
PowerShell.Stop(TimeSpan) void Stop(TimeSpan timeout) REQ-05
02

PSInvocationSettings.Timeout

A new TimeSpan property on PSInvocationSettings. Setting it to any finite value causes the next Invoke() call to throw TimeoutException if the command does not complete within that interval.

var settings = new PSInvocationSettings();

// Opt-in: set a 5-second timeout
settings.Timeout = TimeSpan.FromSeconds(5);

var ps = PowerShell.Create();
ps.AddScript("Start-Sleep -Seconds 60");

try
{
    ps.Invoke(null, settings);
}
catch (TimeoutException ex)
{
    // Fires after 5 seconds
    Console.WriteLine(ex.Message);
}
STA COM caveat. When Timeout is finite, Invoke() dispatches the worker to a ThreadPool thread via Task.Run. ThreadPool threads are MTA. Scripts that rely on STA COM apartment state must leave Timeout at its default InfiniteTimeSpan.
03

PowerShell.Stop(TimeSpan)

A new overload of Stop() that signals the pipeline to stop and waits up to timeout for it to finish. The existing parameterless Stop() is unchanged.

var ps = PowerShell.Create();
ps.AddScript("Start-Sleep -Seconds 300");

var task = Task.Run(() => ps.Invoke());
Thread.Sleep(500);  // let it start

try
{
    ps.Stop(TimeSpan.FromSeconds(10));
    // State is Stopped
}
catch (TimeoutException)
{
    // Pipeline didn't stop within 10s
}

Calling Stop(TimeSpan) on a disposed instance is safe — the internal ObjectDisposedException is silently swallowed.

04

Internal 30-Second Bounds

The following waits were also bounded as part of Phase 1 — they are not configurable but they prevent permanent hangs in edge cases:

LocationBoundOn timeout
DoOpenHelper runspace-open wait30 sForces Broken state
LocalPipeline.Stop() finish wait30 sThrows TimeoutException
LocalConnection.Close() slot waits30 s eachThrows TimeoutException
CoreStop internal wait30 sThrows TimeoutException
StopPipelines() aggregate30 sThrows TimeoutException