Skip to main content
Solved

Request for a Renaming Script


Forum|alt.badge.img+8

Hello beloved Jamf Community.

As I'm no Scripting Expert, I humbly request if any i you could help me with the following script.

I am looking for a Self Service option where the user fills in some text (most likely an asset tag number)
Then In addition to what the user fills in, I need the following prefix to be added:

A Prefix that is set based on the Site as per Jamf Inventory (NY for macs based in New York and UK for macs based in the UK etc etc)
A Prefix that is set based on the Model of the Mac (iMac vs MB)

So as a result it should be something like

NYiMac0012345
or
UKMB0012346

Etc.

Anyone can help me with this please?

Best answer by Mauricio11

@MagicMick Big Sur, big surprises!

Apple got some changes for xpath, a good link:
https://scriptingosx.com/2020/10/dealing-with-xpath-changes-in-big-sur/

To fix your script I would recommend this:

Replace:

1SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xpath '/computer/general/site/name/text()')

With:

1SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xmllint --xpath '/computer/general/site/name/text()' -)

I hope this helps!

View original
Did this topic help you find an answer to your question?

9 replies

dan-snelson
Forum|alt.badge.img+28
  • Honored Contributor
  • 632 replies
  • October 14, 2020

@MagicMick The following may prove helpful

1#!/bin/sh
2####################################################################################################
3#
4# ABOUT
5#
6# Rename Computer
7#
8####################################################################################################
9#
10# HISTORY
11#
12# Version 1.0, 18-Jun-2015, Dan K. Snelson
13# Original version
14#
15####################################################################################################
16
17jamfDisplayMessage() {
18 /usr/local/jamf/bin/jamf displayMessage -message "${1}" &
19}
20
21echo "*** Rename Computer ***"
22
23### Log current computer name
24currentComputerName=$( /usr/sbin/scutil --get ComputerName )
25echo "Current Computer Name: $currentComputerName"
26
27
28### Prompt for new computer name
29newComputerName="$(/usr/bin/osascript -e 'Tell application "System Events" to display dialog "Enter the new computer name:" default answer "" buttons {"Rename","Cancel"} default button 2' -e 'text returned of result' 2>/dev/null)"
30if [ $? -ne 0 ]; then
31 # The user pressed Cancel
32 echo "User clicked Cancel"
33 exit 1 # exit with an error status
34elif [ -z "$newComputerName" ]; then
35 # The user left the computer name blank
36 echo "User left the computer name blank"
37 /usr/bin/osascript -e 'Tell application "System Events" to display alert "No computer name entered; cancelling." as critical'
38 exit 1 # exit with an error status
39fi
40
41
42### Set and log new computer name
43/usr/sbin/scutil --set ComputerName "$newComputerName"
44echo "New Computer Name: $newComputerName"
45
46### Update the JSS
47/usr/local/jamf/bin/jamf recon
48
49# Inform user of computer renamed
50jamfDisplayMessage "Renamed computer from: "$currentComputerName" to "$newComputerName""
51
52echo "Renamed computer from: "$currentComputerName" to "$newComputerName""
53
54exit 0 ## Success
55exit 1 ## Failure

Forum|alt.badge.img+19
  • Honored Contributor
  • 582 replies
  • October 14, 2020

I wrote something similar as part of a larger deployment script. Here is the relevent portion. You will need to generate a CSV file and put it on the computer before running the script. CSV should be in the format:

1New York, NY
2United Kingdom, UK
3Other, OT

But this should give you a starting point to work from:

