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 https://IPADDRESS/resource -Credential $cred -certificate $cert -Body $json -ContentType application/json -Method POST
However when I attempt to use the GET method like:
Invoke-WebRequest -Uri https://IPADDRESS/resource -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 https://IPADDRESS/resource -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
This question is related to
.net
rest
powershell
https
I tried searching for documentation on the EM7 OpenSource REST API. No luck so far.
http://blog.sciencelogic.com/sciencelogic-em7-the-next-generation/05/2011
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 https://IPADDRESS/resource -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 https://IPADDRESS/resource -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 http://search.twitter.com/search.json?q=PowerShell
Hope this helps.
Lee'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 https://stackoverflow.com/a/36266735
$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
New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname {your-site-hostname}
in powershell using admin rights, This will generate all certificates in Personal directory
Make sure website hostname and certificate dns-name should exactly match
An 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()
The 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 https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/
Invoke-WebRequest "DomainName" -SkipCertificateCheck
You can use -SkipCertificateCheck Parameter to achieve this as a one-liner command ( THIS PARAMETER IS ONLY SUPPORTED ON CORE PSEDITION )
If you run this as administrator, that error should go away
These 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
See https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls#schusestrongcrypto
Did you try using System.Net.WebClient
?
$url = 'https://IPADDRESS/resource'
$wc = New-Object System.Net.WebClient
$wc.Credentials = New-Object System.Net.NetworkCredential("username","password")
$wc.DownloadString($url)
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
}
Source: Stackoverflow.com