title: PowerShell + HttpWebRequest throws exception
body: <p>I have a powershell script like this</p>
  
  <pre><code>$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(); 
  </code></pre>
  
  <p>but in line <code>$dataStream = $authRequest.GetRequestStream()</code> it throws an exception:</p>
  
  <blockquote>
    <p>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&amp; context)
       at System.Net.HttpWebRequest.GetRequestStream()
       at GetRequestStream(Object , Object[] )
       at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)</p>
  </blockquote>
  
  <p>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 <code>HttpWebRequest</code> properties properly, so it shouldn't be inner exception too.</p>
  
  <p>It's also strange, because i have a "lib-script" file, and i have multuple scripts calling it, it looks like </p>
  
  <pre><code>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
          }
      }     
  </code></pre>
  
  <p>} </p>
  
  <p>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.</p>
  
  <p>It seems that <code>BeginGetRequestStream</code> fails when connect. Or something like this.</p>
  
  <p>So i've used this code</p>
  
  <pre><code>Import-Module -name "C:\CommonFunctions.ps1" -Global  
  
  $authUrl= 'http://www.someurl.com/somepage'
  $authPostData='j_username=useruseruser&amp;j_password=passpasspass&amp;login=%D0%92%D0%BE%D0%B9%D1%82%D0%B8'
  $cookieContainer = New-Object System.Net.CookieContainer
  
  $content = GetContentFromUrl  $authUrl $cookieContainer #$authPostData
  
  $content
  </code></pre>
  
  <p>and now it fails with:</p>
  
  <blockquote>
    <p>[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)<br>
    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)<br>
    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)<br>
    --- End of inner exception stack trace ---    at System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp; 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)</p>
  </blockquote>
  
  <p>it's much better. I'l add cert to my query. Thanks everybody for help.</p>