Posted on 08-15-2018 02:03 AM
Hi,
I have created a force shutdown script with the help of numerous website and forum:
#!/bin/sh
# First, a little warning:
/usr/bin/osascript << EOT
display dialog "This is a message from the IT Department
Your computer will restart in 15 seconds" giving up after 7 with icon stop buttons {"OK"} default button "OK"
set input to 15
set countdown to input
repeat input times
display dialog "Time remaining!! " & countdown giving up after 1 buttons {"OK"} default button "OK"
set countdown to countdown - 1
end repeat
beep
EOT
# Now we shutdown the computer:
sudo shutdown && exit 0
I push this script via Apple Remote Desktop and if the computer is connected via Ethernet, the Task on ARD completes successfully. But if the computer is connected to the network over the Wi-Fi, then the task remains on "running" and even after a reboot of the client, the task will never return completed or failed... I have to stop the task in order to push the script to an other machine.
What do I need to do on my script so that it returns something to the deployment software, whether it is connected by Ethernet or Wi-Fi?
Thank you in advance for anyone spending some time on my issue.
Posted on 08-15-2018 05:02 AM
Hello @Manu This sounds like an issue is with ARD and not your script. I noticed when I usually use ARD it works better when my computer is on ethernet instead on the wifi. Have you tried plugging the computer you are using to run the script into ethernet? Also have you tried to run the script using Jamf Remote?
Posted on 08-15-2018 06:25 AM
Thank you @gabe2385 for your time. I think the reason ARD's task would say completed when the target computer is connected to Ethernet is because the Ethernet service would stop running once the computer power off. Therefore ARD would be aware that the script has been executed.
But if the target computer is on Wi-Fi, maybe the WiFi service terminates before the script is finished executed and therefore cannot return an exit 0.
Ideally, I would have liked to find a way for my script to return an exit 0 before it finish running the script...
Unfortunately, my company doesn't have Jamf yet, and we are looking into it. The other deployment software that we use is LANDesk and same as ARD, the software doesn't know that the script has finished running because it doesn't return the exit 0.
Posted on 08-15-2018 10:08 AM
Consider putting a 1 minute delay in the shutdown and spinning off the process so your script can exit before it shuts down.
shutdown +1 &
exit 0
Posted on 08-16-2018 03:00 AM
Thanks @mm2270 it does the trick. At first, I wanted a shutdown "now", but I can accept a timer of a minute.
If anyone knows a way to return an exit 0 at the beginning of a script, please let me know, we never know, I may need it in the future.
Posted on 08-16-2018 06:35 AM
A 1-or-2 minute delay usually worked for me, but not always. You can also look at @alexjdale 's recommendation at https://www.jamf.com/jamf-nation/discussions/14940/restart-script-forked, where it actually creates a launchagent and script on the computer, then uses that to initiate the restart. The advantage of doing that is the restart isn't being done directly by the script, so it gives the script/policy ample time to finish running before the computer restarts. I've had the issue you described a few different times when the restart is triggered before a script had a chance to finish running and report back to the JSS, and it's definitely a pain when that happens.
Posted on 08-17-2018 03:14 AM
Thanks @el2493 for your help. I am not very familiar with CocoaDialog but the concept of having a shutdown script in the launchdeamon could resolve the problem. I will post my script later if it works!
Posted on 08-17-2018 05:17 AM
I'm not that familiar with Cocoadialog either, I ended up tweaking it to use jamfhelper. I had built my script to allow deferrals, but if you don't need deferrals it would look like this (haven't tested it, just edited out the deferrals). You'd need to set up parameter 4 (the path to the installed app) in JSS, I built it that way so that it would test to make sure an app was installed before restarting. I had a few cases where an app wouldn't install for some reason but the script would still run and ask a user to restart, if you don't really care about that and just want to force the user to restart then you can always strip out the part between "##Define Parameters" and "##Define commands":
#!/bin/bash -v
#borrowed heavily from alexjdale's restart script (https://www.jamf.com/jamf-nation/discussions/14940/restart-script-forked)
##Define Parameters
pathToApp="$4"
if [ -n "$pathToApp" ]; then
echo "pathToApp defined"
else
echo "pathToApp not defined, cancelling"
exit 1
fi
#Check to see if app exists, if it doesn't then installation failed
if [ -d "$pathToApp" ]; then
echo "App installed"
else
echo "App not installed, cancelling Policy"
exit 1
fi
##Define commands
#process for initial run with immediate restart
initRestart() {
# Create restart script
echo > /tmp/restartscript.sh '#!/bin/bash
#message information
msgRestartHead="Restart Pending"
msgRestart="This computer will restart in 2 minutes. Please save any open documents and close any open applications."
dialogicon="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/Resources/Message.png"
jamfhelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
shutdown -r +2
restartprompt=$("${jamfhelper}" -windowType utility -heading "${msgRestartHead}" -alignHeading center -description "${msgRestart}" -icon "${dialogicon}" -timeout 112)
exit 0'
# Create and load a LaunchDaemon to fork a restart
echo "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.company.restart</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>/tmp/restartscript.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>" > /tmp/restart.plist
sudo chown root:wheel /tmp/restart.plist
sudo chmod 755 /tmp/restart.plist
sudo launchctl load /tmp/restart.plist
}
initRestart
exit 0
Posted on 08-24-2018 03:36 AM
@el2493 Sorry for the delay of my reply, I have been working on many project and it is only now that I got to work on the script.
This new technic gives me the result that I was looking for. It shutdown the computer and returns an exit 0.
Unfortunately, I have now lost the content as it does not display the message (AppleScript Message).
This is my script, which is very similar to your's only I don't use jamfhelper message because I don't have it yet in the company.
#!/bin/bash
#
initShutdown() {
# Create shutdown script
echo > /tmp/Shutdown_Script.sh '#!/bin/bash
# First, a little warning:
/usr/bin/osascript << EOT
display dialog "This is a message from IT Support:
Your computer will restart in 15 seconds" giving up after 7 with icon stop buttons {"OK"} default button "OK"
set input to 15
set countdown to input
repeat input times
display dialog "Time remaining!! " & countdown giving up after 1 buttons {"OK"} default button "OK"
set countdown to countdown - 1
end repeat
beep
EOT
# Now we shutdown the computer:
sudo shutdown -h now && exit 0'
# Create and load a LaunchDaemon to fork a restart
echo "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.company.shutdown</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>/tmp/Shutdown_Script.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>" > /tmp/shutdown.plist
sudo chown root:wheel /tmp/shutdown.plist
sudo chmod 755 /tmp/shutdown.plist
sudo launchctl load /tmp/shutdown.plist
}
initShutdown
exit 0
I am sure I have missed something, but I can't put my finger on it...
I am going to continue working on it, because I have a feeling I am not far from find the solution.
Thanks again for your help on this!
Posted on 08-24-2018 05:16 AM
I think that jamfhelper is automatically installed on enrolled computers. I could be wrong about that, but I don't think we're doing anything special to install it onto computers (unless it's some setting in the JSS that I just haven't come across yet). You can check an enrolled computer to see if it exists at /Library/Application Support/JAMF/bin/jamfHelper.app. I'm not that familiar with AppleScript (I sort of learn just enough of it to do what I need to do at any given time), so I can't provide any help there unfortunately.
Posted on 08-24-2018 06:47 AM
@el2493 No worries, you have been very helpful already and I feel I am not far off. Thanks again!!