What is the equivalent of
curl -u username:password ...
in PowerShell\'s Invoke-RestMethod
? I tried this:
$sec
This version works with Get-Credential
's PSCredential
object. It also works cross-platform in PowerShell 6.0. It does this by avoiding use of BSTR calls, which are sometimes suggested when attempting to extract the password from PSCredential
.
$creds = Get-Credential
$unsecureCreds = $creds.GetNetworkCredential()
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $unsecureCreds.UserName,$unsecureCreds.Password)))
Remove-Variable unsecureCreds
Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} ...
I'm not sure why the but it works with the httpbin service.-Credential
parameter isn't working in your case,
You can try this:
$pwd = ConvertTo-SecureString "MyPassword" -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential ('PsUser', $pwd)
Invoke-RestMethod 'http://httpbin.org/basic-auth/PsUser/MyPassword' -cred $cred
Edit: As noted in the comments, this method will not send the Authorization header on the initial request. It waits for a challenge response then re-sends the request with the Authorization header. This will not work for services that require credentials on the initial request.
You basically need to pass the username and password pair to Invoke-RestMethod
as an encoded credentials variable.
What worked for me was the following:
$USERNAME = 'user'
$PASSWORD = 'password'
$IDP_URL = 'example.com/token'
$credPair = "$($USERNAME):$($PASSWORD)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
$parameters = @{
Uri = $IDP_URL
Headers = @{ 'Authorization' = "Basic $encodedCredentials" }
Method = 'POST'
Body = '...'
ContentType = '...'
}
Invoke-RestMethod @parameters
Note how you can extract the request parameters into $parameters
to avoid bloating your command.
It appears you should combine methods when they fail independently.
Create the credential and add it to the request.
Create the header and add it to the request.
$username = "username";
$password = ConvertTo-SecureString –String "password" –AsPlainText -Force
$credential = New-Object –TypeName "System.Management.Automation.PSCredential" –ArgumentList $username, $password
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
$getProjectUri = "yourUri"
Invoke-RestMethod -Method Get -Uri $getProjectUri -Headers @{Authorization = "Basic $base64AuthInfo" } -Credential $credential -ContentType "application/json"
I've found that using the -WebSession
parameter works, if you pre-create a WebRequestSession object with credentials. I won't rehash how to create a PS Credential object, as that's already been covered in other answers.
$WebSession = New-Object -TypeName Microsoft.PowerShell.Commands.WebRequestSession -Property @{Credentials=$Credential}
Invoke-RestMethod -Uri "your_URI" -WebSession $WebSession
This approach sends the auth header on the first call, so avoids the 401 response.
Incidentally, this approach can also be used to set proxy details (which don't work properly in all versions of PS when specified using the parameters), and handles cookies if your API requires that.
This is the only method that worked for me so far:
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password)))
Invoke-RestMethod -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} ...
But I don't believe there isn't a better way.