Skip to main content
Solved

API assign computers from group X to Site Y


Forum|alt.badge.img+7

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?

Best answer by ChupSuy

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 original
Did this topic help you find an answer to your question?

8 replies

Forum|alt.badge.img+4
  • New Contributor
  • 9 replies
  • February 12, 2017

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!)


Forum|alt.badge.img+4
  • New Contributor
  • 9 replies
  • February 12, 2017

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"

Forum|alt.badge.img+10
  • Contributor
  • 207 replies
  • February 13, 2017

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!


Forum|alt.badge.img+7
  • Author
  • Contributor
  • 14 replies
  • February 13, 2017

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..


Forum|alt.badge.img+7
  • Author
  • Contributor
  • 14 replies
  • Answer
  • February 13, 2017

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

howie_isaacks
Forum|alt.badge.img+23
  • Esteemed Contributor
  • 773 replies
  • April 10, 2024

I hope this helps others in the future. What I needed to do was automate assigning computers to sites. The goal was to use what ever criteria is necessary to get computers into a smart group to be assigned to a site. This script will change the site that a computer is assigned to when used in a policy. Parameter 4 is where we specify the site ID and Parameter 5 is where we specify the site name. This can be used at enrollment if your computers are added into the smart group that the policy is scoped to in time.

#!/bin/zsh ########################### # Assigns a Mac to a specific site. # Use Jamf parameter 4 for site ID. # Use Jamf parameter 5 for site name. # Under API Login, specify the API username and password. ########################### # API login jamfProURL="https://YourServer.jamfcloud.com" username="API_User" password="SuperDuperSecretPassword" # Computer serial number serialNumber=$(system_profiler SPHardwareDataType | grep Serial | /usr/bin/awk '{ print $4 }') # Request auth token authToken=$( /usr/bin/curl \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/token" \\ --user "$username:$password" ) # Parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) # Site variables site_id="$4" site_name="$5" site_xml="/private/tmp/site.xml" # Function - Create site XML file function siteXML() { echo "Writing site assignment XML to /private/tmp/site.xml" tee "$site_xml" << EOF <computer> <general> <site> <id>$site_id</id> <name>$site_name</name> </site> </general> </computer> EOF } # Determine Jamf Pro device id echo "Getting the Jamf Pro device ID..." deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${token}" ${jamfProURL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -) echo "Device ID: $deviceID" # Create the site XML file - run the function siteXML # Assign site to the Mac echo "Assigning Mac to "$site_name" site." curl -sfk -H "Accept: text/xml" -H "Authorization: Bearer ${token}" "${jamfProURL}/JSSResource/computers/id/${deviceID}" -T "$site_xml" -X PUT # Remove the site XML file echo "Removing the site XML file from /private/tmp." rm "$site_xml"

Forum|alt.badge.img+5
  • New Contributor
  • 13 replies
  • September 16, 2024

What API Permissions are required for the above script to work ? I would like to limit to only permissions needed. 


Forum|alt.badge.img+5
  • New Contributor
  • 13 replies
  • September 16, 2024
howie_isaacks wrote:

I hope this helps others in the future. What I needed to do was automate assigning computers to sites. The goal was to use what ever criteria is necessary to get computers into a smart group to be assigned to a site. This script will change the site that a computer is assigned to when used in a policy. Parameter 4 is where we specify the site ID and Parameter 5 is where we specify the site name. This can be used at enrollment if your computers are added into the smart group that the policy is scoped to in time.

#!/bin/zsh ########################### # Assigns a Mac to a specific site. # Use Jamf parameter 4 for site ID. # Use Jamf parameter 5 for site name. # Under API Login, specify the API username and password. ########################### # API login jamfProURL="https://YourServer.jamfcloud.com" username="API_User" password="SuperDuperSecretPassword" # Computer serial number serialNumber=$(system_profiler SPHardwareDataType | grep Serial | /usr/bin/awk '{ print $4 }') # Request auth token authToken=$( /usr/bin/curl \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/token" \\ --user "$username:$password" ) # Parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) # Site variables site_id="$4" site_name="$5" site_xml="/private/tmp/site.xml" # Function - Create site XML file function siteXML() { echo "Writing site assignment XML to /private/tmp/site.xml" tee "$site_xml" << EOF <computer> <general> <site> <id>$site_id</id> <name>$site_name</name> </site> </general> </computer> EOF } # Determine Jamf Pro device id echo "Getting the Jamf Pro device ID..." deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${token}" ${jamfProURL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -) echo "Device ID: $deviceID" # Create the site XML file - run the function siteXML # Assign site to the Mac echo "Assigning Mac to "$site_name" site." curl -sfk -H "Accept: text/xml" -H "Authorization: Bearer ${token}" "${jamfProURL}/JSSResource/computers/id/${deviceID}" -T "$site_xml" -X PUT # Remove the site XML file echo "Removing the site XML file from /private/tmp." rm "$site_xml"

What API Permissions are required for the above script to work ? I would like to limit to only permissions needed. 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings