Search code examples
powershellescapingsequenceinvoke-command

How to escape an Invoke-Webrequest in Powershell


I have a network device with a status page accessible by a Java applet. Using Fiddler I was able to find an http feed of the status, but the page has a constant refresh. (Firefox displays the page but keeps refreshing, Chrome sees it as an extension-less file and tries to save it but never finishes as there is always more data.)

The status page uses NTLM authentication so I though I would use an Invoke-Webrequest. The following code logs in and starts downloading the page but as its a constant data stream never finishes:

$url = "http://xxx.xxx.xxx.xxx/api/notify"
$user = "user"
$pass= "password"
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)
$data = Invoke-restmethod $url -Credential $credential

Is there a way to escape from an Invoke-Webrequest after receiving a certain number of characters? Or is there a better way to do this?


Solution

  • I don't think it's doable with Invoke-WebRequest, but you could use .NET WebRequest and StreamReader classes instead. Example:

    $sUri = "http://www.w3.org" # Replace with your URI
    $sEncoding = "utf-8"
    $iCharactersToRead = 1000 # How many characters we want to read
    $sAuthType = "NTLM"
    $sUserName = "username"
    $sPassword = "password"
    
    # Creating a new HttpWebRequest object.
    [System.Net.HttpWebRequest]$oHttpWebRequest = [System.Net.WebRequest]::Create($sUri)
    # This may be superflous if your HTTP server doesn't use compression.
    $oHttpWebRequest.AutomaticDecompression = `
            ([System.Net.DecompressionMethods]::Deflate `
        -bor [System.Net.DecompressionMethods]::GZip)
    
    # Since you have NTLM auth, you need to add a credential.
    $oCredential = New-Object -TypeName System.Net.NetworkCredential($sUserName, $sPassword)
    $oCredentialCache = New-Object -TypeName System.Net.CredentialCache
    $oCredentialCache.Add($sUri, "NTLM", $oCredential)
    $oHttpWebRequest.Credentials = $oCredentialCache
    
    # Creating a StreamReader object that will read the response stream.
    $oResponseStream = $oHttpWebRequest.GetResponse().GetResponseStream()
    $oContentReader = New-Object -TypeName System.IO.StreamReader($oResponseStream,
        [System.Text.Encoding]::GetEncoding($sEncoding), $true)
    
    # Trying to read the specified number of characters from the stream.
    $sContent = [String]::Empty
    try {
        for ($i = 0; $i -lt $iCharactersToRead; $i++) { 
            $sContent += [Char]$oContentReader.Read() 
        } 
    }
    finally {
        $oContentReader.Close()
    }
    

    Instead of utf-8 you may need to specify another encoding name, depending on which encoding your HTTP server uses. See Encoding.WebName reference for more details.