Script to rename Mac

macboy
Contributor

I am running a script that will ask the end user to enter the machine name. It will not work through Casper (remotely or in a policy) but will work fine if I run it locally. Any ideas why it may not be running? I have included the script below.

!/bin/bash

ComputerName=`/usr/bin/osascript <<EOT
tell application "System Events" activate set ComputerName to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2)
end tell
EOT`

Set New Computer Name

echo $ComputerName
scutil --set HostName $ComputerName
scutil --set LocalHostName $ComputerName
scutil --set ComputerName $ComputerName

echo Rename Successful

exit

Very odd the script runs fine when ran locally through the terminal. But stalls and never runs and never errors out when ran through a policy or through remote.

Thank you.

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

The problem is the Applescript (osascript) call in your script. Applescript messages that call for user interaction don't work well when they are done via a root session, the way a Casper Suite policy will do. Its not Casper's fault. Its the OS doing its job of protecting the user space. Essentially osascript commands called by root can't display to the logged in user (unless the user logged in is root of course)

There are a few ways around it. You can try calling the command as the user with a sudo -u $loggedInUser type syntax, but sometimes even this doesn't work. The more reliable way would be to use launchctl asuser (10.10 & 10.11), orlaunchctl bsexec (10.9 and below)

Another way would be to ditch Applescript and use something like cocoaDialog, which doesn't run into the same restrictions. But this would mean deploying a custom tool to your Macs. You may not want to do that, and I'd understand. Though cocoaDialog, while old now, is still very useful in many regards.

For using launchctl, you can try something like this. Keep in mind this will only work on 10.10 and 10.11. The 'asuser' syntax doesn't exist in earlier OSes.

#!/bin/bash

loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")

ComputerName=$(/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/usr/bin/osascript -e 'tell application "System Events" to set ComputerName to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2)'")

echo "$ComputerName"

Just fill out the remainder of the script with the rest of what you wrote. The above should work, but I only wrote this right here and didn't test it, so give it a try.

View solution in original post

57 REPLIES 57

DBrowning
Valued Contributor II

I have a very similar script but I run mine via Self Service.

macboy
Contributor

I am trying to run it during prestage so it needs to run when the Mac gets placed into the JSS. It will make call to it but it never runs the script. So I tried it by itself not running during that process and it doesn't work. I do not want the end user to have to go into self service.

thoule
Valued Contributor II

I see you are calling 'osascript'. A policy run via the JSS does not have access to a user's working environment. That makes things like notification windows or running a launch agent very difficult. Jamfers have typically used bsexec or sudo as user to try.

If you run the script though Self Service, it is rooted in the user's process, so then it is allowed to create the dialog boxes you are looking for.

To fix this, search for some postings about notifications to users and how they do it. With 10.11, I've pretty much given up trying to fight that dragon. or actually, I just use jamfHelper which seems to usually be able to present to the user without trouble.

Kaltsas
Contributor III

This is what I use in my DEP workflow to prompt for naming the machine. Maybe you can adapt it to your needs. I don't set the host name because I have another script that runs on all machines that sets the host name from the ComputerName (this resolves some issues with EPO)

#!/bin/bash

/usr/bin/osascript << EOF 
property compName : ""

repeat while compName is ""
    tell application "Finder"
        activate
        display dialog "What should this computer be named:" default answer compName
        set compName to text returned of result
    end tell
end repeat

try
    do shell script "hostname " & quoted form of compName 
on error errorMsg number errorNum
    display alert "Error " & errorNum message errorMsg buttons "Cancel" default button 1
end try
EOF

name=$(hostname)
scutil --set ComputerName "${name}"
scutil --set LocalHostName "${name}"

CAJensen01
Contributor
  1. You need quotes in the echo "Rename Successful"

Otherwise, this worked as expected for me as a policy.

#!/bin/bash
ComputerName=`/usr/bin/osascript << EOT
tell application "System Events"
    activate 
    set ComputerName to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2)
end tell
EOT`

#Set New Computer Name
echo $ComputerName
scutil --set HostName $ComputerName
scutil --set LocalHostName $ComputerName
scutil --set ComputerName $ComputerName

echo "Rename Successful"

exit 0

dgreening
Valued Contributor II

I use a script which leverages CocoaDialog to prompt local support for the new machine name and accomplishes a re-bind to AD via a custom policy trigger. This policy has an Update Inventory on it already, so its not in this script:

#!/bin/sh
########################################################################
# Created By: Ross Derewianko Ping Identity Corporation
# Creation Date: February, 2015 
# Last modified: December 14th, 2015
# Modified for Sapient: December 14th, 2015 - Daniel Greening
# Brief Description: Changes machine hostname
########################################################################

#check for CocoaDialog & if not install it

if [ -d "/Library/Application Support/JAMF/bin/CocoaDialog.app" ]; then
    CoDi="/Library/Application Support/JAMF/bin/CocoaDialog.app/Contents/MacOS/cocoaDialog"
else
    echo "CocoaDialog.app not found installing" 
    jamf policy -event cocoa
    CoDi="/Library/Application Support/JAMF/bin/CocoaDialog.app/Contents/MacOS/cocoaDialog"
fi

########################################################################
# Functions
#######################################################################

#asks for the new hostname & then call in the cleaner!

function cdprompt() {
    hostname=`"$CoDi" standard-inputbox --float --title "Sapient LS Computer Rename Utility" --informative-text "Enter the new computer name using Sapient naming convention:"`

    if [ "$hostname" == "2" ]; then
        echo "user cancelled"
        exit 1
    fi
    cleanhostname
}

#cleans the first two characters out (cocoaDialog adds a 1 
 to the string value which we don't need.)

function cleanhostname() {
    hostname=${hostname:2}
}

#checks for a blank hostname, and if its blank prompt agian 

function checkforblank() {
    while [[ -z $hostname && {$hostname+1} ]]
    do
        cdprompt
    done
}

function sethostname() {
    scutil --set HostName $hostname
    scutil --set ComputerName $hostname 
    scutil --set LocalHostName $hostname
}

########################################################################
# Script
########################################################################

cdprompt
checkforblank
sethostname
jamf policy -event ADBind

rderewianko
Valued Contributor II

Here's yet another way it could be written (this one was just more for fun)
Your version pasted was problematic... You need to paste the script with three ticks (the key beside 1) on the front end of the script and the end. Otherwise markup gets in the way.

#!/bin/bash
###functions
function machinename () {
    osascript <<EOT
        tell application "Finder"
            activate
            set nameentry to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2)
            end tell
EOT
}

