How to correctly access v2.0 of REST API in PowerShell for mailbox management - powershell

We have a PowerShell script which checks a service mailbox and updates our wallboards with information, then moves the relevant emails to the deleted folder. This was set up under API v1.0 which is now deprecated and we're needing to get it changed for version 2.0.
Unfortunately, this has led to a lot of confusion and a lot of scratched heads which isn't too fun. This has occurred mainly around getting an oAuth2 token then feeding it into the request for the mailbox.
So far, we've managed to get the Azure AD app registered and it's providing an authentication token, but that's coming back as unauthorised from Microsoft Graph.
# tenantID, clientSecret and clientID not here.
# The resource URI
$resource = "https://graph.microsoft.com"
# Your Client ID and Client Secret obainted when registering your WebApp
$redirectUri = "http://returnuri"
# UrlEncode the ClientID and ClientSecret and URL's for special characters
$clientIDEncoded = [System.Web.HttpUtility]::UrlEncode($ClientID)
$clientSecretEncoded = [System.Web.HttpUtility]::UrlEncode($clientSecret)
$redirectUriEncoded = [System.Web.HttpUtility]::UrlEncode($redirectUri)
$resourceEncoded = [System.Web.HttpUtility]::UrlEncode($resource)
$scopeEncoded = [System.Web.HttpUtility]::UrlEncode("https://outlook.office.com/user.readwrite.all")
$body = #"
client_id=$ClientID
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=$clientSecretEncoded
&grant_type=client_credentials
"#
$userid = 'userID'
$accessToken = Invoke-RestMethod "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token" -Method Post -Body $body
#
#$cred = $(Get-Credential)
Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users/$userid/messages" -Headers #{Authorization = "Bearer $($accessToken.access_token)"} -Credential $cred
Expected results: access to the mailbox.
Actual results:
Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
At line:32 char:1
+ Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users/$useri ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Related

Microsoft Graph "Access is denied. Check credentials and try again" in PowerShell

I am unable to list events in a calendar via MS Graph API: calls result in "Access is denied". Switching to raw HTTP results in error 403 as well. I am able to create an event via a POST to /events endpoint, though.
This is the code I am executing:
$tenant = '<SNIP>'
$client_id = '<SNIP>'
$client_secret = '<SNIP>'
$scope = [System.Web.HttpUtility]::UrlEncode('https://graph.microsoft.com/.default')
$url = "https://login.microsoftonline.com/$tenant/oauth2/v2.0/token"
$Body = "client_id=$client_id&scope=$scope&client_secret=$client_secret&grant_type=client_credentials"
$response = Invoke-RestMethod $url -Method Post -Body $Body -Headers #{'Content-Type'='application/x-www-form-urlencoded'}
$token = $response.access_token
Connect-MgGraph -AccessToken $token
Get-MgUserEvent -UserId '17160c5f-dd86-46cc-92b8-54d6e94861e6'
Output:
.\Calendar.ps1
Welcome To Microsoft Graph!
Get-MgUserEvent : Access is denied. Check credentials and try again.
In C:\Users\SYSTOLA-rk\Calendar.ps1:15 Zeichen:1
+ Get-MgUserEvent -UserId '17160c5f-dd86-46cc-92b8-54d6e94861e6'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ({ UserId = 1716..., Property = }:<>f__AnonymousType39`7) [Get-MgUserEvent_List1], RestException`1
+ FullyQualifiedErrorId : ErrorAccessDenied,Microsoft.Graph.PowerShell.Cmdlets.GetMgUserEvent_List1
Here are the permissions in Azure configured for the app (I lack reputation for posting images): App Permissions

JIRA Cloud API GET Request - Works in Postman, but not Powershell

I am able to perform a GET Request from Jira successfully in Postman, but am unable to make the same request in Powershell due to an authentication error. I know that my credentials are correct because there are or GET Requests that are successful. My guess is that it has something to do with the URL (https://arnold.jira.com/admin/rest/um/1/user).
Since I know that my credentials are correct, I am not sure what else I can try.
# Create a new session using the Jira REST API
$user = 'john.rambo#arnold.com'
$pass = '8675309'
$pair = "$($user):$($pass)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"
$Headers = #{
Authorization = $basicAuthValue;
Accept = 'application/json'
}
# Perform the GET Request
$UserEmail = 'dolf.lundgren#arnold.com'
$UserAttributeLink = 'https://arnold.jira.com/admin/rest/um/1/user?email=' + $UserEmail + '&expand=attributes'
$UserAttributes = Invoke-RestMethod ($UserAttributeLink) -Headers $Headers -Method GET -ContentType "application/json"
I expect to have the info returned, but am met with this error:
Invoke-RestMethod : User failed to authenticate
At line:12 char:19
+ ... ttributes = Invoke-RestMethod ($UserAttributeLink) -Headers $Headers ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Method: GET, Reques\u2026PowerShell/6.2.1
}:HttpRequestMessage) [Invoke-RestMethod], HttpResponseException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Outlook Task REST API - Not authorized 401

