title: Using Managed Identity in a Azure Function to access Graph API
body: <p><strong>Short version</strong><br />
  I want to avoid username/passwords/secrets/key valults/etc. by using Managed Identity, in a PowerShell script, running on Azure Functions.<br />
  It seems to fail on:</p>
  <pre><code>Import-Module Microsoft.Graph.Authentication
  Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All' 
  </code></pre>
  <p><strong>Background</strong><br />
  I have followed <a href="https://docs.microsoft.com/en-us/azure/app-service/scenario-secure-app-access-microsoft-graph-as-app?tabs=azure-powershell%2Ccommand-line" rel="nofollow noreferrer">Access Microsoft Graph from a secured app as the app</a>, and the setup seems to be fine.<br />
  I enable System Identity on the Azure Function and give permission to Microsoft Graph, when I check Enterprise App, permissions seems fine. And I find the managed identity in GraphAggregatorService (00000003-0000-0000-c000-000000000000).</p>
  <p>When I debug from VScode, with my identity, the script works perfectly.</p>
  <p>When Azure Functions runs the code, the following happens:</p>
  <pre><code>WARNING: Interactive authentication is not supported in this session,
  falling back to DeviceCode. Future versions will not automatically fallback to DeviceCode.
  </code></pre>
  <p>Then</p>
  <pre><code>ERROR: Could not find file 'C:\home\site\wwwroot\.graph'. 
  Exception : Type : System.IO.FileNotFoundException 
  Message : Could not find file 'C:\home\site\wwwroot\.graph'. 
  FileName : C:\home\site\wwwroot\.graph TargetSite : 
  Name : MoveNext DeclaringType : Microsoft.Graph.PowerShell.Authentication.Cmdlets.ConnectMgGraph+&lt;ProcessRecordAsync&gt;d__52, Microsoft.Graph.Authentication, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 
  ...&lt;cut&gt;
  Line : Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All' PositionMessage : At C:\home\site\wwwroot\TestPowerShellTimer\run.ps1:15 char:1 + Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All' 
  ...&lt;cut&gt;
  </code></pre>
  <p><strong>Code</strong></p>
  <pre><code># Input bindings are passed in via param block.
  param($Timer)
  
  Import-Module Microsoft.Graph.Authentication
  Connect-MgGraph -Scopes 'Reports.Read.All', 'Group.ReadWrite.All' 
  
  $reportJson = Invoke-GraphRequest -Uri 'https://graph.microsoft.com/beta/reports/credentialUserRegistrationDetails?$top=5000' -Method GET
  </code></pre>
  <p><strong>Why</strong><br />
  I could have used Connect-MsOnline (doing the same with msonline), but the code uses uses significantly longer time to complete.<br />
  <strong>What</strong><br />
  I am looping through our users to see if they have set up MFA, and add them to a security group. No, there is no way to do this with azure ad dynamic groups afaik. But if someone has suggestions to other ways of achieving this, feel free to mention it...</p>
  <p><strong>My thoughts</strong><br />
  Obviously, I am missing something or totally misunderstood something.<br />
  The part of the errormsg &quot;C:\home\site\wwwroot.graph&quot;, I cannot figure out. Google is not my friend at this point.</p>
  <p>I guess I have to, somehow, instruct AzF to use the managed identity:</p>
  <pre><code>Import-Module Microsoft.Graph.Authentication
  Connect-MgGraph -Scopes -TenantId -ClientId 
  </code></pre>
  <p>but I cannot figure out how. I realize that I have ended up with guessing, and then it is time to ask for help.</p>
  <p>How to use managed identity in Azure Functions with the Microsoft.Graph.Authentication module?</p>