Cloud Script Request - Update Intune Primary User with Immy Primary User

An Immy partner has suggested this as a request:

A hugely valuable cloud script for all MSPs would be to update the Intune computer with the Immy primary user logic. This would free up the manual process of reassigning users in Intune for proper use of Company Portal, and compliance policies.

What is the functional purpose of doing this?

Functionally, not super imperative - however when pushing for Compliance Policies and Company Portal it’s the right way to do it. It shows up across several places for the user, and it’s much cleaner if the devices they actually use show up there.

It seems fairly simple to setup given that Immy already has the User Affinity automation, so it’d just be a matter of adjusting the Intune user based on that.

We are 100% on Intune. We uninstalled the company portal from all of our clients when we moved all the apps to Immy. So, this meant I really didn’t care about the device assignments.

Though, I guess I can see the point of keeping things organized.

1 Like

In case it helps:
Find the primary user of a Microsoft Intune device. | Microsoft Learn

Powershell to Set Device Primary User : r/Intune (reddit.com)

Manage Windows Autopilot with PowerShell | Syst & Deploy (systanddeploy.com)

I second this - currently we have to manually assign the Primary user to the device in Intune, which is a bit of a hassel for a “Hands off” deployment.

I’ve not figured out a way to use the Cloud Script to do this on my own - so having a Global/Native way to do this, would be super helpful.

I am attempting to figure this out now. This and many other similar tasks are an important step in our current processes that will make or break this solution working for us.

I am having a very difficult time finding the documentation and examples I need to make a Cloud Script work.

Anything would be helpful.

Hello. First time trying to post a script and I’m very new to IB. Here is my attempt at the issue. It’s working, but I have zero confidence it is optimal or using Immy.bot properly. Any recommendations/improvements/tips welcome!


