Posted on 02-12-2017 09:18 AM
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?
Solved! Go to Solution.
Posted on 02-13-2017 01:22 AM
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
Posted on 02-12-2017 01:34 PM
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!)
Posted on 02-12-2017 01:52 PM
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"
Posted on 02-12-2017 07:15 PM
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!
Posted on 02-12-2017 08:48 PM
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..
Posted on 02-13-2017 01:22 AM
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
Posted on 04-10-2024 01:12 PM
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"
Posted on 09-16-2024 09:10 AM
What API Permissions are required for the above script to work ? I would like to limit to only permissions needed.
Posted on 09-16-2024 09:05 AM
What API Permissions are required for the above script to work ? I would like to limit to only permissions needed.