1#!/bin/bash
2
3# This script will generate a computer name based on location, model type, and asset tag and update the computer name.
4
5# Variables
6
7# Location of CSV file that includes Location Names, Location Abbreviation
8BUILDNAMELIST="/path/to/BUILDINGS.csv"
9
10# Determine the model type of the computer
11MODELTYPE=$(sysctl hw.model | awk '{print $2}')
12
13# Set these variables through a script or prompts.
14ASSETTAG='C123455'
15LOC='New York'
16
17GenerateComputerName() { # Generate Computer Name based on Building, Mac Type (DT/LT), and Asset Tag
18 #Get Location Prefix from text file
19 PREFIX=$(cat $BUILDNAMELIST | grep "$LOC" | awk -F, '{print $2}')
20 if [[ $PREFIX == "" || $LOC == "" ]]; then
21 PREFIX="XXX"
22 fi
23
24 #Check to see if the Model Name is a "MacBook" or "Parallels" and assign model descriptor (LT, VM, or DT)
25 COMPUTERNAME=$PREFIX
26 if [[ ${MODELTYPE:0:7} == "MacBook" ]]; # Check for "Macbook", if so, device is a Laptop
27 then
28 COMPUTERNAME+="LT"
29 elif [[ ${MODELTYPE:0:7} == "Paralle" ]]; # Check for "Parallels", if so, device is a Virtual Machine
30 then
31 COMPUTERNAME+="VM"
32 else
33 COMPUTERNAME+="DT" # Otherwise, the device must be a Desktop
34 fi
35
36 #Add Asset Tag Number to Name and "Mac" suffix
37 COMPUTERNAME+=$ASSETTAG
38 COMPUTERNAME+="Mac"
39 echo $COMPUTERNAME
40}
41
42# Generate the computer name
43NEWCOMPUTERNAME=$(GenerateComputerName)
44
45# Update the Computer Name
46/usr/sbin/scutil --set ComputerName $NEWCOMPUTERNAME
47echo $NEWCOMPUTERNAME

mm2270
Forum|alt.badge.img+24
  • Legendary Contributor
  • 7886 replies
  • October 14, 2020

@MagicMick If you want to go the route of using the API to get the site name information, then you can try something like the following.
This script does some error checking, but not with everything. So if for example, the API name and password aren't correct or don't have the proper permissions, it will fail. Just something to keep in mind.

EDIT: Added a case statement for the Site name to set the site prefix characters. You'll need to add any extra checks as required.

1#!/bin/bash
2
3## The API username and password are obtained from script parameters 4 and 5
4API_USER="$4"
5API_PASS="$5"
6
7JAMF_PLIST="/Library/Preferences/com.jamfsoftware.jamf.plist"
8
9## Two sanity checks:
10## 1. Make sure the Mac is enrolled in a JPS. The Jamf plist should be present for us to pull the URL from
11## 2. Check to make sure we received parameters 4 and 5 for the API_USER and API_PASS variables or else we cannot get info using the API
12
13if [ -e "$JAMF_PLIST" ]; then
14 ## Here we get the URL for the Jamf Pro server this Mac is enrolled in
15 echo "Found the Jamf plist. Checking for the URL now..."
16 JPS_URL=$(/usr/bin/defaults read "$JAMF_PLIST" jss_url)
17else
18 echo "This Mac does not appear to be enrolled in a Jamf Pro server. Exiting..."
19 exit 1
20fi
21
22if [[ -z "$API_USER" || -z "$API_PASS" ]]; then
23 ## Either $4 or $5 weren't passed to the script, so we can't continue
24 echo "The API user or API password items are blank. Please make sure the script parameters are correctly filled in and try again. Exiting..."
25 exit 2
26else
27 echo "API variables were passed to the script. Continuing..."
28fi
29
30## Get the UUID of the device
31UUID=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}')
32
33echo "UUID: $UUID"
34
35## Here we get the Site name using the API
36SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xpath '/computer/general/site/name/text()')
37
38echo "Site Name: $SITE_NAME"
39
40## Modify this case statement with additional checks to set the correct site tag for the final name
41case "$SITE_NAME" in
42 *"New York"*)
43 SITE_PREFIX="NY" ;;
44 *UK*)
45 SITE_PREFIX="UK" ;;
46 *Other*)
47 SITE_PREFIX="OT" ;;
48 *)
49 SITE_PREFIX="$SITE_NAME" ;;
50esac
51
52## Get the Model ID from the device
53MODEL_ID=$(sysctl hw.model | awk '{print $NF}')
54echo "Model ID: $MODEL_ID"
55
56## Determine the model prefix we should use based on the model id
57case "$MODEL_ID" in
58 iMac*)
59 MODEL_PREFIX="iMac" ;;
60 MacBook*)
61 MODEL_PREFIX="MB" ;;
62 MacPro*)
63 MODEL_PREFIX="MP" ;;
64 Macmini*)
65 MODEL_PREFIX="MM" ;;
66 *)
67 MODEL_PREFIX="Mac" ;;
68esac
69
70echo "Model prefix: $MODEL_PREFIX"
71
72promptForTag () {
73### Ask user for the Asset Tag
74ASSET_TAG=$(/usr/bin/osascript <<- EOF
75tell application "System Events"
76 get text returned of (display dialog "Enter the asset tag for this computer:" default answer "" buttons {"Enter"} default button 1)
77end tell
78EOF)
79}
80
81## This while loop will ensure we get an asset tag from the prompt
82while [ -z "$ASSET_TAG" ]; do
83 promptForTag
84done
85
86echo "Asset Tag: $ASSET_TAG"
87
88## Assign the full new computer name to a variable
89NEW_NAME="${SITE_PREFIX}${MODEL_PREFIX}${ASSET_TAG}"
90echo "Computer will be renamed to: $NEW_NAME"
91
92## Set the new computer name
93/usr/sbin/scutil --set ComputerName "$NEW_NAME"
94
95echo "Computer was renamed to: $NEW_NAME"
96
97## Collect updated inventory
98/usr/local/jamf/bin/jamf recon

