PowerShell, Intune, and Microsoft Graph X-Ray

I used Microsoft Graph X-Ray as a tool for getting the PowerShell cmdlets needed for scripting specific actions in the Azure / Entra ID portal in the past. But you can also use it for Intune 🙂 In this blog post, I will show you how this works.

What is Microsoft Graph?

“Microsoft Graph is the gateway to data and intelligence in Microsoft 365. It provides a unified programmability model that you can use to access the tremendous amount of data in Microsoft 365, Windows, and Enterprise Mobility + Security. Use the wealth of data in Microsoft Graph to build apps for organizations and consumers that interact with millions of users.

Microsoft Graph exposes REST APIs and client libraries to access data on the following Microsoft cloud services:

  • Microsoft 365 core services: Bookings, Calendar, Delve, Excel, Microsoft 365 compliance eDiscovery, Microsoft Search, OneDrive, OneNote, Outlook/Exchange, People (Outlook contacts), Planner, SharePoint, Teams, To Do, Viva Insights
  • Enterprise Mobility + Security services: Advanced Threat Analytics, Advanced Threat Protection, Azure Active Directory, Identity Manager, and Intune
  • Windows services: activities, devices, notifications, Universal Print
  • Dynamics 365 Business Central services

Source: https://learn.microsoft.com/en-us/graph/overview

What is Microsoft Graph X-Ray?

It’s a developer tool created by Merill Fernando (Principal Product Manager @ Microsoft Entra) that can be added to your Microsoft Edge, Google Chrome (and other Chromium-based) browsers. It can be found here for Microsoft Edge and here for Google Chrome. It’s also available as a Windows Store app and can be found here. They work the same for both browser platforms. The Windows Store App has a built-in browser with the debug Windows already available, and I will use that one for the examples below. (Press F12 and select Graph X-Ray from the menu bar for the browser version.)

How does this work?

When you open Graph X-Ray (The Windows Store version), you will be presented with this screen:

The left pane is for logging into your environment. The two panes to the right will show you the history of your Graph calls and the Stack Trace. This is the one that will show you the cmdlets for the actions you’re doing in the left browser pane.

After logging in, it will default to the Microsoft Entra ID portal (The “old” portal.azure.com). You can switch to your Intune Management portal by entering https://intune.microsoft.com/ in the address bar and selecting Go. You will start seeing items being added to the Graph Call Stack Trace pane on the right when selecting things in the Intune admin center. For example, I selected Devices, and that showed me this: (These are the 5 last items in a long list)

For every action you do, selecting/creating/deleting/updating will show you the relevant PowerShell modules you need to import together with the cmdlets you need to run to do that action. It also offers the Microsoft Graph URLs and the action (Get/Post/Put/Patch/Update).

Example of using Graph X-Ray to create a PowerShell script

Creating a Configuration Profile

In the example, I used Graph X-Ray to supply me with the modules and cmdlets to create a Configuration Profile in which I configure a Welcome Message for users logging in to their Intune Device in my tenant. When I was done manually creating the Configuration Profile, I used the Save Script button in the Graph Call Stack Trace to save all the steps. I couldn’t find it straight away, but it was saved in my Downloads folder as “Unconfirmed 148217.crdownload” 🙂

You can edit that file, and it will show you all the steps you followed in browsing the Intune admin center to the point that you saved the Configuration Profile. I removed all the Get-MgBeta… commands from it and all duplicates because it sometimes lists the same commands/params twice.

These steps were needed in this example:

Import-Module Microsoft.Graph.Beta.DeviceManagement
Import-Module Microsoft.Graph.Beta.DeviceManagement.Actions
Import-Module Microsoft.Graph.Beta.Groups