function renameComputer(){
    #Set New Computer Name
    echo "The New Computer name is: $ComputerName"
    scutil --set HostName $ComputerName
    scutil --set LocalHostName $ComputerName
    scutil --set ComputerName $ComputerName

    echo Rename Successful
}

###Script
ComputerName=$(machinename) 
renameComputer
exit 0

```

mm2270
Legendary Contributor III

The problem is the Applescript (osascript) call in your script. Applescript messages that call for user interaction don't work well when they are done via a root session, the way a Casper Suite policy will do. Its not Casper's fault. Its the OS doing its job of protecting the user space. Essentially osascript commands called by root can't display to the logged in user (unless the user logged in is root of course)

There are a few ways around it. You can try calling the command as the user with a sudo -u $loggedInUser type syntax, but sometimes even this doesn't work. The more reliable way would be to use launchctl asuser (10.10 & 10.11), orlaunchctl bsexec (10.9 and below)

Another way would be to ditch Applescript and use something like cocoaDialog, which doesn't run into the same restrictions. But this would mean deploying a custom tool to your Macs. You may not want to do that, and I'd understand. Though cocoaDialog, while old now, is still very useful in many regards.

For using launchctl, you can try something like this. Keep in mind this will only work on 10.10 and 10.11. The 'asuser' syntax doesn't exist in earlier OSes.

#!/bin/bash

loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")

ComputerName=$(/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" "/usr/bin/osascript -e 'tell application "System Events" to set ComputerName to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2)'")

echo "$ComputerName"

Just fill out the remainder of the script with the rest of what you wrote. The above should work, but I only wrote this right here and didn't test it, so give it a try.

rderewianko
Valued Contributor II

@dgreening I love that script.

macboy
Contributor

Your script errored out as well. It did work if ran locally but not through Remote.

mm2270
Legendary Contributor III

Hi @macboy Whose script were you referring to?

macboy
Contributor

Sorry I was referring to @Kaltsas .

Kaltsas
Contributor III

It runs locally on a machine after a DEP machine is enrolled so that seems plausible. It's kind of a kludge and I'm already seeing way better ways to do this in this thread than I am.

macboy
Contributor

That seems to work @mm2270 . It worked for me remotely now I will try it through a policy but imagine it will work fine. Thank you so much.

rderewianko
Valued Contributor II

@dgreening I love that script ;)

dgreening
Valued Contributor II

@rderewianko Yes! Thanks for creating the original! It works GREAT (and ensures that our local support staff does not skip steps in the rename process)!

rderewianko
Valued Contributor II

I recently published another version I've been toying with. For renaming a bound machine (and changing the name in AD) Here

dgreening
Valued Contributor II

@rderewianko Dead link. :)

rderewianko
Valued Contributor II

jhuls
Contributor III

I keep seeing mixed comments regarding renaming machines. I see some stating to do the following...

scutil --set HostName $ComputerName
scutil --set LocalHostName $ComputerName
scutil --set ComputerName $ComputerName

Then I've read some posts that state to only do...

scutil --set LocalHostName $ComputerName
scutil --set ComputerName $ComputerName

Those same people say to never set HostName. Does anyone here know why and can explain it in plain english?

stevewood
Honored Contributor II
Honored Contributor II

@jhuls I believe, and someone correct me please if I am wrong, that changing the HostName will affect your Active Directory bind if you are bound to AD. I believe that the HostName is the name that you see in AD, and if your computer is bound when you change it, you could break that bind.

bcrockett
Contributor III

Have folks had success with this type of script in a macOS10.13+ deployment?

rderewianko
Valued Contributor II

If you're talking about the one above, Here

Cocoa Dialogue does not work on 10.13 there is a new version in development.
Here but there has yet to be a release.

yadin
Contributor

I'm doing this with a one liner in a Policy under Files and Processes -> Execute command

var=$(osascript -e 'tell application "Finder" to set CompName to text returned of (display dialog "Enter the proper machine name" with title "Improper Machine Name" default answer"")') && var2=$(echo "$var" | tr '[:lower:]' '[:upper:]') && jamf setComputerName -name $var2

This pops up a simple prompt for a name, uppercases it, and sets it using the jamf command that takes care of all 3 of the commands others have mentioned using. I have this Policy scoped to a smart group based on name prefix. The only down side so far is that there seems to be a 20 min delay until the console reflects this new name, which means the prompt may come up again.

csa
New Contributor III

Anyone had success doing this for domain bound machines with AD (mobile managed) user accounts?

yadin
Contributor

Not sure what you mean. You have to name the machine before you bind to AD, and renaming after that means local name and domain record are out of sync (which is why Windows doesn't allow that). So I guess my answer is yes, we name the machine and then bind it to AD, and that's all automated where possible using DNS as a setup requirement, and then the user logs in with their domain account and we use mobility settings for offline access later.

csa
New Contributor III

sorry I should have clarified. We have several machines that were "accidentally" bound to AD with names that don't follow our standards. I was wondering if anyone had success in changing machines names post AD bind and still preserving the domain account setup of the user.

yadin
Contributor

I've not done that recently. And by recently I mean since OS 10.9 I think.... but as I understand it and remember it, it's as I said. The system name has no impact on the bind record name because the AD plugin is completely separate from the name in Sharing in every way. As such, changing the name would have no impact on the domain logins or cached accounts. In the other direction, if I'm not mistaken, you can script binding to happen to a record name other than defaulting to the machine name. I'd say grab a test machine to make sure before deploying something though :)

csa
New Contributor III

Thank you. Did not realize that Bind record and Machine name are not related. Changing machine name thru JAMF (post binding) causes failure when adding a new domain account to the system. Have to unbind and rebind to fix. Will test having separate names on our lab machine and update.

yadin
Contributor

Hmmm.... I'm assuming if you send a rename through JAMF it's using the jamf setcomputername functionality which is doing at least 3 rename commands at the system level, possibly more. If you simply send a terminal command to set computername and localhostname (I think those are the two set in Sharing UI) I think you'll be fine (but again that means hostname and the AD record will differ so YMMV). Whatever JAMF is doing (again I assume you're just using the rename UI command in the console) it must also be changing the ID for the AD plugin which obviously breaks the bind. Yes it would be most clean to unbind and rebind with everything having the right name, but....
Good luck!

csa
New Contributor III

Yes thats what I am going to ask our team to test. See which breaks the bind functionality:
scutil --set HostName $ComputerName
scutil --set LocalHostName $ComputerName
scutil --set ComputerName $ComputerName

daniel_ross
Contributor III

One thing that popped up for me when running @rderewianko's script was to allow a JAMF process. I'm going to assume that's a KEXT of some sort that I can whitelist?

mhegge
Contributor III

@rderewianko Using your script, I am getting the following:

Script result: 46:54: execution error: An error of type -10810 has occurred. (-10810)
The New Computer name is: SCPreferencesSetHostName() failed: No such key
SCPreferencesSetLocalHostName() failed: No such key
Could not open prefs: No such key
Rename Successful


!/bin/bash

functions

function machinename () { osascript <<EOT tell application "Finder" activate set nameentry to text returned of (display dialog "Please Input New Computer Name" default answer "" with icon 2) end tell
EOT
}

function renameComputer(){ #Set New Computer Name echo "The New Computer name is: $ComputerName" scutil --set HostName $ComputerName scutil --set LocalHostName $ComputerName scutil --set ComputerName $ComputerName

echo Rename Successful
}

Script

ComputerName=$(machinename) renameComputer
exit 0

walt
Contributor III

@daniel_ross that is part of TCC, since its using a tell event it appears. same thing occurs with our similar script. We are trying to figure out a way to whitelist that but have not been able to yet.

MikaelDez
Contributor

I'm trying to accomplish the same thing, renaming a mac using Self Service. Has anyone had any luck with macOS 10.14/15? I used mm270's script (as well as others). When I select the policy in Self Service, it executes and hangs up on "Running", no other response.

dlondon
Valued Contributor

Hi @mikedesmarais, @Mauricio gave me some good pointers here: https://www.jamf.com/jamf-nation/discussions/33691/self-service-get-user-input-with-script

Here's my hacked version of his script which I have in Self Service and looks to be working in Mojave and Catalina.
Note - I think I needed to create a Configuration Profile to give jamf greater access to avoid a PPPC popup.

#!/bin/bash
# GetUserInputFromSelfService-ComputerName.bash
# slightly modified from suggestion by Mauricio Pellizzon https://www.jamf.com/jamf-nation/discussions/32795/script-best-way-to-request-user-input
# 2019-10-29

userName=$(ls -la /dev/console | cut -d " " -f 4)

user_entry=""

validateResponce() {
    case "$user_entry" in
        "noinput" ) echo "empty input" & askInput ;;
        "cancelled" ) echo "time out/cancelled" & exit 1 ;;
        * ) echo "$user_entry"  ;;
    esac
}

askInput() {
user_entry=$(sudo -u "$userName" osascript <<EOF
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set theTextReturned to "nil"
tell application "System Events"
activate
try
set theResponse to display dialog "Please enter Computer Name" with title "Get Computer Name" buttons "Save" default button "Save" default answer ""
set theTextReturned to the text returned of theResponse
end try
if theTextReturned is "nil" then
return "cancelled"
else if theTextReturned is "" then
return "noinput"
else
return theTextReturned
end if
end tell
EOF
)
validateResponce "$user_entry"
}

askInput "$userName"

# Make it lower case - just a convention
lower="$(echo $user_entry | tr [:upper:] [:lower:])"

#/usr/local/bin/jamf setComputerName -name $user_entry
/usr/local/bin/jamf setComputerName -name $lower

# Update the server so it knows the name
/usr/local/bin/jamf recon

exit 0

KMak84
Contributor

I am having issues with my renaming convention. At the point of enrollment.

As we have soo many Non DEP machines, we are doing a Web Enrollment method.

So it will start with

  1. Change Machine Name @Enrollment trigger
  2. Base Apps @Enrollment trigger

So I used @rderewianko script it prompts but when I the second @enrollment trigger kicks in, towards the end it will bind to AD. It binds to AD with the name as an example "Macbook Air" but the machine when I have checked it in system preferences etc it is what I entered when the dialogue box appears.

Any ideas what may have gone wrong

KMak84
Contributor

I was using this originally but it was so problematic to get the user dialogue box to appear.

!/bin/sh

###########################################################################

Change Computer Name

###########################################################################

hostname=$(/usr/bin/osascript <<-'EOF'
tell application "System Events" activate set input to display dialog "Enter New Computer Name: " default answer "" buttons {"OK"} default button 1 return text returned of input as string
end tell
EOF
)
echo "$hostname"

###########################################################################

Set New Computer Name

###########################################################################

scutil --set ComputerName "$hostname"
scutil --set LocalHostName "$hostname"
scutil --set HostName "$hostname"

sleep 20

exit 0 ## Success
exit 1 ## Failure

larry_barrett
Valued Contributor

I pared this down so I can just type in what I want to name the computer. I run it as a Self Service policy only for Techs. My only practical use will be when we wipe devices and reassign them.

#!/bin/sh
#  Name Your Computer.sh
#  
#
#  Created by Carey-Peterson, Rob on 10/25/19.
#  

tag=$(/usr/bin/osascript << EOD
tell application "System Events"
activate
set AssetTag to text returned of (display dialog "What is your Computer name?" default answer "" buttons {"Continue"} default button 1)
end tell
EOD)


#This takes the data collected from the user and sets it as the Computer Name and submits the name to the Jamf API

deviceName="$tag"

#set all the name in all the places
/usr/local/bin/jamf setcomputername -name "$deviceName"
/usr/local/bin/jamf recon