Posted on 12-20-2018 11:29 AM
Background information: I need to mass remove all devices from all groups via api
I've been reading through all the API Calls available from jamfs /api page, i've come to the conclusion if it would be anywhere, it would be here
[https://ENTERJSS.URLHERE] :8443/api/#!/mobiledevicecommands/createMobileDeviceCommandURL_post
but via "Delete" (assuming a Remove From Groups Option is an available command) instead of "Post" but "Post" is all that's available. Am I missing something?
Does anyone know of a way to remove an iOS Device from all static groups via API Call?
Thank you
Solved! Go to Solution.
Posted on 01-08-2019 08:04 AM
@Hugonaut I came up with a script for you that will take a mobile device ID and remove it from any static groups it is a member of. You really need a good XML parser to make this easier, I prefer xmlstarlet and this script leverages that. To install xmlstarlet you can install homebrew using this command:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Then install xmlstarlet with this command:
brew install xmlstarlet
Here is the script:
#!/bin/bash
# written by Ryan Ball
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
jssURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url | sed s'/.$//')
outputDir="/Users/$loggedInUser/Documents/Export_$(date +%m-%d-%Y)"
# Make sure xmlstarlet is installed
if ! which xmlstarlet ; then
echo "You must install xmlstarlet before using this script."
echo "Try "brew install xmlstarlet""
exit 1
fi
clear
echo -n "Enter JSS Username: "
read -r jssUser
clear
echo -n "Enter $jssUser's Pass: "
read -r -s jssPass
clear
echo -n "Enter the Mobile Device ID that you want to remove from Static Groups: "
read -r deviceID
read -r -p "Are you sure you want to remove Mobile Device with ID $deviceID from all Static Groups? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "Continuing..."
else
echo "Done!"
exit 0
fi
mkdir -p "$outputDir"
echo "Getting list of groups for device with ID $deviceID..."
deviceGroupIDs=($(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevices/id/$deviceID" | xmlstarlet sel -t -v '//mobile_device/mobile_device_groups/mobile_device_group/id')) # | xmlstarlet sel -t -m "/mobile_device_groups/mobile_device_group[is_smart='false']" -v id -n))
echo "Getting list of Static mobile device groups..."
staticGroupIDs+=($(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups" | xmlstarlet sel -t -m "/mobile_device_groups/mobile_device_group[is_smart='false']" -v id -n))
echo "Determining Group membership..."
staticGroupsTheDeviceIsIn=($(echo "${staticGroupIDs[@]}" "${deviceGroupIDs[@]}" | tr ' ' '
' | sort | uniq -d))
echo "Device ID $deviceID is in ${#deviceGroupIDs[@]} groups total; ${#staticGroupsTheDeviceIsIn[@]} of which are Static."
sleep 3
for id in "${staticGroupsTheDeviceIsIn[@]}"; do
echo "Obtaining name of mobile device Static Group with ID: $id"
groupName=$(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" | xmlstarlet sel -t -v '//mobile_device_group/name')
if [[ -n "$groupName" ]]; then
echo "Writing XML of mobile device Static Group "$groupName" to the output file..."
curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" -o "${outputDir}/Backup_${id}_${groupName}.xml"
if [[ -f "${outputDir}/Backup_${id}_${groupName}.xml" ]]; then
modifiedXML=$(xmlstarlet ed -d '//mobile_device[id='"$deviceID"']' "${outputDir}/Backup_${id}_${groupName}.xml")
putXML=$(curl -X PUT -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" -H "Content-Type: text/xml" -d "$modifiedXML" 2> /dev/null)
if [[ -n "$putXML" ]]; then
echo "Success; Static Group "$groupName" (ID $id) was successfully modified."
else
echo "Error; failed to modify Static Group "$groupName" (ID $id)."
sleep 1
fi
else
echo "Error; could not write XML data locally."
sleep 1
fi
else
echo "Error; can't GET name of Static Group with ID: $id"
sleep 1
fi
done
echo "Done!"
exit 0
Enjoy!
Posted on 12-20-2018 11:39 AM
If you are referring to smart groups, you would not be able to do that as smart groups are populated dynamically based on attributes of the device; i.e. apps installed, username, building, etc.
To remove a device from all static groups, you'd need to get the ID of the device, loop through all the static groups and check to see if the device is in each group, get the xml of the static group if the device's ID is detected in the group, remove it from the XML, then PUT the new XML for the static group.
Posted on 12-20-2018 11:48 AM
@ryan.ball brilliant, you're good man! so, i dont need to check against it, BUT I will go ahead and overwrite the xml with a blank slate. I will test this, thank you!
Posted on 12-20-2018 12:03 PM
I would assume the XML you'd need to modify would be the static group's XML, not the device's.
Posted on 12-21-2018 05:06 AM
@ryan.ball really appreciate it, outside of the box thinking, you always come through with great solutions.
Posted on 12-27-2018 08:05 AM
@ryan.ball any idea where a static groups xml sheet would be located?! I'm having trouble locating it
Posted on 12-27-2018 10:36 AM
@Hugonaut you can do a GET call to pull down an xml file of the static groups. or go to https://yourjamfproserver.company.com:8443/api and run the Try Out process to get the XML response. You would need the name or ID for this though.
/JSSResource/mobiledevicegroups/id/{id}
/JSSResource/mobiledevicegroups/name/{name}
If you don't have a list of all static group names or IDs you could use
/JSSResource/mobiledevicegroups
and look for
<is_smart>false</is_smart>
could be useful to feed your script the static groups that you are trying to zero out.
Also if you are in the macadmins Slack workspace, you can check #jss-api channel for help as well.
Posted on 12-27-2018 11:27 AM
Thank you @exno i'm familiar with that part and know where to look as far as the url goes - :8443/JSSResource/mobiledevicegroups/id/## -
I just want to know where that darn sheet lives! and if it doesn't "live" somewhere accessible, how to replace it with a blank slate and containing no devices
Posted on 01-08-2019 08:04 AM
@Hugonaut I came up with a script for you that will take a mobile device ID and remove it from any static groups it is a member of. You really need a good XML parser to make this easier, I prefer xmlstarlet and this script leverages that. To install xmlstarlet you can install homebrew using this command:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Then install xmlstarlet with this command:
brew install xmlstarlet
Here is the script:
#!/bin/bash
# written by Ryan Ball
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
jssURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url | sed s'/.$//')
outputDir="/Users/$loggedInUser/Documents/Export_$(date +%m-%d-%Y)"
# Make sure xmlstarlet is installed
if ! which xmlstarlet ; then
echo "You must install xmlstarlet before using this script."
echo "Try "brew install xmlstarlet""
exit 1
fi
clear
echo -n "Enter JSS Username: "
read -r jssUser
clear
echo -n "Enter $jssUser's Pass: "
read -r -s jssPass
clear
echo -n "Enter the Mobile Device ID that you want to remove from Static Groups: "
read -r deviceID
read -r -p "Are you sure you want to remove Mobile Device with ID $deviceID from all Static Groups? [y/N] " response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]
then
echo "Continuing..."
else
echo "Done!"
exit 0
fi
mkdir -p "$outputDir"
echo "Getting list of groups for device with ID $deviceID..."
deviceGroupIDs=($(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevices/id/$deviceID" | xmlstarlet sel -t -v '//mobile_device/mobile_device_groups/mobile_device_group/id')) # | xmlstarlet sel -t -m "/mobile_device_groups/mobile_device_group[is_smart='false']" -v id -n))
echo "Getting list of Static mobile device groups..."
staticGroupIDs+=($(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups" | xmlstarlet sel -t -m "/mobile_device_groups/mobile_device_group[is_smart='false']" -v id -n))
echo "Determining Group membership..."
staticGroupsTheDeviceIsIn=($(echo "${staticGroupIDs[@]}" "${deviceGroupIDs[@]}" | tr ' ' '
' | sort | uniq -d))
echo "Device ID $deviceID is in ${#deviceGroupIDs[@]} groups total; ${#staticGroupsTheDeviceIsIn[@]} of which are Static."
sleep 3
for id in "${staticGroupsTheDeviceIsIn[@]}"; do
echo "Obtaining name of mobile device Static Group with ID: $id"
groupName=$(curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" | xmlstarlet sel -t -v '//mobile_device_group/name')
if [[ -n "$groupName" ]]; then
echo "Writing XML of mobile device Static Group "$groupName" to the output file..."
curl -X GET -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" -o "${outputDir}/Backup_${id}_${groupName}.xml"
if [[ -f "${outputDir}/Backup_${id}_${groupName}.xml" ]]; then
modifiedXML=$(xmlstarlet ed -d '//mobile_device[id='"$deviceID"']' "${outputDir}/Backup_${id}_${groupName}.xml")
putXML=$(curl -X PUT -s -u "$jssUser:$jssPass" "$jssURL/JSSResource/mobiledevicegroups/id/$id" -H "Content-Type: text/xml" -d "$modifiedXML" 2> /dev/null)
if [[ -n "$putXML" ]]; then
echo "Success; Static Group "$groupName" (ID $id) was successfully modified."
else
echo "Error; failed to modify Static Group "$groupName" (ID $id)."
sleep 1
fi
else
echo "Error; could not write XML data locally."
sleep 1
fi
else
echo "Error; can't GET name of Static Group with ID: $id"
sleep 1
fi
done
echo "Done!"
exit 0
Enjoy!
Posted on 01-10-2019 07:04 AM
Thank you very much! You're the man, Jamf really needs some kind of point system on the forum! haha
Gonna put this to work.