Using "Invoke-MgGraphRequest" within the Microsoft Graph PowerShell

October 12, 2021
3 min read
Syndicated

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.

Liam Cleary

Liam Cleary

Liam began his career as a computer trainer. He quickly realized that programming, breaking and hacking were much more fun. Liam spent the next few years working within core infrastructure and security services. He is now the founder and owner of SharePlicity, a consulting company focusing on Microsoft 365 and Azure technology. His role within SharePlicity is to help organizations implement Microsoft 365 and Azure technology to enhance internal and external collaboration, document, and records management, automate business processes, and implement security controls and protection. He is a long-time Microsoft MVP and Microsoft Certified Trainer, focusing on architecture, security and crossing the boundary into software development. Over the past few years, his specialty has been security in Microsoft 365, Azure and its surrounding platforms. Liam also creates online training courses for Pluralsight, LinkedIn Learning and Cloud Academy, and he teaches multiple Microsoft certification courses for Opsgility and Microsoft. You can find him at user groups and conferences, teaching classes, offering advice, spending time in the community, teaching his kids how to code, raspberry PI programming, hacking the planet, building Lego robots, or coaching soccer. You may also find him running races in the dark, hiking, or mountain biking at breakneck speeds.