Mauricio11
Forum|alt.badge.img+11
  • Valued Contributor
  • 173 replies
  • October 15, 2020

In addition to mm2270 script above I would recommend adding:

A. For consistence, set the host names to the same as the computer.

1 /usr/sbin/scutil --set LocalHostName "$NEW_NAME"
2 /usr/sbin/scutil --set HostName "$NEW_NAME"

B. Check if the name has not been taken in Jamf. Rely on user's input can be challenging.

We have a process to autogenerate a unique computer name based on our naming convention and to test it we have this:

1checkNameAvailable() {
2 macName=""
3 response=$(/usr/bin/curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" --write-out '%{http_code}' --output /dev/null --request GET "${JPS_URL}JSSResource/computers/name/$NEW_NAME" )
4
5 case "$response" in
6 200 ) echo "Computer Name $NEW_NAME in use" ;;
7 404 ) macName="OK" ;;
8 5** ) echo "Server error: $response" ;;
9 esac
10
11 }
12
13generateComputerName() {
14 genenerateName
15 checkNameAvailable "$NEW_NAME"
16 while true;
17 do
18 if [ -z "$macName" ]; then
19 genenerateName
20 checkNameAvailable "$NEW_NAME"
21 else
22 break
23 fi
24 done
25 echo "$NEW_NAME"
26}

Basically if you cannot find that computer name in Jamf means you are good to use it.

'genenerateName' function is the process to generate a new name...

@MagicMick You said "I am looking for a Self Service option where the user fills in some text (most likely an asset tag number)", do you have that in place already? Can you avoid that by just generating one automatically and saving the manual/self-service route?


Forum|alt.badge.img+8
  • Author
  • Contributor
  • 63 replies
  • October 15, 2020

Hi @dan-snelson @RBlount @mm2270 @Mauricio

Thank you all so so much for your quick and detailed suggestion. I'm sure I'll be able to make good use of all the info provided. It really means a lot to me that you guys are willing to spend the time to help a fellow Admin.

@Mauricio If there was a way for me to know which tag belongs to which computer, I would have obviously done that. But with Zero Toch/DEP we send tags and machines seperately, the user needs to stick the tag ont he asset and then via a SS policy I want the user to let Jamf know which tag belongs to which machine. Does that make sense?


Mauricio11
Forum|alt.badge.img+11
  • Valued Contributor
  • 173 replies
  • October 16, 2020

@MagicMick Indeed, it makes sense, if you have a naming process in place that uses tags, that is the way to do it. Regards.


Forum|alt.badge.img+8
  • Author
  • Contributor
  • 63 replies
  • December 4, 2020

Hi @dan-snelson @RBlount @mm2270 @Mauricio

So I created a new script based on all your guys handy hints and tips. And it was working fine! But now under Big Sur it doesn't seem to work anymore? Any ideas?