I am trying to access the Outlook Rest API 2.0 from Powershell to view and create tasks. I created an application and am successfully retrieving the access_token and the required scope (Tasks.ReadWrite). See my response:
token_type : Bearer
scope : openid Tasks.ReadWrite
expires_in : 3600
ext_expires_in : 3600
access_token : token_value
id_token : id_token_value
Hoever when trying to get a list of tasks i am getting a 401 response (not authorized). See the powershell code below:
$header = #{"Bearer" = "$($response.access_token)"}
$task_list = Invoke-RestMethod -Method Get -Header $Header -Uri" https://outlook.office.com/api/v2.0/me/tasks"
The exception is the following:
Invoke-RestMethod : the remote server returned an error (401) unauthorized
+ $task_list = Invoke-RestMethod -Method Get -Header $Header -Uri "https ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMetho
d], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCo
mmand
This is not the correct method to transmit a bearer token in the header. I'm no expert on the matter, but RFC 6750 says you should transmit it with an Authorization header with the Bearer method, like this:
$header = #{"Authorization" = "Bearer $($response.access_token)"}

Connect Azure Data Catalog REST API using powershell

i want to connect to Azure Data Catalog RestAPI using power shell script and below is my script which failed to run.
Get an Access Token with ADAL
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext ("{0}" -f $login)
$authenticationResult = $authContext.AcquireToken($ResourceId, $ClientId, $redirectUri, $PromptBehavior);
($token = $authenticationResult.AccessToken) | Out-File $accessToken
$authContext.AcquireToken($ResourceId, $ClientId, $redirectUri, $PromptBehavior)
$headers = #{
"Authorization" = ("Bearer {0}" -f $token);
}
$url = "https://api.azuredatacatalog.com/catalogs/DefaultCatalog/search/search?searchTerms=name:=Orders&count=10&api-version=2016-03-30"
$response = Invoke-RestMethod -Method GET -Uri $url -Headers $headers
I am getting below error message
Invoke-RestMethod :
401 - Unauthorized: Access is denied due to invalid credentials.
Server Error
401 - Unauthorized: Access is denied due to invalid credentials.
You do not have permission to view this directory or page using the credentials that you supplied.
At line:1 char:13
+ $response = Invoke-RestMethod -Method GET -Uri $url -Headers $headers
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Please help me in resolving the issue
You might need to grant your application access to the Azure Data Catalog via Azure AD.
Do note that this may require Administrator Approval to complete.

'CompactToken parsing failed with error code: -2147184105' when trying to access Users with Office 365 Unified API using PowerShell

I am trying to list users using Office 365 Unified API with the following code:
$TenantID = "xxx"
$F_ClientID = "yyy"
$F_ClientSecret = "zzz"
Add-Type #'
using System;
public class OAuthContext{
public string AccessToken{get;set;}
public string TokenType{get;set;}
public string ExpiresIn{get;set;}
public string RefreshToken{get;set;}
}
'#
$Uri = "https://login.microsoftonline.com/$($TenantID)/oauth2/token"
$ContentType = 'application/x-www-form-urlencoded'
$Headers = #{}
$Body = [System.Text.Encoding]::UTF8.GetBytes('grant_type=client_credentials&client_id='+$F_ClientID+'&client_secret='+$F_Clie ntSecret+'&resource"=https://graph.microsoft.com')
$Response = Invoke-RestMethod -Method POST -Uri $Uri -Headers $Headers -ContentType $ContentType -Body $Body
$Response
$Context = New-Object OAuthContext
$Context.AccessToken = $Response.access_token
$Context.ExpiresIn = $Response.expires_in
$Context.RefreshToken = $Response.refresh_token
$Context.TokenType = $Response.token_type
$Context
$Headers = #{}
$Headers.Add('Authorization',$Context.TokenType + ' ' + $Context.AccessToken)
$Headers
$Uri = "https://graph.microsoft.com/v1.0/users"
Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers
As seen from the result, the access token seems to be successfully generated.
But when trying to list the users, I get the following error:
Invoke-RestMethod : {
"error": {
"code": "InvalidAuthenticationToken",
"message": "CompactToken parsing failed with error code: -2147184105",
"innerError": {
"request-id": "067c7044-0c59-4a39-86ac-b89e6b13229c",
"date": "2016-02-12T17:09:56"
}
}
}
At line:41 char:1
+ Invoke-RestMethod -Method GET -Uri $Uri -Headers $Headers
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I don't really know what I am doing wrong here!
Thanks for your help!
The response actually indicates that the access token was not successfully generated or passed to the graph endpoint. Microsoft Graph couldn't parse it as a JWT token and thus attempted to process it as a Microsoft Account/Live Id compact token, which also failed. Please check the response that you got from the call to login.microsoftonline.com and that the token passed to graph.microsoft.com is a valid JWT token.
Can you check through this page if the client secret that you are sending matches the result of the page when coding it?
The recipient when viewing 'application / x-www-form-urlencoded' will decode the url, and if your client secret is not encode well, someone characters will disappear. (This was my problem)
I used this code and it worked
What i recommend is to test your query you are sending to the graph api by using the graph explorer tool first. and then mimic the same request in your PS script.
https://graphexplorer2.azurewebsites.net