Set scope tag by domain of primary user with automation
This automation solves a very small specific use case. As soon as the mobile devices (IOS, Android) are registered in Intune and are not set up via enrollment type profiles, no more scope tags can be set based on device parameters. This is where this automation comes into play.
The script runs regularly and goes through all IOS & Android devices in Intune. There it takes the primary user of the device and resolves the domain to the scope tag via an API. Then the script sets the scope tag in Intune via the API.
PowerShell Script
Param(
$Device,
$Domain
)
$Success = @()
$NoPM = @()
$NoScopeTag = @()
$NoShortName = @()
$NoOwner = @()
$NoDevice = @()
#Azure Login with Identity
try
{
# "Logging in to Azure..."
Connect-AzAccount -Identity
}
catch {
Write-Error -Message $_.Exception
throw $_.Exception
}
$resourcegroupname = "<yourresourcegroupname>"
$storageaccountname = "<yourstorageaccountname>"
$storagetablename = "<yourstoragetablename>"
#storage account/table connection
$storageaccountkey = (Get-AzStorageAccountKey -ResourceGroupName $resourcegroupname -AccountName $storageaccountname | where {$_.keyname -eq "key1"}).value
$storageContext = New-AzStorageContext -StorageAccountName $storageaccountname -StorageAccountKey $storageaccountkey
$table = Get-AzStorageTable -name $storagetablename -context $storageContext
$hostnames = get-AzTableRow -table $table.CloudTable
#Collect Credential Data for Graph API
$tenantId = Get-AutomationVariable -Name "<yourunbooktenantidvariable>"
$ClientId = Get-AutomationVariable -Name "<yourunbookclientidvariable>"
$CredentialObject = Get-AutomationPSCredential -Name "<yourrunbookclientsecretsecret>"
$ClientSecret = $CredentialObject.GetNetworkcredential().password
$WebhookURI = Get-AutomationVariable -Name "<yourteamswebhookuri>"
$FunctionURL = Get-AutomationVariable -Name "<yourfunctionapiurl>"
$Body = @{
"tenant" = $TenantId
"client_id" = $ClientId
"scope" = "https://graph.microsoft.com/.default"
"client_secret" = $ClientSecret
"grant_type" = "client_credentials"
}
$Params = @{
"Uri" = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
"Method" = "Post"
"Body" = $Body
"ContentType" = "application/x-www-form-urlencoded"
}
$AuthResponse = Invoke-RestMethod @Params
$Header = @{
"Authorization" = "Bearer $($AuthResponse.access_token)"
#"ConsistencyLevel" = "eventual"
}
Function Send-Logs(){
param (
[String]$LogType,
[Hashtable]$LogBodyList
)
$LogBodyJSON = @"
{
"logtype": "$LogType",
"logbody": {}
}
"@
$LogBodyObject = ConvertFrom-JSON $LogBodyJSON
Foreach($Log in $LogBodyList.GetEnumerator()){
$LogBodyObject.logbody | Add-Member -MemberType NoteProperty -Name $log.key -Value $log.value
}
$Body = ConvertTo-JSON $LogBodyObject
$Response = Invoke-Restmethod -uri $FunctionURL -Body $Body -Method POST -ContentType "application/json"
return $Response
}
function Send-ToTeams {
$CurrentTime = Get-Date
$Body = @{
"@context" = "https://schema.org/extensions"
"@type" = "MessageCard"
"themeColor" = "880808"
"title" = "RB-INT-ALL-PS1-MobileDeviceScopingByPrimaryUser-PROD-WE ist durchgelaufen"
"text" = @"
Parameter:
<br>Device ID: $Device
<br>Domain: $Domain
<ul><li>Erfolgreiche Zuweisungen in Intune: $($Success.Count)</li><li>Scope Tag in Intune nicht gefunden: $($NoScopeTag.Count)</li><li>Shortname by Domain in Storage Table nicht gefunden: $($NoShortName.Count)</li><li>Owner in Intune nicht gefunden: $($NoOwner.Count)</li></ul>
"@
}
$JsonBody = $Body | ConvertTo-JSON
Invoke-RestMethod -Method Post -Body $JsonBody -Uri $WebhookURI | out-null
}
#get all Scope Tags
$uri = "https://graph.microsoft.com/beta/deviceManagement/roleScopeTags"
$Results = Invoke-RestMethod -Method GET -Uri $uri -ContentType "application/json" -Headers $header
$scopeTags = $results.value
if($device){
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$($device)" -ContentType "Application/Json" -Header $Header
$managedDevices += $Results
# $managedDevices
}elseif($Domain){
Add-Type -AssemblyName System.Web
$encodedURL = [System.Web.HttpUtility]::UrlEncode($Domain)
#get android and ios managed devices
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$filter=(contains(activationlockbypasscode,%20%27$encodedURL%27))%20and%20startswith(operatingSystem,'ios')" -ContentType "Application/Json" -Header $Header
$ResultsValue = $Results.value
if ($results."@odata.nextLink" -ne $null) {
$NextPageUri = $results."@odata.nextLink"
##While there is a next page, query it and loop, append results
While ($NextPageUri -ne $null) {
$NextPageRequest = (Invoke-RestMethod -Headers $Header -Uri $NextPageURI -Method Get)
$NxtPageData = $NextPageRequest.Value
$NextPageUri = $NextPageRequest."@odata.nextLink"
$ResultsValue = $ResultsValue + $NxtPageData
}
}
$managedDevices += $ResultsValue
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$filter=(contains(activationlockbypasscode,%20%27$encodedURL%27))%20and%20startswith(operatingSystem,'android')" -ContentType "Application/Json" -Header $Header
$ResultsValue = $Results.value
if ($results."@odata.nextLink" -ne $null) {
$NextPageUri = $results."@odata.nextLink"
##While there is a next page, query it and loop, append results
While ($NextPageUri -ne $null) {
$NextPageRequest = (Invoke-RestMethod -Headers $Header -Uri $NextPageURI -Method Get)
$NxtPageData = $NextPageRequest.Value
$NextPageUri = $NextPageRequest."@odata.nextLink"
$ResultsValue = $ResultsValue + $NxtPageData
}
}
$managedDevices += $ResultsValue
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices/$($device)" -ContentType "Application/Json" -Header $Header
$managedDevices += $Results
# $managedDevices
}else{
#get android and ios managed devices
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$filter=startswith(operatingSystem,'ios')" -ContentType "Application/Json" -Header $Header
$ResultsValue = $Results.value
if ($results."@odata.nextLink" -ne $null) {
$NextPageUri = $results."@odata.nextLink"
##While there is a next page, query it and loop, append results
While ($NextPageUri -ne $null) {
$NextPageRequest = (Invoke-RestMethod -Headers $Header -Uri $NextPageURI -Method Get)
$NxtPageData = $NextPageRequest.Value
$NextPageUri = $NextPageRequest."@odata.nextLink"
$ResultsValue = $ResultsValue + $NxtPageData
}
}
$managedDevices += $ResultsValue
$Results = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?`$filter=startswith(operatingSystem,'android')" -ContentType "Application/Json" -Header $Header
$ResultsValue = $Results.value
if ($results."@odata.nextLink" -ne $null) {
$NextPageUri = $results."@odata.nextLink"
##While there is a next page, query it and loop, append results
While ($NextPageUri -ne $null) {
$NextPageRequest = (Invoke-RestMethod -Headers $Header -Uri $NextPageURI -Method Get)
$NxtPageData = $NextPageRequest.Value
$NextPageUri = $NextPageRequest."@odata.nextLink"
$ResultsValue = $ResultsValue + $NxtPageData
}
}
$managedDevices += $ResultsValue
}
write-output "Intune Devices: $($managedDevices.count)"
#compare and collect MEID devices, which are managed by intune
foreach($managedDevice in $managedDevices){
#configure hostname if device has an owner
if($managedDevice.userPrincipalName){
#get domainname of user
$dn = ($managedDevice.userprincipalname -split "@")[1]
$shortname = ($hostnames | where {$_.dn -eq $dn}).shortname
if($shortname){
#check if scope tag exists based on azure table
$scopeTag = $scopeTags | where {$_.displayName -like "SCT-INT-$shortname-INTUNE-*-PROD"}
if($scopeTag){
$assignBody = @{
roleScopeTagIds = @("$($scopeTag.id)")
}
$JSON = $assignBody | ConvertTo-Json
$uri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices('$($managedDevice.id)')"
# Invoke-RestMethod -Uri $uri -Headers $header -Method Patch -Body $JSON -ContentType "application/json"
write-output "$($managedDevice.id) - Assigning Scope Tag to $($scopeTag.displayName)"
$Success += $managedDevice.ID
} else {
write-warning "$($managedDevice.id) - Scope Tag $($scopeTag.displayName) does not exist!"
$NoScopeTag += $managedDevice.ID
}
} else {
write-warning "$($managedDevice.id) - Domain $dn not in Storage Table!"
$NoShortName += $managedDevice.ID
}
} else {
write-warning "$($managedDevice.id) - Device has no Owners"
$NoOwner += $managedDevice.ID
}
}
$Logs = @{
"successassignment"="$($Success.count)"
"errornoscopetag"="$($NoScopeTag.count)"
"errornoshortname"="$($NoShortName.count)"
"errornoowner"="$($NoOwner.count)"
}
Send-Logs -LogType "MobileDeviceScopingByPrimaryUserExecutions" -LogBodyList $Logs
Send-ToTeams