Delete user from multiple classes in one go.

conitsupport
Contributor

Is it possible to remove the user from all of their enrolled classes at once? (as it takes 7 clicks and a paste of the user name in the search box, to remove a user from one class and if they are in 15 classes which many of our users are this is very time consuming)

4 REPLIES 4

m_donovan
Contributor III

I would think that you could accomplish this using the API. This also depends on how comfortable/familiar you are running scripts against your JSS API. There may be someone that already has a script for this (anyone have one?) or modifying an existing script shouldn't be terribly difficult. If you would like to look into this let me know and I will see what I can find.

conitsupport
Contributor

Sure that would be great, we haven't got any API's as yet and its very time consuming removing one user at a time from classes, sometimes we are lucky and one or two users are in same classes, but still very long winded.

m_donovan
Contributor III

So removing all students from a given class is relatively easy. I assume from your original post that you are wanting to only remove select students from multiple classes. Are your students added individually to classes or are they added as a group of students to a class?

m_donovan
Contributor III

Here is a script that I have working in my environment. It assumes the students to be removed were added individually to the class. I tested it against roughly 50 classes searching for 3 users that were in only 2 of the classes. It took approximately 2 mins to find and remove the 3 users from the classes they were in. Depending on the size of your environment and the number of users you are searching for it could take significantly longer. There are more than likely more efficient ways to accomplish this task. I am learning scripting by doing so this is what I came up with and if anyone has any other ideas I would love to hear them. As with anything you use in the JSS you need to test this in your environment before using it in mass as it may not have the desired outcome for you.

#!/bin/bash

## Remove_a_user_from_multiple_classes.sh
## Author:  Mike Donovan (mike.donovan@killeenisd.org)
## Created: 30 June 2017

##########################################################################################
#
#   This script was built with heavy reliance on other scripts from Mike Morales
#   as well as others. 
#
#   Although it works in my environment it may not work in yours. DO NOT RUN in your
#   production environment until you have thoroughly tested it and feel confident 
#   about its use.
#
#   You will need a CSV file with a single column of JSS user ID's with no header.
#   There should be no spaces in the name of the CSV file and it is best if it is 
#   located on the desktop.
#
##########################################################################################

##########################################################################################
#       USER DEFINABLE VARIABLES INPUT YOUR ENVIRONMENTS VALUES
##########################################################################################
apiuser="yourapiuser"
apipass="yourapipass"
## Set the JSS URL !! NO TRAILING SLASH !!
jssurl="https://your_org.com:8443"
##########################################################################################
#       USER DEFINABLE VARIABLES INPUT YOUR ENVIRONMENTS VALUES
##########################################################################################

##########################################################################################
#       FUNCTION TO REMOVE A SPECIFIED STUDENT ID FROM ALL CLASSES DO NOT EDIT
##########################################################################################
removeFromClass(){

    removeID=$1 ## Variable passed in with function call

    ## Verify API user credentials are present
    if [[ "$apiuser" != "" ]] && [[ "$apipass" != "" ]]; then

        #Get a list of all class ID's
        classIDList=$(curl -H "Accept: text/xml" -sfku "${apiuser}:${apipass}" "${jssurl}/JSSResource/classes" -X GET 2>/dev/null | xmllint --format - | grep -B1 "<name>" | awk -F'>|<' '/<id>/{print $3}')

        #store the list of ID's in an array
        declare -a arrayOfIDList=($classIDList)

        #iterate through the array of ID's checking each ID for the presence of the remove ID.
        for idInList in "${arrayOfIDList[@]}"; do

            ## Get the contents of the Student ID tags this should skip any class that does not have individually added students check to see if the remove ID is present
            classData=$(curl -H "Accept: text/xml" -sfku "${apiuser}:${apipass}" "${jssurl}/JSSResource/classes/id/${idInList}" -X GET | xmllint --format - | awk '/<student_ids>/,/</student_ids>/' | grep "$removeID")

            # If the remove ID was present 
            if [ ! -z "$classData" ];then
                echo "Class $idInList contains $removeID"
                # Get entire contents of the identified classes XML from the JSS and export to a file in the tmp directory
                curl -H "Accept: text/xml" -sfku "${apiuser}:${apipass}" "${jssurl}/JSSResource/classes/id/${idInList}" -X GET | xmllint --format - > "/private/tmp/${idInList}.xml"
                ## Create the start of the update XML file
                echo "<class>" > "/tmp/${idInList}mod.xml"
                # Pull out only the information between the <student_ids> tags then remove any line containing the remove ID finally append to the mod file.
                sed -n '/<student_ids>/,/</student_ids>/p' "/tmp/${idInList}.xml" | awk "!/$removeID/" >> "/tmp/${idInList}mod.xml"
                # Append a closing </class> tag to the end of the mod file
                echo "</class>" >> "/tmp/${idInList}mod.xml"

                ## Upload the mod file to the JSS. The use of PUT will update the existing record for the class with the specified ID.
                curl -sku "${apiuser}:${apipass}" "${jssurl}/JSSResource/classes/id/${idInList}" -T "/tmp/${idInList}mod.xml" -X PUT 2>&1 > /dev/null

                ## Check to see if we got a 0 exit status from the PUT command
                if [ $? == 0 ]; then
                    #if all is well
                    echo "Class "$idInList" was modified."
                else
                    # if something went wrong with upload
                    echo "Class Modification failed"
                    ## Clean up the xml file
                    #rm -f "/tmp/${idInList}mod.xml" ### may want to keep this file for troubleshooting###
                    exit 1
                fi
                    ## everything checks out  
                    ## Clean up the xml file
                    rm -f "/tmp/${idInList}mod.xml"

            fi
        done

    fi
}
##########################################################################################
#       FUNCTION TO REMOVE A SPECIFIED STUDENT ID FROM ALL CLASSES
##########################################################################################

##########################################################################################
#       MAIN SCRIPT EXECUTION DO NOT EDIT
##########################################################################################

##################Select input file 
file=$(/usr/bin/osascript << EOF
POSIX path of (choose file with prompt "Select the CSV file that contains the user ID's")
EOF)
if [ "$file" == "false" ]; then
    echo "User exited."
    exit 0
elif [ -z "$file" ]; then
    echo "File is empty"
    # No file was selected
    osascript -e 'Tell application "System Events" to display alert "You must select a file. Exiting script now..." as warning'
    exit 1 # exit with an error status
fi

#Verify we can read the file
data=$(cat $file)
if [[ "$data" == "" ]]; then
    echo "Unable to read the file path specified"
    echo "Ensure there are no spaces and that the path is correct"
    exit 1
fi

#Get a count of items in the file
numberOfItems=$(awk -F, 'END {printf "%s
", NR}' $file)
echo "Number of items: " $numberOfItems
#Set a counter for the loop
itemCounter="0"

#Iterate through the file one line at a time
while [ $itemCounter -lt $numberOfItems ]; do

    itemCounter=$[$itemCounter+1]
    line=$(echo "$data" | head -n $itemCounter | tail -n 1)
    stuID=$(echo "$line" | awk -F , '{print}' | tr -d '
') # "tr -d '
'" Removes trailing carriage return

    removeFromClass $stuID # Call function and pass it the student ID read from the CSV file

done

##########################################################################################
#       MAIN SCRIPT EXECUTION DO NOT EDIT
##########################################################################################

exit 0 # We get here if everything worked as expected