process{    #Appears you have to specifically start the "process" if you set dynamicparameters.
 
    $Headers = Get-ImmyAzureAuthHeader

    $RemoteComputerName = (Get-ImmyComputer).Name
    $RemoteComputerPersonEmail = (Get-ImmyComputer).PrimaryPersonEmail
    $RemotePrimaryPersonCloudID = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/users/$RemoteComputerPersonEmail"  -Headers $Headers).Id
   
    $IntuneDeviceID = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices?filter=(deviceName eq '$RemoteComputerName')" -Headers $Headers).value.Id
    
    $IntuneDevicePrimaryUserID = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/manageddevices/$IntuneDeviceID/users" -Headers $Headers).value.Id

switch ($method)  #Switches to different tasks depending on what IB needs. 
{
    "test" 
    {
        if ($RemotePrimaryPersonCloudID -eq $IntuneDevicePrimaryUserID){   #Compares the requested (drop down selection) category to the devices current in Entra/Intune. 
            return $true    #If Entra/Intune matches returns True to IB.
        }
        else{
            return $false}  #If Entra/Intune doesn't match returns False to IB. If IB is set to enforced, will move onto "Set" condition.
    }
    "set"
    {
    
        $Body = @{
            "@odata.id" = "https://graph.microsoft.com/beta/users/$RemotePrimaryPersonCloudID"
        }
        $JsonBody = $Body | ConvertTo-Json  #Converts the Body to Json for Graph API. 

        Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$IntuneDeviceID/users/`$ref" -Headers $Headers -Body $JsonBody -ContentType "application/json" -Method "Post"  

        #For Loop that checks every few seconds for Entra/Intune to update so the IB "Test" process after this doesn't fail.
        For ($i = 0; $i -lt 20; $i++){
            Start-Sleep -Seconds 10
            $UpdateCheck = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/manageddevices/$IntuneDeviceID/users" -Headers $Headers).value.Id
            If ($UpdateCheck -eq $RemotePrimaryPersonCloudID){
                write-host "Updated successfully!"
                Break #Breaks out of loop once it confirms Entra/Intune is showing the update. 
            }
            else{
                write-host "Different - Waiting ..."
            }
        }
    }
    "get"
    {
        $IntuneDevicePrimaryUserEmail = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/manageddevices/$IntuneDeviceID/users" -Headers $Headers).value.imAddresses
        return $IntuneDevicePrimaryUserEmail #Returns the Target's current category in Entra/Intune to IB when doing "Monitor".  
    }
}
}

Bonus, I created one that updates the Category for the Intune Device. It fills the dynamic drop down with all the current categories, allowing you to select it on onboarding.

#Dynamic Parameters used to populate the Drop Down select menu in the IB onboarding process. 
dynamicparam   
{
    $Headers = Get-ImmyAzureAuthHeader  #IB command - Gets the Azure authentication headers to be used in Graph API actions. 
    $CloudCategoryList = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceCategories/" -Headers $Headers).value.DisplayName

    New-ParameterCollection @(  #IB command - New collection (Parameter Group) for Onboarding. 
        New-DropdownParameter -Name IntuneCategory -ValidValues $CloudCategoryList -Mandatory -Ordered #IB command - Actual drop down list in Group, populated with Categories pulled from Graph API Rest Get. 
    ) 
}

process{    #Appears you have to specifically start the "process" if you set dynamicparameters.
 
    $Headers = Get-ImmyAzureAuthHeader
    $RemoteComputerName = (Get-ImmyComputer).Name #IB command - Get Computer information from Target Computer.
    $CurrentDeviceCloudInfo = Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices?filter=(deviceName eq '$RemoteComputerName')" -Headers $Headers
    $IntuneDeviceID = $CurrentDeviceCloudInfo.value.Id 
    $CurrentCategory = $CurrentDeviceCloudInfo.value.deviceCategoryDisplayName 

switch ($method)  #Switches to different tasks depending on what IB needs. 
{
    "test" 
    {
        if ($CurrentCategory -eq $IntuneCategory){   #Compares the requested (drop down selection) category to the devices current in Entra/Intune. 
            return $true    #If Entra/Intune matches returns True to IB.
        }
        else{
            return $false}  #If Entra/Intune doesn't match returns False to IB. If IB is set to enforced, will move onto "Set" condition.
    }
    "set"
    {
        $NewCategoryID = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/deviceCategories?filter=(displayName eq '$IntuneCategory')" -Headers $Headers).value.Id #Get Device Category ID

        $Body = @{
            "@odata.id" = "https://graph.microsoft.com/beta/deviceManagement/deviceCategories/$NewCategoryID"
        }
        $JsonBody = $Body | ConvertTo-Json  #Converts the Body to Json for Graph API. 

        Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$IntuneDeviceID/deviceCategory/`$ref" -Headers $Headers -Body $JsonBody -ContentType "application/json" -Method "Put"  

        #For Loop that checks every few seconds for Entra/Intune to update so the IB "Test" process after this doesn't fail.
        For ($i = 0; $i -lt 20; $i++){
            Start-Sleep -Seconds 10
            $UpdateCheck = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices?filter=(deviceName eq '$RemoteComputerName')" -Headers $Headers).value.deviceCategoryDisplayName
            If ($UpdateCheck -eq $IntuneCategory){
                write-host "Updated successfully!"
                Break #Breaks out of loop once it confirms Entra/Intune is showing the update. 
            }
            else{
                write-host "Different - Waiting ..."
            }
        }
    }
    "get"
    {
        # You can return anything from here, used when in "Monitor" mode
        return $CurrentCategory #Returns the Target's current category in Entra/Intune to IB when doing "Monitor".  
    }
}
}

~Tweak in discord if you want to chat with an IB noob. :smiley:

P.S. Thanks all the discord people for the help, especially NickLD.

Double P.S. I see someone started an Alpha version of the Intune script. I learned a lot from it after doing mine, thank you, but I couldn’t figure out a way to use the AzureDevice ID like you are when doing Intune related tasks. I had to use the IntuneDeviceID. I look forward to the end result!

This is EXECELLENT!

I’ve been trying to make something similar for ages, and then I test your script and see how dumb my examples were.

Great to have this running, we can use this for now until a global solution is provided! But for now this just works :smiley:

1 Like

Just wanted to say that I love the ability to set the Intune device category during onboarding. We leverage categories to target certain Intune configurations so this is huge for us. I don’t see that functionality in the alpha script, but hopefully it gets added at some point.

@twilson completed this task and it is now available in global. You can now sync the primary user to/from Intune.