The Get-MgUser cmdlet in Microsoft Graph PowerShell allows you to find information on a user, group of users or all users within your organisation from the command line. It will also expose more information about your users than you can normally find through web-based management portals such as the Azure AD admin Center or Microsoft 365 admin center.
In this tutorial, I am going to walk you through how to use the Get-MgUser cmdlet in Microsoft Graph PowerShell to find and export useful information about your users. I will also cover how you can filter and manipulate your search results to find the specific information you need.
Contents
- Why use the Get-MgUser cmdlet?
- Pre-requisites
- Finding the required permissions to run Get-MgUser
- Find information on a single user
- Selecting specific properties
- Find nested properties with the Microsoft Graph reference documentation
- Find hidden information with -ExpandProperty or -Expand
- Filter Get-MgUser search results
- Find users with the search parameter
- Combining search and filter options
Why use the Get-MgUser cmdlet?
Get-MgUser is the preferred command to use to find information about your users through a command line interface. The command is found within the Microsoft Graph PowerShell SDK which is the successor to PowerShell modules such as MSOnline and AzureAD.
There are many different parameters your can use with Get-MgUser, such as:
-ExpandProperty <String[]>
-Property <String[]>
-Filter <String>
-Search <String>
-Skip <Int32>
-Sort <String[]>
-Top <Int32>
-ConsistencyLevel <String>
-PageSize <Int32>
-All
-CountVariable <String>
Pre-requisites
To use the Get-MgUser command you need to ensure the following:
- You are running PowerShell 5.1 or later
- .NET Framework 4.7.2 or later is installed
- You have the Microsoft Graph PowerShell SDK installed
Finding the required permissions to run Get-MgUser
Before you connect to Microsoft Graph, you must ensure you use the -scope parameter with the correct permissions defined to run the command.
To find the minimum level of permissions you need to find information on your user, use the Find-MgGraphCommand cmdlet to find permissions for the Get-MgUser cmdlet.
Find-MgGraphCommand -command Get-MgUser |`
Select -First 1 -ExpandProperty Permissions
You do not need to be connected to your organisation to run this command however you do need to have Microsoft Graph PowerShell installed. Here is the expected output, although the description does not show, assumptions can be made accurately based on the permission name.
Based on the above output, in order to run our command, we can use the following command to connect to Microsoft Graph with the least permissions required.
Connect-MgGraph -Scopes "User.Read.All"
Find information on a single user
To find the information of a single user, you can run the following command to show a list of all users’ display names, usernames and Ids. From here you can copy the Id for your target user to allow you to target that user directly.
Get-MgUser | select DisplayName, UserPrincipalName, Id
Once you have copied the user ID, place it into the following command to display all information on a user account.
Get-MgUser -UserId 5965d511-e639-4a28-bfbb-b2cb08e83907 | fl
If you already know the username of your user, you can replace the Id with the username instead for the same result.
Get-MgUser -UserId [email protected] | fl
Selecting specific properties
When you target a specific user and include the ‘format list’ parameter, you get pages of information, where most of it is empty or irrelevant. Using the select parameter, we can select the attributes that are displayed.
For example, to only display the display name, username and user id, we can use the following command.
Get-MgUser -UserId [email protected] | `
select DisplayName, UserprincipalName, Id
Use a PIPE with the Format-Line parameter to identify which attributes you want to report on and save your commands for a later date.
Some of the properties you wish you view may not be immediately visible, this is because they are nested. For example, if you want to view if a user has automatic replies enabled on their mailbox, you can run the following.
Get-MgUser -UserId [email protected] -Property MailboxSettings | `
Select @{Name = 'AutomaticReply'; Expression = {$_.MailboxSettings.AutomaticRepliesSetting.status}}
It’s not easy to find these settings sometimes, however, the Microsoft Graph documentation is the best place to start when you need to extract specific information.
Find nested properties with the Microsoft Graph reference documentation
Many of the properties when calling the Get-MgUser cmdlet are nested. This is also true of other cmdlets in the Microsoft Graph and to find these properties the Graph API reference documentation on Microsoft Learn is the best place to look.
In the example above where I found the automatic reply settings for a mailbox, we can look this up in the documentation as follows.
1. Start by going to https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0#properties, this page shows all the properties, the value type and an explanation of each property.
2. Find the initial property and select the type field if it is clickable. Here I selected mailboxSettings.
3. You will see a similar page that displays all the properties of the mailboxSettings attribute. Here I selected automaticRepliesSetting.
4. We can see that if we want to view the status of the autoreply settings on a user’s mailbox, we need the status attribute. Which is nested in MailboxSettings > AutomaticReplySettings.
So we know that our setting value is located in MailboxSettings.AutomaticRepliesSetting.status, however, this must be included in our command as an expression. Failing to do so and you will get an error like the following:
Select : A mandatory entry for expression is missing.
So to make this work, once we have defined the -property parameter in our command we can PIPE, then use the select command to extract our value, as follows:
Select @{Name = ‘AutomaticReply’; Expression = {$_.MailboxSettings.AutomaticRepliesSetting.status}}
AutomaticReply
————–
disabled
Find hidden information with -ExpandProperty or -Expand
If you have used the format-list command to view all user attributes for a user, you may have found that many are empty. I am not sure why this is, but some may certainly contain information. You can use either the Expand or ExpandProperty parameters to display information that was not immediately visible.
Another unusual quirk is that not all commands will accept the user username after Get-MgUser, hence why at the start of tutorial, I highlighted you can either parse the UserPricincipalName or the Id into your command. This is true of the next command I am going to show you.
For example, to display the last sign-in information for a user, you can do the following.
get-mguser -userid (get-mguser -UserId "[email protected]").id `
-property signinactivity | Select-Object -expandproperty signinactivity
You can see in the above command, without knowing the user’s Id, we have selected the Id property and called the user twice within our command. If you do not specify the id in your command, you will get an error like the following:
get-mguser : {“@odata.context”:”http://reportingservice.activedirectory.windowsazure.com/$metadata#Edm.String”,”value”:”Get By Key only supports UserId and the key has to be a valid Guid”}
As such, to use the same command above with the user id, you can run the following.
get-mguser -userid 841e1f59-a0e2-4062-896a-8c84c36f1811 `
-property signinactivity | Select-Object -expandproperty signinactivity
You will find that not all attributes are presented in the same format. This means that information cannot always be extracted in the same way. For example, if we want to view the name of the manager for a specific user, we can run the following command.
Get-MgUser -UserId [email protected] -ExpandProperty manager | `
Select @{Name = 'Manager'; Expression = {$_.Manager.AdditionalProperties.displayName}}
Filter Get-MgUser search results
You can use the -Filter parameter to filter search results for your users. When using the filter parameter there are only a few logical operators you can use, these are:
- eq The attribute is equal to
- le The attribute is less than or equal to (alphabetically)
- gt The attribute is greater than or equal to (alphabetically)
- and Attribute 1 is equal to and attribute 2 is equal to
- or Attribute 1 is equal to or attribute 2 is equal to
- startswith The property start with
- endswith The property ends with
Below I will show you an example of how to use each of the logical operators in your commands.
To start we can use the eq operator to find users with attributes that match a specific value, here will filter for users with a display name equal to ‘John Smith’.
get-mguser -filter "DisplayName eq 'John Smith'"
In a similar format to the above, we can use the le or ge operator to find users whose display name starts with a letter less or greater than ‘G’ in the alphabet.
#Filter users whos name begins with a letter before G in the alphabet
get-mguser -filter "DisplayName le 'g'"
#Filter users whos name begins with a letter after G in the alphabet
get-mguser -filter "DisplayName ge 'g'"
To find all users in your tenant who’s display name starts with the letter D, you can use the startswith operator.
get-mguser -filter "startswith(Displayname, 'D')"
Similar to the above, we can the user endswith operator to find users whose primary mail address ends with a specific domain name. For this command it is important we specify the -CountVariable and -ConsistencyLevel parameters.
Get-MgUser -CountVariable CountVar -Filter "endsWith(mail,'it-career.online')" `
-Sort "displayName" -ConsistencyLevel eventual
The above commands can now be paired up with the and operator to fine-tune our results. For example, to find users who have the main domain of it-career.online and display name that starts with a D.
Get-MgUser -CountVariable CountVar -Filter `
"endsWith(mail,'it-career.online') and startswith(Displayname, 'D')" `
-Sort "displayName" -ConsistencyLevel eventual
Similar to the above, the or operator can be used in the same way to broaden our results. Here we are searching for users with primary mail addresses that end in ‘it-career.online’ or ‘it-career.info’.
Get-MgUser -CountVariable CountVar -Filter `
"endsWith(mail,'it-career.online') or endsWith(mail,'it-career.info')" `
-Sort "displayName" -ConsistencyLevel eventual
Find users with the search parameter
Similar to the filter option, we can also use the -search parameter to fine-tune our user search results. I mentioned above about using the -ConsistencyLevel option and setting to eventual, we will need to do this in the following commands.
Below we are searching for users with a display name that start with the letter I.
Get-MgUser -ConsistencyLevel eventual -Search '"DisplayName:I"'
It is not clear exactly on the search parameter works, other than it searches by phrases, for example. If the display name is ‘John Smith’ I could use the search terms:
- ‘”DisplayName:J”‘
- ‘”DisplayName:John”‘
- ‘”DisplayName:Smith”‘
- ‘”DisplayName:S”‘
However, it will not find values that may belong in the middle or at the end of a word. For example, John Smith will not appear in my search results if I use the following:
- ‘”DisplayName:h”‘
- ‘”DisplayName:th”‘
- ‘”DisplayName:hn”‘
Combining search and filter options
When using the Get-MgUser cmdlet, the search and filter parameters are not mutually exclusive, although arguably with the lack of features/documentation, it does not bring a whole load of benefits to combine the two, however you can.
For example, if you want to filter for all users with the domain it-career.online and search the results for users in a particular department, you could run the following.
Get-MgUser -Filter "endsWith(mail,'it-career.online')" `
-Search 'Department:Marketing' -ConsistencyLevel eventual
No idea how old this article is, but wish I’d had it before dealing with “-filter”, since MS’s documentation of it is a hot mess. Note that, sometime between 1.23 and 1.27, it started failing if you looked for recent messages using lastUpdatedDateTime and the date was in quotes. And lastUpdatedDateTime for a chat isn’t “when was the last chat”, it’s “when did you last change anything about the metadata of that chat”. The fact that it’s nearly impossible to get all chats in the past 2 weeks is a source of constant pain. Unless they fixed it at some point and didn’t document it.
It can often be frustrating, especially as lots of items in the PowerShell documentation doesn’t reflect what they have in the API documentation, but there are ways a means of finding what you need, often frustrating though! I wrote this post about a week ago, as there was no clear details on how advanced queries are handled, only a single MS doc which references an ‘index store’. 🙂
Thanks for your article, I need help on how to list the Aliases of each email from PowerShell.