I have a powershell script like this
$timer = [System.Diagnostics.Stopwatch]::StartNew()
$cookieContainer = New-Object System.Net.CookieContainer
try
{
[system.Net.HttpWebRequest] $authRequest = [system.Net.HttpWebRequest]::Create($authUrl)
$authRequest.CookieContainer = $cookieContainer
$authRequest.Method = "POST";
$authRequest.ContentType = "application/x-www-form-urlencoded";
$byteArray = [System.Text.Encoding]::UTF8.GetBytes($authPostData)
$authRequest.ContentLength = $byteArray.Length
$dataStream = $authRequest.GetRequestStream()
$dataStream.Write($byteArray, 0, $byteArray.Length)
$dataStream.Close()
$authResponse = $authRequest.GetResponse();
but in line $dataStream = $authRequest.GetRequestStream()
it throws an exception:
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Management.Automation.PSInvalidOperationException: There is no Runspace available to run scripts in this thread. You can provide one in the DefaultRunspace property of the System.Management.Automation.Runspaces.Runspace type. The script block you attempted to invoke was: $true at System.Net.Security.SslState.CheckOldKeyDecryptedData(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security.SslState.CheckEnqueueRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest request) at System.Net.Security._SslStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) --- End of inner exception stack trace --- at System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.TlsStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead) --- End of inner exception stack trace --- at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context) at System.Net.HttpWebRequest.GetRequestStream() at GetRequestStream(Object , Object[] ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)
I've tried to solve it or google, but it didn't help. I just don't understand why it fails with multi-threading exception, because i don't create any additional thread and I'm calling HttpWebRequest
properties properly, so it shouldn't be inner exception too.
It's also strange, because i have a "lib-script" file, and i have multuple scripts calling it, it looks like
function GetRequest([string] $url, [System.Net.CookieContainer] $cookieContainer, [string] $postParams, [string] $userAgent)
{
[system.Net.HttpWebRequest] $request = [system.Net.HttpWebRequest]::Create($url)
$request.CookieContainer = $cookieContainer
$request.UserAgent = $userAgent
if (![string]::IsNullOrEmpty($postParams))
{
$request.Method = "POST"
$request.ContentType = "application/x-www-form-urlencoded"
$request.ContentLength = $postParams.Length
[System.IO.TextWriter] $requestWriter = New-Object System.IO.StreamWriter($request.GetrequestStream())
$requestWriter.Write($postParams)
$requestWriter.Close()
$requestWriter.Dispose();
}
return [system.Net.HttpWebRequest] $request
}
function GetContentFromUrl([System.String] $url, [System.Net.CookieContainer] $cookieContainer, [System.String] $postParams, [string] $userAgent)
{
try
{
$request = GetRequest $url $cookieContainer $postParams $userAgent
$Response = $request.GetResponse()
[System.IO.TextReader] $ContentStream = New-Object System.IO.StreamReader($Response.GetResponseStream())
$Content = [System.Web.HttpUtility]::HtmlDecode($ContentStream.ReadToEnd())
$ContentStream.Close()
$Response.Close()
if($Response.StatusCode -ne 200)
{
throw;
}
return $Content
}
catch [System.Net.WebException]
{
try
{
# Write-Host $Error[0] -foregroundcolor "magenta"
$exception = $_.Exception
$status = GetStatusDescription( $exception.Status)
$Error = GetExceptionDetails( $exception)
$errorInfo = GetErrorInfo($exception)
$errorDescription = GetErrorDescription($exception)
$responseText = GetFailedResponseText -exception ($exception)
if($exception.Response -ne $null)
{
$exception.Response.Close()
}
SetResult -result $false -info $errorInfo -properties (GetAdditionalProperties -pingUrl $url -responseUri $exception.Response.ResponseUri -httpResponseStatusCode ($exception.Response.StatusCode) -errorCode ($ErrorCode.WebError) -errorDescription $errorDescription -responseText ($responseText))
Exit
}
catch [System.Exception]
{
[System.String] $resultText = "При получении ответа произошла ошибка :{0} {1} {2} " -f ($status, $exception, $exception.GetType())
SetResult -result $false -info $errorInfo -properties (GetAdditionalProperties -pingUrl $url -resultCount 0 -errorDescription $errorDescription -httpResponseStatusCode 0)
Exit
}
}
}
and I never had any problem with it. Other scripts just was calling GetContent function and was receiving content from url. But it fails with same exception, when other scripts (>30) works fine.
It seems that BeginGetRequestStream
fails when connect. Or something like this.
So i've used this code
Import-Module -name "C:\CommonFunctions.ps1" -Global
$authUrl= 'http://www.someurl.com/somepage'
$authPostData='j_username=useruseruser&j_password=passpasspass&login=%D0%92%D0%BE%D0%B9%D1%82%D0%B8'
$cookieContainer = New-Object System.Net.CookieContainer
$content = GetContentFromUrl $authUrl $cookieContainer #$authPostData
$content
and now it fails with:
[DBG]: PS C:\Users\Administrator\Documents> $exception.ToString() System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secu re channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to th e validation procedure. at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exce ption exception)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequ est) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object st ate, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boo lean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size) at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace --- at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context) at System.Net.HttpWebRequest.GetRequestStream() at GetRequestStream(Object , Object[] ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformatio n methodInformation, Object[] originalArguments)
it's much better. I'l add cert to my query. Thanks everybody for help.