Skip to main content
Solved

help with comp name script


ImAMacGuy
Forum|alt.badge.img+23

I've been trying to adapt our computer naming script to wait for input from the user by cobbling together information fromhere and here and probably a few others, I can't seem to get it to work.

I just can't seem to figure out what I'm doing wrong, maybe there's an easier way? Can someone take a crack at it?

Original script that works (however if someone's not staring at the screen and they miss the prompts, then the names get messed up)

Also, if you can happen to fix the part at the top I commented out that looked at the machine type (laptop/desktop) and automatically puts in the correct type - that would be awesome :).

identifying data in script removed due to internal security requirements - but scrubbed version below retains the syntax and just made generic

1#!/bin/bash
2set -x
3# jamf recon
4loggedInUser=$(stat -f%Su /dev/console)
5loggedInUID=$(id -u $loggedInUser)
6
7if [[ "$loggedInUser" != "root" ]] && [[ "$loggedInUser" != "_mbsetup" ]]; then
8 ## Create local script
9 cat << EOD > /private/tmp/computerrenamescript.sh
10#!/bin/bash
11
12TT=$(/usr/bin/osascript -e 'tell application "System Events" to set MacTYPE to text returned of (display dialog "Please input the machine type - MD = Mac Desktop or ML = Mac Laptop" default answer "" with icon 2)')
13
14#ModelType=$(system_profiler SPHardwareDataType | grep 'Model Name:' | awk '{ print $3 }')
15#echo "$ModelType"
16
17#if [[ "$ModelType" == "MacBook" ]]; then
18# TT=ML
19#else
20# TT=MD
21#fi
22
23
24BB=$(/usr/bin/osascript -e 'tell application "System Events" to set BRAND to text returned of (display dialog "Please input the brand - AA = AA, AB = AB, AC = AC," default answer "" with icon 2)')
25
26LL=$(/usr/bin/osascript -e 'tell application "System Events" to set MacLoc to text returned of (display dialog "Please enter the location - BA = BA, BB = BB, BC = BC" default answer "" with icon 2)')
27
28NN=$(/usr/bin/osascript -e 'tell application "System Events" to set DEPARTMENT to text returned of (display dialog "Please enter department - 01 = 01, 02 = 02, " default answer "" with icon 2)')
29
30SN=$(system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $4}' | tail -c -8) #this grabs the last 7 of the serial number
31
32echo "${TT}${BB}${LL}${NN}${SN}" > /private/tmp/computerrenametext.txt
33
34EOD
35
36 ## Make script executable
37 /bin/chmod +x /private/tmp/computerrenamescript.sh
38
39 ## Run the script as logged in user
40 /bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/private/tmp/computerrenamescript.sh"
41
42 ## Get the new name from the local file
43 newComputerName=$(cat /tmp/computerrenametext.txt)
44
45 if [ ! -z "$newComputerName" ]; then
46 echo "$newComputerName"
47 ## Rename the computer to the new name
48 /usr/local/bin/jamf setComputerName -name "$newComputerName"
49 echo $newComputerName
50 scutil --set HostName $newComputerName
51 scutil --set LocalHostName $newComputerName
52 scutil --set ComputerName $newComputerName
53 dscacheutil -flushcache
54 jamf recon
55 ## Remove local script
56 rm -f /private/tmp/computerrenamescript.sh
57
58 exit 0
59 else
60 echo "No name was found to rename to"
61
62 ## Remove local script
63 rm -f /private/tmp/computerrenamescript.sh
64
65 exit 1
66 fi
67else
68 echo "No-one logged in. Exiting"
69 exit 0
70fi

Best answer by tlarkin

So, I was looking for a random post to do my #100daysofcode tonight and this was the first post that asked for script help. So, here is my Python version of this. It does not require TCC/PPPC and I tried to mimic your requirements as well as I could. Basically if you can get rid of the tell application parts of Applescripts in 10.14+ you can avoid a lot of the TCC/PPPC prompts.

