Implements a RequestDelegate
for executing PowerShell
scripts
The scripts are executed in a new PowerShell
per request. The pipelines are connected to the request and response bodies.
param(
[parameter(Mandatory=$true)]
$HttpContext
)
$Response=$HttpContext.Response
$Response.StatusCode=200
$Response.ContentType='text/plain'
[System.Text.Encoding]::ASCII
'Hello World'
Writing the ASCII
encoding to the output allows control of the encoding.
param(
[parameter(Mandatory=$true)]
$HttpContext,
[parameter(ValueFromPipeline=$true,Mandatory=$true)]
$pipelineInput
)
$Response=$HttpContext.Response
$Response.StatusCode=200
$Response.ContentType=$HttpContext.Request.ContentType
Write-Output $pipelineInput -NoEnumerate
The -NoEnumerate
is to write a byte array rather than individual bytes onto the pipeline.
The delegate uses the asynchronous programming model in order to allow overlapping of both input and output.
An InitialSessionState
can be used to provide state that will be shared by each request invocation.
The request body is fed into to the input pipeline. The input can either be an IFormCollection
, a byte array or a string depending on the Content-Type
.
The output pipeline is written to the response body. The output is written as the objects are added to the pipeline. Only primitives that can be converted to characters or bytes are supported. An Encoding
type will set the current character encoding.
The response status and any headers should be applied to the HttpContext
before the output is written.
The HttpRequest.RequestAborted
is forwarded to the PowerShell.StopAsync
to cancel long running pipelines when client has disconnected and response is no longer possible.
The code includes some hopefully interesting techniques
PowerShell
delegate uses asynchronous programming to simultaneously read and write the input and output pipelines while executing thePowerShell
script without using threads; see PowerShellDelegate/PowerShellDelegate.cs- Test harness uses
WebApplicationFactory
with top-level programs; see UnitTests/WebApplicationFactoryBuilder.cs - Generates native packages to install matching
AspNetCore
runtime; see AspNetForPowerShell/package.ps1 PowerShell
can be used at different levels;- Standalone app; see DemoApp/DemoApp.ps1
- Main
Program
; see TestPs1/Program.ps1 Startup
configuration; see TestEol/Startup.ps1RequestDelegate
handler; see TestCgi/RequestDelegate.ps1
- Combining with
Controllers
; see TestApi/Program.cs - Combining with static content; see TestCgi/Program.cs
- Access resources from
PowerShell
; see TestEol/Startup.ps1 - Get services by type, eg
ILogger
; TestPs1/Program.ps1 - Extension to add
Cmdlets
toInitialSessionState
; see Extensions/InitialSessionStateExtensions.cs - Using unit tests to validate
PowerShell
implementation; see UnitTests/TestPs1Tests.cs