API assign computers from group X to Site Y

ChupSuy
New Contributor III

Hi All,

I'm trying to automate the actual Computer to Site assignment via API as we keep on having Computers assigned to wrong Sites.. :) So far I have not had much success, does anyone maybe have an idea how to tackle this?

1 ACCEPTED SOLUTION

ChupSuy
New Contributor III

As promised, here my complete script to Bulk Update all Computer Group members to Site Y...
I hope it can be of help to others as well...

The script is tested in our companies JSS environment and multiple groups with a large count of nodes, however, the execution of any script is on your own risk.

#!/bin/bash

# ################################################################################################################################################
#               
# Script Name:  API_GroupComputersToSite.sh
#
# Author:       Sven Ramm
# Date:         02/13/2017
# Version:      1.0
#               
# Purpose:      Bulk assign all Computer members of group X to Site Y
#
# Changes:      - 02/13/2017
#                   - Script creation
# ################################################################################################################################################

## Change these 3 variables to match your setup. API account must have API write privs
apiUser="YourAPIUser"
apiPass="Your API User Password"
jssURL="https://YourJSS.com:8443"
# ################################################################################################################################################

tmpXML="/tmp/site_location.xml"
logFile="/var/log/JAMF_API.log"

if [[ -z "$apiUser" ]] || [[ -z "$apiPass" ]] || [[ -z "$jssURL" ]]; then
    echo "The API username, password or JSS URL were not specified in the script. Please add these details and try again."
    exit 1
fi

# ################################################################################################################################################
# ################################################################################################################################################

# Function to provide logging of the script's actions to
# the log file defined by the logFile variable
Logging(){

    DATE=`date +%Y-%m-%d %H:%M:%S`
    LOG="$logFile"

    echo "$DATE" " $1" >> $LOG

}

# Function to create the basic XML informations to be PUT via API
WriteUpdateXML () {

    local SiteID=$1
    local SiteName=$2

    ## Create the xml for upload via API
    echo "<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <computer>
        <general>
            <site>
                <id>$SiteID</id>
                <name>$SiteName</name>
            </site>
        </general>
    </computer>" > "$tmpXML"

}

# Function to Find ALL computers in a Group and assign these to a given Site
AssignGroupComputersToSite () {

    local GroupID=$1
    local SiteID=$2
    local SiteName=$3

    Logging "Group ID: $GroupID" 
    Logging "Site ID: $SiteID"
    Logging "Site Name: $SiteName"

    echo "Please wait & be patience..." 
    echo "You may monitor any progress in $logFile"
    echo "Assigning Computers of Group ID: $GroupID, to Site $SiteName"

    # Write tmp XML file
    WriteUpdateXML "$SiteID" "$SiteName"

    #GET API Resources from
    local APIResource="/JSSResource/computergroups/id/$GroupID"

    # Get ALL Computers which are members in SmartGroup 
    local ComputersInGroup_XML=`/usr/bin/curl -X GET -H"Accept: application/xml" -s -u "$apiUser:$apiPass"  ${jssURL%/}${APIResource}`
    local COUNT=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/size/text()" 2> /dev/null`

    # Loop through the X results
    for (( INDEX=1; INDEX<=$COUNT; INDEX++ )); do
        COMPUTER_ID=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/computer[$INDEX]/id/text()" 2> /dev/null`
        COMPUTER_NAME=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/computer[$INDEX]/name/text()" 2> /dev/null`

        AssignGroupComputersToSite=$(curl -sfku "${apiUser}":"${apiPass}" "${jssURL}/JSSResource/computers/id/${COMPUTER_ID}" -T "$tmpXML" -X PUT)
        if [ $? == 0 ]; then
            Logging "Count: $INDEX Successful updated Site data for: $COMPUTER_NAME"
        else
            Logging "Count: $INDEX Failed to update Site data for: $COMPUTER_NAME"  
        fi
        #sleep 0.5
    done

}

# ################################################################################################################################################
# ################################################################################################################################################

