While doing some Intune automation the other day I got stuck on trying to assign a script to a group.
Using the graph API documentation sent me on a wild goose chase so just wanted to write a small writeup if someone else ran into the same problem.
This post will only focus on how to properly format the JSON to assign a device management script to an already existing group. It will not describe how to connect to the graph API, there are plenty of resources for that.
MS documentation is here:
https://docs.microsoft.com/en-us/graph/api/intune-shared-devicemanagementscript-assign?view=graph-rest-beta
This "function" is still under the beta tag which could explain the poor documentation and also beware that anything under beta can be changed so be careful and only use in a lab.
According to this you could either use an odata.type of #microsoft.graph.deviceManagementScriptGroupAssignment or #microsoft.graph.deviceManagementScriptAssignment.
When using the #microsoft.graph.deviceManagementScriptGroupAssignment there does not seem to be a way to add excluded groups (non that I could figure out anyway and the documentation wasn't really any help).
Adding 2 groups and 1 exclude group in the Intune portal:

Using developer mode in Edge tells you that the Intune portal uses the #microsoft.graph.deviceManagementScriptAssignment with the URI https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/{deviceManagementScriptId}/assign. It also shows the payload that was sent to add these 3 groups:

The JSON formatted:
It also shows if you already have one (or more groups) assigned, adding a new one will actually enumerate all the old ones, add the new one to the list and write everything again. This means that if you do not check for current assignments and just add your group all old ones will be gone!!
The ID of the script can be found in the url after browsing to the script (it can of course be retrieved via Graph as well).

The ID of the group is found on the group overview:

Putting it into a script
But before we can set a new assignment we first need to enumerate all current ones:
$assignmentsuri = "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/$ScriptID/assignments"
$Respons = (Invoke-RestMethod -Uri $assignmentsuri -Headers $authToken -Method Get).value
Then we need to rebuild a new JSON based on the old groups:
$requestBody = @{
deviceManagementScriptAssignments = @()
}
#Check if there already are assigned groups to the script
if ($Respons) {
foreach ($group in $($Respons)) {
# Get group assignment
if ($group.target."@odata.type" -eq "#microsoft.graph.groupAssignmentTarget") {
# Verify so the new groupID isn't already assigned.
if (!$group.target.groupId -eq $groupID) {
$requestBody.deviceManagementScriptAssignments += @{
"target" = $group.target
}
}
else {
Write-Warning "A group with ID=$groupID is already assigned to '$ScriptID'"
}
}
# Get exclusion group assignment
if ($group.target."@odata.type" -eq "#microsoft.graph.exclusionGroupAssignmentTarget") {
$requestBody.deviceManagementScriptAssignments += @{
"target" = $group.target
}
}
}
}
Make sure the new group isn't already assigned and also check for any exclude groups.
Then add the new group:
$requestBody.deviceManagementScriptAssignments += @{
"target" = @{
"@odata.type" = "#microsoft.graph.groupAssignmentTarget"
"groupId" = "$groupID"
}
}
This will create a JSON that looks like this:
{
"deviceManagementScriptAssignments": [
{
"target": {
"@odata.type": "#microsoft.graph.exclusionGroupAssignmentTarget",
"deviceAndAppManagementAssignmentFilterId": null,
"deviceAndAppManagementAssignmentFilterType": "none",
"groupId": "2f79f598-d2c3-49a2-928a-00aa9dcec099"
}
},
{
"target": {
"@odata.type": "#microsoft.graph.groupAssignmentTarget",
"deviceAndAppManagementAssignmentFilterId": null,
"deviceAndAppManagementAssignmentFilterType": "none",
"groupId": "7c1bd75a-61dd-47c9-aee4-84865ef2f9a8"
}
},
{
"target": {
"@odata.type": "#microsoft.graph.groupAssignmentTarget",
"groupId": "d4e11197-c81b-4f07-891a-1262c89bb648"
}
}
]
}
The parameters deviceAndAppManagementAssignmentFilterId and deviceAndAppManagementAssignmentFilterType is fetched from the current assignments. These can be used but is not required as can be seen in the last target group (which is the group being added).
And finally POST it back to graph:
$restore = $requestBody | ConvertTo-Json -Depth 99
$assignuri = "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts/$ScriptID/assign"
Invoke-RestMethod -Uri $assignuri -Headers $authToken -Method post -Body $restore -ContentType "application/json; charset=utf-8"
And in the portal everything now looks as expected!

The complete script can be found here:
Set-IntuneDeviceManangementScriptAssignment.ps1 at github.com
This is just an example but hopefully it helps someone!
/Matt
Twitter: matbg