I have been using a Python script that uses a Google Sheet to locate serial numbers and match them up with names. When trying to use this with the M1 Mac's, it seems that the script isn't working as it should. Upon investigation, the script I was using was only updating the computer name, but not the two hostnames. On the Intel Mac's, this didn't seem to be an issue, but with the M1 Mac's, renaming via the script has become unreliable. More often than not, I have to manually rename the computers and manually add them to AD.
Anyone have a better script for this? Here is mine that I cobbled together from other threads on Jamf Nation.
#!/usr/bin/python
'''
Rename computer from remote CSV using Jamf binary
Pass in the URL to your remote CSV file using script parameter 4
The remote CSV could live on a web server you control, OR be a Google Sheet
specified in the following format:
https://docs.google.com/spreadsheets/u/0/d/1H9gsdRtmzb0v9TY8r47j8p8uUs8vhSZS3v446czCOjU/export?format=csv&id=<document ID>&gid=0
'''
import os
import sys
import urllib2
import subprocess
CSV_PATH = '/var/tmp/computernames.csv'
def download_csv(url):
'''Downloads a remote CSV file to CSV_PATH'''
try:
# open the url
csv = urllib2.urlopen(url)
# ensure the local path exists
directory = os.path.dirname(CSV_PATH)
if not os.path.exists(directory):
os.makedirs(directory)
# write the csv data to the local file
with open(CSV_PATH, 'w+') as local_file:
local_file.write(csv.read())
# return path to local csv file to pass along
return CSV_PATH
except (urllib2.HTTPError, urllib2.URLError):
print 'ERROR: Unable to open URL', url
return False
except (IOError, OSError):
print 'ERROR: Unable to write file at', CSV_PATH
return False
def rename_computer(path):
'''Renames a computer using the Jamf binary and local CSV at <path>'''
cmd = ['/usr/local/bin/jamf', 'setComputerName', '-fromFile', path]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = proc.communicate()
if proc.returncode == 0:
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
return out.split(' ')[-1]
else:
return False
def main():
'''Main'''
try:
csv_url = sys.argv[4]
except ValueError:
print 'ERROR: You must provide the URL of a remote CSV file.'
sys.exit(1)
computernames = download_csv(csv_url)
if computernames:
rename = rename_computer(computernames)
if rename:
print 'SUCCESS: Set computer name to', rename
else:
print ('ERROR: Unable to set computer name. Is this device in the '
'remote CSV file?')
sys.exit(1)
else:
print 'ERROR: Unable to set computer name without local CSV file.'
sys.exit(1)
if __name__ == '__main__':
main()
https://www.jamf.com/jamf-nation/discussions/36187/rename-computer-using-gsheet
This is the script that I'm using to rename our new M1 computers as well and it works great except that it only changes the computer name. I have no experience with python but in looking at the code, wondering if I can add a couple of lines to rename the HostName and LocalHostName assuming I want them to be the same as the computer name? Would the following addition break the python code?
def rename_computer(path):
'''Renames a computer using the Jamf binary and local CSV at <path>'''
cmd = ['/usr/local/bin/jamf', 'setComputerName', '-fromFile', path]
cmd = ['/usr/local/bin/jamf', 'setHostName', '-fromFile', path]
cmd = ['/usr/local/bin/jamf', 'setLocalHostName', '-fromFile', path]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, _ = proc.communicate()
if proc.returncode == 0:
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
return out.split(' ')[-1]
else:
return False
@kbremner I had not thought to try that… I will do so and report back.
As I looked over the code again I think part of the issue with why it isn't working for me is that setHostName and setLocalHostName are not verbs available with the Jamf Binary so those would have to be rewritten using the native macOS commands?
@kbremner I think I have found a solution to setting the other two names... I found a Jamf document on setting names and it suggested this script to go along with the Jamf binary command that renames the computers.
#!/bin/bash
# get Computer Name
computerName=$( /usr/sbin/scutil --get ComputerName )
echo "Computer Name: $computerName"
# create network name using only alphanumeric characters and hyphens for spaces
networkName=$( /usr/bin/sed -e 's/ /-/g' -e 's/[^[:alnum:]-]//g' <<< "$computerName" )
echo "Network Name: $networkName"
# set hostname and local hostname
/usr/sbin/scutil --set HostName "$networkName"
/usr/sbin/scutil --set LocalHostName "$networkName"
exit 0
@kbremner I think I have found a solution to setting the other two names... I found a Jamf document on setting names and it suggested this script to go along with the Jamf binary command that renames the computers.
#!/bin/bash
# get Computer Name
computerName=$( /usr/sbin/scutil --get ComputerName )
echo "Computer Name: $computerName"
# create network name using only alphanumeric characters and hyphens for spaces
networkName=$( /usr/bin/sed -e 's/ /-/g' -e 's/[^[:alnum:]-]//g' <<< "$computerName" )
echo "Network Name: $networkName"
# set hostname and local hostname
/usr/sbin/scutil --set HostName "$networkName"
/usr/sbin/scutil --set LocalHostName "$networkName"
exit 0
So Kwoodard,
What's your update on scripts you are using. Did you find a fix for the M1's? I am also using a Google Sheet and would love for it to work with my new macs. And looking at the above script, I would run that in the same policy to make sure both computer name and hostname are changed?
Thanks for any advice.
Here is what we came up with. Written in bash script, so far has been working on everything...
#!/bin/bash
CSV_PATH='/var/tmp/computernames.csv'
# Downloads a remote CSV file to CSV_PATH
function download_csv() {
# -s flag to turn off curl's output
# -f flag to have catchable exit status
# -L for url link
# -o for output to filename
# double quotes around CSV_URL becuase curl prefers the url in quotes
curl -s -f -L -o "$CSV_PATH" ""$CSV_URL""
CURL_STATUS=$?
echo "waiting 10 seconds"
sleep 10
echo "finished waiting"
if [[ $CURL_STATUS -eq 0 ]]; then
echo "Successfully downloaded $CSV_URL to $CSV_PATH"
elif [[ $CURL_STATUS -eq 3 ]]; then
# File I/O error
echo "ERROR: Unable to write file at $CSV_PATH"
exit 1
else
# Download error
echo "ERROR: Unable to open URL at $CSV_URL"
exit 1
fi
}
# Renames a computer using the Jamf binary and local CSV at CSV_PATH
function rename_computer() {
/usr/local/bin/jamf help
JAMF_MESSAGE=$(sudo /usr/local/bin/jamf setComputerName -fromFile "$CSV_PATH")
JAMF_STATUS=$?
echo $JAMF_STATUS
echo $JAMF_MESSAGE
if [[ JAMF_STATUS -eq 0 ]]; then
RENAME=$(echo $JAMF_MESSAGE | awk 'END{print $NF}')
echo $RENAME
if [[ -n RENAME ]]; then
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
echo "SUCCESS: Set computer name to $RENAME"
else
echo "ERROR: Unable to set computer name. Is this device in the remote CSV file?"
exit 1
fi
else
echo "ERROR: Unable to set computer name without local CSV file."
exit 1
fi
}
if [[ -z $4 ]]; then
echo 'ERROR: You must provide the URL of a remote CSV file.'
exit 1
fi
CSV_URL=$4
#call download_csv
download_csv
#call rename_computer
rename_computer
Here is what we came up with. Written in bash script, so far has been working on everything...
#!/bin/bash
CSV_PATH='/var/tmp/computernames.csv'
# Downloads a remote CSV file to CSV_PATH
function download_csv() {
# -s flag to turn off curl's output
# -f flag to have catchable exit status
# -L for url link
# -o for output to filename
# double quotes around CSV_URL becuase curl prefers the url in quotes
curl -s -f -L -o "$CSV_PATH" ""$CSV_URL""
CURL_STATUS=$?
echo "waiting 10 seconds"
sleep 10
echo "finished waiting"
if [[ $CURL_STATUS -eq 0 ]]; then
echo "Successfully downloaded $CSV_URL to $CSV_PATH"
elif [[ $CURL_STATUS -eq 3 ]]; then
# File I/O error
echo "ERROR: Unable to write file at $CSV_PATH"
exit 1
else
# Download error
echo "ERROR: Unable to open URL at $CSV_URL"
exit 1
fi
}
# Renames a computer using the Jamf binary and local CSV at CSV_PATH
function rename_computer() {
/usr/local/bin/jamf help
JAMF_MESSAGE=$(sudo /usr/local/bin/jamf setComputerName -fromFile "$CSV_PATH")
JAMF_STATUS=$?
echo $JAMF_STATUS
echo $JAMF_MESSAGE
if [[ JAMF_STATUS -eq 0 ]]; then
RENAME=$(echo $JAMF_MESSAGE | awk 'END{print $NF}')
echo $RENAME
if [[ -n RENAME ]]; then
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
echo "SUCCESS: Set computer name to $RENAME"
else
echo "ERROR: Unable to set computer name. Is this device in the remote CSV file?"
exit 1
fi
else
echo "ERROR: Unable to set computer name without local CSV file."
exit 1
fi
}
if [[ -z $4 ]]; then
echo 'ERROR: You must provide the URL of a remote CSV file.'
exit 1
fi
CSV_URL=$4
#call download_csv
download_csv
#call rename_computer
rename_computer
Thank you so much. I will be testing this out soon!
Thank you so much. I will be testing this out soon!
I have a shorter one that doesn't display some of the echo commands and such, but I still use this one daily. Lets me see what's going on in the logs if something fails.
And you more than likely already know this, but $4 is where the script calls the URL for your Google sheet, the option when you are creating the Policy... (My brain is mush today, I hope this makes sense)
Thanks kwoodard for bash script. Works great! I was using the python version but now that python is not included with macOS 12.3 our erase-n-place workflows were broken... bash to rescue!
Thanks kwoodard for bash script. Works great! I was using the python version but now that python is not included with macOS 12.3 our erase-n-place workflows were broken... bash to rescue!
Glad it's working out for you! I'm hoping to get it updated for zsh, but thats a longer term project.
Glad it's working out for you! I'm hoping to get it updated for zsh, but thats a longer term project.
I'm new to scripting, so I'm having problems figuring out specifically where to insert the URL of my Google Sheet. Do I substitute the $4 with the URL in both locations, or in a totally different spot? Sorry if this is a silly question.
I'm new to scripting, so I'm having problems figuring out specifically where to insert the URL of my Google Sheet. Do I substitute the $4 with the URL in both locations, or in a totally different spot? Sorry if this is a silly question.
$4 is Parameter 4 when you are creating the profile in Jamf Pro...
$4 is Parameter 4 when you are creating the profile in Jamf Pro...
Forgot about that part of scripting from the Jamf 200 course. I'm on the right page now. Thanks very much for your help.
Forgot about that part of scripting from the Jamf 200 course. I'm on the right page now. Thanks very much for your help.
No worries, took me a bit to figure that out too.
Here is what we came up with. Written in bash script, so far has been working on everything...
#!/bin/bash
CSV_PATH='/var/tmp/computernames.csv'
# Downloads a remote CSV file to CSV_PATH
function download_csv() {
# -s flag to turn off curl's output
# -f flag to have catchable exit status
# -L for url link
# -o for output to filename
# double quotes around CSV_URL becuase curl prefers the url in quotes
curl -s -f -L -o "$CSV_PATH" ""$CSV_URL""
CURL_STATUS=$?
echo "waiting 10 seconds"
sleep 10
echo "finished waiting"
if [[ $CURL_STATUS -eq 0 ]]; then
echo "Successfully downloaded $CSV_URL to $CSV_PATH"
elif [[ $CURL_STATUS -eq 3 ]]; then
# File I/O error
echo "ERROR: Unable to write file at $CSV_PATH"
exit 1
else
# Download error
echo "ERROR: Unable to open URL at $CSV_URL"
exit 1
fi
}
# Renames a computer using the Jamf binary and local CSV at CSV_PATH
function rename_computer() {
/usr/local/bin/jamf help
JAMF_MESSAGE=$(sudo /usr/local/bin/jamf setComputerName -fromFile "$CSV_PATH")
JAMF_STATUS=$?
echo $JAMF_STATUS
echo $JAMF_MESSAGE
if [[ JAMF_STATUS -eq 0 ]]; then
RENAME=$(echo $JAMF_MESSAGE | awk 'END{print $NF}')
echo $RENAME
if [[ -n RENAME ]]; then
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
echo "SUCCESS: Set computer name to $RENAME"
else
echo "ERROR: Unable to set computer name. Is this device in the remote CSV file?"
exit 1
fi
else
echo "ERROR: Unable to set computer name without local CSV file."
exit 1
fi
}
if [[ -z $4 ]]; then
echo 'ERROR: You must provide the URL of a remote CSV file.'
exit 1
fi
CSV_URL=$4
#call download_csv
download_csv
#call rename_computer
rename_computer
@kwoodard Thanks for this!
My organization wasn't too keen on putting the details in a google sheet so I ended up writing a script to create a CSV. Then do the remaining steps. Here is an example, hope this helps anyone in a similar situation.
cat << 'EOF' >/tmp/Mac_Computer_Names.csv
SERIAL, NAME, DEVICE_TYPE, Asset,
C02XXXXXXXXX, Computer-Name-01, iMac, XXXXXX,
D25XXXXXXXXX, Computer-Name-02, iMac, XXXXXX,
D25XXXXXXXXX, Computer-Name-03, iMac, XXXXXX,
EOF
/usr/local/bin/jamf setComputerName -fromFile '/private/tmp/Mac_Computer_Names.csv'
rm -Rf /private/tmp/Mac_Computer_Names.csv
My organization wasn't too keen on putting the details in a google sheet so I ended up writing a script to create a CSV. Then do the remaining steps. Here is an example, hope this helps anyone in a similar situation.
cat << 'EOF' >/tmp/Mac_Computer_Names.csv
SERIAL, NAME, DEVICE_TYPE, Asset,
C02XXXXXXXXX, Computer-Name-01, iMac, XXXXXX,
D25XXXXXXXXX, Computer-Name-02, iMac, XXXXXX,
D25XXXXXXXXX, Computer-Name-03, iMac, XXXXXX,
EOF
/usr/local/bin/jamf setComputerName -fromFile '/private/tmp/Mac_Computer_Names.csv'
rm -Rf /private/tmp/Mac_Computer_Names.csv
That's essentially what the Google sheet is doing, creating a csv that the Jamf policy downloads to the computer.
Here is what we came up with. Written in bash script, so far has been working on everything...
#!/bin/bash
CSV_PATH='/var/tmp/computernames.csv'
# Downloads a remote CSV file to CSV_PATH
function download_csv() {
# -s flag to turn off curl's output
# -f flag to have catchable exit status
# -L for url link
# -o for output to filename
# double quotes around CSV_URL becuase curl prefers the url in quotes
curl -s -f -L -o "$CSV_PATH" ""$CSV_URL""
CURL_STATUS=$?
echo "waiting 10 seconds"
sleep 10
echo "finished waiting"
if [[ $CURL_STATUS -eq 0 ]]; then
echo "Successfully downloaded $CSV_URL to $CSV_PATH"
elif [[ $CURL_STATUS -eq 3 ]]; then
# File I/O error
echo "ERROR: Unable to write file at $CSV_PATH"
exit 1
else
# Download error
echo "ERROR: Unable to open URL at $CSV_URL"
exit 1
fi
}
# Renames a computer using the Jamf binary and local CSV at CSV_PATH
function rename_computer() {
/usr/local/bin/jamf help
JAMF_MESSAGE=$(sudo /usr/local/bin/jamf setComputerName -fromFile "$CSV_PATH")
JAMF_STATUS=$?
echo $JAMF_STATUS
echo $JAMF_MESSAGE
if [[ JAMF_STATUS -eq 0 ]]; then
RENAME=$(echo $JAMF_MESSAGE | awk 'END{print $NF}')
echo $RENAME
if [[ -n RENAME ]]; then
# on success the jamf binary reports 'Set Computer Name to XXX'
# so we split the phrase and return the last element
echo "SUCCESS: Set computer name to $RENAME"
else
echo "ERROR: Unable to set computer name. Is this device in the remote CSV file?"
exit 1
fi
else
echo "ERROR: Unable to set computer name without local CSV file."
exit 1
fi
}
if [[ -z $4 ]]; then
echo 'ERROR: You must provide the URL of a remote CSV file.'
exit 1
fi
CSV_URL=$4
#call download_csv
download_csv
#call rename_computer
rename_computer
This script worked great for me. Even ran faster than the old Python script. 4-6-2022
Hi @kwoodard Can you please share your googlesheet? I just need to know details needed. Thank you so much
Hi @kwoodard Can you please share your googlesheet? I just need to know details needed. Thank you so much
You will need the serial in column a and the name in b. The sheet must be openly shared. The format of the link must call the .CSV format.
Sent from my iPad
Hi @kwoodard Can you please share your googlesheet? I just need to know details needed. Thank you so much
Here is where I started.
https://www.macblog.org/posts/automatically-renaming-computers-from-a-google-sheet-with-jamf-pro/
Thank you so much @kwoodard @meaderp
@kwoodard Thank you for this it saved me the headaches. I been using the original rename-computer.py piece since 2017 and this script now takes its place in 2022 I was wondering if there was a way to stop the echoing of the JAMF options binary while running it echoed the the options despite it being successful and exiting with 0.
@kwoodard Thank you for this it saved me the headaches. I been using the original rename-computer.py piece since 2017 and this script now takes its place in 2022 I was wondering if there was a way to stop the echoing of the JAMF options binary while running it echoed the the options despite it being successful and exiting with 0.
You can. I did the echo's so I could follow which step things were on and it helped with troubleshooting.