I'm trying to better understand Add-Type in PowerShell after running into an issue of trying to do a REST API call and avoiding a self-signed cert issue. Code is as follows.
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
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("InternalApiKey", "d472f0e9-23c9-4fff-aec9-cc1f2d5d6a85")
$response = Invoke-RestMethod 'https://localhost:9443/api/GetStats/' -Method 'GET' -Headers $headers
$response | ConvertTo-Json
When I run this it breaks with the error.
"New-Object: Cannot find type [TrustAllCertsPolicy]: verify that the assembly containing this type is loaded." And then, because that failed I get the error, "Invoke-RestMethod: The remote certificate is invalid because of errors in the certificate chain: PartialChain"
Just stumbled upon the fact it works as expected in PowerShell 5.1.22000.282 and does not in PowerShell 7.2.1. What changes can I make to make it work in both version of PowerShell?
Update: this link has some code to get it running in both versions of PowerShell. I accepted the answer I did because it was the most helpful and because I'm sharing this other answer. https://github.com/PowerShell/PowerShell/issues/7092
In PowerShell 7.x, the web cmdlets have a -SkipCertificateCheck
switch you can use instead:
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("InternalApiKey", "d472f0e9-23c9-4fff-aec9-cc1f2d5d6a85")
$response = Invoke-RestMethod 'https://localhost:9443/api/GetStats/' -SkipCertificateCheck -Method 'GET' -Headers $headers
If the endpoint is already sending JSON, you might as well use Invoke-WebRequest
instead (rather than letting Invoke-RestMethod
convert from JSON to objects and then back again with ConvertTo-Json
):
$response = Invoke-WebRequest 'https://localhost:9443/api/GetStats/' -SkipCertificateCheck -Method 'GET' -Headers $headers
$response.Content # this now contains the body of the raw response from the API, eg. JSON/XML/whatever