How to spoof a hostname for Invoke-WebRequest (without messing around in the HOSTS file)

Despite moving on to Docker/Kubernetes and therefore Linux, I still get PowerShell questions from colleagues. This particular case was a colleague who wanted to test that each of several webservers behind a load balancer was properly processing a SAML request, without having to change his HOSTS file every time. As a Texas girl, I can’t resist a dare, so here we go: how to [mock | spoof | fake | manipulate] the IP address of a hostname for a web request. We’ve tried this with Invoke-WebRequest; it might also work for Invoke-RestMethod.

Since the site my colleague was testing was HTTPS-only, you first have to tell PowerShell to not worry about SSL certificates. There’s a TechNet Forum answer that refers to a now-disappeared Connect article that has one part of the script we’re using, as well as the oldest post (on a blog that hasn’t been updated in 2.5 years) with another part of the script, so for the sake of everyone’s sanity, a copy of that script as my colleague and I use it:

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
Add-Type -AssemblyName System.Web
Add-Type -AssemblyName system.Security
Add-Type -AssemblyName System

Add-Type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

… as for the actual spoofing, a moderate amount of Googling later yielded a Reddit thread, with the right answer buried in the middle of, well, a Reddit thread (“fix your network so you don’t need to edit host files”):

Invoke-WebRequest https://192.168.65.2 -Headers @{ host="awesome.mandie.net" }

Remember that the PowerShell session will uncritically accept all HTTPS answers, so close it and start a new one when you need to say, use the AzureRM modules!