How to authenticate without sending my username and password for HTTP requests? - powershell

Currently, following is how I am sending request from PS to update a parameter:
$pair="$("username"):$("password")"
$encodedCreds=[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue="Basic $encodedCreds"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", $basicAuthValue)
$headers.Add("Content-Type", 'text/plain')
$headers.Add("Origin", 'https://teamcity.server.io')
Invoke-RestMethod -Method Put -Uri $url -Headers $headers -Body $updated_version
But I do not want my username and password mentioned like this anymore.
What other ways do I have to authenticate myself for HTTP requests made within from TeamCity Build Step through PS?

Had to use the basic auth but instead of using my own credentials used a super user created by the dev ops that is available to everyone in the company.

Related

Cant' Access API with Powershell but can access using Postman, Python, or cURL

I'm trying to get data back from an API online using Powershell with the command Invoke-WebRequest -UseBasicParsing $request_string -Method Get -Headers $headers) but am getting back Invoke-WebRequest : The remote server returned an error: (403) Forbidden.
I am supplying a $headers dictionary. Strangely, I can access the API using Postman, Python, and cURL. It's only when using Powershell commands that I get the 403 error. In fact, I used Postman's Code Snippet feature to generate my Powershell code, and it still doensn't work! Postman's Powershell Code Snippet was:
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer {removed for security}")
$response = Invoke-RestMethod '{removed for security}' -Method 'GET' -Headers $headers
$response | ConvertTo-Json
To recap, both Invoke-WebRequest and Invoke-RestMethod don't work.
Any help here is much appreciated.
Thanks!
Figured it out on my own.
The API vendor enforced https requirement instead of just http. Apparently, Postman, Python, and cURL can figure that out on their own and change the request accordingly, but Powershell cannot.

need to add authentication header to azure devops api request

I'm trying to get information on my latest builds by sending a GET request to the Azure DevOps REST Api. I'm using Azure DevOps Server 2020 with the Patch 1 update. I need to add an authorization header to the request. The header I added is not working.
I'm doing the request in Powershell. Here's my code:
$PAT = 'personal access token'
$ENCODED = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($PAT))
$headers = #{
Authorization="Basic $ENCODED"
}
Invoke-RestMethod -Uri [azure devops server url]/[project name]/_apis/build/latest/Build?api-version=5.0 -Method Get -Headers $headers
When I run the code I get the error: Invoke Method: The format of value [PAT] is invalid
UPDATE:
I updated the header syntax. Now the reponse I get:
Invoke-RestMethod:
TF400813: Resource not available for anonymous access. Client authentication required. - Azure DevOps Server
I also tried passing my Azure DevOps username and password in the header like this:
$headers = #{
Authorization="Basic [domain\username]:[password]"
}
and I got this in response:
Invoke-RestMethod: Response status code does not indicate success: 401 (Unauthorized).
Do I have to enable some setting in Azure DevOps?
I usually reference to this demo to run REST API in PowerShell, it can work fine:
$uri = "request URI"
$pat = "personal access token"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", ("Basic {0}" -f $base64AuthInfo))
$headers.Add("Content-Type", "application/json")
. . .
$body = "{
. . .
}"
Invoke-RestMethod -Uri $uri -Headers $headers -Body $body -Method POST
In your case, the issue seems is caused by the encoding. Try using ASCII or UTF8, instead of Unicode.
To view more details, you can see "Use personal access tokens".

Create folder in user mailbox with Graph API

want to use the Graph API to create a folder in a user's mailbox that exists in Exchange Online.
As a result of the investigation, if I use "https://graph.microsoft.com/v1.0/users/testuser01#domain.com/mailFolders", I feel that it is possible, but an error is displayed and I cannot create it.
Currently, "Exchange> Mail.ReadWrite, MailboxSettings.ReadWrite" is assigned to the execution user (admin).
However, it says "Access is denied. Check credentials and try again." Is the permission wrong?
Or is the specified URL incorrect?
Sorry to trouble you, but thank you for your response.
【Append】
$body = #{
grant_type="client_credentials"
resource=$resource
client_id=$ClientID
client_secret=$ClientSecret
}
`#Get Token
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantName/oauth2/token -Body $body
API Permissions
You are using the client credential flow to get the token to call Microsoft Graph - Create MailFolder, so you need to add the Application permission Mail.ReadWrite of Micrsoft Graph to your AD App.
1.Add the Application permission Mail.ReadWrite like below.
2.Click the Grant admin consent for xxx button, and make sure the $resource in your request is https://graph.microsoft.com.
Update:
Here is a powershell sample to call Create MailFolder API to create MailFolder.
$uri = "https://graph.microsoft.com/v1.0/users/joyw#xxxxx.onmicrosoft.com/mailFolders"
$headers = #{
'Content-Type' = 'application/json'
'Authorization' = 'Bearer <access-token-here>'
}
$body = ConvertTo-Json #{
"displayName" = "testfolder1"
}
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $body
Check the result in the Graph Explorer with List mailFolders:

Powershell Invoke-Restmethod aborted due to SSL/TLS Secure Channel (Smartsheets API)

I am having trouble calling smartsheets api with powershell Invoke-Restmethod cmdlet.
The attached script has worked before. See error message regarding SSL/TLS below.
$apiKey = "**********"
$url = "https://api.smartsheet.com/2.0/sheets"
$get_headers = #{"Authorization" = "Bearer " + $apiKey}
$put_headers = #{}
$put_headers.Add("Authorization", "Bearer " + $apiKey)
$put_headers.Add("Content-Type", "application/json")
$response = Invoke-RestMethod -Uri $url -Headers $get_headers
Invoke-RestMethod : The request was aborted: Could not create SSL/TLS secure
channel.
Is there anyway around this error?
The Smartsheet API dropped support for TLS 1.0, which is the default for Powershell.
The link Palansen shared above has some good solutions. Basically, you'll need to tell Powershell to use TLS 1.2 when invoked.

POSTing data to ServiceNow via Powershell using Invoke-WebRequest

I am trying to POST information into a table in ServiceNow via a Powershell script. When I run it I get an error
Invoke-WebRequest : The remote server returned an error: (500) Internal Server Error.
Can someone help me figure out how to solve this? Thank you all in advance.
$userName = 'helpMe'
$password = 'iAmStuck' | ConvertTo-SecureString -asPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName, $password)
$uri = 'stuff'
$postParams = "test"
#[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-WebRequest -Uri $uri -Method Post -Body $postParams -Credential $cred
ServiceNow has a REST API explorer with various code examples to start working with.
Below is an example that I threw together that posts to the incident table with an admin account. Two important factors here, the user must have roles (here for info https://docs.servicenow.com/bundle/istanbul-servicenow-platform/page/integrate/inbound-rest/reference/r_RESTAPIRoles.html) to use the API and must have access to the table you are trying to post to. Also, note that the body of the post needs to be RAW JSON and all the correct header data is supplied in the URL. If successful ServiceNow will return JSON data about the post.
# Eg. User name="admin", Password="admin" for this code sample.
$user = "admin"
$pass = "noPassword"
# Build auth header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass)))
# Set proper headers
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add('Authorization',('Basic {0}' -f $base64AuthInfo))
$headers.Add('Accept','application/json')
$headers.Add('Content-Type','application/json')
# Specify endpoint uri
$uri = "https://xxxxx.service-now.com/api/now/table/incident"
# Specify HTTP method
$method = "post"
# Specify request body
{request.body ? "$body = \"" :""}}{\"active\":\"true\",\"number\":\"123\",\"short_description\":\"test\"}"
# Send HTTP request
$response = Invoke-WebRequest -Headers $headers -Method $method -Uri $uri -Body $body
# Print response
$response.RawContent
Even though you posted code, you posted nothing relevant to the problem. Whatever ServiceNow is might have an API for reference on what it's expecting. Often when interacting with web-based APIs, there is a structure that is required for the API to be able to understand the data you're supplying in $postParams. Sometimes it can just be key->value pairs in the case of a flat HTTP POST but often times for RESTful APIs you'll need to structure a JSON header as defined by the API documentation.
If you do a search for "servicenow powershell interaction" it looks like there's a GitHub project for interacting with ServiceNow via PowerShell and also a PDF that specifcally covers this topic.