Dynamic Win 11 Supported Group

Dynamic security groups in Azure AD are great, but wouldn’t it be great if a dynamic query existed to add to groups based on Windows 11 compatibility.

Until such a query exists, I have put together a script using the metrics from Endpoint Analytics Work from Anywhere report.

As usual, the script can be found on GitHub here

To make it as dynamic as possible, I would recommend using Azure Automation Runbook to run regularly (obviously with an app registration)

After connecting to Graph, it creates two lists of machines, compliant and non-compliant


##Get Devices compliant/not compliant with windows 11
write-host "Inspecting devices for Windows 11 compliance"
$reporturi = "https://graph.microsoft.com/beta/deviceManagement/userExperienceAnalyticsWorkFromAnywhereMetrics('allDevices')/metricDevices?`$select=id,deviceName,managedBy,manufacturer,model,osDescription,osVersion,upgradeEligibility,azureAdJoinType,upgradeEligibility,ramCheckFailed,storageCheckFailed,processorCoreCountCheckFailed,processorSpeedCheckFailed,tpmCheckFailed,secureBootCheckFailed,processorFamilyCheckFailed,processor64BitCheckFailed,osCheckFailed&dtFilter=all&`$orderBy=osVersion asc"

$reportdata = (invoke-mggraphrequest -uri $reporturi -method GET).value

$compliantdevices = @()
$noncompliantdevices = @()
write-host "Checking Machines for Compatibility"
$counter = 0

foreach ($machine in $reportdata) {
    $counter++
    $deviceid = $machine.id
    Write-Progress -Activity 'Processing Devices' -CurrentOperation $deviceid -PercentComplete (($counter / $reportdata.count) * 100)

    $w11compliance = $machine.upgradeEligibility
    if ($w11compliance -eq "Capable") {
        $compliantdevices += $machine.deviceName
    }
    else {
        $noncompliantdevices += $machine.deviceName
    }
}

Next, it checks if the groups exist already and if not creates the two groups.

After creating, it checks if the machine is in the group and if not, adds it in


write-host "Creating AAD Groups"
##Create AAD Groups
write-host "Creating Windows 11 Group"
$win11groupexist = (get-mggroup -filter "displayName eq '$w11groupname'").id
write-host "Creating Windows 10 Group"
$win10groupexist = (get-mggroup -filter "displayName eq '$w10groupname'").id

##Windows 11
##Check if group exists
write-host "Checking if Windows 11 Group Exists"
if ($null -ne $win11groupexist) {
##It exists, add members
write-host "Windows 11 Group Exists, adding members"
foreach ($compliantdevice in $compliantdevices) {
    $compliantdeviceid = (Get-MgDevice -Filter "displayName eq '$compliantdevice'").id
    ##Check if already in the group
    write-host "Checking if $compliantdevice is already in the group"
    $groupmember = (get-mggroupmember -GroupId $win11groupexist) | where-object ID -eq $compliantdeviceid
    if ($null -eq $groupmember) {
    write-host "Adding $compliantdevice to the group"
   new-mggroupmember -GroupId $win11groupexist -DirectoryObjectId  $compliantdeviceid
    }
}
}
else {
##Does not, create it first
write-host "Windows 11 Group does not exist, creating it"
$win11group = new-mggroup -DisplayName $w11groupname -Description "Devices Compliant with Windows 11" -SecurityEnabled -mailEnabled:$false -MailNickname $w11groupname
$win11groupid = $win11group.id
foreach ($compliantdevice in $compliantdevices) {
    $compliantdeviceid = (Get-MgDevice -Filter "displayName eq '$compliantdevice'").id

    ##Check if already in the group
    write-host "Checking if $compliantdevice is already in the group"
    $groupmember = (get-mggroupmember -GroupId $win11groupid) | where-object ID -eq $compliantdeviceid
    if ($null -eq $groupmember) {
        write-host "Adding $compliantdevice to the group"
    new-mggroupmember -GroupId $win11groupid -DirectoryObjectId  $compliantdeviceid
    }
}
}


##Windows 10
##Check if group exists
write-host "Checking if Windows 10 Group Exists"
if ($null -ne $win10groupexist) {
    ##It exists, add members
    write-host "Windows 10 Group Exists, adding members"
    foreach ($noncompliantdevice in $noncompliantdevices) {
        $noncompliantdeviceid = (Get-MgDevice -Filter "displayName eq '$noncompliantdevice'").id
        ##Check if already in the group
        write-host "Checking if $noncompliantdevice is already in the group"
        $groupmember = (get-mggroupmember -GroupId $win10groupexist) | where-object ID -eq $noncompliantdeviceid
        if ($null -eq $groupmember) {
            write-host "Adding $noncompliantdevice to the group"
            new-mggroupmember -GroupId $win10groupexist -DirectoryObjectId $noncompliantdeviceid
        }
    }
    }
    else {
    ##Does not, create it first
    write-host "Windows 10 Group does not exist, creating it"
    $win10group = new-mggroup -DisplayName $w10groupname -Description "Devices Not Compliant with Windows 10" -SecurityEnabled -MailEnabled:$false -MailNickname $w10groupname
    $win10groupid = $win10group.id
    foreach ($noncompliantdevice in $noncompliantdevices) {
        $noncompliantdeviceid = (Get-MgDevice -Filter "displayName eq '$noncompliantdevice'").id

        ##Check if already in the group
        $groupmember = (get-mggroupmember -GroupId $win10groupid) | where-object ID -eq $noncompliantdeviceid
        if ($null -eq $groupmember) {
            write-host "Adding $noncompliantdevice to the group"
            new-mggroupmember -GroupId $win10groupid -DirectoryObjectId  $noncompliantdeviceid
        }
    }
    }

I then use these groups to assign and exclude against Feature Update policies, but whatever works for you.

1 thought on “Dynamic Win 11 Supported Group”

Leave a Comment