Powershell Invoke-RestMethod Call using Windows store certificate (Basic Authorization ?) - rest

I would like to call a remote Rest web service from a Windows server hosting the remote certificate.
I've exported the certificate from the remote server and added it to the Windwos store. (/Personal/myCert)
I would like to use it on a Invoke-RestMethod PowerShell command.
Here bellow is the code I've tried
# Variables
$Remote_Uri = "https://remote.example.com/service/search"
$Remote_CertificateName = "myCert"
$Remote_ApiKey = "oisdjfSOEDJFKQDfSDKFjsQDKFJ"
$Remote_ContentType = "application/json"
$LocalArtifactPath = "C:\RemoteObjects.json"
# Get Certificate
$Remote_CertificateThumbprint = (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match $Remote_CertificateName}).Thumbprint;
$Certificate = Get-ChildItem -Path Cert:\LocalMachine\My\$Remote_CertificateThumbprint
# Basic Encoding
$encoding = [System.Text.Encoding]::ASCII.GetBytes($Certificate)
$encodedString = [System.Convert]::ToBase64String($encoding)
$BasicAuth = "Basic " + $encodedString
# Set Headers
$Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$Headers.Add("Authorization", $BasicAuth)
$Headers.Add("api", $Remote_ApiKey)
$Headers.Add("Content-Type", $Remote_ContentType)
# Self-signed certificate
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
# Call Rest Service
Invoke-RestMethod -Method Get -Uri $Remote_Uri -OutFile $LocalArtifactPath -Headers $Headers
Invoke-RestMethod -Method Get -Uri $Remote_Uri -OutFile $LocalArtifactPath -Certificate $Certificate
Invoke-RestMethod -Method Get -Uri $Remote_Uri -OutFile $LocalArtifactPath -CertificateThumbprint $Remote_CertificateThumbprint
# Self-signed certificate off
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
The three lines with Invoke-RestMethod commands failed with respectively :
Wrong header (this was expected but I gave it a try)
Authorization is empty or scheme is not basic
Certificate thumbprint not found
I've got the rest call working with #{"AUTHORIZATION"="Basic Base64Encode(user:pass)"} so I can tell the service is answering but I would like not to use user:pass in my script.
I would like to use the Certificate I've added to the Windows Store.
I'm wondering about two things :
Is the "Basic" authorization scheme is the good one to use with a certificate ?
In powershell, how to use a certificate from the local windows store running Invoke-RestMethod command ?
Thank you for your help