1#!/usr/bin/python
2
3import subprocess
4from SystemConfiguration import SCDynamicStoreCopyConsoleUser
5import sys
6import plistlib
7
8# vars for current user
9USER, UID, GID = SCDynamicStoreCopyConsoleUser(None, None, None)
10# dialogs
11BRAND = """
12set BRAND to text returned of (display dialog "Please input the brand - AA = AA, AB = AB, AC = AC," default answer "" with title "Brand")
13"""
14LOCATION = """
15set MacLoc to text returned of (display dialog "Please enter the location - BA = BA, BB = BB, BC = BC" default answer "" with title "Location")
16"""
17DEPARTMENT = """
18set DEPARTMENT to text returned of (display dialog "Please enter department - 01 = 01, 02 = 02, " default answer "" with title "Department")
19"""
20MODEL = """
21set MacTYPE to text returned of (display dialog "Please input the machine type - MD = Desktop, ML = Laptop, " default answer "" with title "Mac Model")
22"""
23# functions
24
25def get_serial():
26 """get last 7 characters of serial number"""
27 # system profiler command
28 cmd = ["system_profiler", "SPHardwareDataType", "-xml"]
29 # run the command
30 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
31 out, err = proc.communicate()
32 # load output into a var
33 data = plistlib.readPlistFromString(out)
34 # grab sreial number, mutate serail to last 7 characters
35 serial = data[0]["_items"][0]["serial_number"]
36 serial = serial[-7:]
37
38 return serial
39
40
41def computer_name(name):
42 """name computer function"""
43 # options for scutil, since macOS has 3 hostnames
44 options = ["HostName", "ComputerName", "LocalHostName"]
45 # loop through options and pass the name to set it
46 for option in options:
47 subprocess.call(["scutil", "--set", option, name])
48
49
50def osascript(osastring):
51 """Wrapper to run AppleScript commands"""
52 # command to run the applescripts
53 cmd = ['/usr/bin/osascript', '-e', osastring]
54 # execute subprocess with commands
55 proc = subprocess.Popen(cmd, shell=False, bufsize=1,
56 stdin=subprocess.PIPE,
57 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
58 (out, err) = proc.communicate()
59 # test for non zero exit status
60 if proc.returncode != 0:
61 print('Error: ', err.decode('UTF-8'))
62 # if we get output return it
63 if out:
64 return out.decode('UTF-8').rstrip('
65')
66 return u''
67
68
69def main():
70 """run the logic"""
71 # if at login window USER will return None
72 # exit if we find _mbsetupuser
73 if USER is not None and USER != "_mbsetupuser":
74 # prompt for brand
75 brand = osascript(BRAND).decode('utf-8')
76 # prompt for location
77 loc = osascript(LOCATION).decode('utf-8')
78 # prompt for department
79 dept = osascript(DEPARTMENT).decode('utf-8')
80 # get the last 7 characters of the serial number
81 ser = get_serial()
82 # prompt for model
83 model = osascript(MODEL).decode('utf-8')
84 # build the computer name
85 name = str(model + brand + loc + dept + ser)
86 # set the computer name
87 computer_name(name)
88 else:
89 # if at login window or _mbsetupuser found, exit
90 sys.exit(0)
91
92
93if __name__ == "__main__":
94 main()

if you wanted all the characters to be uppercase too, that would be super easy to do in Python, just call .upper() to capitalize them.

Hope this helps, and thanks for the problem so I can count this toward my #100daysofcode

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

9 replies

Forum|alt.badge.img+9
  • Contributor
  • 154 replies
  • July 14, 2020

Hi @jwojda,
For the computer model you can use:

1#Determine Mac Type
2hwIdentifier=$(sysctl -n hw.model)
3
4#Simplify the model type
5if [[ "$hwIdentifier" =~ "MacBookPro" ]] ; then
6modelType="MBP"
7elif [[ "$hwIdentifier" =~ "MacBookAir" ]] ; then
8modelType="MBA"
9elif [[ "$hwIdentifier" =~ "iMac" ]] ; then
10modelType="iMac"
11elif [[ "$hwIdentifier" =~ "MacBook" ]] ; then
12modelType="MB"
13elif [[ "$hwIdentifier" =~ "Macmini" ]] ; then
14modelType="MM"
15elif [[ "$hwIdentifier" =~ "MacPro" ]] ; then
16modelType="MP"
17fi

I worked on a similar script in this thread Script: Best way to request user input.

Are there always just 3 options? It may be easier if you offer your users a dropdown menu like:

1#!/bin/sh
2#Applescript list to bash variable output
3
4brandSelected=$( osascript<<APPLESCRIPT
5
6tell application "System Events" to set selectBrand to {"AA", "AB", "AC"}
7
8set selectBrand to choose from list selectBrand with prompt "Please input the brand - AA = AA, AB = AB, AC = AC," default items {"AA"}
9
10selectBrand
11
12APPLESCRIPT
13)
14
15echo $brandSelected

ImAMacGuy
Forum|alt.badge.img+23
  • Author
  • Esteemed Contributor
  • 1310 replies
  • July 15, 2020

@shaquir Thanks! I will give that a try. There are always those 4 inputs and then part of the serial number.

I can try setting up the menu, theoretically those would wait till something is selected?


Forum|alt.badge.img+9
  • Contributor
  • 154 replies
  • July 15, 2020

I'm a little confused by the local script within a script approach. Was there any other complication you ran into when you first wrote it?

Also, what's the urgency for users to update it (are they existing users that need to update the naming or new users)?
- I ask to try and determine the best approach, jamf policy/script wise, to ensure it runs when an actual user is signed in.


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • Answer
  • July 15, 2020

So, I was looking for a random post to do my #100daysofcode tonight and this was the first post that asked for script help. So, here is my Python version of this. It does not require TCC/PPPC and I tried to mimic your requirements as well as I could. Basically if you can get rid of the tell application parts of Applescripts in 10.14+ you can avoid a lot of the TCC/PPPC prompts.

1#!/usr/bin/python
2
3import subprocess
4from SystemConfiguration import SCDynamicStoreCopyConsoleUser
5import sys
6import plistlib
7
8# vars for current user
9USER, UID, GID = SCDynamicStoreCopyConsoleUser(None, None, None)
10# dialogs
11BRAND = """
12set BRAND to text returned of (display dialog "Please input the brand - AA = AA, AB = AB, AC = AC," default answer "" with title "Brand")
13"""
14LOCATION = """
15set MacLoc to text returned of (display dialog "Please enter the location - BA = BA, BB = BB, BC = BC" default answer "" with title "Location")
16"""
17DEPARTMENT = """
18set DEPARTMENT to text returned of (display dialog "Please enter department - 01 = 01, 02 = 02, " default answer "" with title "Department")
19"""
20MODEL = """
21set MacTYPE to text returned of (display dialog "Please input the machine type - MD = Desktop, ML = Laptop, " default answer "" with title "Mac Model")
22"""
23# functions
24
25def get_serial():
26 """get last 7 characters of serial number"""
27 # system profiler command
28 cmd = ["system_profiler", "SPHardwareDataType", "-xml"]
29 # run the command
30 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
31 out, err = proc.communicate()
32 # load output into a var
33 data = plistlib.readPlistFromString(out)
34 # grab sreial number, mutate serail to last 7 characters
35 serial = data[0]["_items"][0]["serial_number"]
36 serial = serial[-7:]
37
38 return serial
39
40
41def computer_name(name):
42 """name computer function"""
43 # options for scutil, since macOS has 3 hostnames
44 options = ["HostName", "ComputerName", "LocalHostName"]
45 # loop through options and pass the name to set it
46 for option in options:
47 subprocess.call(["scutil", "--set", option, name])
48
49
50def osascript(osastring):
51 """Wrapper to run AppleScript commands"""
52 # command to run the applescripts
53 cmd = ['/usr/bin/osascript', '-e', osastring]
54 # execute subprocess with commands
55 proc = subprocess.Popen(cmd, shell=False, bufsize=1,
56 stdin=subprocess.PIPE,
57 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
58 (out, err) = proc.communicate()
59 # test for non zero exit status
60 if proc.returncode != 0:
61 print('Error: ', err.decode('UTF-8'))
62 # if we get output return it
63 if out:
64 return out.decode('UTF-8').rstrip('
65')
66 return u''
67
68
69def main():
70 """run the logic"""
71 # if at login window USER will return None
72 # exit if we find _mbsetupuser
73 if USER is not None and USER != "_mbsetupuser":
74 # prompt for brand
75 brand = osascript(BRAND).decode('utf-8')
76 # prompt for location
77 loc = osascript(LOCATION).decode('utf-8')
78 # prompt for department
79 dept = osascript(DEPARTMENT).decode('utf-8')
80 # get the last 7 characters of the serial number
81 ser = get_serial()
82 # prompt for model
83 model = osascript(MODEL).decode('utf-8')
84 # build the computer name
85 name = str(model + brand + loc + dept + ser)
86 # set the computer name
87 computer_name(name)
88 else:
89 # if at login window or _mbsetupuser found, exit
90 sys.exit(0)
91
92
93if __name__ == "__main__":
94 main()

if you wanted all the characters to be uppercase too, that would be super easy to do in Python, just call .upper() to capitalize them.

Hope this helps, and thanks for the problem so I can count this toward my #100daysofcode


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • July 15, 2020

Also, instead of prompting for Model you can probably get that in code and not prompt, but I put the prompt in since you put it in your requirements


ImAMacGuy
Forum|alt.badge.img+23
  • Author
  • Esteemed Contributor
  • 1310 replies
  • July 15, 2020

@tlarkin that's awesome, what I needed! The model I tried to do on my own but couldn't get it to work properly ever. The only other thing that I've noticed a few times is that people put in too many characters, which was causing the binding was failing due to being over 15characters total. would it be difficult to add a limit of 2 characters per input to help prevent user error?

I came across this that talks about limiting to a certain amount of characters, but the examples look like they would be in a different structure than what you had done.


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • July 15, 2020

You found it, so Python has a built in called len() which you can use to count instances, or characters in different data types.

1>>> string = "abc123"
2>>> len(string)
36
4>>> if len(string) > 2:
5... print("violation, can only be 2 characters")
6...
7violation, can only be 2 characters

Do you map LDAP users to the "User and Location" info in jamf?


ImAMacGuy
Forum|alt.badge.img+23
  • Author
  • Esteemed Contributor
  • 1310 replies
  • July 15, 2020

@tlarkin we don't, in the cloud, but don't have any of the JIM servers stood up... yet.


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • July 15, 2020

you can use LDAP EAs to deploy user info locally via profile. So like dept, user name, email, etc.

1% defaults read /Library/Managed Preferences/email.plist
2{
3 email = "tom.larkin@acmecorp.com";
4}

That is an example of something I payload to all users, so you could look at something like this and then scrape that data later on.


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