1#!/bin/sh
2
3## Here we get the Site name using the API
4SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xpath '/computer/general/site/name/text()')
5
6echo "Site Name: $SITE_NAME"
7
8## Modify this case statement with additional checks to set the correct site tag for the final name
9case "$SITE_NAME" in
10 *"New York"*)
11 SITE_PREFIX="NY" ;;
12 *Exeter*)
13 SITE_PREFIX="EX" ;;
14 *Orlando*)
15 SITE_PREFIX="OL" ;;
16 *)
17 SITE_PREFIX="$SITE_NAME" ;;
18esac
19
20## Get the Model ID from the device
21MODEL_ID=$(sysctl hw.model | awk '{print $NF}')
22echo "Model ID: $MODEL_ID"
23
24## Determine the model prefix we should use based on the model id
25case "$MODEL_ID" in
26 iMac*)
27 MODEL_PREFIX="-IM-" ;;
28 MacBook*)
29 MODEL_PREFIX="-MB-" ;;
30 MacPro*)
31 MODEL_PREFIX="-MP-" ;;
32 Macmini*)
33 MODEL_PREFIX="-MM-" ;;
34 *)
35 MODEL_PREFIX="-Mc-" ;;
36esac
37
38echo "Model prefix: $MODEL_PREFIX"
39
40promptForTag () {
41### Ask user for the Asset Tag
42ASSET_TAG=$(/usr/bin/osascript <<- EOF
43tell application "System Events"
44 get text returned of (display dialog "Enter the asset tag for this computer:" default answer "" buttons {"Enter"} default button 1)
45end tell
46EOF)
47}
48
49## This while loop will ensure we get an asset tag from the prompt
50while [ -z "$ASSET_TAG" ]; do
51 promptForTag
52done
53
54echo "Asset Tag: $ASSET_TAG"
55
56## Assign the full new computer name to a variable
57NEW_NAME="${SITE_PREFIX}${MODEL_PREFIX}${ASSET_TAG}"
58echo "Computer will be renamed to: $NEW_NAME"
59
60## Set the new computer name
61/usr/sbin/scutil --set ComputerName "$NEW_NAME"
62/usr/sbin/scutil --set LocalHostName "$NEW_NAME"
63/usr/sbin/scutil --set HostName "$NEW_NAME"
64
65echo "Computer was renamed to: $NEW_NAME"
66
67## Collect updated inventory
68/usr/local/jamf/bin/jamf recon

Script result: Found the Jamf plist. Checking for the URL now...
API variables were passed to the script. Continuing...
UUID: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
Usage:
/usr/bin/xpath5.28 [options] -e query [-e query...] [filename...]

If no filenames are given, supply XML on STDIN. You must provide at
least one query. Each supplementary query is done in order, the
previous query giving the context of the next one.

Options:

-q quiet, only output the resulting PATH.
-s suffix, use suffix instead of linefeed.
-p postfix, use prefix instead of nothing.
-n Don't use an external DTD.
Site Name: Model ID: iMac16,2
Model prefix: -IM-
Asset Tag: 00566
Computer will be renamed to: -IM-00566
scutil: invalid option -- I
usage: /usr/sbin/scutil interactive access to the dynamic store.

or: /usr/sbin/scutil --prefs [preference-file] interactive access to the [raw] stored preferences.

or: /usr/sbin/scutil [-W] -r nodename or: /usr/sbin/scutil [-W] -r address or: /usr/sbin/scutil [-W] -r local-address remote-address check reachability of node, address, or address pair (-W to "watch").

or: /usr/sbin/scutil -w dynamic-store-key [ -t timeout ] -w wait for presense of dynamic store key -t time to wait for key

or: /usr/sbin/scutil --get pref or: /usr/sbin/scutil --set pref [newval] or: /usr/sbin/scutil --get filename path key pref display (or set) the specified preference. Valid preferences include: ComputerName, LocalHostName, HostName newval New preference value to be set. If not specified, the new value will be read from standard input.

or: /usr/sbin/scutil --dns show DNS configuration.

or: /usr/sbin/scutil --proxy show "proxy" configuration.

or: /usr/sbin/scutil --nwi show network information

or: /usr/sbin/scutil --nc show VPN network configuration information. Use --nc help for full command list

or: /usr/sbin/scutil --allow-new-interfaces [off|on] manage new interface creation with screen locked.

or: /usr/sbin/scutil --error err# display a descriptive message for the given error code
scutil: invalid option -- I
usage: /usr/sbin/scutil interactive access to the dynamic store.

