<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>PowerShell on David Hamann</title><link>https://davidhamann.de/tags/powershell/</link><description>Recent content in PowerShell on David Hamann</description><generator>Hugo</generator><language>en</language><copyright>&amp;copy; David Hamann</copyright><lastBuildDate>Sun, 08 Dec 2019 00:00:00 +0000</lastBuildDate><atom:link href="https://davidhamann.de/tags/powershell/feed.xml" rel="self" type="application/rss+xml"/><item><title>Running commands in a specific user context in PowerShell</title><link>https://davidhamann.de/2019/12/08/running-command-different-user-powershell/</link><pubDate>Sun, 08 Dec 2019 00:00:00 +0000</pubDate><guid>https://davidhamann.de/2019/12/08/running-command-different-user-powershell/</guid><description>&lt;p&gt;If you find yourself in a limited cmd shell but have obtained credentials for another user, you can leverage PowerShell&amp;rsquo;s &lt;code&gt;Invoke-Command&lt;/code&gt; cmdlet to execute a script block in the security context of that specific user. This can be helpful in a penetration test setting or CTF.&lt;/p&gt;
&lt;p&gt;One thing to be aware of is that you cannot just pass a user and password string to the &lt;code&gt;-Credential&lt;/code&gt; parameter of &lt;code&gt;Invoke-Command&lt;/code&gt;, but need to create a valid &lt;em&gt;PSCredential&lt;/em&gt; object first.&lt;/p&gt;
&lt;p&gt;While the &lt;code&gt;Get-Credential&lt;/code&gt; cmdlet can give you such an object, it&amp;rsquo;s unlikely that you can get prompted given your current access. To work around this, you can create a PSCredential yourself and pass it to &lt;code&gt;Invoke-Command&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A fully functional one-liner (here, just reading a file) could look like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;powershell.exe -c &amp;#34;$user=&amp;#39;WORKGROUP\John&amp;#39;; $pass=&amp;#39;password123&amp;#39;; try { Invoke-Command -ScriptBlock { Get-Content C:\Users\John\Desktop\secret.txt } -ComputerName Server123 -Credential (New-Object System.Management.Automation.PSCredential $user,(ConvertTo-SecureString $pass -AsPlainText -Force)) } catch { echo $_.Exception.Message }&amp;#34; 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I like to add a &lt;code&gt;try {} catch {}&lt;/code&gt; and a redirect from of stderr to stdout (&lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt;) to be able to see errors as most limited shells wouldn&amp;rsquo;t give you the stderr output otherwise.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-5.1"&gt;Invoke-Command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/convertto-securestring?view=powershell-5.1"&gt;ConvertTo-SecureString&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=powershellsdk-1.1.0"&gt;System.Management.Automation.PSCredential&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>HTTP requests with PowerShell's Invoke-WebRequest – by Example</title><link>https://davidhamann.de/2019/04/12/powershell-invoke-webrequest-by-example/</link><pubDate>Fri, 12 Apr 2019 00:00:00 +0000</pubDate><guid>https://davidhamann.de/2019/04/12/powershell-invoke-webrequest-by-example/</guid><description>&lt;p&gt;If you ever find yourself on a Windows system needing to make a HTTP request, the &lt;code&gt;Invoke-WebRequest&lt;/code&gt; cmdlet will be your friend.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s have a look on how to send various things with &lt;code&gt;iwr&lt;/code&gt; (legit alias!) and how to get around common issues. We will be focussing on (manually) sending/requesting data, not so much on reading/parsing it.&lt;/p&gt;
&lt;p&gt;In case it&amp;rsquo;s the first time you&amp;rsquo;re using &lt;code&gt;Invoke-WebRequest&lt;/code&gt; or doing stuff with PowerShell in general, I recommend reading this post sequentially from top to bottom.&lt;/p&gt;
&lt;p&gt;I will be using PowerShell 5.1 for this article. You can find your version with &lt;code&gt;$PSVersionTable&lt;/code&gt;. As destination we will use several HTTP endpoints from &lt;a href="https://httpbin.org"&gt;httpbin.org&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-simple-first-request"&gt;A simple first request&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Staying with the defaults, this command will translate to the following request:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET /json HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; de-DE) WindowsPowerShell/5.1.17763.316
Host: httpbin.org
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What we get back is a &lt;em&gt;HtmlWebResponseObject&lt;/em&gt; in a nicely formatted way, displaying everything from (parts) of the body, response headers, length, etc.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s store the response in a variable to be able to access the individual parts:&lt;/p&gt;
&lt;h2 id="accessing-parts-of-the-response"&gt;Accessing parts of the response&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Invoke-WebRequest&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;StatusCode&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="mf"&gt;200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Headers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;---&lt;/span&gt; &lt;span class="p"&gt;-----&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Access-Control&lt;/span&gt;&lt;span class="n"&gt;-Allow-Credentials&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Access-Control&lt;/span&gt;&lt;span class="n"&gt;-Allow-Origin&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="nb"&gt;keep-alive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Content-Length&lt;/span&gt; &lt;span class="mf"&gt;429&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Content-Type&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Date&lt;/span&gt; &lt;span class="n"&gt;Wed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10&lt;/span&gt; &lt;span class="n"&gt;Apr&lt;/span&gt; &lt;span class="mf"&gt;2019&lt;/span&gt; &lt;span class="mf"&gt;20&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;33&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;00&lt;/span&gt; &lt;span class="n"&gt;GMT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="n"&gt;nginx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The content can be accessed with &lt;code&gt;$r.Content&lt;/code&gt;. If we want to see what actually came back and was being parsed, we can use &lt;code&gt;$r.RawContent&lt;/code&gt;. And, as we can redirect outputs just like in any other shell, we could store the response like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$r.RawContent &amp;gt; C:\My\Path\to\file.txt
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="setting-request-headers"&gt;Setting request headers&lt;/h2&gt;
&lt;p&gt;Custom request headers can be set by passing a hash table to &lt;em&gt;Invoke-WebRequest&lt;/em&gt;&amp;rsquo;s &lt;code&gt;-Headers&lt;/code&gt; option. The syntax for creating a hash table is as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt; &lt;span class="p"&gt;[&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;...}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s make a new request and add some custom headers. We&amp;rsquo;ll also start using the alias &lt;code&gt;iwr&lt;/code&gt; from now on to safe some typing.&lt;/p&gt;
&lt;div class="notice notice-info"&gt;
 &lt;strong&gt;Tip:&lt;/strong&gt; A list of aliases for a cmdlet can be retrieved with &lt;code&gt;Get-Alias -Definition &amp;lt;cmdlet&amp;gt;&lt;/code&gt;, in our case &lt;code&gt;Get-Alias -Definition Invoke-WebRequest&lt;/code&gt;.