# to find ALL Site names & ID's assosiated check the API help @ https://YourJSS.com:8443/api/#!/sites
# to find Group names & assosiated Group ID's check the API help @ https://YourJSS.com:8443/api/#!/computergroups/findComputerGroups_get

# USAGE: AssignGroupComputersToSite "Group ID" "Site ID" "Site Name"

# ################################################################################################################################################
# ################################################################################################################################################

# Empty Log File for today's run
cat /dev/null > $logFile

# ################################################################################################################################################
# ################################################################################################################################################

# Assign members of Group "Example All Berlin Computers" Group ID: 59 to Site ID: 6 Site Name: "Berlin"
Logging "######################################################################"
Logging "START assigning Group Computers to Site                              #"
Logging "######################################################################"

AssignGroupComputersToSite "59" "6" "Berlin"

Logging "######################################################################"
Logging "END assigning Group Computers to Site                                #"
Logging "######################################################################"


exit 0

View solution in original post

5 REPLIES 5

brytox
New Contributor III

It's quite quick to update it, there are a few things to think about.

Do you already know all the sites names and ids, and can all users access all sites.

I've got round that by using a generic user in my scripts that has access to all sites.

I'll post some code for you later in no one else has. (I'm on my phone just now!)

brytox
New Contributor III

Here is a python script that updates the computers site. so long as the user has access to both.

Ive taken this from a tool I made, but it used a fixed site name and id.

import sys, datetime, time, calendar, uuid, csv, base64, urllib2, xml.etree.ElementTree as ET, os, logging
from datetime import datetime

xml_update="""<?xml version="1.0" encoding="UTF-8"?>
<computer>
<general>
<site>
<id>"""+siteid+"""</id>
<name>"""+sitename+"""</name>
</site>
</general>
</computer>"""
try:
    request = urllib2.Request('https://'+mdmurl+'/JSSResource/computers/serialnumber/'+serialnumber)
    request.add_header('Authorization', 'Basic ' + base64.b64encode(username+':'+password))
    request.add_header('Content-Type', 'text/xml')
    request.get_method = lambda: 'PUT'
    response = urllib2.urlopen(request, xml_update)
except Exception, e:
    print "MDM Error"

stevevalle
Contributor III

We do this as part of our DEP enrolment.

All machines start off in the "DEP enrolment" site (specified from the PreStage Enrollment). This site only contains DEP related policies.

As part of the DEP process, we copy an xml file to the /tmp folder of the Mac

<computer>
  <general>
    <site>
      <id>3</id>
      <name>Production</name>
    </site>
  </general>
</computer>

then use a script to change the site

#!/bin/sh

apiURL="https://jss.address.here:8443"
apiUser="username"
apiPass="password"

# Get serial number of Mac so it can be identified in the JSS
serial=$(system_profiler SPHardwareDataType | grep 'Serial Number (system)' | awk '{print $NF}')

# Upload the xml file
curl -sfku $apiUser:$apiPass $apiURL/JSSResource/computers/serialnumber/$serial/subset/general -T /private/tmp/ChangeSite-Production.xml -X PUT

exit 0

then remove the file from the Mac once done.

Hope that helps!

ChupSuy
New Contributor III

thx a lot for your snippets.. :) I'm actually looking for doing Bulk Update.. had a closer look into the API & usage of it and come up with a script.. will post it here as soon as I've completed it..

ChupSuy
New Contributor III

As promised, here my complete script to Bulk Update all Computer Group members to Site Y...
I hope it can be of help to others as well...

The script is tested in our companies JSS environment and multiple groups with a large count of nodes, however, the execution of any script is on your own risk.

#!/bin/bash

# ################################################################################################################################################
#               
# Script Name:  API_GroupComputersToSite.sh
#
# Author:       Sven Ramm
# Date:         02/13/2017
# Version:      1.0
#               
# Purpose:      Bulk assign all Computer members of group X to Site Y
#
# Changes:      - 02/13/2017
#                   - Script creation
# ################################################################################################################################################

