title: Accessing Microsoft Graph With PowerShell
body: <p>I've been having a hell of a time trying to access the Microsoft Graph using PowerShell. </p>
  
  <p>First I tried using the <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#request-an-authorization-code" rel="nofollow noreferrer">authorization flow</a> and <code>Invoke-WebRequest</code> and <code>Invoke-RestMethod</code> neither of which I could get to work. </p>
  
  <p>Then I found <a href="https://blogs.technet.microsoft.com/cloudlojik/2017/09/05/using-powershell-to-connect-to-microsoft-graph-api/" rel="nofollow noreferrer">this blog</a> that showed how to do it using PowerShell and a couple of the Azure modules.  Below is the code I'm using (ripped right from that blog) but every time I get to the <code>Invoke-RestMethod</code> (in the do-while loop) instead of getting the result of the query I get a <code>403 Forbidden error</code>: </p>
  
  <blockquote>
    <p>Invoke-RestMethod : The remote server returned an error: (403) Forbidden.</p>
  </blockquote>
  
  <pre class="lang-powershell prettyprint-override"><code>Function GetAuthToken {
      Param (
          [Parameter()]
          $TenantName
      )
      Import-Module Azure
      $clientId = "1950a258-227b-4e31-a9cf-717495945fc2"
      $resourceAppIdURI = "https://graph.microsoft.com"
      $authority = "https://login.microsoftonline.com/$TenantName"
      $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
      $Credential = Get-Credential
      $AADCredentialUser = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential" -ArgumentList $credential.UserName, $credential.Password
      $authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $AADCredentialUser)
      Write-Output $authResult
  }
  
  Function GetAllObjectOfType {
      param
      (
          [Parameter(Mandatory = $true)]
          $Tenant,
          [Parameter(Mandatory = $true)]
          $Type,
          [Parameter(Mandatory = $false)]
          $BatchSize = 100,
          [Parameter(Mandatory = $false)]
          $Version = 'Beta'
      )
  
      #------Get the authorization token------#
      $token = GetAuthToken -TenantName $tenant
  
      #------Building Rest Api header with authorization token------#
      $authHeader = @{
          'Content-Type'  = 'application/json'
          'Authorization' = $token.CreateAuthorizationHeader()
      }
  
      #------Initial URI Construction------#
      #$uritest = "https://graph.microsoft.com/v1.0/users/user@contoso.com/mailFolders/Inbox/childFolders"
      $uritest = "https://graph.microsoft.com/v1.0/me/mailFolders/Inbox"
      #Join-Path -Path ''
      $ObjCapture = @()
      do {
          $users = Invoke-RestMethod -Uri $uritest -Headers $authHeader -Method Get
          $FoundUsers = ($Users.value).count
          write-host "URI" $uri " | Found:" $FoundUsers
          #------Batched URI Construction------#
          $uri = $users.'@odata.nextlink'
          $ObjCapture = $ObjCapture + $users.value
  
      }until ($uri -eq $null)
      $ObjCapture
  }
  </code></pre>
  
  <p>I can run this same query (<code>/v1.0/me/mailFolders/Inbox</code>) from the Graph Explorer and it runs perfectly fine with no errors.</p>
  
  <p>The <code>GetAuthToken</code> seems to be working as I do get a token back with an expiry, refresh token, etc and the <code>$token.CreateAuthorizationHeader()</code> also returns the correct <code>Authorization = Bearer token</code></p>
  
  <p>I've never done anything with the Microsoft Graph before so I'm sure there is something I'm doing wrong but I cannot for the life of me figure out what.</p>