or: /usr/sbin/scutil --prefs [preference-file] interactive access to the [raw] stored preferences.

or: /usr/sbin/scutil [-W] -r nodename or: /usr/sbin/scutil [-W] -r address or: /usr/sbin/scutil [-W] -r local-address remote-address check reachability of node, address, or address pair (-W to "watch").

or: /usr/sbin/scutil -w dynamic-store-key [ -t timeout ] -w wait for presense of dynamic store key -t time to wait for key

or: /usr/sbin/scutil --get pref or: /usr/sbin/scutil --set pref [newval] or: /usr/sbin/scutil --get filename path key pref display (or set) the specified preference. Valid preferences include: ComputerName, LocalHostName, HostName newval New preference value to be set. If not specified, the new value will be read from standard input.

or: /usr/sbin/scutil --dns show DNS configuration.

or: /usr/sbin/scutil --proxy show "proxy" configuration.

or: /usr/sbin/scutil --nwi show network information

or: /usr/sbin/scutil --nc show VPN network configuration information. Use --nc help for full command list

or: /usr/sbin/scutil --allow-new-interfaces [off|on] manage new interface creation with screen locked.

or: /usr/sbin/scutil --error err# display a descriptive message for the given error code
scutil: invalid option -- I
usage: /usr/sbin/scutil interactive access to the dynamic store.

or: /usr/sbin/scutil --prefs [preference-file] interactive access to the [raw] stored preferences.

or: /usr/sbin/scutil [-W] -r nodename or: /usr/sbin/scutil [-W] -r address or: /usr/sbin/scutil [-W] -r local-address remote-address check reachability of node, address, or address pair (-W to "watch").

or: /usr/sbin/scutil -w dynamic-store-key [ -t timeout ] -w wait for presense of dynamic store key -t time to wait for key

or: /usr/sbin/scutil --get pref or: /usr/sbin/scutil --set pref [newval] or: /usr/sbin/scutil --get filename path key pref display (or set) the specified preference. Valid preferences include: ComputerName, LocalHostName, HostName newval New preference value to be set. If not specified, the new value will be read from standard input.

or: /usr/sbin/scutil --dns show DNS configuration.

or: /usr/sbin/scutil --proxy show "proxy" configuration.

or: /usr/sbin/scutil --nwi show network information

or: /usr/sbin/scutil --nc show VPN network configuration information. Use --nc help for full command list

or: /usr/sbin/scutil --allow-new-interfaces [off|on] manage new interface creation with screen locked.

or: /usr/sbin/scutil --error err# display a descriptive message for the given error code
Computer was renamed to: -IM-00566
Retrieving inventory preferences from https://xxxxx.jamfcloud.com/...
Finding extension attributes...
Locating accounts...
Locating package receipts...
Locating applications...
Searching path: /System/Applications
Locating hard drive information...
Locating software updates...
Locating plugins...
Searching path: /Library/Internet Plug-Ins
Locating fonts...
Searching path: /private/var/jamfadmin/Library/Fonts
Searching path: /Users/XXXX/Library/Fonts
Searching path: /Library/Fonts
Searching path: /System/Library/Fonts
Searching path: /Applications
Searching path: /Library/Application Support/Adobe/Fonts
Locating hardware information (Mac OS X 10.16.0)...
Gathering application usage information...
Submitting data to https://XXXXX.jamfcloud.com/...
<computer_id>169</computer_id>

QuotedText

Mauricio11
Forum|alt.badge.img+11
  • Valued Contributor
  • 173 replies
  • Answer
  • December 4, 2020

@MagicMick Big Sur, big surprises!

Apple got some changes for xpath, a good link:
https://scriptingosx.com/2020/10/dealing-with-xpath-changes-in-big-sur/

To fix your script I would recommend this:

Replace:

1SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xpath '/computer/general/site/name/text()')

With:

1SITE_NAME=$(curl -H "Accept: application/xml" -sku "${API_USER}:${API_PASS}" "${JPS_URL}JSSResource/computers/udid/${UUID}/subset/general" | xmllint --xpath '/computer/general/site/name/text()' -)

I hope this helps!


Forum|alt.badge.img+8
  • Author
  • Contributor
  • 63 replies
  • December 4, 2020

@Mauricio Many many many thanks! All good now!


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