Microsoft Graph "Access is denied. Check credentials and try again" in PowerShell - 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

Related

How to make -AccessTokens work with Connect-MicrosoftTeams cmdlet?

I am following this link to connect to Microsoft Teams using Access Tokens:
https://learn.microsoft.com/en-us/MicrosoftTeams/teams-powershell-application-authentication
Here is the code:
$ClientSecret = 'xxxxx~xx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
$ApplicationID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$TenantID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
$graphtokenBody = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $ApplicationID
Client_Secret = $ClientSecret
}
$graphToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $graphtokenBody | Select-Object -ExpandProperty Access_Token
$teamstokenBody = #{
Grant_Type = "client_credentials"
Scope = "48ac35b8-9aa8-4d74-927d-1f4a14a0b239/.default"
Client_Id = $ApplicationID
Client_Secret = $ClientSecret
}
$teamsToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $teamstokenBody | Select-Object -ExpandProperty Access_Token
Connect-MicrosoftTeams -AccessTokens #("$graphToken", "$teamsToken")
The application is registered in Azure AD and has been assigned the API permissions as mentioned in the article. I have assigned Teams administrator role to the application as well. Tokens get populated correctly.
Running the code produces the following error:
Connect-MicrosoftTeams : Object reference not set to an instance of an object.
At line:29 char:1
+ Connect-MicrosoftTeams -AccessTokens #("$graphToken", "$teamsToken")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : AuthenticationError: (:) [Connect-MicrosoftTeams], NullReferenceException
+ FullyQualifiedErrorId : Connect-MicrosoftTeams,Microsoft.TeamsCmdlets.Powershell.Connect.ConnectMicrosoftTeams
Connect-MicrosoftTeams : Object reference not set to an instance of an object.
At line:29 char:1
+ Connect-MicrosoftTeams -AccessTokens #("$graphToken", "$teamsToken")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-MicrosoftTeams], NullReferenceException
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.TeamsCmdlets.Powershell.Connect.ConnectMicrosoftTeams
If someone had this issue and have successfully resolved it or have some tips on how to resolve it, please help.
I tried to reproduce the same in my environment and got the same error as below:
The error usually occurs if the version of Microsoft teams you are trying to connect is older than 4.7.1-preview version.
To resolve the error, try updating the Microsoft teams PowerShell version to 4.7.1-preview or later and this type of authentication is supported only in commercial environments.
Get-InstalledModule -Name MicrosoftTeams
Update-Module -Name MicrosoftTeams
After updating the PowerShell Module, I am able to connect to Microsoft Teams successfully like below:
$ClientSecret = "ClientSecret"
$ApplicationID = "AppID"
$TenantID = "TenantID"
$graphtokenBody = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $ApplicationID
Client_Secret = $ClientSecret
}
$graphToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $graphtokenBody | Select-Object -ExpandProperty Access_Token
$teamstokenBody = #{
Grant_Type = "client_credentials"
Scope = "48ac35b8-9aa8-4d74-927d-1f4a14a0b239/.default"
Client_Id = $ApplicationID
Client_Secret = $ClientSecret
}
$teamsToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -Method POST -Body $teamstokenBody | Select-Object -ExpandProperty Access_Token
Connect-MicrosoftTeams -AccessTokens #("$graphToken", "$teamsToken")
Reference:
PowerShell Gallery | MicrosoftTeams 4.9.1

Use Graph API to get contacts from Outlook.com

I am trying to get a list of contacts via Graph API. In the portal.azure.com I went to App registrations and did a new registrations. I created secrets and added permission (picture below)
I am connecting to Graph API with this code
$Body = #{
'tenant' = $TenantId
'client_id' = $ClientId
'scope' = 'https://graph.microsoft.com/.default'
'client_secret' = $ClientSecret
'grant_type' = 'client_credentials'
}
$Params = #{
'Uri' = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
'Method' = 'Post'
'Body' = $Body
'ContentType' = 'application/x-www-form-urlencoded'
}
$AuthResponse = Invoke-RestMethod #Params
$Headers = #{
'Authorization' = "Bearer $($AuthResponse.access_token)"
}
$Result = Invoke-RestMethod -Uri 'https://graph.microsoft.com/v1.0/users' -Headers $Headers
However I get the error message
*Invoke-RestMethod : {
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"date": "2020-09-04T17:54:13",
"request-id": "2113f712-f022-4ebc-8263-d26c469840d0"
}
}
}
At line:31 char:11
$Result = Invoke-RestMethod -Uri 'https://graph.microsoft.com/v1.0/us ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand*
I assume when I get the user ID then I should be able to call https://graph.microsoft.com/v1.0/users/ID/contacts API and I should be able to create/delete contacts. What am I missing or how can I achieve it please?
Edit: I don't believe my answer is accurate as the "Me" endpoint won't work with the client_credential flow.
Original answer --
The Users endpoint is to query all users in your organization, which is different from contacts.
To get your outlook.com contacts, you need to have the following delegated permission in your application.
You will need to grant your application one of the following permissions
permissions (delegated)
OrgContact.Read.All
Directory.Read.All
Directory.ReadWrite.All
Directory.AccessAsUser.All
The endpoint you will be using is : https://graph.microsoft.com/v1.0/me/contacts
You can experiment the different endpoints with Microsoft Graph explorer. The website will also inform you of the required permissions for each calls (through the Modify permissions tab) and give you insights on all aspects of the call itself.

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

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

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

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.