## Change these 3 variables to match your setup. API account must have API write privs
apiUser="YourAPIUser"
apiPass="Your API User Password"
jssURL="https://YourJSS.com:8443"
# ################################################################################################################################################

tmpXML="/tmp/site_location.xml"
logFile="/var/log/JAMF_API.log"

if [[ -z "$apiUser" ]] || [[ -z "$apiPass" ]] || [[ -z "$jssURL" ]]; then
    echo "The API username, password or JSS URL were not specified in the script. Please add these details and try again."
    exit 1
fi

# ################################################################################################################################################
# ################################################################################################################################################

# Function to provide logging of the script's actions to
# the log file defined by the logFile variable
Logging(){

    DATE=`date +%Y-%m-%d %H:%M:%S`
    LOG="$logFile"

    echo "$DATE" " $1" >> $LOG

}

# Function to create the basic XML informations to be PUT via API
WriteUpdateXML () {

    local SiteID=$1
    local SiteName=$2

    ## Create the xml for upload via API
    echo "<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <computer>
        <general>
            <site>
                <id>$SiteID</id>
                <name>$SiteName</name>
            </site>
        </general>
    </computer>" > "$tmpXML"

}

# Function to Find ALL computers in a Group and assign these to a given Site
AssignGroupComputersToSite () {

    local GroupID=$1
    local SiteID=$2
    local SiteName=$3

    Logging "Group ID: $GroupID" 
    Logging "Site ID: $SiteID"
    Logging "Site Name: $SiteName"

    echo "Please wait & be patience..." 
    echo "You may monitor any progress in $logFile"
    echo "Assigning Computers of Group ID: $GroupID, to Site $SiteName"

    # Write tmp XML file
    WriteUpdateXML "$SiteID" "$SiteName"

    #GET API Resources from
    local APIResource="/JSSResource/computergroups/id/$GroupID"

    # Get ALL Computers which are members in SmartGroup 
    local ComputersInGroup_XML=`/usr/bin/curl -X GET -H"Accept: application/xml" -s -u "$apiUser:$apiPass"  ${jssURL%/}${APIResource}`
    local COUNT=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/size/text()" 2> /dev/null`

    # Loop through the X results
    for (( INDEX=1; INDEX<=$COUNT; INDEX++ )); do
        COMPUTER_ID=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/computer[$INDEX]/id/text()" 2> /dev/null`
        COMPUTER_NAME=`echo $ComputersInGroup_XML | /usr/bin/xpath "/computer_group/computers/computer[$INDEX]/name/text()" 2> /dev/null`

        AssignGroupComputersToSite=$(curl -sfku "${apiUser}":"${apiPass}" "${jssURL}/JSSResource/computers/id/${COMPUTER_ID}" -T "$tmpXML" -X PUT)
        if [ $? == 0 ]; then
            Logging "Count: $INDEX Successful updated Site data for: $COMPUTER_NAME"
        else
            Logging "Count: $INDEX Failed to update Site data for: $COMPUTER_NAME"  
        fi
        #sleep 0.5
    done

}

# ################################################################################################################################################
# ################################################################################################################################################

# to find ALL Site names & ID's assosiated check the API help @ https://YourJSS.com:8443/api/#!/sites
# to find Group names & assosiated Group ID's check the API help @ https://YourJSS.com:8443/api/#!/computergroups/findComputerGroups_get

# USAGE: AssignGroupComputersToSite "Group ID" "Site ID" "Site Name"

# ################################################################################################################################################
# ################################################################################################################################################

# Empty Log File for today's run
cat /dev/null > $logFile

# ################################################################################################################################################
# ################################################################################################################################################

# Assign members of Group "Example All Berlin Computers" Group ID: 59 to Site ID: 6 Site Name: "Berlin"
Logging "######################################################################"
Logging "START assigning Group Computers to Site                              #"
Logging "######################################################################"

AssignGroupComputersToSite "59" "6" "Berlin"

Logging "######################################################################"
Logging "END assigning Group Computers to Site                                #"
Logging "######################################################################"


exit 0