When working with the Microsoft Graph PowerShell cmdlets, you will notice that you need to use the “Microsoft.Graph.Users” object to manage the most common user tasks. This core object contains all the commands for adding, updating, removing Users, Groups, and associated tasks within Microsoft ToDo and Outlook. 

However, if you need to perform actions for a specific user, such as remote lock a device, send mail, assign licenses, or even change a user password, you must use the “Microsoft.Graph.Users.Actions” object. Along with this object, the Graph provides “Microsoft.Graph.Users.Functions,” which adds to the actions but focus on specific tasks for the current or selected user. However, these two objects require particular formats and at the moment do not always work correctly. An ongoing issue of this is here: https://github.com/microsoftgraph/microsoft-graph-devx-api/issues/307

It means that we need to find another way (for now) to retrieve the values we need. The good news is that we have the command “Invoke-MgGraphRequest” for this.

Getting Started

First, let’s connect to an existing Azure Active Directory (Azure AD) user to see how this works using the standard PowerShell Graph commands.

$upn = "adelev@m365x.onmicrosoft.com"
Connect-MgGraph -Scopes `
		"User.ReadWrite.All", `
		"Group.ReadWrite.All", `
		"GroupMember.ReadWrite.All", `
		"Directory.ReadWrite.All"

$user = Get-MgUser `
		-UserId $upn

We have a variable containing our selected user object now, so we can now perform various tasks.

For example, if we wanted to retrieve all the security groups, directory roles, and administrative units to which the retrieved account belongs, we would need to use some kind of PowerShell similar to this.

Retrieve assigned User Groups

$groupmemberships = New-Object System.Collections.ArrayList
$groups = Get-MgUserMemberOf `
			-UserId $user.Id | `
				Select-Object `
					-ExpandProperty AdditionalProperties

$groups | ? { ($_.'@odata.type' -eq '#microsoft.graph.group') `
	-and ($_.'securityEnabled' -eq 'True') } | `
		ForEach-Object { `
				$groupmemberships.Add(@{ `
					"Group"=$_.displayName;}) `
				}
$groupmemberships

Retrieve assigned Directory Roles

$directoryroles = New-Object System.Collections.ArrayList
$roles = Get-MgDirectoryRole

$roles | ForEach-Object { `
	$role = $_
	Get-MgDirectoryRoleMember `
		-DirectoryRoleId $_.Id } | ForEach-Object { `
			if($_.Id -eq $user.Id) { `
				$directoryroles.Add(@{ `
					"Role"=$role.DisplayName;}) `
				} `
			}
$directoryroles

Retrieve assigned Administrative Units

$administrativeunits = New-Object System.Collections.ArrayList
$units = Get-MgAdministrativeUnit

$units | ForEach-Object { `
	$unit = $_
	Get-MgAdministrativeUnitMember `
		-AdministrativeUnitId $_.Id } | ForEach-Object { `
			if($_.Id -eq $user.Id) { `
				$administrativeunits.Add(@{ `
					"Unit"=$unit.DisplayName; }) `
				} `
			}
$administrativeunits

To perform the same tasks using the “Invoke-MgGraphRequest” command, we update the PowerShell to something like this. Notice we can use the actual Graph URL with variables and methods. The nice thing about this approach is that we can read the standard Microsoft Graph documentation to find the URLs.

https://docs.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0

Retrieve assigned User Groups using the Invoke Command

$groupmemberships = New-Object System.Collections.ArrayList
$url = "https://graph.microsoft.com/beta/users"
$object = "microsoft.graph.group"
$body = @{}

$groups = Invoke-MgGraphRequest `
	-Uri "$url/$($user.Id)/memberOf/$object" `
	-Method GET `
	-Body $body

$groups.value | ForEach-Object {
	$groupmemberships.Add(@{ `
		"Group"=$_.displayName;}) `
}
$groupmemberships

Retrieve assigned Directory Roles using the Invoke Command

$directoryroles = New-Object System.Collections.ArrayList
$url = "https://graph.microsoft.com/beta/users"
$object = "microsoft.graph.directoryrole"
$body = @{}

$roles = Invoke-MgGraphRequest `
	-Uri "$url/$($user.Id)/memberOf/$object" `
	-Method GET `
	-Body $body

$roles.value | ForEach-Object {
	$directoryroles.Add(@{ `
		"Role"=$_.displayName;}) `
}
$directoryroles

Retrieve assigned Administrative Units using Invoke Command

$administrativeunits = New-Object System.Collections.ArrayList
$url = "https://graph.microsoft.com/beta/users"
$object = "microsoft.graph.administrativeUnit"
$body = @{}

$units = Invoke-MgGraphRequest `
	-Uri "$url/$($user.Id)/memberOf/$object" `
	-Method GET `
	-Body $body

$units.value | ForEach-Object {
	$administrativeunits.Add(@{ `
		"Unit"=$_.displayName;}) `
}
$administrativeunits

As you can see, you can utilize the generic “Invoke-MgGraphRequest” command to retrieve the exact details like the specific commands. In fact, what is nice about this approach is if you are used to using the Graph Explorer tool, you can test it all there, so you know the correct URLs to utilize.