Dynamic Device Scope Tags with Azure Functions and Teams

Daniel Petri
7 min readMar 2, 2023

--

So it’s finally time for a new version of DUDE! If you are reading about DUDE for the first time, I’ll tell you it stands for Dynamic User and Device Enumeration. The purpose of this solution is to have dynamic user groups based on any attribute supported in Azure AD groups and a corresponding assigned device group. The script will then check who’s in the user group, grab all the users devices from Intune and add them to the desired group. If a user is removed from the user group, their device will also automatically be removed from the device group.

New to this version is that we will have a masterlist in Teams (SharePoint List) where we manage our groups.

If you want to read the history of DUDE, check out my old blog posts:
Dynamic Device Scope Tags with Azure Functions — Daniel Moon Petri
Dynamic Device Scope Tags with Azure Automation — Daniel Moon Petri

Now let’s get started!

Create Groups, Tags & Assign

This time around we are lazy so we will use PowerShell to create our user and device groups, scope tags and assign the scope tags. If you want to do this the manual way, check out my older blog posts.
Grab the script on my GitHub: DUDE-CreateGroupsTagsAssign.ps1

This script uses “Get-MsalToken”, if you don’t know what that is, head over to this great post by Ben Reader: Authenticating to Microsoft Graph with PowerShell

Before you run the script, make sure to update the variables. You can add as many groups as you want.

#region Variables
$ClientId = ""
$TenantId = ""
$Groups = @(
[PSCustomObject]@{
UserGroupName = "Endpoint-DUDE Users IT"
UserGroupDescription = "IT Users"
UserGroupMembershipRule = "(user.department -eq `"IT`")"
DeviceGroupName = "Endpoint-DUDE Devices IT"
DeviceGroupDescription = "IT Users Devices"
ScopeTagName = "IT"
ScopeTagDescription = "IT"
}
[PSCustomObject]@{
UserGroupName = "Endpoint-DUDE Users HR"
UserGroupDescription = "HR Users"
UserGroupMembershipRule = "(user.department -eq `"HR`")"
DeviceGroupName = "Endpoint-DUDE Devices HR"
DeviceGroupDescription = "HR Users Devices"
ScopeTagName = "HR"
ScopeTagDescription = "HR"
}
)
#endregion

The script output should look something like this:

Usergroup "Endpoint-DUDE Users IT" was successfully created
Devicegroup "Endpoint-DUDE Devices IT" was successfully created
Scopetag "IT" was successfully created
Scopetag "IT" was successfully assigned
Usergroup "Endpoint-DUDE Users HR" was successfully created
Devicegroup "Endpoint-DUDE Devices HR" was successfully created
Scopetag "HR" was successfully created
Scopetag "HR" was successfully assigned

Now we got our user groups, device groups, scope tags and the scope tags have been assigned to the device groups.

Teams Masterlist

To make the group management as easy as possible I have chosen to put the masterlist in Teams (Sharepoint List). This also makes alot of other automation possible from within the same list. More on that later.

In my case I have a “Intune Operations” Team where I have created a channel called “Automation”. To add the list to your Team press the +

Select “Lists” and press “Save”.

Select “Create a list”, then select “Blank list”. Give it a name, select a nice emoji and hit “Create”. Then select the dots and “Open in Sharepoint”:

Make sure to add two columns with single line of text. One called “UserGroup” and one called “DeviceGroup”:

Make sure to apply the following column settings:

Now lets grab the list ID, we will need it later. Click on “Site contents:

Select the dots of your list and click “Settings”:

Copy the list ID from the URL:

We will also need the SharePoint Site ID. To get this, simply add “_api/site/id” to your site url and make a note of the Site ID:

Now lets go back to Teams and add the groups that we created earlier. In my case:

Azure Functions

Let’s create our function app! Go to Function App — Microsoft Azure, click “Create” and fill the required information and click “Next”:
I will not go into azure functions pricing in this post, you can read about it here, however there are some limitations that we need to consider like the fact that the consumption plan have a maximum runtime of 10 min. More info about azure functions scale and hosting can be found here. For the purpose of this blog I will select the consumption plan.

Select a storage account and click “Next”:

On the Networking tab, hit “Next”

Enable Application Insights and press “Next”:

On the Deployment tab, hit “Next”

On the Tags tab, hit “Next”

Review your settings and press “Create”.

We will use a managed identity to access our resources securely. When the deployment is completed, head back to Function App — Microsoft Azure, select your newly created function app, select “Identity”, enable system assigned managed identity, hit save and make a note of the “Object (principal) ID”

We need to add the permissions needed via PowerShell. Install the AzureAD module if you don’t already have (Install-Module AzureAD). Make sure to update the $TenantID and $PrincipalID variables before executing

$TenantID = ".onmicrosoft.com"
$PrincipalID = "93e385e3-d19b-426e-b532-7856505fd169"

# Add permissions
$Permissions = "Device.Read.All", "DeviceManagementManagedDevices.Read.All", "Group.Read.All", "GroupMember.ReadWrite.All", "User.Read.All", "Sites.Read.All"
Connect-AzureAD -TenantId $TenantID
$GraphServicePrincipal = Get-AzureADServicePrincipal -SearchString "Microsoft Graph" | Select-Object -first 1
$AppRole = $GraphServicePrincipal.AppRoles | Where-Object { $Permissions -contains $_.Value -and $_.AllowedMemberTypes -contains "Application" }
foreach ($Role in $AppRole) {
New-AzureAdServiceAppRoleAssignment -ObjectId $PrincipalID -PrincipalId $PrincipalID -ResourceId $GraphServicePrincipal.ObjectId -Id $Role.Id
}

Head over to Enterprise applications — Microsoft Azure to verify the permissions. Select “managed identities” as the application type and open your system assigned managed identity. The object ID value matches the object ID of the managed identity that you previously created.

Select “permissions” and it should look something like this:

Head back to Function App — Microsoft Azure, select your function app, select “App files”, select “profile.ps1”, remove the following lines or use # and click “Save”

Select “Functions”, click “Create”, select “Timer trigger”, add a name and a schedule. In my example “0 0 11,23 * * *” will schedule this to run at 11 and 23 (UTC) every day. Hit “Create”

Open the newly created function, select “Code + Test” and remove any existing code from “run.ps1”. Copy the script from my GitHub: DUDE-SP-AzureFunctions.ps1 , paste it in “run.ps1” and make sure to update the variables before you hit “Save”.
The $MasterSPSiteID variable should be the SharePoint Site ID where the masterlist is located. The $MasterlistID variable should be the ID of the masterlist.

Select “Test/Run” and hit “Run” and you should get an output like this:

The End

That’s it! We’re done! This will now manage your DUDE groups automatically according to the timer you’ve set. Everything will of course be logged in the audit logs etc. Just imagine how much more we can automate from this list. Hope you had fun! To be continued…

🤘🏻

--

--