0

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.

Alex Zhukovskiy
  • 9,565
  • 11
  • 75
  • 151
  • http://stackoverflow.com/questions/4926060/powershell-runspace-problem-with-downloadfileasync seems like a similar question to me. – JensG Nov 16 '13 at 09:58
  • i seen it, but i don't help in my case. I've copy-pasted it, but i don't get this exception in described case. – Alex Zhukovskiy Nov 16 '13 at 11:15
  • 2
    I've seen that exception before when trying to use a URL that has a self-signed cert or a cert with an unrecognized authority. I have also see it when trying to provide my own callback to the `System.Net.ServicePointMAnager.ServerCertificatValidationCallback' delegate. Your question does not specify, are you dealing with any of those scenarios. – Joseph Alcorn Nov 16 '13 at 16:52
  • 3
    Also, if you are able to use PowerShell 3.0 or above, you should look into using [Invoke-WebRequest](http://technet.microsoft.com/en-us/library/hh849901(v=wps.620).aspx), as it might be able to greatly simplify your code. – Joseph Alcorn Nov 16 '13 at 16:58
  • Yeah, I see nothing in the script you've shown here that should be directly causing a threading issue. I second the recommendation to use IWR if you're on V3 or V4. To see if it is a SSL/cert issue can you try the code on a non https:// url or is it the case that the other "30" that "do" work are not using https? – Keith Hill Nov 16 '13 at 18:09
  • I've manipulated with this script, and i dunno what I did (because I did nothing), but now it fails with cert exception (`The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.`). So @Joseph Alcorn is right. I've added code used for catch this error Thanks for help everybody – Alex Zhukovskiy Nov 18 '13 at 08:38
  • This may also be related http://stackoverflow.com/questions/25143946/powershell-3-0-invoke-webrequest-https-fails-on-all-requests – Brandon LeBlanc Mar 10 '16 at 21:42
  • @JoachimBrandonLeBlanc thank you, but anyway it seems that there is no clearly solution exist for now... `Try to reset and see what happens` is not very helpful, unfortunly. Keep waiting for an answer. Well, I will vote up this question and answer, they are useful anyway. – Alex Zhukovskiy Mar 11 '16 at 08:06

0 Answers0