Skip to main content
Question

Rename computer using Google Sheet


kwoodard
Forum|alt.badge.img+12

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

69 replies

Forum|alt.badge.img+7
  • Valued Contributor
  • 89 replies
  • April 7, 2021

https://www.jamf.com/jamf-nation/discussions/36187/rename-computer-using-gsheet


Forum|alt.badge.img+4
  • Contributor
  • 11 replies
  • May 11, 2021

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

kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • May 11, 2021

@kbremner I had not thought to try that… I will do so and report back.


Forum|alt.badge.img+4
  • Contributor
  • 11 replies
  • May 12, 2021

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?


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • May 12, 2021

@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

Darkman24
Forum|alt.badge.img+1
  • New Contributor
  • 5 replies
  • February 11, 2022
kwoodard wrote:

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


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • February 11, 2022

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

 


Darkman24
Forum|alt.badge.img+1
  • New Contributor
  • 5 replies
  • February 11, 2022
kwoodard wrote:

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!


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • February 11, 2022
Darkman24 wrote:

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)


Forum|alt.badge.img+3
  • New Contributor
  • 8 replies
  • March 16, 2022

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! 


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • March 16, 2022
tcaldana wrote:

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.


Forum|alt.badge.img+3
  • New Contributor
  • 2 replies
  • March 16, 2022
kwoodard wrote:

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.


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • March 16, 2022
FMCSD_TimK wrote:

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

 


Forum|alt.badge.img+3
  • New Contributor
  • 2 replies
  • March 16, 2022
kwoodard wrote:

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


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • March 16, 2022
FMCSD_TimK wrote:

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.


thomasC
Forum|alt.badge.img+10
  • Contributor
  • 57 replies
  • March 17, 2022
kwoodard wrote:

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! 


Forum|alt.badge.img+2
  • New Contributor
  • 14 replies
  • March 31, 2022

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

 

 


kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • March 31, 2022
Luke_cater wrote:

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.


Forum|alt.badge.img+4
  • Contributor
  • 11 replies
  • April 6, 2022
kwoodard wrote:

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


averion_j
Forum|alt.badge.img+2
  • New Contributor
  • 4 replies
  • April 22, 2022

Hi @kwoodard Can you please share your googlesheet? I just need to know details needed. Thank you so much


Forum|alt.badge.img+4
  • Contributor
  • 11 replies
  • April 22, 2022
averion_j wrote:

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

kwoodard
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • April 22, 2022
averion_j wrote:

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/ 


averion_j
Forum|alt.badge.img+2
  • New Contributor
  • 4 replies
  • April 26, 2022

Thank you so much @kwoodard  @meaderp 


Forum|alt.badge.img+11
  • Valued Contributor
  • 135 replies
  • May 13, 2022

@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
Forum|alt.badge.img+12
  • Author
  • Valued Contributor
  • 280 replies
  • May 13, 2022
Heavy_D wrote:

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


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