&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Headers&lt;/span&gt; &lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Accept&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;X-My-Header&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Hello World&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will produce something like:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET /headers HTTP/1.1
X-My-Header: Hello World
Accept: application/json
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that if you want to set cookies, you should do so with &lt;code&gt;Invoke-WebRequest&lt;/code&gt;&amp;rsquo;s &lt;code&gt;-WebSession&lt;/code&gt; option (see below). Manually including a &lt;em&gt;Cookie&lt;/em&gt; HTTP header will not work. The same applies, &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1"&gt;according to the docs&lt;/a&gt;, to the user agent, which should only be set via the &lt;code&gt;-UserAgent&lt;/code&gt; option, not via &lt;code&gt;-Headers&lt;/code&gt; (in practice, I had no issues setting it via &lt;code&gt;-Headers&lt;/code&gt;, though).&lt;/p&gt;
&lt;h3 id="debugging-request-headers"&gt;Debugging request headers&lt;/h3&gt;
&lt;p&gt;Debugging the request headers can be done with a service like &lt;a href="https://httpbin.org"&gt;httpbin.org&lt;/a&gt; (httpbin.org/headers) or simply by sniffing the traffic (e.g. with Wireshark) while making the request. Unfortunately, I am not aware of any way inside PowerShell to retrieve the headers that were actually sent.&lt;/p&gt;
&lt;h2 id="sending-data-and-setting-the-content-type"&gt;Sending data and setting the content type&lt;/h2&gt;
&lt;p&gt;To give our request a body, we can either use the &lt;code&gt;-Body&lt;/code&gt; option, the &lt;code&gt;-InFile&lt;/code&gt; option or use a pipeline. For these examples we will do a &lt;em&gt;POST&lt;/em&gt; request, so use &lt;code&gt;-Method 'POST'&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Before actually sending data, let&amp;rsquo;s talk about the content type. If you do a &lt;em&gt;POST&lt;/em&gt; request, but neither specify a Content-Type header nor use the &lt;code&gt;-ContentType&lt;/code&gt; option, Invoke-WebRequest will automatically set the content type to &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;More gotchas: when you &lt;em&gt;do&lt;/em&gt; set a Content-Type header via &lt;code&gt;-Headers&lt;/code&gt;, say &lt;code&gt;application/json; charset=utf8&lt;/code&gt; and then pipe a utf8 file to &lt;code&gt;iwr&lt;/code&gt; like so&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Get-Content&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;-ReadCount&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Method&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Headers&lt;/span&gt; &lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json; charset=utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; you may not actually send what you expect, as &lt;code&gt;iwr&lt;/code&gt; will not read the piped data as utf8.&lt;/p&gt;
&lt;p&gt;Depending on the encoding, you may send something like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{ &amp;#34;umlauts&amp;#34;: &amp;#34;äüö&amp;#34; }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As something like this (ISO-8859-1):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;7b 20 22 75 6d 6c 61 75 74 73 22 3a 20 22 e4 fc f6 22 20 7d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Instead of like this (UTF-8):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;7b 20 22 75 6d 6c 61 75 74 73 22 3a 20 22 c3 a4 c3 bc c3 b6 22 20 7d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To be on the safe side, make sure to either use the &lt;code&gt;-InFile&lt;/code&gt; option (and specify the &lt;code&gt;-Headers&lt;/code&gt;) and/or use a pipeline, but set the &lt;code&gt;-ContentType&lt;/code&gt; option (instead of the Content-Type header in the &lt;code&gt;-Headers&lt;/code&gt;) the &lt;em&gt;Invoke-WebRequest&lt;/em&gt; cmdlet provides:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Get-Content&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;txt&lt;/span&gt; &lt;span class="n"&gt;-ReadCount&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Method&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-ContentType&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json; charset=utf-8&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; will properly send the UTF-8 data.&lt;/p&gt;
&lt;h3 id="using--body"&gt;Using -Body&lt;/h3&gt;
&lt;p&gt;If you want to build your body manually in the command, you can use the &lt;code&gt;-Body&lt;/code&gt; option:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Method&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-ContentType&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json; charset=utf-8&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Body&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;{&amp;#34;hello&amp;#34;: &amp;#34;world&amp;#34;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For posting form data, you can use a hash table (going with the default &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; here):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Method&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;-Body&lt;/span&gt; &lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;world&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="sending-cookies-building-sessions"&gt;Sending Cookies, building sessions&lt;/h2&gt;
&lt;p&gt;When having multiple interactions with an endpoint, you might want to use a session object, for example to capture/send cookies. The Invoke-WebRequest cmdlet provides the option &lt;code&gt;-SessionVariable&lt;/code&gt;, which you can give a target variable name to be used later for subsequent requests with the &lt;code&gt;-WebSession&lt;/code&gt; option. Since we&amp;rsquo;re focussing on just manually sending data, let&amp;rsquo;s rather see, how we can manually create a .NET CookieContainer, add a cookie, and then pass the whole thing to &lt;code&gt;iwr&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;New-Object&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;PowerShell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;WebRequestSession&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$c&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;New-Object&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Hello&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;World&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;httpbin.org&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://httpbin.org/cookies&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-WebSession&lt;/span&gt; &lt;span class="nv"&gt;$s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This basically just translates to a &lt;code&gt;Cookie: Hello=World&lt;/code&gt; header.&lt;/p&gt;
&lt;div class="notice notice-info"&gt;
 The arguments to .Net.Cookie are referenced &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.net.cookie?view=netframework-4.7.2"&gt;here at the MS docs&lt;/a&gt;; in short, we&amp;rsquo;re using Name, Value, Path, Domain. Inspect &lt;code&gt;$c&lt;/code&gt; to see other attributes to set (like http only, secure, expiry, etc.)
&lt;/div&gt;

&lt;h2 id="authentication"&gt;Authentication&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s look at three ways to authenticate against a web service: using basic auth, using client certificates and using Windows authentication via NTLM or Kerberos.&lt;/p&gt;
&lt;h3 id="using-basic-auth"&gt;Using Basic Auth&lt;/h3&gt;
&lt;p&gt;In this case we will not wait for a server challenge, but build the Authorization header ourselves (don&amp;rsquo;t do this with sensitive creds as they will go right into your history file!):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$creds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;System.Convert&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="no"&gt;System.Text.Encoding&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;AzureDiamond:hunter2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://httpbin.org/basic-auth/AzureDiamond/hunter2&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-Headers&lt;/span&gt; &lt;span class="vm"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Authorization&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Basic &amp;#39;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$creds&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you want to use your Windows user&amp;rsquo;s credentials for the request, you can just use the &lt;code&gt;-Credential&lt;/code&gt; option, as in &lt;code&gt;-Credential domain\you&lt;/code&gt;. In this case, there&amp;rsquo;s no need for you to create the Authorization header yourself. Not though, that this will make two requests; one that the server will answer with a 401, and another one with your credentials.&lt;/p&gt;
&lt;h3 id="using-a-client-certificate"&gt;Using a client certificate&lt;/h3&gt;
&lt;p&gt;Using a client-certificate-based authentication is easiest when you access the certificate directly from the Windows cert store. Make sure to have your client certificate and private key installed, then use the &lt;code&gt;-CertificateThumbprint&lt;/code&gt; option to pass the thumbprint of the cert you want to use. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-ChildItem&lt;/span&gt; &lt;span class="n"&gt;Cert&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;CurrentUser&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt; &lt;span class="c"&gt;# Check installed certs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Thumbprint&lt;/span&gt; &lt;span class="n"&gt;Subject&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;----------&lt;/span&gt; &lt;span class="p"&gt;-------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;28D8AB79A7976FEED36D1DF0B9AC3D3F36B7C4DF&lt;/span&gt; &lt;span class="n"&gt;CN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BadSSL&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;Certificate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BadSSL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;San&lt;/span&gt; &lt;span class="n"&gt;Francisco&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;California&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;US&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://client.badssl.com&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;-CertificateThumbprint&lt;/span&gt; &lt;span class="n"&gt;28D8AB79A7976FEED36D1DF0B9AC3D3F36B7C4DF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="using-windows-authentication--http-negotiate"&gt;Using Windows authentication / HTTP Negotiate&lt;/h3&gt;
&lt;p&gt;You can also instruct &lt;code&gt;iwr&lt;/code&gt; to use the domain credentials of the current user (for example for an intranet service). This is helpful if you want to send requests to an endpoint that wants you to connect via a Windows Authentication provider like NTLM or Kerberos.&lt;/p&gt;
&lt;p&gt;Just adding &lt;code&gt;-DefaultCredentials&lt;/code&gt; to your &lt;code&gt;iwr&lt;/code&gt; will handle the negotiation for you:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="nb"&gt;my-domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;local&lt;/span&gt; &lt;span class="n"&gt;-UseDefaultCredentials&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;iwr&lt;/code&gt; will make an unauthenticated request which will result in a 401 error, then make another request (or more) for the NTLMSSP (NTLM Secure Service Provider) or SPNEGO (Simple Protected Negotiation) negotiation.&lt;/p&gt;
&lt;div class="notice notice-warning"&gt;
 Note that &lt;code&gt;-DefaultCredentials&lt;/code&gt; will not work for Basic Auth!
&lt;/div&gt;

&lt;h2 id="catching-exceptions"&gt;Catching exceptions&lt;/h2&gt;
&lt;p&gt;Combining all the options from above can lead to errors, so let&amp;rsquo;s see how we can catch these exceptions.&lt;/p&gt;
&lt;p&gt;Something like the following will give an error (invalid option to &lt;code&gt;iwr&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;-SomethingInvalid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, this will also give an error (syntactically correct command, but server returns a 404):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;doesnt-exist&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can catch all kinds of exceptions by wrapping the request into a try-catch block:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;iwr &lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="p"&gt;//&lt;/span&gt;&lt;span class="n"&gt;httpbin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="nb"&gt;doesnt-exist&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;Exception&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will catch all exceptions. If you want to handle certain exceptions differently, use multiple catch statements.&lt;/p&gt;
&lt;p&gt;We can access the exception though the pipeline variable &lt;code&gt;$_&lt;/code&gt;. The server response object (obviously only if it is a WebException and not something like a Command exception, ParameterBindException, etc.) can then be accessed via &lt;code&gt;$r.Response&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="more-information"&gt;More information&lt;/h2&gt;
&lt;p&gt;There are naturally many more options, more scenarios and the whole topic about response parsing I didn&amp;rsquo;t mention here. Have a look at the &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1"&gt;official docs&lt;/a&gt; for a first overview, then start tinkering.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;</description></item></channel></rss>