[{"data":1,"prerenderedAt":2351},["ShallowReactive",2],{"post:\u002F2025\u002F04\u002F17\u002Fpowershell-intune-bulk-assign-app-protection-policies-by-group\u002F":3},{"post":4,"newer":2301,"older":2310,"related":2321,"series":2349},{"id":5,"title":6,"body":7,"canonical":2282,"categories":2283,"date":2286,"description":2287,"extension":2288,"featured":2289,"hero":2290,"image":2290,"meta":2291,"navigation":676,"path":2292,"readingTime":451,"seo":2293,"series":2290,"seriesOrder":2290,"sites":2294,"source":2290,"stem":2295,"tags":2296,"updated":2290,"url":2299,"__hash__":2300},"blog\u002Fblog\u002F2025\u002F04\u002F17\u002Fpowershell-intune-bulk-assign-app-protection-policies-by-group.md","PowerShell: Intune – Bulk Assign App Protection Policies by Group",{"type":8,"value":9,"toc":2274},"minimark",[10,19,30,35,87,91,212,221,225,228,284,287,327,330,363,366,374,377,427,431,2144,2148,2216,2220,2270],[11,12,13,14,18],"p",{},"App Protection Policy assignment in the Intune console is a one-at-a-time affair: open the policy, click Assignment, pick groups, save, repeat for the next policy. When a reorg lands and I need to add a dozen new department groups to three or four existing policies, I reach for Microsoft Graph instead. The catch is that the ",[15,16,17],"code",{},"assign"," action on these policies takes the complete assignment list in its request body, so the script has to read the existing assignments before it writes a new list, or everyone who was already targeted silently drops off.",[11,20,21,22,25,26,29],{},"This version uses only Graph v1.0 endpoints: list the iOS or Android policies, read ",[15,23,24],{},"\u002Fassignments"," on the one you picked, merge in the new group targets (as includes or as exclusions), and post the combined list to ",[15,27,28],{},"managedAppPolicies\u002F{id}\u002Fassign",".",[31,32,34],"h2",{"id":33},"requirements","Requirements",[36,37,38,42,56,78,81,84],"ul",{},[39,40,41],"li",{},"PowerShell 7.x (Windows PowerShell 5.1 also works).",[39,43,44,47,48,51,52,55],{},[15,45,46],{},"Microsoft.Graph.Authentication"," and ",[15,49,50],{},"Microsoft.Graph.Groups"," modules (",[15,53,54],{},"Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Groups -Scope CurrentUser",").",[39,57,58,59,62,63,65,66,69,70,73,74,77],{},"Graph permissions, delegated or application: ",[15,60,61],{},"DeviceManagementApps.ReadWrite.All"," (the only permission the v1.0 ",[15,64,17],{}," action accepts) and ",[15,67,68],{},"Group.Read.All"," to resolve group names. ",[15,71,72],{},"GroupMember.Read.All"," is also enough for ",[15,75,76],{},"Get-MgGroup"," if you want the narrower scope.",[39,79,80],{},"An active Intune license on the tenant. Microsoft notes that the Intune Graph API requires one.",[39,82,83],{},"An Intune role that can edit app protection policies (Intune Administrator, or a custom role with the app protection permissions) for the signed-in account.",[39,85,86],{},"The Entra ID groups must already exist; the script doesn't create them.",[31,88,90],{"id":89},"parameters","Parameters",[92,93,94,113],"table",{},[95,96,97],"thead",{},[98,99,100,104,107,110],"tr",{},[101,102,103],"th",{},"Name",[101,105,106],{},"Type",[101,108,109],{},"Required",[101,111,112],{},"Description",[114,115,116,133,161,178,198],"tbody",{},[98,117,118,124,127,130],{},[119,120,121],"td",{},[15,122,123],{},"PolicyName",[119,125,126],{},"String",[119,128,129],{},"Yes",[119,131,132],{},"Display name of the App Protection Policy, exactly as it appears in Intune",[98,134,135,140,142,144],{},[119,136,137],{},[15,138,139],{},"Platform",[119,141,126],{},[119,143,129],{},[119,145,146,149,150,153,154,149,157,160],{},[15,147,148],{},"iOS"," or ",[15,151,152],{},"Android","; picks the ",[15,155,156],{},"iosManagedAppProtections",[15,158,159],{},"androidManagedAppProtections"," collection",[98,162,163,168,173,175],{},[119,164,165],{},[15,166,167],{},"GroupNames",[119,169,126,170],{},[171,172],"span",{},[119,174,129],{},[119,176,177],{},"Display names of the Entra ID groups to add to the assignment",[98,179,180,185,188,191],{},[119,181,182],{},[15,183,184],{},"AsExclusion",[119,186,187],{},"Switch",[119,189,190],{},"No",[119,192,193,194,197],{},"Adds the groups as excluded groups (",[15,195,196],{},"exclusionGroupAssignmentTarget",") instead of included groups",[98,199,200,205,207,209],{},[119,201,202],{},[15,203,204],{},"RemoveExisting",[119,206,187],{},[119,208,190],{},[119,210,211],{},"Replaces the assignment list instead of merging with what's already there",[11,213,214,215,218,219,29],{},"The script supports ",[15,216,217],{},"-WhatIf",", which resolves everything and prints the final assignment count without calling ",[15,220,17],{},[31,222,224],{"id":223},"usage","Usage",[11,226,227],{},"Add three new groups to an existing iOS policy without disturbing who's already assigned:",[229,230,235],"pre",{"className":231,"code":232,"language":233,"meta":234,"style":234},"language-powershell shiki shiki-themes github-dark",".\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"Corporate Data - iOS\" -Platform iOS -GroupNames \"SG-Sales-EMEA\", \"SG-Sales-APAC\", \"SG-Finance-Contractors\"\n","powershell","",[15,236,237],{"__ignoreMap":234},[171,238,241,244,248,252,255,259,261,264,267,270,273,276,279,281],{"class":239,"line":240},"line",1,[171,242,29],{"class":243},"s95oV",[171,245,247],{"class":246},"sDLfK","\\Add-IntuneAppProtectionAssignment.ps1",[171,249,251],{"class":250},"snl16"," -",[171,253,254],{"class":243},"PolicyName ",[171,256,258],{"class":257},"sU2Wk","\"Corporate Data - iOS\"",[171,260,251],{"class":250},[171,262,263],{"class":243},"Platform iOS ",[171,265,266],{"class":250},"-",[171,268,269],{"class":243},"GroupNames ",[171,271,272],{"class":257},"\"SG-Sales-EMEA\"",[171,274,275],{"class":250},",",[171,277,278],{"class":257}," \"SG-Sales-APAC\"",[171,280,275],{"class":250},[171,282,283],{"class":257}," \"SG-Finance-Contractors\"\n",[11,285,286],{},"Exclude a pilot group from an Android policy, previewing first:",[229,288,290],{"className":231,"code":289,"language":233,"meta":234,"style":234},".\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"BYOD Baseline - Android\" -Platform Android -GroupNames \"SG-MAM-Pilot\" -AsExclusion -WhatIf\n",[15,291,292],{"__ignoreMap":234},[171,293,294,296,298,300,302,305,307,310,312,314,317,319,322,324],{"class":239,"line":240},[171,295,29],{"class":243},[171,297,247],{"class":246},[171,299,251],{"class":250},[171,301,254],{"class":243},[171,303,304],{"class":257},"\"BYOD Baseline - Android\"",[171,306,251],{"class":250},[171,308,309],{"class":243},"Platform Android ",[171,311,266],{"class":250},[171,313,269],{"class":243},[171,315,316],{"class":257},"\"SG-MAM-Pilot\"",[171,318,251],{"class":250},[171,320,321],{"class":243},"AsExclusion ",[171,323,266],{"class":250},[171,325,326],{"class":243},"WhatIf\n",[11,328,329],{},"Replace the assignment list entirely for an Android policy:",[229,331,333],{"className":231,"code":332,"language":233,"meta":234,"style":234},".\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"BYOD Baseline - Android\" -Platform Android -GroupNames \"SG-BYOD-All\" -RemoveExisting\n",[15,334,335],{"__ignoreMap":234},[171,336,337,339,341,343,345,347,349,351,353,355,358,360],{"class":239,"line":240},[171,338,29],{"class":243},[171,340,247],{"class":246},[171,342,251],{"class":250},[171,344,254],{"class":243},[171,346,304],{"class":257},[171,348,251],{"class":250},[171,350,309],{"class":243},[171,352,266],{"class":250},[171,354,269],{"class":243},[171,356,357],{"class":257},"\"SG-BYOD-All\"",[171,359,251],{"class":250},[171,361,362],{"class":243},"RemoveExisting\n",[11,364,365],{},"Sample output:",[229,367,372],{"className":368,"code":370,"language":371,"meta":234},[369],"language-text","Resolved policy 'Corporate Data - iOS' (id: 3f2c9b4a-...)\nResolved group 'SG-Sales-EMEA' (id: 8a1d...)\nResolved group 'SG-Sales-APAC' (id: 5e77...)\nResolved group 'SG-Finance-Contractors' (id: c410...)\nExisting assignments preserved: 2\nNew group targets added: 3 (include)\nAssignment updated: 5 target(s) on 'Corporate Data - iOS'.\n","text",[15,373,370],{"__ignoreMap":234},[11,375,376],{},"To check the result afterwards, read the assignments back:",[229,378,380],{"className":231,"code":379,"language":233,"meta":234,"style":234},"$uri = \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002FdeviceAppManagement\u002FiosManagedAppProtections\u002F\u003Cpolicy-id>\u002Fassignments\"\n(Invoke-MgGraphRequest -Method GET -Uri $uri).value | ForEach-Object { $_.target }\n",[15,381,382,393],{"__ignoreMap":234},[171,383,384,387,390],{"class":239,"line":240},[171,385,386],{"class":243},"$uri ",[171,388,389],{"class":250},"=",[171,391,392],{"class":257}," \"https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0\u002FdeviceAppManagement\u002FiosManagedAppProtections\u002F\u003Cpolicy-id>\u002Fassignments\"\n",[171,394,396,399,402,404,407,409,412,415,418,421,424],{"class":239,"line":395},2,[171,397,398],{"class":243},"(",[171,400,401],{"class":246},"Invoke-MgGraphRequest",[171,403,251],{"class":250},[171,405,406],{"class":243},"Method GET ",[171,408,266],{"class":250},[171,410,411],{"class":243},"Uri $uri).value ",[171,413,414],{"class":250},"|",[171,416,417],{"class":246}," ForEach-Object",[171,419,420],{"class":243}," { ",[171,422,423],{"class":246},"$_",[171,425,426],{"class":243},".target }\n",[31,428,430],{"id":429},"script","Script",[229,432,434],{"className":231,"code":433,"language":233,"meta":234,"style":234},"\u003C#\n.SYNOPSIS\n    Adds Entra ID groups to an Intune App Protection Policy assignment.\n.DESCRIPTION\n    Connects to Microsoft Graph, resolves an iOS or Android App Protection\n    Policy by display name, resolves the target groups by display name, and\n    calls the v1.0 assign action. The assign action takes the complete list of\n    assignments, so the script reads the policy's current assignments first\n    and merges the new group targets into them (unless -RemoveExisting is set).\n    Groups can be added as included or excluded targets. Supports -WhatIf.\n.PARAMETER PolicyName\n    Display name of the App Protection Policy, exactly as it appears in Intune.\n.PARAMETER Platform\n    iOS or Android. Picks the iosManagedAppProtections or\n    androidManagedAppProtections collection.\n.PARAMETER GroupNames\n    Display names of the Entra ID groups to add to the assignment.\n.PARAMETER AsExclusion\n    Adds the groups as excluded groups instead of included groups.\n.PARAMETER RemoveExisting\n    Replaces the assignment list instead of merging with what is already\n    assigned.\n.EXAMPLE\n    .\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"Corporate Data - iOS\" -Platform iOS -GroupNames \"SG-Sales-EMEA\", \"SG-Sales-APAC\"\n.EXAMPLE\n    .\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"BYOD Baseline - Android\" -Platform Android -GroupNames \"SG-MAM-Pilot\" -AsExclusion -WhatIf\n.NOTES\n    Author  : Thomas Lasswell (https:\u002F\u002Fwww.techcolumnist.com)\n    Version : 1.0 (2025-04-17)\n    Requires: Microsoft.Graph.Authentication, Microsoft.Graph.Groups;\n              DeviceManagementApps.ReadWrite.All and Group.Read.All.\n.LINK\n    https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fintune-mam-targetedmanagedappprotection-assign?view=graph-rest-1.0\n#>\n\n[CmdletBinding(SupportsShouldProcess = $true)]\nparam (\n    [Parameter(Mandatory = $true)]\n    [string]$PolicyName,\n\n    [Parameter(Mandatory = $true)]\n    [ValidateSet('iOS', 'Android')]\n    [string]$Platform,\n\n    [Parameter(Mandatory = $true)]\n    [string[]]$GroupNames,\n\n    [Parameter(Mandatory = $false)]\n    [switch]$AsExclusion,\n\n    [Parameter(Mandatory = $false)]\n    [switch]$RemoveExisting\n)\n\n$ErrorActionPreference = 'Stop'\n$graph = 'https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0'\n\n# Follow @odata.nextLink so large collections are read completely.\nfunction Get-GraphCollection {\n    param ([string]$Uri)\n    $items = @()\n    while ($Uri) {\n        $page = Invoke-MgGraphRequest -Method GET -Uri $Uri\n        $items += $page.value\n        $Uri = $page.'@odata.nextLink'\n    }\n    return $items\n}\n\nif (-not (Get-MgContext)) {\n    Connect-MgGraph -Scopes \"DeviceManagementApps.ReadWrite.All\", \"Group.Read.All\" -NoWelcome\n}\n\n$resource = if ($Platform -eq 'iOS') { 'iosManagedAppProtections' } else { 'androidManagedAppProtections' }\n\n# Resolve the policy by display name (client-side match, exact and case-insensitive).\n$policies = @(Get-GraphCollection -Uri \"$graph\u002FdeviceAppManagement\u002F$resource\" |\n    Where-Object { $_.displayName -eq $PolicyName })\n\nif ($policies.Count -eq 0) {\n    throw \"No $Platform App Protection Policy found with display name '$PolicyName'.\"\n}\n\nif ($policies.Count -gt 1) {\n    throw \"Multiple $Platform App Protection Policies matched '$PolicyName'. Rename them so the display name is unique.\"\n}\n\n$policyId = $policies[0].id\nWrite-Host \"Resolved policy '$PolicyName' (id: $policyId)\"\n\n# Resolve each target group to its object id. Single quotes are doubled for OData.\n$targetType = if ($AsExclusion) { '#microsoft.graph.exclusionGroupAssignmentTarget' } else { '#microsoft.graph.groupAssignmentTarget' }\n\n$groupTargets = foreach ($groupName in $GroupNames) {\n    $escapedName = $groupName.Replace(\"'\", \"''\")\n    $group = @(Get-MgGroup -Filter \"displayName eq '$escapedName'\" -Property \"id,displayName\")\n\n    if ($group.Count -eq 0) {\n        throw \"No Entra ID group found with display name '$groupName'.\"\n    }\n\n    if ($group.Count -gt 1) {\n        throw \"Multiple Entra ID groups matched '$groupName'. Use a unique display name.\"\n    }\n\n    Write-Host \"Resolved group '$groupName' (id: $($group[0].Id))\"\n\n    @{\n        target = @{\n            '@odata.type' = $targetType\n            groupId       = $group[0].Id\n        }\n    }\n}\n\n# Read the current assignment list so the assign call does not drop anyone.\n$existingAssignments = @()\n\nif (-not $RemoveExisting) {\n    $current = Get-GraphCollection -Uri \"$graph\u002FdeviceAppManagement\u002F$resource\u002F$policyId\u002Fassignments\"\n    $existingAssignments = @($current | ForEach-Object { @{ target = $_.target } })\n    Write-Host \"Existing assignments preserved: $($existingAssignments.Count)\"\n}\n\n# De-duplicate on group id so re-running the script is safe.\n$existingGroupIds = @($existingAssignments |\n    Where-Object { $_.target.ContainsKey('groupId') } |\n    ForEach-Object { $_.target.groupId })\n\n$newTargets = @($groupTargets | Where-Object { $_.target.groupId -notin $existingGroupIds })\n$finalAssignments = @($existingAssignments) + $newTargets\n\n$mode = if ($AsExclusion) { 'exclude' } else { 'include' }\nWrite-Host \"New group targets added: $($newTargets.Count) ($mode)\"\n\nif ($newTargets.Count -eq 0 -and -not $RemoveExisting) {\n    Write-Host \"Nothing to change.\"\n    return\n}\n\n$body = @{ assignments = $finalAssignments } | ConvertTo-Json -Depth 10\n\nif ($PSCmdlet.ShouldProcess($PolicyName, \"Assign $($finalAssignments.Count) target(s)\")) {\n    Invoke-MgGraphRequest -Method POST -Uri \"$graph\u002FdeviceAppManagement\u002FmanagedAppPolicies\u002F$policyId\u002Fassign\" -Body $body -ContentType \"application\u002Fjson\"\n    Write-Host \"Assignment updated: $($finalAssignments.Count) target(s) on '$PolicyName'.\"\n}\n",[15,435,436,442,449,455,463,469,475,481,487,493,499,510,516,526,532,538,548,554,564,570,580,586,592,600,606,613,619,627,633,639,645,651,659,665,671,678,702,711,731,745,750,767,787,799,804,821,833,838,856,869,874,891,901,907,912,923,934,939,945,958,972,986,995,1015,1027,1041,1047,1056,1062,1067,1087,1111,1116,1121,1161,1166,1172,1209,1227,1232,1248,1269,1274,1279,1294,1312,1317,1322,1339,1359,1364,1370,1397,1402,1422,1443,1481,1486,1501,1515,1520,1525,1538,1551,1556,1561,1591,1596,1605,1617,1628,1644,1650,1655,1660,1665,1671,1683,1688,1700,1730,1763,1784,1789,1794,1800,1816,1836,1849,1854,1885,1904,1909,1935,1959,1964,1984,1992,1998,2003,2008,2039,2044,2076,2116,2139],{"__ignoreMap":234},[171,437,438],{"class":239,"line":240},[171,439,441],{"class":440},"sAwPA","\u003C#\n",[171,443,444,446],{"class":239,"line":395},[171,445,29],{"class":246},[171,447,448],{"class":250},"SYNOPSIS\n",[171,450,452],{"class":239,"line":451},3,[171,453,454],{"class":440},"    Adds Entra ID groups to an Intune App Protection Policy assignment.\n",[171,456,458,460],{"class":239,"line":457},4,[171,459,29],{"class":246},[171,461,462],{"class":250},"DESCRIPTION\n",[171,464,466],{"class":239,"line":465},5,[171,467,468],{"class":440},"    Connects to Microsoft Graph, resolves an iOS or Android App Protection\n",[171,470,472],{"class":239,"line":471},6,[171,473,474],{"class":440},"    Policy by display name, resolves the target groups by display name, and\n",[171,476,478],{"class":239,"line":477},7,[171,479,480],{"class":440},"    calls the v1.0 assign action. The assign action takes the complete list of\n",[171,482,484],{"class":239,"line":483},8,[171,485,486],{"class":440},"    assignments, so the script reads the policy's current assignments first\n",[171,488,490],{"class":239,"line":489},9,[171,491,492],{"class":440},"    and merges the new group targets into them (unless -RemoveExisting is set).\n",[171,494,496],{"class":239,"line":495},10,[171,497,498],{"class":440},"    Groups can be added as included or excluded targets. Supports -WhatIf.\n",[171,500,502,504,507],{"class":239,"line":501},11,[171,503,29],{"class":246},[171,505,506],{"class":250},"PARAMETER",[171,508,509],{"class":250}," PolicyName\n",[171,511,513],{"class":239,"line":512},12,[171,514,515],{"class":440},"    Display name of the App Protection Policy, exactly as it appears in Intune.\n",[171,517,519,521,523],{"class":239,"line":518},13,[171,520,29],{"class":246},[171,522,506],{"class":250},[171,524,525],{"class":250}," Platform\n",[171,527,529],{"class":239,"line":528},14,[171,530,531],{"class":440},"    iOS or Android. Picks the iosManagedAppProtections or\n",[171,533,535],{"class":239,"line":534},15,[171,536,537],{"class":440},"    androidManagedAppProtections collection.\n",[171,539,541,543,545],{"class":239,"line":540},16,[171,542,29],{"class":246},[171,544,506],{"class":250},[171,546,547],{"class":250}," GroupNames\n",[171,549,551],{"class":239,"line":550},17,[171,552,553],{"class":440},"    Display names of the Entra ID groups to add to the assignment.\n",[171,555,557,559,561],{"class":239,"line":556},18,[171,558,29],{"class":246},[171,560,506],{"class":250},[171,562,563],{"class":250}," AsExclusion\n",[171,565,567],{"class":239,"line":566},19,[171,568,569],{"class":440},"    Adds the groups as excluded groups instead of included groups.\n",[171,571,573,575,577],{"class":239,"line":572},20,[171,574,29],{"class":246},[171,576,506],{"class":250},[171,578,579],{"class":250}," RemoveExisting\n",[171,581,583],{"class":239,"line":582},21,[171,584,585],{"class":440},"    Replaces the assignment list instead of merging with what is already\n",[171,587,589],{"class":239,"line":588},22,[171,590,591],{"class":440},"    assigned.\n",[171,593,595,597],{"class":239,"line":594},23,[171,596,29],{"class":246},[171,598,599],{"class":250},"EXAMPLE\n",[171,601,603],{"class":239,"line":602},24,[171,604,605],{"class":440},"    .\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"Corporate Data - iOS\" -Platform iOS -GroupNames \"SG-Sales-EMEA\", \"SG-Sales-APAC\"\n",[171,607,609,611],{"class":239,"line":608},25,[171,610,29],{"class":246},[171,612,599],{"class":250},[171,614,616],{"class":239,"line":615},26,[171,617,618],{"class":440},"    .\\Add-IntuneAppProtectionAssignment.ps1 -PolicyName \"BYOD Baseline - Android\" -Platform Android -GroupNames \"SG-MAM-Pilot\" -AsExclusion -WhatIf\n",[171,620,622,624],{"class":239,"line":621},27,[171,623,29],{"class":246},[171,625,626],{"class":250},"NOTES\n",[171,628,630],{"class":239,"line":629},28,[171,631,632],{"class":440},"    Author  : Thomas Lasswell (https:\u002F\u002Fwww.techcolumnist.com)\n",[171,634,636],{"class":239,"line":635},29,[171,637,638],{"class":440},"    Version : 1.0 (2025-04-17)\n",[171,640,642],{"class":239,"line":641},30,[171,643,644],{"class":440},"    Requires: Microsoft.Graph.Authentication, Microsoft.Graph.Groups;\n",[171,646,648],{"class":239,"line":647},31,[171,649,650],{"class":440},"              DeviceManagementApps.ReadWrite.All and Group.Read.All.\n",[171,652,654,656],{"class":239,"line":653},32,[171,655,29],{"class":246},[171,657,658],{"class":250},"LINK\n",[171,660,662],{"class":239,"line":661},33,[171,663,664],{"class":440},"    https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fintune-mam-targetedmanagedappprotection-assign?view=graph-rest-1.0\n",[171,666,668],{"class":239,"line":667},34,[171,669,670],{"class":440},"#>\n",[171,672,674],{"class":239,"line":673},35,[171,675,677],{"emptyLinePlaceholder":676},true,"\n",[171,679,681,684,687,689,693,696,699],{"class":239,"line":680},36,[171,682,683],{"class":243},"[",[171,685,686],{"class":246},"CmdletBinding",[171,688,398],{"class":243},[171,690,692],{"class":691},"s9osk","SupportsShouldProcess",[171,694,695],{"class":250}," =",[171,697,698],{"class":246}," $true",[171,700,701],{"class":243},")]\n",[171,703,705,708],{"class":239,"line":704},37,[171,706,707],{"class":250},"param",[171,709,710],{"class":243}," (\n",[171,712,714,717,720,722,725,727,729],{"class":239,"line":713},38,[171,715,716],{"class":243},"    [",[171,718,719],{"class":246},"Parameter",[171,721,398],{"class":243},[171,723,724],{"class":691},"Mandatory",[171,726,695],{"class":250},[171,728,698],{"class":246},[171,730,701],{"class":243},[171,732,734,736,739,742],{"class":239,"line":733},39,[171,735,716],{"class":243},[171,737,738],{"class":250},"string",[171,740,741],{"class":243},"]$PolicyName",[171,743,744],{"class":250},",\n",[171,746,748],{"class":239,"line":747},40,[171,749,677],{"emptyLinePlaceholder":676},[171,751,753,755,757,759,761,763,765],{"class":239,"line":752},41,[171,754,716],{"class":243},[171,756,719],{"class":246},[171,758,398],{"class":243},[171,760,724],{"class":691},[171,762,695],{"class":250},[171,764,698],{"class":246},[171,766,701],{"class":243},[171,768,770,772,775,777,780,782,785],{"class":239,"line":769},42,[171,771,716],{"class":243},[171,773,774],{"class":246},"ValidateSet",[171,776,398],{"class":243},[171,778,779],{"class":257},"'iOS'",[171,781,275],{"class":250},[171,783,784],{"class":257}," 'Android'",[171,786,701],{"class":243},[171,788,790,792,794,797],{"class":239,"line":789},43,[171,791,716],{"class":243},[171,793,738],{"class":250},[171,795,796],{"class":243},"]$Platform",[171,798,744],{"class":250},[171,800,802],{"class":239,"line":801},44,[171,803,677],{"emptyLinePlaceholder":676},[171,805,807,809,811,813,815,817,819],{"class":239,"line":806},45,[171,808,716],{"class":243},[171,810,719],{"class":246},[171,812,398],{"class":243},[171,814,724],{"class":691},[171,816,695],{"class":250},[171,818,698],{"class":246},[171,820,701],{"class":243},[171,822,824,826,828,831],{"class":239,"line":823},46,[171,825,716],{"class":243},[171,827,738],{"class":250},[171,829,830],{"class":243},"[]]$GroupNames",[171,832,744],{"class":250},[171,834,836],{"class":239,"line":835},47,[171,837,677],{"emptyLinePlaceholder":676},[171,839,841,843,845,847,849,851,854],{"class":239,"line":840},48,[171,842,716],{"class":243},[171,844,719],{"class":246},[171,846,398],{"class":243},[171,848,724],{"class":691},[171,850,695],{"class":250},[171,852,853],{"class":246}," $false",[171,855,701],{"class":243},[171,857,859,861,864,867],{"class":239,"line":858},49,[171,860,716],{"class":243},[171,862,863],{"class":250},"switch",[171,865,866],{"class":243},"]$AsExclusion",[171,868,744],{"class":250},[171,870,872],{"class":239,"line":871},50,[171,873,677],{"emptyLinePlaceholder":676},[171,875,877,879,881,883,885,887,889],{"class":239,"line":876},51,[171,878,716],{"class":243},[171,880,719],{"class":246},[171,882,398],{"class":243},[171,884,724],{"class":691},[171,886,695],{"class":250},[171,888,853],{"class":246},[171,890,701],{"class":243},[171,892,894,896,898],{"class":239,"line":893},52,[171,895,716],{"class":243},[171,897,863],{"class":250},[171,899,900],{"class":243},"]$RemoveExisting\n",[171,902,904],{"class":239,"line":903},53,[171,905,906],{"class":243},")\n",[171,908,910],{"class":239,"line":909},54,[171,911,677],{"emptyLinePlaceholder":676},[171,913,915,918,920],{"class":239,"line":914},55,[171,916,917],{"class":246},"$ErrorActionPreference",[171,919,695],{"class":250},[171,921,922],{"class":257}," 'Stop'\n",[171,924,926,929,931],{"class":239,"line":925},56,[171,927,928],{"class":243},"$graph ",[171,930,389],{"class":250},[171,932,933],{"class":257}," 'https:\u002F\u002Fgraph.microsoft.com\u002Fv1.0'\n",[171,935,937],{"class":239,"line":936},57,[171,938,677],{"emptyLinePlaceholder":676},[171,940,942],{"class":239,"line":941},58,[171,943,944],{"class":440},"# Follow @odata.nextLink so large collections are read completely.\n",[171,946,948,951,955],{"class":239,"line":947},59,[171,949,950],{"class":250},"function",[171,952,954],{"class":953},"svObZ"," Get-GraphCollection",[171,956,957],{"class":243}," {\n",[171,959,961,964,967,969],{"class":239,"line":960},60,[171,962,963],{"class":250},"    param",[171,965,966],{"class":243}," ([",[171,968,738],{"class":250},[171,970,971],{"class":243},"]$Uri)\n",[171,973,975,978,980,983],{"class":239,"line":974},61,[171,976,977],{"class":243},"    $items ",[171,979,389],{"class":250},[171,981,982],{"class":250}," @",[171,984,985],{"class":243},"()\n",[171,987,989,992],{"class":239,"line":988},62,[171,990,991],{"class":250},"    while",[171,993,994],{"class":243}," ($Uri) {\n",[171,996,998,1001,1003,1006,1008,1010,1012],{"class":239,"line":997},63,[171,999,1000],{"class":243},"        $page ",[171,1002,389],{"class":250},[171,1004,1005],{"class":246}," Invoke-MgGraphRequest",[171,1007,251],{"class":250},[171,1009,406],{"class":243},[171,1011,266],{"class":250},[171,1013,1014],{"class":243},"Uri $Uri\n",[171,1016,1018,1021,1024],{"class":239,"line":1017},64,[171,1019,1020],{"class":243},"        $items ",[171,1022,1023],{"class":250},"+=",[171,1025,1026],{"class":243}," $page.value\n",[171,1028,1030,1033,1035,1038],{"class":239,"line":1029},65,[171,1031,1032],{"class":243},"        $Uri ",[171,1034,389],{"class":250},[171,1036,1037],{"class":243}," $page.",[171,1039,1040],{"class":257},"'@odata.nextLink'\n",[171,1042,1044],{"class":239,"line":1043},66,[171,1045,1046],{"class":243},"    }\n",[171,1048,1050,1053],{"class":239,"line":1049},67,[171,1051,1052],{"class":250},"    return",[171,1054,1055],{"class":243}," $items\n",[171,1057,1059],{"class":239,"line":1058},68,[171,1060,1061],{"class":243},"}\n",[171,1063,1065],{"class":239,"line":1064},69,[171,1066,677],{"emptyLinePlaceholder":676},[171,1068,1070,1073,1076,1079,1081,1084],{"class":239,"line":1069},70,[171,1071,1072],{"class":250},"if",[171,1074,1075],{"class":243}," (",[171,1077,1078],{"class":250},"-not",[171,1080,1075],{"class":243},[171,1082,1083],{"class":246},"Get-MgContext",[171,1085,1086],{"class":243},")) {\n",[171,1088,1090,1093,1095,1098,1101,1103,1106,1108],{"class":239,"line":1089},71,[171,1091,1092],{"class":246},"    Connect-MgGraph",[171,1094,251],{"class":250},[171,1096,1097],{"class":243},"Scopes ",[171,1099,1100],{"class":257},"\"DeviceManagementApps.ReadWrite.All\"",[171,1102,275],{"class":250},[171,1104,1105],{"class":257}," \"Group.Read.All\"",[171,1107,251],{"class":250},[171,1109,1110],{"class":243},"NoWelcome\n",[171,1112,1114],{"class":239,"line":1113},72,[171,1115,1061],{"class":243},[171,1117,1119],{"class":239,"line":1118},73,[171,1120,677],{"emptyLinePlaceholder":676},[171,1122,1124,1127,1129,1132,1135,1138,1141,1144,1147,1150,1153,1155,1158],{"class":239,"line":1123},74,[171,1125,1126],{"class":243},"$resource ",[171,1128,389],{"class":250},[171,1130,1131],{"class":250}," if",[171,1133,1134],{"class":243}," ($Platform ",[171,1136,1137],{"class":250},"-eq",[171,1139,1140],{"class":257}," 'iOS'",[171,1142,1143],{"class":243},") { ",[171,1145,1146],{"class":257},"'iosManagedAppProtections'",[171,1148,1149],{"class":243}," } ",[171,1151,1152],{"class":250},"else",[171,1154,420],{"class":243},[171,1156,1157],{"class":257},"'androidManagedAppProtections'",[171,1159,1160],{"class":243}," }\n",[171,1162,1164],{"class":239,"line":1163},75,[171,1165,677],{"emptyLinePlaceholder":676},[171,1167,1169],{"class":239,"line":1168},76,[171,1170,1171],{"class":440},"# Resolve the policy by display name (client-side match, exact and case-insensitive).\n",[171,1173,1175,1178,1180,1182,1184,1187,1189,1192,1195,1198,1201,1204,1206],{"class":239,"line":1174},77,[171,1176,1177],{"class":243},"$policies ",[171,1179,389],{"class":250},[171,1181,982],{"class":250},[171,1183,398],{"class":243},[171,1185,1186],{"class":246},"Get-GraphCollection",[171,1188,251],{"class":250},[171,1190,1191],{"class":243},"Uri ",[171,1193,1194],{"class":257},"\"",[171,1196,1197],{"class":243},"$graph",[171,1199,1200],{"class":257},"\u002FdeviceAppManagement\u002F",[171,1202,1203],{"class":243},"$resource",[171,1205,1194],{"class":257},[171,1207,1208],{"class":250}," |\n",[171,1210,1212,1215,1217,1219,1222,1224],{"class":239,"line":1211},78,[171,1213,1214],{"class":246},"    Where-Object",[171,1216,420],{"class":243},[171,1218,423],{"class":246},[171,1220,1221],{"class":243},".displayName ",[171,1223,1137],{"class":250},[171,1225,1226],{"class":243}," $PolicyName })\n",[171,1228,1230],{"class":239,"line":1229},79,[171,1231,677],{"emptyLinePlaceholder":676},[171,1233,1235,1237,1240,1242,1245],{"class":239,"line":1234},80,[171,1236,1072],{"class":250},[171,1238,1239],{"class":243}," ($policies.Count ",[171,1241,1137],{"class":250},[171,1243,1244],{"class":246}," 0",[171,1246,1247],{"class":243},") {\n",[171,1249,1251,1254,1257,1260,1263,1266],{"class":239,"line":1250},81,[171,1252,1253],{"class":250},"    throw",[171,1255,1256],{"class":257}," \"No ",[171,1258,1259],{"class":243},"$Platform",[171,1261,1262],{"class":257}," App Protection Policy found with display name '",[171,1264,1265],{"class":243},"$PolicyName",[171,1267,1268],{"class":257},"'.\"\n",[171,1270,1272],{"class":239,"line":1271},82,[171,1273,1061],{"class":243},[171,1275,1277],{"class":239,"line":1276},83,[171,1278,677],{"emptyLinePlaceholder":676},[171,1280,1282,1284,1286,1289,1292],{"class":239,"line":1281},84,[171,1283,1072],{"class":250},[171,1285,1239],{"class":243},[171,1287,1288],{"class":250},"-gt",[171,1290,1291],{"class":246}," 1",[171,1293,1247],{"class":243},[171,1295,1297,1299,1302,1304,1307,1309],{"class":239,"line":1296},85,[171,1298,1253],{"class":250},[171,1300,1301],{"class":257}," \"Multiple ",[171,1303,1259],{"class":243},[171,1305,1306],{"class":257}," App Protection Policies matched '",[171,1308,1265],{"class":243},[171,1310,1311],{"class":257},"'. Rename them so the display name is unique.\"\n",[171,1313,1315],{"class":239,"line":1314},86,[171,1316,1061],{"class":243},[171,1318,1320],{"class":239,"line":1319},87,[171,1321,677],{"emptyLinePlaceholder":676},[171,1323,1325,1328,1330,1333,1336],{"class":239,"line":1324},88,[171,1326,1327],{"class":243},"$policyId ",[171,1329,389],{"class":250},[171,1331,1332],{"class":243}," $policies[",[171,1334,1335],{"class":246},"0",[171,1337,1338],{"class":243},"].id\n",[171,1340,1342,1345,1348,1350,1353,1356],{"class":239,"line":1341},89,[171,1343,1344],{"class":246},"Write-Host",[171,1346,1347],{"class":257}," \"Resolved policy '",[171,1349,1265],{"class":243},[171,1351,1352],{"class":257},"' (id: ",[171,1354,1355],{"class":243},"$policyId",[171,1357,1358],{"class":257},")\"\n",[171,1360,1362],{"class":239,"line":1361},90,[171,1363,677],{"emptyLinePlaceholder":676},[171,1365,1367],{"class":239,"line":1366},91,[171,1368,1369],{"class":440},"# Resolve each target group to its object id. Single quotes are doubled for OData.\n",[171,1371,1373,1376,1378,1380,1383,1386,1388,1390,1392,1395],{"class":239,"line":1372},92,[171,1374,1375],{"class":243},"$targetType ",[171,1377,389],{"class":250},[171,1379,1131],{"class":250},[171,1381,1382],{"class":243}," ($AsExclusion) { ",[171,1384,1385],{"class":257},"'#microsoft.graph.exclusionGroupAssignmentTarget'",[171,1387,1149],{"class":243},[171,1389,1152],{"class":250},[171,1391,420],{"class":243},[171,1393,1394],{"class":257},"'#microsoft.graph.groupAssignmentTarget'",[171,1396,1160],{"class":243},[171,1398,1400],{"class":239,"line":1399},93,[171,1401,677],{"emptyLinePlaceholder":676},[171,1403,1405,1408,1410,1413,1416,1419],{"class":239,"line":1404},94,[171,1406,1407],{"class":243},"$groupTargets ",[171,1409,389],{"class":250},[171,1411,1412],{"class":250}," foreach",[171,1414,1415],{"class":243}," ($groupName ",[171,1417,1418],{"class":250},"in",[171,1420,1421],{"class":243}," $GroupNames) {\n",[171,1423,1425,1428,1430,1433,1436,1438,1441],{"class":239,"line":1424},95,[171,1426,1427],{"class":243},"    $escapedName ",[171,1429,389],{"class":250},[171,1431,1432],{"class":243}," $groupName.Replace(",[171,1434,1435],{"class":257},"\"'\"",[171,1437,275],{"class":250},[171,1439,1440],{"class":257}," \"''\"",[171,1442,906],{"class":243},[171,1444,1446,1449,1451,1453,1455,1457,1459,1462,1465,1468,1471,1473,1476,1479],{"class":239,"line":1445},96,[171,1447,1448],{"class":243},"    $group ",[171,1450,389],{"class":250},[171,1452,982],{"class":250},[171,1454,398],{"class":243},[171,1456,76],{"class":246},[171,1458,251],{"class":250},[171,1460,1461],{"class":243},"Filter ",[171,1463,1464],{"class":257},"\"displayName eq '",[171,1466,1467],{"class":243},"$escapedName",[171,1469,1470],{"class":257},"'\"",[171,1472,251],{"class":250},[171,1474,1475],{"class":243},"Property ",[171,1477,1478],{"class":257},"\"id,displayName\"",[171,1480,906],{"class":243},[171,1482,1484],{"class":239,"line":1483},97,[171,1485,677],{"emptyLinePlaceholder":676},[171,1487,1489,1492,1495,1497,1499],{"class":239,"line":1488},98,[171,1490,1491],{"class":250},"    if",[171,1493,1494],{"class":243}," ($group.Count ",[171,1496,1137],{"class":250},[171,1498,1244],{"class":246},[171,1500,1247],{"class":243},[171,1502,1504,1507,1510,1513],{"class":239,"line":1503},99,[171,1505,1506],{"class":250},"        throw",[171,1508,1509],{"class":257}," \"No Entra ID group found with display name '",[171,1511,1512],{"class":243},"$groupName",[171,1514,1268],{"class":257},[171,1516,1518],{"class":239,"line":1517},100,[171,1519,1046],{"class":243},[171,1521,1523],{"class":239,"line":1522},101,[171,1524,677],{"emptyLinePlaceholder":676},[171,1526,1528,1530,1532,1534,1536],{"class":239,"line":1527},102,[171,1529,1491],{"class":250},[171,1531,1494],{"class":243},[171,1533,1288],{"class":250},[171,1535,1291],{"class":246},[171,1537,1247],{"class":243},[171,1539,1541,1543,1546,1548],{"class":239,"line":1540},103,[171,1542,1506],{"class":250},[171,1544,1545],{"class":257}," \"Multiple Entra ID groups matched '",[171,1547,1512],{"class":243},[171,1549,1550],{"class":257},"'. Use a unique display name.\"\n",[171,1552,1554],{"class":239,"line":1553},104,[171,1555,1046],{"class":243},[171,1557,1559],{"class":239,"line":1558},105,[171,1560,677],{"emptyLinePlaceholder":676},[171,1562,1564,1567,1570,1572,1574,1577,1579,1582,1584,1586,1589],{"class":239,"line":1563},106,[171,1565,1566],{"class":246},"    Write-Host",[171,1568,1569],{"class":257}," \"Resolved group '",[171,1571,1512],{"class":243},[171,1573,1352],{"class":257},[171,1575,1576],{"class":250},"$",[171,1578,398],{"class":257},[171,1580,1581],{"class":243},"$group",[171,1583,683],{"class":257},[171,1585,1335],{"class":246},[171,1587,1588],{"class":257},"].Id)",[171,1590,1358],{"class":257},[171,1592,1594],{"class":239,"line":1593},107,[171,1595,677],{"emptyLinePlaceholder":676},[171,1597,1599,1602],{"class":239,"line":1598},108,[171,1600,1601],{"class":250},"    @",[171,1603,1604],{"class":243},"{\n",[171,1606,1608,1611,1613,1615],{"class":239,"line":1607},109,[171,1609,1610],{"class":243},"        target ",[171,1612,389],{"class":250},[171,1614,982],{"class":250},[171,1616,1604],{"class":243},[171,1618,1620,1623,1625],{"class":239,"line":1619},110,[171,1621,1622],{"class":257},"            '@odata.type'",[171,1624,695],{"class":250},[171,1626,1627],{"class":243}," $targetType\n",[171,1629,1631,1634,1636,1639,1641],{"class":239,"line":1630},111,[171,1632,1633],{"class":243},"            groupId       ",[171,1635,389],{"class":250},[171,1637,1638],{"class":243}," $group[",[171,1640,1335],{"class":246},[171,1642,1643],{"class":243},"].Id\n",[171,1645,1647],{"class":239,"line":1646},112,[171,1648,1649],{"class":243},"        }\n",[171,1651,1653],{"class":239,"line":1652},113,[171,1654,1046],{"class":243},[171,1656,1658],{"class":239,"line":1657},114,[171,1659,1061],{"class":243},[171,1661,1663],{"class":239,"line":1662},115,[171,1664,677],{"emptyLinePlaceholder":676},[171,1666,1668],{"class":239,"line":1667},116,[171,1669,1670],{"class":440},"# Read the current assignment list so the assign call does not drop anyone.\n",[171,1672,1674,1677,1679,1681],{"class":239,"line":1673},117,[171,1675,1676],{"class":243},"$existingAssignments ",[171,1678,389],{"class":250},[171,1680,982],{"class":250},[171,1682,985],{"class":243},[171,1684,1686],{"class":239,"line":1685},118,[171,1687,677],{"emptyLinePlaceholder":676},[171,1689,1691,1693,1695,1697],{"class":239,"line":1690},119,[171,1692,1072],{"class":250},[171,1694,1075],{"class":243},[171,1696,1078],{"class":250},[171,1698,1699],{"class":243}," $RemoveExisting) {\n",[171,1701,1703,1706,1708,1710,1712,1714,1716,1718,1720,1722,1725,1727],{"class":239,"line":1702},120,[171,1704,1705],{"class":243},"    $current ",[171,1707,389],{"class":250},[171,1709,954],{"class":246},[171,1711,251],{"class":250},[171,1713,1191],{"class":243},[171,1715,1194],{"class":257},[171,1717,1197],{"class":243},[171,1719,1200],{"class":257},[171,1721,1203],{"class":243},[171,1723,1724],{"class":257},"\u002F",[171,1726,1355],{"class":243},[171,1728,1729],{"class":257},"\u002Fassignments\"\n",[171,1731,1733,1736,1738,1740,1743,1745,1747,1749,1752,1755,1757,1760],{"class":239,"line":1732},121,[171,1734,1735],{"class":243},"    $existingAssignments ",[171,1737,389],{"class":250},[171,1739,982],{"class":250},[171,1741,1742],{"class":243},"($current ",[171,1744,414],{"class":250},[171,1746,417],{"class":246},[171,1748,420],{"class":243},[171,1750,1751],{"class":250},"@",[171,1753,1754],{"class":243},"{ target ",[171,1756,389],{"class":250},[171,1758,1759],{"class":246}," $_",[171,1761,1762],{"class":243},".target } })\n",[171,1764,1766,1768,1771,1773,1775,1778,1781],{"class":239,"line":1765},122,[171,1767,1566],{"class":246},[171,1769,1770],{"class":257}," \"Existing assignments preserved: ",[171,1772,1576],{"class":250},[171,1774,398],{"class":257},[171,1776,1777],{"class":243},"$existingAssignments.Count",[171,1779,1780],{"class":257},")",[171,1782,1783],{"class":257},"\"\n",[171,1785,1787],{"class":239,"line":1786},123,[171,1788,1061],{"class":243},[171,1790,1792],{"class":239,"line":1791},124,[171,1793,677],{"emptyLinePlaceholder":676},[171,1795,1797],{"class":239,"line":1796},125,[171,1798,1799],{"class":440},"# De-duplicate on group id so re-running the script is safe.\n",[171,1801,1803,1806,1808,1810,1813],{"class":239,"line":1802},126,[171,1804,1805],{"class":243},"$existingGroupIds ",[171,1807,389],{"class":250},[171,1809,982],{"class":250},[171,1811,1812],{"class":243},"($existingAssignments ",[171,1814,1815],{"class":250},"|\n",[171,1817,1819,1821,1823,1825,1828,1831,1834],{"class":239,"line":1818},127,[171,1820,1214],{"class":246},[171,1822,420],{"class":243},[171,1824,423],{"class":246},[171,1826,1827],{"class":243},".target.ContainsKey(",[171,1829,1830],{"class":257},"'groupId'",[171,1832,1833],{"class":243},") } ",[171,1835,1815],{"class":250},[171,1837,1839,1842,1844,1846],{"class":239,"line":1838},128,[171,1840,1841],{"class":246},"    ForEach-Object",[171,1843,420],{"class":243},[171,1845,423],{"class":246},[171,1847,1848],{"class":243},".target.groupId })\n",[171,1850,1852],{"class":239,"line":1851},129,[171,1853,677],{"emptyLinePlaceholder":676},[171,1855,1857,1860,1862,1864,1867,1869,1872,1874,1876,1879,1882],{"class":239,"line":1856},130,[171,1858,1859],{"class":243},"$newTargets ",[171,1861,389],{"class":250},[171,1863,982],{"class":250},[171,1865,1866],{"class":243},"($groupTargets ",[171,1868,414],{"class":250},[171,1870,1871],{"class":246}," Where-Object",[171,1873,420],{"class":243},[171,1875,423],{"class":246},[171,1877,1878],{"class":243},".target.groupId ",[171,1880,1881],{"class":250},"-notin",[171,1883,1884],{"class":243}," $existingGroupIds })\n",[171,1886,1888,1891,1893,1895,1898,1901],{"class":239,"line":1887},131,[171,1889,1890],{"class":243},"$finalAssignments ",[171,1892,389],{"class":250},[171,1894,982],{"class":250},[171,1896,1897],{"class":243},"($existingAssignments) ",[171,1899,1900],{"class":250},"+",[171,1902,1903],{"class":243}," $newTargets\n",[171,1905,1907],{"class":239,"line":1906},132,[171,1908,677],{"emptyLinePlaceholder":676},[171,1910,1912,1915,1917,1919,1921,1924,1926,1928,1930,1933],{"class":239,"line":1911},133,[171,1913,1914],{"class":243},"$mode ",[171,1916,389],{"class":250},[171,1918,1131],{"class":250},[171,1920,1382],{"class":243},[171,1922,1923],{"class":257},"'exclude'",[171,1925,1149],{"class":243},[171,1927,1152],{"class":250},[171,1929,420],{"class":243},[171,1931,1932],{"class":257},"'include'",[171,1934,1160],{"class":243},[171,1936,1938,1940,1943,1945,1947,1950,1952,1954,1957],{"class":239,"line":1937},134,[171,1939,1344],{"class":246},[171,1941,1942],{"class":257}," \"New group targets added: ",[171,1944,1576],{"class":250},[171,1946,398],{"class":257},[171,1948,1949],{"class":243},"$newTargets.Count",[171,1951,1780],{"class":257},[171,1953,1075],{"class":257},[171,1955,1956],{"class":243},"$mode",[171,1958,1358],{"class":257},[171,1960,1962],{"class":239,"line":1961},135,[171,1963,677],{"emptyLinePlaceholder":676},[171,1965,1967,1969,1972,1974,1976,1979,1982],{"class":239,"line":1966},136,[171,1968,1072],{"class":250},[171,1970,1971],{"class":243}," ($newTargets.Count ",[171,1973,1137],{"class":250},[171,1975,1244],{"class":246},[171,1977,1978],{"class":250}," -and",[171,1980,1981],{"class":250}," -not",[171,1983,1699],{"class":243},[171,1985,1987,1989],{"class":239,"line":1986},137,[171,1988,1566],{"class":246},[171,1990,1991],{"class":257}," \"Nothing to change.\"\n",[171,1993,1995],{"class":239,"line":1994},138,[171,1996,1997],{"class":250},"    return\n",[171,1999,2001],{"class":239,"line":2000},139,[171,2002,1061],{"class":243},[171,2004,2006],{"class":239,"line":2005},140,[171,2007,677],{"emptyLinePlaceholder":676},[171,2009,2011,2014,2016,2018,2021,2023,2026,2028,2031,2033,2036],{"class":239,"line":2010},141,[171,2012,2013],{"class":243},"$body ",[171,2015,389],{"class":250},[171,2017,982],{"class":250},[171,2019,2020],{"class":243},"{ assignments ",[171,2022,389],{"class":250},[171,2024,2025],{"class":243}," $finalAssignments } ",[171,2027,414],{"class":250},[171,2029,2030],{"class":246}," ConvertTo-Json",[171,2032,251],{"class":250},[171,2034,2035],{"class":243},"Depth ",[171,2037,2038],{"class":246},"10\n",[171,2040,2042],{"class":239,"line":2041},142,[171,2043,677],{"emptyLinePlaceholder":676},[171,2045,2047,2049,2051,2054,2057,2059,2062,2064,2066,2069,2071,2074],{"class":239,"line":2046},143,[171,2048,1072],{"class":250},[171,2050,1075],{"class":243},[171,2052,2053],{"class":246},"$PSCmdlet",[171,2055,2056],{"class":243},".ShouldProcess($PolicyName",[171,2058,275],{"class":250},[171,2060,2061],{"class":257}," \"Assign ",[171,2063,1576],{"class":250},[171,2065,398],{"class":257},[171,2067,2068],{"class":243},"$finalAssignments.Count",[171,2070,1780],{"class":257},[171,2072,2073],{"class":257}," target(s)\"",[171,2075,1086],{"class":243},[171,2077,2079,2082,2084,2087,2089,2091,2093,2095,2098,2100,2103,2105,2108,2110,2113],{"class":239,"line":2078},144,[171,2080,2081],{"class":246},"    Invoke-MgGraphRequest",[171,2083,251],{"class":250},[171,2085,2086],{"class":243},"Method POST ",[171,2088,266],{"class":250},[171,2090,1191],{"class":243},[171,2092,1194],{"class":257},[171,2094,1197],{"class":243},[171,2096,2097],{"class":257},"\u002FdeviceAppManagement\u002FmanagedAppPolicies\u002F",[171,2099,1355],{"class":243},[171,2101,2102],{"class":257},"\u002Fassign\"",[171,2104,251],{"class":250},[171,2106,2107],{"class":243},"Body $body ",[171,2109,266],{"class":250},[171,2111,2112],{"class":243},"ContentType ",[171,2114,2115],{"class":257},"\"application\u002Fjson\"\n",[171,2117,2119,2121,2124,2126,2128,2130,2132,2135,2137],{"class":239,"line":2118},145,[171,2120,1566],{"class":246},[171,2122,2123],{"class":257}," \"Assignment updated: ",[171,2125,1576],{"class":250},[171,2127,398],{"class":257},[171,2129,2068],{"class":243},[171,2131,1780],{"class":257},[171,2133,2134],{"class":257}," target(s) on '",[171,2136,1265],{"class":243},[171,2138,1268],{"class":257},[171,2140,2142],{"class":239,"line":2141},146,[171,2143,1061],{"class":243},[31,2145,2147],{"id":2146},"notes","Notes",[36,2149,2150,2167,2186,2193,2199,2210],{},[39,2151,2152,2153,2155,2156,2159,2160,2163,2164,29],{},"The request body of ",[15,2154,17],{}," is the full ",[15,2157,2158],{},"assignments"," collection, and Microsoft's reference gives no merge option. Post only the new group and the other assignments are gone. Always read ",[15,2161,2162],{},"...\u002Fassignments"," first unless you deliberately want ",[15,2165,2166],{},"-RemoveExisting",[39,2168,2169,2170,47,2172,2174,2175,2177,2178,2181,2182,2185],{},"Endpoint choice: v1.0 documents the list and assignments calls under ",[15,2171,156],{},[15,2173,159],{},", and the ",[15,2176,17],{}," action under ",[15,2179,2180],{},"\u002FdeviceAppManagement\u002FmanagedAppPolicies\u002F{id}\u002Fassign",", which is what the script posts to. Microsoft recommends v1.0 over ",[15,2183,2184],{},"\u002Fbeta"," for Intune where both exist, because beta changes more often.",[39,2187,2188,2189,2192],{},"The v1.0 list call doesn't document ",[15,2190,2191],{},"$filter"," support, so the script pulls the collection and matches the display name locally. With a few dozen policies that's one or two requests.",[39,2194,2195,2196,2198],{},"Existing assignment targets are copied as-is, including any ",[15,2197,196],{}," entries, so current exclusions survive the merge. De-duplication only compares group ids: a group that is already included won't also be added as an exclusion. Remove it in the console first if that's what you want.",[39,2200,2201,2202,2205,2206,2209],{},"The script doesn't touch Device Configuration profiles or Compliance Policies. Those use different resources (",[15,2203,2204],{},"deviceConfigurations",", ",[15,2207,2208],{},"deviceCompliancePolicies",") with their own assign actions.",[39,2211,2212,2213,2215],{},"Write limits: Microsoft's documented Intune Graph limit is 100 POST\u002FPUT\u002FPATCH\u002FDELETE requests per 20 seconds per app per tenant. One policy is one ",[15,2214,17],{}," call, so you only get near that if you loop the script over hundreds of policies.",[31,2217,2219],{"id":2218},"source","Source",[36,2221,2222,2231,2238,2245,2257,2263],{},[39,2223,2224],{},[2225,2226,2230],"a",{"href":2227,"rel":2228},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fintune-mam-targetedmanagedappprotection-assign?view=graph-rest-1.0",[2229],"nofollow","assign action (targetedManagedAppProtection), Graph v1.0",[39,2232,2233],{},[2225,2234,2237],{"href":2235,"rel":2236},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fintune-mam-iosmanagedappprotection-list?view=graph-rest-1.0",[2229],"List iosManagedAppProtections, Graph v1.0",[39,2239,2240],{},[2225,2241,2244],{"href":2242,"rel":2243},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fintune-mam-targetedmanagedapppolicyassignment-list?view=graph-rest-1.0",[2229],"List targetedManagedAppPolicyAssignments, Graph v1.0",[39,2246,2247,47,2252,2256],{},[2225,2248,2251],{"href":2249,"rel":2250},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fresources\u002Fintune-shared-groupassignmenttarget?view=graph-rest-1.0",[2229],"groupAssignmentTarget",[2225,2253,196],{"href":2254,"rel":2255},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fapi\u002Fresources\u002Fintune-shared-exclusiongroupassignmenttarget?view=graph-rest-1.0",[2229]," resource types",[39,2258,2259],{},[2225,2260,76],{"href":2261,"rel":2262},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fpowershell\u002Fmodule\u002Fmicrosoft.graph.groups\u002Fget-mggroup?view=graph-powershell-1.0",[2229],[39,2264,2265],{},[2225,2266,2269],{"href":2267,"rel":2268},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fgraph\u002Fthrottling-limits",[2229],"Microsoft Graph throttling limits (Intune)",[2271,2272,2273],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}",{"title":234,"searchDepth":395,"depth":395,"links":2275},[2276,2277,2278,2279,2280,2281],{"id":33,"depth":395,"text":34},{"id":89,"depth":395,"text":90},{"id":223,"depth":395,"text":224},{"id":429,"depth":395,"text":430},{"id":2146,"depth":395,"text":2147},{"id":2218,"depth":395,"text":2219},"techcolumnist",[2284,2285],"ps","scripts","2025-04-17T14:00:00Z","A Microsoft Graph PowerShell script that adds Entra ID groups to an Intune App Protection Policy through the v1.0 assign action without dropping existing assignments.","md",false,null,{},"\u002Fblog\u002F2025\u002F04\u002F17\u002Fpowershell-intune-bulk-assign-app-protection-policies-by-group",{"title":6,"description":2287},[2282],"blog\u002F2025\u002F04\u002F17\u002Fpowershell-intune-bulk-assign-app-protection-policies-by-group",[233,2297,2298],"intune","entra-id","\u002F2025\u002F04\u002F17\u002Fpowershell-intune-bulk-assign-app-protection-policies-by-group\u002F","ozUcuHkB0-UcYvBrwVpvA9lCtcXE9wO3Ffhuuj5zYeI",{"title":2302,"description":2303,"date":2304,"url":2305,"categories":2306,"tags":2307,"image":2290,"readingTime":465,"canonical":2282,"sites":2309,"series":2290,"seriesOrder":2290},"PowerShell: Azure – Rotate Storage Account Access Keys on a Schedule","A runbook-ready script that regenerates the older of a storage account's two access keys, using KeyCreationTime, and writes the new connection string to Key Vault.","2025-04-24T14:00:00Z","\u002F2025\u002F04\u002F24\u002Fpowershell-azure-rotate-storage-account-access-keys-on-a-schedule\u002F",[2284,2285],[233,2308],"azure",[2282],{"title":2311,"description":2312,"date":2313,"url":2314,"categories":2315,"tags":2316,"image":2290,"readingTime":457,"canonical":2282,"sites":2320,"series":2290,"seriesOrder":2290},"PowerShell: Windows Server – Tune the TCP Stack for 10GbE Workloads","A PowerShell script that audits and tunes RSS, RSC, checksum\u002FLSO offloads, jumbo frames and TCP autotuning on Windows Server 10GbE adapters, and flags ignored legacy tweaks.","2025-04-10T14:00:00Z","\u002F2025\u002F04\u002F10\u002Fpowershell-windows-server-optimize-the-tcp-stack-for-10gbe-workloads\u002F",[2284,2285],[233,2317,2318,2319],"windows","tcp","network",[2282],[2322,2333,2341],{"title":2323,"description":2324,"date":2325,"url":2326,"categories":2327,"tags":2328,"image":2290,"readingTime":465,"canonical":2282,"sites":2332,"series":2290,"seriesOrder":2290},"PowerShell: Windows 11 – Strip Preinstalled Apps from an Image","A PowerShell script that removes provisioned apps from a mounted Windows 11 WIM or a running system, plus the Windows 11 24H2+ policy that does it natively.","2025-11-05T14:00:00Z","\u002F2025\u002F11\u002F05\u002Fpowershell-windows-11-strip-preinstalled-apps-from-a-deployment-image\u002F",[2284,2285],[233,2329,2330,2331,2297],"windows-11","debloat","gpo",[2282],{"title":2334,"description":2335,"date":2336,"url":2337,"categories":2338,"tags":2339,"image":2290,"readingTime":451,"canonical":2282,"sites":2340,"series":2290,"seriesOrder":2290},"PowerShell: Intune – Force Compliance Re-Evaluation Fleet-Wide","A Microsoft Graph PowerShell script that sends the syncDevice action to every matching Intune-managed device, throttled, so compliance is re-evaluated at once.","2025-10-22T14:00:00Z","\u002F2025\u002F10\u002F22\u002Fpowershell-intune-force-a-compliance-policy-re-evaluation-fleet-wide\u002F",[2284,2285],[233,2297],[2282],{"title":2342,"description":2343,"date":2344,"url":2345,"categories":2346,"tags":2347,"image":2290,"readingTime":471,"canonical":2282,"sites":2348,"series":2290,"seriesOrder":2290},"PowerShell: Intune – Remediation Script for Stuck BitLocker Encryption","An Intune Remediations detect and remediate pair that finds paused, suspended or stalled BitLocker encryption on Windows and fixes the cases that have a documented fix.","2025-09-10T14:00:00Z","\u002F2025\u002F09\u002F10\u002Fpowershell-intune-remediation-script-for-stuck-bitlocker-encryption\u002F",[2284,2285],[233,2297,2317],[2282],{"doc":2290,"posts":2350},[],1790052512564]