Adding this [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 in my script fixed the "The underlying connection was closed" issue.
Before this crosscheck whether IIS is enabled in your system.

Related

How To Copy/Download Azure Storage Blob To Azure Windows Virtual Machine Using Managed Identity Through Powershell Scripts

I am able to Upload File From Virtual Machine To Storage Account Container using Managed Identity Through PowerShell Scripting
I followed This Microsoft Document Link: https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-datalake
Followed Steps:
I Signed into Azure Portal
created Managed Identity Resource
created one Windows VM and enabled system-assigned managed identity
created Azure Storage Account & Assigned Storage Blob Data Contributor role to VM under your storage account
Now connected to VM and run below PowerShell commands to get access token:
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com' -Method GET -Headers #{Metadata="true"}
$content = $response.Content | ConvertFrom-Json
$AccessToken = $content.access_token
Followed Below PowerShell Scripts for Uploading Files from VM TO Azure Storage Container
$file = "C:\Users\VMWindows0102\Desktop\test/localfile.txt" #File path
$name = (Get-Item $file).Name
$url="https://adls0102.blob.core.windows.net/container/$($name)"
$RequestHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$RequestHeader.Add("Authorization", "Bearer $AccessToken")
$RequestHeader.Add("x-ms-version", "2019-02-02")
$RequestHeader.Add("x-ms-blob-type", "BlockBlob")
$result = Invoke-WebRequest -Uri $url -Method Put -Headers $RequestHeader -InFile $file
file uploaded to container successfully from VM Local Drive
but, Now I Need Similar PowerShell Script For Downloading File From Azure Storage To Virtual Machine Local Drive Using Managed Identity Please Help...
Thanks In Advance
I tried to reproduce the same in my environment to download the blob files using PowerShell:
I created a virtual machine and assigned Managed Identity to assign the RBAC Role. Like below.
Azure Portal > Storage Account > Select Your Storage Account > Access Control (IAM) > Add role assignment
Here is the script to download the blob file using powershell.
Login to your Virtual Machine and open powershell ISE as administrator and run below powershell code to download blob file.
Connect-AzAccount -identity
$responseID = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com/' `
-Headers #{Metadata="true"}
$val =$response.Content | ConvertFrom-Json
$access_token = $content.access_token
$Path = "C:\Venkat"
$url="https://Storageaccount.blob.core.windows.net/testcontainer/Test.txt"
$RequestHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$RequestHeader.Add("Authorization", "Bearer $access_token")
$RequestHeader.Add("x-ms-version", "2019-02-02")
$result = Invoke-WebRequest -Uri $url -Headers $RequestHeader
$result.content
$output = $result.content
Invoke-WebRequest -Headers $header -Uri $url -OutFile "C:\Venkat\Test.txt" -PassThru
Output:
Followed Steps:
I Sign into Azure Portal
create Managed Identity Resource
create Windows VM and enable system-assigned managed identity
create Azure Storage Account & Assign Storage Blob Data Contributor role to VM under your storage account
Now connect to VM and run below PowerShell commands to Download Blob to Virtual Machine using Managed Identity:
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com' -Method GET -Headers #{Metadata="true"}
$content = $response.Content | ConvertFrom-Json
$AccessToken = $content.access_token
$content.access_token
$RequestHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$RequestHeader.Add("Authorization", "Bearer $AccessToken")
$RequestHeader.Add("x-ms-version", "2019-02-02")
$RequestHeader.Add("x-ms-blob-type", "BlockBlob")
$url="https://adls0102.blob.core.windows.net/container/sample.txt"
$file = "C:\Users\VMWindows0102\Desktop\test\sample.txt"
$result = Invoke-WebRequest -Uri $url -Method Get -Headers $RequestHeader -OutFile $file
Note: Here we don't Require extra Azure Managed Identity Resource
Thank You

Powershell7 proxy authentication

I'm a PowerShell novice and I inherited some code that's forced me to use Powershell7 over 5.1 on my Windows Server 2012 and now I can't get my credentials to authenticate across the organisation's proxy. I'm thinking there's something in the Powershell7 environment that's not installed/no longer supported/not configured correctly. The code below works in 5.1 but in 7, I get a message back from our proxy saying it's missing credentials. Can anyone shed light on what to do?
#*************************************************************************
# Proxy Credentials
#*************************************************************************
[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('http://proxy.############')
$username ="###################"
$password ="###################"
$securePwd = $password| convertto-securestring -AsPlainText -Force
$Creds=new-object System.Management.Automation.PSCredential ($username,$securePwd)
$Wcl=New-Object System.Net.WebClient
$Wcl.Proxy.Credentials=$Creds
#*************************************************************************
# Authentication Call
#*************************************************************************
$uri = 'https://testapi.com/web/authenticate'
$params = '{"userName": "######",
"password": "########"
}'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$token =Invoke-Webrequest -Method Post -Uri $uri -body $params -ContentType "application/json" -UseBasicParsing |ConvertFrom-Json | Select AuthenticateResult
write-host $token
#*************************************************************************
This was something specific to the service account I was using to log in to the server. Changed the account and it worked on both versions. No idea what the difference was but I got what I needed.

use azure credentials in web requests

I need to create a solution to download the usage reports on a scheduled basis from here: https://reports.office.com/pbi/v1.0/{tenantid}/UserActivity
This should be as simple as:
$cred = Get-AutomationPSCredential -Name 'reportingserviceaccount'
$uri = "https://reports.office.com/pbi/v1.0/{tenantid}/UserActivity"
Invoke-RestMethod -Method Get -Uri $uri -Credential $cred -OutFile C:\users\Public\output.json
or
Invoke-WebRequest -Uri $uri -Credential $cred -OutFile C:\users\Public\output.json
However, both cases I only get the login form downloaded instead of the data. When I open the url in my browser I can correctly see the json response. Can somebody give me a hint what am I missing?

how to implement soapup certificat with password authentification

I am using soapui to hit a webservice it's working but im trying to create an implementation with PowerShell, the probleme is im using Invoke-RestMethod to send my request with -certificate and I call my certificat in this way :
$Certificat = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$Certificat.Import($Dir,$password,"DefaultKeySet");
$status = Invoke-RestMethod -Method 'Post' -Uri $url -Body $body -Certificate $Certificat
the server return 403 error that mean he didnt receive the certificat. my question is there is another method to implement the sending of soap ui call with certificat that require a password.
Looking at your code again, (I guess I should have scrolled all the way right), you are not specifying a cert.
This...
$Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
... try it this way.
$Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\mycert.cer")

How to use PowerShell invoke-webrequest with Windows Authentication and Username\Password

The following PowerShell invoke-webrequest works for me when the Windows Service I'm running it from has permission to call the webservice. However, this isn't always the case.
I need to the ability to use Windows Authentication but also set the account username\password for the call. Does anyone have some sample code for doing this?
Invoke-WebRequest -UseBasicParsing "url" -UseDefaultCredentials -Method GET
You may set the UseDefaultCredentials property of Invoke-WebRequest module to true. Link to the official doc: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-6
$url = "http://yourURL"
$wc = New-Object System.Net.WebClient
$wc.UseDefaultCredentials = $true
$response = $wc.DownloadString($url)