$params = @{
	id = "00000000-0000-0000-0000-000000000000"
	displayName = "Welcome text"
	roleScopeTagIds = @(
		"0"
	)
	"@odata.type" = "#microsoft.graph.windows10EndpointProtectionConfiguration"
	applicationGuardEnabledOptions = "notConfigured"
	firewallCertificateRevocationListCheckMethod = "deviceDefault"
	firewallPacketQueueingMethod = "deviceDefault"
	deviceGuardLocalSystemAuthorityCredentialGuardSettings = "notConfigured"
	defenderSecurityCenterNotificationsFromApp = "notConfigured"
	windowsDefenderTamperProtection = "notConfigured"
	defenderSecurityCenterITContactDisplay = "notConfigured"
	xboxServicesAccessoryManagementServiceStartupMode = "manual"
	xboxServicesLiveAuthManagerServiceStartupMode = "manual"
	xboxServicesLiveGameSaveServiceStartupMode = "manual"
	xboxServicesLiveNetworkingServiceStartupMode = "manual"
	applicationGuardBlockClipboardSharing = "notConfigured"
	defenderPreventCredentialStealingType = "notConfigured"
	defenderAdobeReaderLaunchChildProcess = "notConfigured"
	defenderOfficeCommunicationAppsLaunchChildProcess = "notConfigured"
	defenderAdvancedRansomewareProtectionType = "notConfigured"
	defenderNetworkProtectionType = "notConfigured"
	localSecurityOptionsFormatAndEjectOfRemovableMediaAllowedUser = "notConfigured"
	localSecurityOptionsSmartCardRemovalBehavior = "noAction"
	localSecurityOptionsInformationDisplayedOnLockScreen = "notConfigured"
	localSecurityOptionsMinimumSessionSecurityForNtlmSspBasedClients = "none"
	localSecurityOptionsMinimumSessionSecurityForNtlmSspBasedServers = "none"
	lanManagerAuthenticationLevel = "lmAndNltm"
	localSecurityOptionsAdministratorElevationPromptBehavior = "notConfigured"
	localSecurityOptionsStandardUserElevationPromptBehavior = "notConfigured"
	userRightsAccessCredentialManagerAsTrustedCaller = $null
	userRightsLocalLogOn = $null
	userRightsAllowAccessFromNetwork = $null
	userRightsActAsPartOfTheOperatingSystem = $null
	userRightsBackupData = $null
	userRightsChangeSystemTime = $null
	userRightsCreateGlobalObjects = $null
	userRightsCreatePageFile = $null
	userRightsCreatePermanentSharedObjects = $null
	userRightsCreateSymbolicLinks = $null
	userRightsCreateToken = $null
	userRightsDebugPrograms = $null
	userRightsBlockAccessFromNetwork = $null
	userRightsDenyLocalLogOn = $null
	userRightsRemoteDesktopServicesLogOn = $null
	userRightsDelegation = $null
	userRightsGenerateSecurityAudits = $null
	userRightsImpersonateClient = $null
	userRightsIncreaseSchedulingPriority = $null
	userRightsLoadUnloadDrivers = $null
	userRightsLockMemory = $null
	userRightsManageAuditingAndSecurityLogs = $null
	userRightsManageVolumes = $null
	userRightsModifyFirmwareEnvironment = $null
	userRightsModifyObjectLabels = $null
	userRightsProfileSingleProcess = $null
	userRightsRemoteShutdown = $null
	userRightsRestoreData = $null
	userRightsTakeOwnership = $null
	bitLockerRecoveryPasswordRotation = "notConfigured"
	bitLockerPrebootRecoveryMsgURLOption = "default"
	localSecurityOptionsLogOnMessageTitle = "Welcome to PowerShellisfun!"
	applicationGuardAllowPrintToPDF = $false
	applicationGuardAllowPrintToXPS = $false
	applicationGuardAllowPrintToLocalPrinters = $false
	applicationGuardAllowPrintToNetworkPrinters = $false
	firewallProfileDomain = $null
	firewallProfilePrivate = $null
	firewallProfilePublic = $null
	deviceGuardEnableVirtualizationBasedSecurity = $false
	deviceGuardEnableSecureBootWithDMA = $false
}

New-MgBetaDeviceManagementDeviceConfiguration -BodyParameter $params

I deleted the manually created Configuration Profile and ran the script listed above. You must use Connect-MgGraph first to connect to your tenant and have the PowerShell modules installed that it uses. (Check all lines that have Import-Module in them and use Install-Module to install those modules if you haven’t already done that in the past.)

I used this to connect to Microsoft Graph using a ReadWrite scope. (If you need to consent to specific permissions, you will be prompted.)

Connect-MgGraph -Scopes 'DeviceManagementConfiguration.ReadWrite.All'

After running the script, you should see something like this:

And in the Intune Admin Center, it will look like this:

Assigning the created Configuration Profile

Now that the Configuration Profile is created, it needs to be assigned. In the downloaded script from Graph X-Ray, some lines mention the assignment of the Configuration Profile, but those refer to the variable $deviceConfigurationId, which is not set. But you can use the cmdlets specified in the output to do that. This is what I used to assign the Autopilot Devices group from my tenant to the newly created Configuration Profile:

$deviceConfigurationId=(Get-MgBetaDeviceManagementDeviceConfiguration | Where-Object DisplayName -eq 'Welcome text').Id
$params = @{
	assignments = @(
		@{
			target = @{
				"@odata.type" = "#microsoft.graph.groupAssignmentTarget"
				groupId = "e128d547-5a73-4328-ac64-6a72e423f528"
			}
		}
	)
}
Set-MgBetaDeviceManagementDeviceConfiguration -DeviceConfigurationId $deviceConfigurationId -BodyParameter $params

After running this, the Configuration Profile “Welcome text” is assigned to the Autopilot Devices group:

Note: I did get an error “Set-MgBetaDeviceManagementDeviceConfiguration_Assign: Object reference not set to an instance of an object.”, but the assignment was done correctly?!

Wrapping up

This was an example of how you can create something in Intune with PowerShell using Graph X-Ray to supply you with the correct cmdlets and modules you should incorporate in your script. Very powerful, not only for Intune but also for Azure/Entra ID things!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.