If you are making an HTTP request to a RESTful web service, you can use the PowerShell Invoke-RestMethod cmdlet. This provides a very simple HTTP REST interface, and will also format the result into a PowerShell object.
If you would like to use your own functions, you can follow the instructions below.
This is a helper function to format (indent) an XML response from a web service.
Here is the function to make the http call. It dumps the response data on the terminal and also returns it as a string to the caller. If there is an error it will dump the HTTP status code and comment on the terminal and return the response StatusDescription. Remove or comment out the Write-Host lines if you don't want it to write anything to the terminal.
This is how the function is called.
You can also send any other HTTP verbs (DELETE, PUT, etc).
If you would like to use your own functions, you can follow the instructions below.
This is a helper function to format (indent) an XML response from a web service.
function Format-XML { Param ([string]$xml) $out = New-Object System.IO.StringWriter $Doc=New-Object system.xml.xmlDataDocument $doc.LoadXml($xml) $writer=New-Object system.xml.xmltextwriter($out) $writer.Formatting = [System.xml.formatting]::Indented $doc.WriteContentTo($writer) $writer.Flush() $out.flush() Write-Output $out.ToString() }
Here is the function to make the http call. It dumps the response data on the terminal and also returns it as a string to the caller. If there is an error it will dump the HTTP status code and comment on the terminal and return the response StatusDescription. Remove or comment out the Write-Host lines if you don't want it to write anything to the terminal.
function Http-Web-Request([string]$method,[string]$encoding,[string]$server,[string]$path,$headers,[string]$postData) { ## Compose the URL and create the request $url = "$server/$path" [System.Net.HttpWebRequest] $request = [System.Net.HttpWebRequest] [System.Net.WebRequest]::Create($url) ## Add the method (GET, POST, etc.) $request.Method = $method ## Add an headers to the request foreach($key in $headers.keys) { $request.Headers.Add($key, $headers[$key]) } ## We are using $encoding for the request as well as the expected response $request.Accept = $encoding ## Send a custom user agent if you want $request.UserAgent = "PowerShell script" ## Create the request body if the verb accepts it (NOTE: utf-8 is assumed here) if ($method -eq "POST" -or $method -eq "PUT") { $bytes = [System.Text.Encoding]::UTF8.GetBytes($postData) $request.ContentType = $encoding $request.ContentLength = $bytes.Length [System.IO.Stream] $outputStream = [System.IO.Stream]$request.GetRequestStream() $outputStream.Write($bytes,0,$bytes.Length) $outputStream.Close() } ## This is where we actually make the call. try { [System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse() $sr = New-Object System.IO.StreamReader($response.GetResponseStream()) $txt = $sr.ReadToEnd() ## NOTE: comment out the next line if you don't want this function to print to the terminal Write-Host "CONTENT-TYPE: " $response.ContentType ## NOTE: comment out the next line if you don't want this function to print to the terminal Write-Host "RAW RESPONSE DATA:" . $txt ## If we have XML content, print out a pretty version of it if ($response.ContentType.StartsWith("text/xml")) { ## NOTE: comment out the next line if you don't want this function to print to the terminal Format-XML($txt) } ## Return the response body to the caller return $txt } ## This catches errors from the server (404, 500, 501, etc.) catch [Net.WebException] { [System.Net.HttpWebResponse] $resp = [System.Net.HttpWebResponse] $_.Exception.Response ## NOTE: comment out the next line if you don't want this function to print to the terminal Write-Host $resp.StatusCode -ForegroundColor Red -BackgroundColor Yellow ## NOTE: comment out the next line if you don't want this function to print to the terminal Write-Host $resp.StatusDescription -ForegroundColor Red -BackgroundColor Yellow ## Return the error to the caller return $resp.StatusDescription } }
This is how the function is called.
## Define any custom headers in a Hashtable $headers = @{ apikey = "your authentication key" } ## Sample GET request that returns a random list of numbers $result = Http-Web-Request "GET" "text/xml" "http://www.random.org" "/integers/?num=10&min=1&max=6&col=1&base=10&format=plain&rnd=new" $headers "" ## Sample POST request $utf8PostData = @"Put your XML, JSON, name-value pairs, etc. here "@ $result = Http-Web-Request "POST" 'text/xml' "http://example.com" "/web/service/endpoint" $headers $postData ## Sample POST request with JSON Data $utf8PostData = @" { key1: 'value1', key2: 'value2', number1: 1 } "@ $result = Http-Web-Request "POST" 'application/json' "http://example.com" "/posts" $headers $postData
You can also send any other HTTP verbs (DELETE, PUT, etc).
I copied your function and did a simple get and it worked first time. Saved me a lot of time, Thanks
ReplyDeleteYou're welcome. Glad I could help.
DeleteHey Aaron, how a JSON would look like inside the postData?
ReplyDeleteAlex, I added a JSON sample request above.
DeleteJust stumbled on this. Very nice explanation and examples. I wish more people would copy your style and thoroughness.
ReplyDeleteThanks! I'm glad I was able to help.
Delete