Using Powershell v3's Invoke-WebRequest and Invoke-RestMethod I have succesfully used the POST method to post a json file to a https website.
The command I'm using is
$cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("cert.crt") Invoke-WebRequest -Uri -Credential $cred -certificate $cert -Body $json -ContentType application/json -Method POST However when I attempt to use the GET method like:
Invoke-WebRequest -Uri -Credential $cred -certificate $cert -Method GET The following error is returned
Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send. At line:8 char:11 + $output = Invoke-RestMethod -Uri -Credential $cred + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand I have attempted using the following code to ignore SSL cert, but I'm not sure if its actually doing anything.
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} Can someone provide some guideance on what might be going wrong here and how to fix it?
Thanks
311 Answers
This work-around worked for me:
Basically, in your PowerShell script:
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 $result = Invoke-WebRequest -Uri "" 6Lee's answer is great, but I also had issues with which protocols the web server supported.
After also adding the following lines, I could get the https request through. As pointed out in this answer
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols My full solution with Lee's code.
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; } } "@ $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 10An alternative implementation in pure powershell (without Add-Type of c# source):
#requires -Version 5 #requires -PSEdition Desktop class TrustAllCertsPolicy : System.Net.ICertificatePolicy { [bool] CheckValidationResult([System.Net.ServicePoint] $a, [System.Security.Cryptography.X509Certificates.X509Certificate] $b, [System.Net.WebRequest] $c, [int] $d) { return $true } } [System.Net.ServicePointManager]::CertificatePolicy = [TrustAllCertsPolicy]::new() Did you try using System.Net.WebClient?
$url = ' $wc = New-Object System.Net.WebClient $wc.Credentials = New-Object System.Net.NetworkCredential("username","password") $wc.DownloadString($url) 6Invoke-WebRequest "DomainName" -SkipCertificateCheck
You can use -SkipCertificateCheck Parameter to achieve this as a one-liner command ( THIS PARAMETER IS ONLY SUPPORTED ON CORE PSEDITION )
1The following worked worked for me (and uses the latest non deprecated means to interact with the SSL Certs/callback functionality), and doesn't attempt to load the same code multiple times within the same powershell session:
if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { $certCallback=@" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ Add-Type $certCallback } [ServerCertificateValidationCallback]::Ignore(); This was adapted from the following article
I found that when I used the this callback function to ignore SSL certificates [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
I always got the error message Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send. which sounds like the results you are having.
I found this forum post which lead me to the function below. I run this once inside the scope of my other code and it works for me. function Ignore-SSLCertificates { $Provider = New-Object Microsoft.CSharp.CSharpCodeProvider $Compiler = $Provider.CreateCompiler() $Params = New-Object System.CodeDom.Compiler.CompilerParameters $Params.GenerateExecutable = $false $Params.GenerateInMemory = $true $Params.IncludeDebugInformation = $false $Params.ReferencedAssemblies.Add("System.DLL") > $null $TASource=@' namespace Local.ToolkitExtensions.Net.CertificatePolicy { public class TrustAll : System.Net.ICertificatePolicy { public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem) { return true; } } } '@ $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource) $TAAssembly=$TAResults.CompiledAssembly ## We create an instance of TrustAll and attach it to the ServicePointManager $TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll") [System.Net.ServicePointManager]::CertificatePolicy = $TrustAll }
I tried searching for documentation on the EM7 OpenSource REST API. No luck so far.
There's a lot of talk about OpenSource REST API, but no link to the actual API or any documentation. Maybe I was impatient.
Here are few things you can try out
$a = Invoke-RestMethod -Uri -Credential $cred -certificate $cert $a.Results | ConvertFrom-Json Try this to see if you can filter out the columns that you are getting from the API
$a.Results | ft or, you can try using this also
$b = Invoke-WebRequest -Uri -Credential $cred -certificate $cert $b.Content | ConvertFrom-Json Curl Style Headers
$b.Headers I tested the IRM / IWR with the twitter JSON api.
$a = Invoke-RestMethod Hope this helps.
1These registry settings affect .NET Framework 4+ and therefore PowerShell. Set them and restart any PowerShell sessions to use latest TLS, no reboot needed.
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 1- Run this command
New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname {your-site-hostname}
in powershell using admin rights, This will generate all certificates in Personal directory
- To get rid of Privacy error, select these certificates, right click → Copy. And paste in Trusted Root Certification Authority/Certificates.
- Last step is to select correct bindings in IIS. Go to IIS website, select Bindings, Select SNI checkbox and set the individual certificates for each website.
Make sure website hostname and certificate dns-name should exactly match
If you run this as administrator, that error should go away