PowerShell must support calling Async APIs - by Joel 'Jaykul' Bennett

Status : 


Sign in
to vote
ID 838221 Comments
Status Active Workarounds
Type Suggestion Repros 0
Opened 3/21/2014 12:17:05 PM
Access Restriction Public


Currently PowerShell has it's own systems (based on "Jobs") for doing asynchronous tasks -- while this was admirable in the .Net 2.0 and 3.0 era, in the modern .Net Framework we have new "IAsyncResult" task APIs, and they do not work in PowerShell at all.

As more and more of the .Net Framework itself and 3rd party APIs begin to depend on Tasks, IAsyncResult, and C#s "async" and "await" keywords to create asynchronous programming interfaces and web-based APIs, it is critical that PowerShell support working with these APIs, whether through extensions to the language (like C#'s await keyword) or via wrapper cmdlets which map these tasks to the existing Job mechanism, lest PowerShell find itself locked in the past and unable to access modern toolkits or manage modern apps.
Sign in to post a comment.
Posted by Kirk Munro on 5/23/2014 at 12:44 PM
I tripped on this issue this week and lost a huge chunk of time trying to chase down the root cause.

My problem was that I was trying to allow for self-signed certificates to work in an Invoke-WebRequest call to a REST endpoint by assigning an appropriate callback to ServicePointManager.ServerCertificateValidationCallback. It was appearing to work, but only intermittently because I was also invoking some binary cmdlets that make web request calls to the same server, and the connection was being persisted behind the scenes so it worked only if I recently invoked one of the binary cmdlets first.

If I opened a native PowerShell session and invoked my script directly, the callback wasn't properly being invoked, and my self-signed certificate was not accepted. To solve this problem I created a few static methods in C#: one for the callback itself, one to enable the callback (assign it to ServerCertificateValidationCallback) and one to disable the callback (assign ServerCertificateValidationCallback to null). Then adding this to PowerShell via Add-Type gave me access to those methods from PowerShell, and the callback worked fine when invoked directly in the C# dll that was being generated.

Here's a reproduction scenario showing how it can fail:

# Define the URI
$uri = "https://some-uri-to-a-rest-endpoint-that-has-a-self-signed-certificate"

# Don't try this at home kids, it allows for any certificate, not just valid and self-signed certificates
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

# Now invoke the web request to get data from the REST endpoint that has a self-signed certificate
Invoke-WebRequest -Uri $uri -Method Get

That last call will fail with trust issues even though it appears that the certificate validator callback should return true for self-signed certificates.