Microsoft Graph PowerShell acts as a wrapper for the Microsoft Graph API, providing you with a mechanism to programmatically work with resources in Microsoft 365 and Microsoft Entra. Unfortunately, there is a slightly higher learning curve when using this tool, compared to its predecessors the MSOnline and AzureAD modules. Unlike these modules, when you use Microsoft Graph PowerShell, by default a standard application is registered in Microsoft Entra named Microsoft Graph Command Line Tools.
Although you can target this application (which maintains the same application ID always) with Conditional Access, your login to the application will not be impacted by the policy, instead, it will just show no application match in the sign-in logs against your policy, even while the application ID is consistent with the policy.
You can still enforce Conditional Access by selecting All Cloud Apps within your policy, but in many scenarios, a deeper level of control is required. In this tutorial, I will show you the right way to use Conditional Access to protect logins with Microsoft Graph PowerShell.
Prevent login to the built-in Microsoft Graph Command Line Tools application
As there isn’t much we can do with the default application. The Microsoft Graph Command Lines Tool app is a public app, which can be called by anyone, similar to the fact that Microsoft Outlook is just a client app, which itself cannot be targeted with Conditional Access. The best course of action is to prevent login to the application altogether. This might seem like a drastic step but is the only and best course of action to begin with.
Follow the below steps to prevent sign-in to the application:
- Login to Microsoft Entra (https://entra.microsoft.com/)
- Select Applications > Enterprise Applications
- Select Microsoft Graph Command Line Tools then Properties
- Change Enabled for users to sign-in to No.
One sign-in is disabled, if users then try to run Connect-MgGraph without any additional parameters, they will be prevented form logging in to the interactive browser session and will be presented with the following error message:
Limit your Global Administrators and Privileged Role Administrators
Privileged Role Administrators and Global Administrators have the right to grant tenant-wide permissions to applications in Microsoft Entra. Not only that, but they can easily reset the previous settings configured on the Microsoft Graph Command Lines Tools app, either intentionally, or unintentionally by deleting and creating the app (which used to be the only way to revoke previously granted API permissions).
Take a look at your Global Administrators, ideally, you should have between 2 and 4 Global Admins and/or Privileged Role Admins, who indirectly also have Global Admin rights. Maintaining this amount of Global Admins is manageable, simple training can be provided to these users so they follow the principles set out in this post.
Additional monitoring can also be configured using tools such as Azure Automation, PowerShell or Microsoft Sentinel to monitor the actions they take.
Register new applications with the necessary Microsoft Graph permissions
If you have followed the first step and blocked access to the built-in public Microsoft Graph application in Microsoft Entra, the only way to then connect to Microsoft Graph PowerShell is to create a new app registration and use that to connect. As any application you create is now a private app to you and not deemed as a third-party ‘public’ app that can be used by default in any organisation, you can now target Conditional Access policies to it.
The idea behind this step is that you have multiple applications in Microsoft Entra that allow you to perform specific actions. Personally, my recommendation is to create 3 or 4 applications which pertain to different groups, for example, Level1Support, Level2Support and so on. Assignment should then be required for these applications and admin consent requests configured for assigning permissions.
To create a new application for interaction PowerShell sessions, follow the below steps:
1. Login to Microsoft Entra
2. Select Applications > App registrations > New registration
3. Name your application then keep all other settings as default and click Register
4. On the applications list, select your application and click Authentication
5. Click Add a platform, then choose Mobile and desktop applications
6. Under Custom Redirect URIs, enter http://localhost and click Configure.
Once you have created your application using the above steps, within PowerShell you can then run the following connection command with your own Tenant ID and Client ID.
Connect-MgGraph -TenantID **** -ClientID ****
Apply Conditional Access policies to Microsoft Graph PowerShell
Conditional Access is the critical step here, although following the steps above puts you in good standing by ensuring PowerShell sessions are not over-privileged and not everyone can attempt to connect to your application publically without prior knowledge, we can still take it one step further.
To apply a Conditional Access policy to your Microsoft Graph PowerShell application, follow the below steps:
1. Login to Microsoft Entra
2. Select Protect > Conditional Access
3. Click New Policy
4. On the Target resources tab, click Select apps then Select and choose your new application from the pop-out search window.
Here is an example of a similar policy I have configured:
- Name: Protected Management Applications
- Users: PowerShell user group
- Target resources: My Graph PowerShell apps
- Conditions: All trusted locations
- Grant: Require authentication strength + Require device to be marked as compliant
For some reason I can’t connect to the new app. It gives this error.
AADSTS50011: The redirect URI ‘http://localhost:50133’ specified in the request does not match the redirect URIs configured for the application ‘AppID’. Make sure the redirect URI sent in the request matches one added to your application in the Azure portal.
I have no idea what that localhost is referencing. I did enable Public Client Flows to allow SSO for domain-joined Windows devices but that didn’t change anything. Curious if you have seen this?
Hi Marc, I missed a step, I have resolved this now in the guide!
Awesome, it works now! Thanks Daniel 🙂