Skip to main content
Question

Restarting the Jamf binary when Macs stopping checking in


Show first post

50 replies

jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • March 2, 2023
itinspectorio wrote:

I have a question if you please. Do we upload plist via Profile, create policy with 


/bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist


But where we input Script? Also in this policy? 

 


You install the script (say via a package) to the Mac in this location;

/Library/Scripts/jamfRestart.sh

 It has to run on the Mac, as the JamfBinary may not be working and not checking in.


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • March 2, 2023
MatG wrote:

@jamesandre 
is there a way to test this out on a Mac that is working fine?


In the script you could substitute the Jamf binary for an App that you've had open for more than a day, say

"/usr/local/[j]amf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300"

for 

"/Applications/Microsoft Outlook.app/Contents/MacOS/Microsoft Outlook"

 

Then run the script. 

 

 


Forum|alt.badge.img+5
  • New Contributor
  • 8 replies
  • April 25, 2023
itinspectorio wrote:

I have a question if you please. Do we upload plist via Profile, create policy with 


/bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist


But where we input Script? Also in this policy? 

 


i mashed together a single script that should create the files in the proper locations and start the launchdaemon. this makes it easier to install via a jamf policy for newbies like me. you still need to setup the computer extension attribute for the reporting. 

 

#!/bin/bash cat << 'EOF' > /Library/Scripts/jamfRestart.sh #!/bin/bash processRuntime=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300" | awk '{ print $3; }' | grep -o '.*[-]' | awk -F\\- '{print $1}') processCheck=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300" | awk '{ print $2; }') logLocation="/var/log/jamfRestart.log" scriptLogging(){ DATE=`date +%Y-%m-%d\\ %H:%M:%S` LOG="$logLocation" echo "$DATE" " $1" >> $LOG } if [ "${processRuntime}" = "" ]; then scriptLogging "JamfBinary has not run for more than 1 day" else scriptLogging "JamfBinary has run for ${processRuntime} days" scriptLogging "JamfBinary Process ID: ${processCheck}" scriptLogging "Quitting JamfBinary..." sudo kill -9 ${processCheck} fi exit 0 EOF chmod 644 /Library/Scripts/jamfRestart.sh chown root:wheel /Library/Scripts/jamfRestart.sh cat << EOF > /Library/LaunchDaemons/com.example.jamfRestart.plist <?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.example.jamfrestart</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>/Library/Scripts/jamfRestart.sh</string> </array> <key>RunAtLoad</key> <false/> <key>StartInterval</key> <integer>86400</integer> </dict> </plist> EOF chmod 644 /Library/LaunchDaemons/com.example.jamfRestart.plist chown root:wheel /Library/LaunchDaemons/com.example.jamfRestart.plist /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

 


Forum|alt.badge.img+10
  • Valued Contributor
  • 193 replies
  • April 25, 2023

@MCfreiz Nice...just out of interest how can this be tested?


connorb
Forum|alt.badge.img+4
  • New Contributor
  • 4 replies
  • July 27, 2023

Hi @jamesandre, do you think it's necessary at all to call a jamf recon and/or jamf policy once the binary has been killed?

I'm thinking of implementing this into my organization but just want to be sure there isn't anything additional I should throw in to get the devices talking back immediately.


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • August 15, 2023
connorb wrote:

Hi @jamesandre, do you think it's necessary at all to call a jamf recon and/or jamf policy once the binary has been killed?

I'm thinking of implementing this into my organization but just want to be sure there isn't anything additional I should throw in to get the devices talking back immediately.


You can add that if you want, should not cause any harm.


Forum|alt.badge.img+5
  • Contributor
  • 32 replies
  • September 6, 2023

@jamesandre Just curious why you are choosing to look for:
/usr/local/jamf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300

instead of just

/usr/local/jamf/bin/jamf policy

I get this message if I try to interrupt:
/usr/local/jamf/bin/jamf policy -event CLIENT_CHECKIN -stopConsoleLogs

Would it better to look for just "jamf policy" so you catch more?  Is there a downside?  What if the binary gets hung during an inventory cycle?  Should we also be looking for other actions like recon?  

 


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • September 12, 2023
chelm wrote:

@jamesandre Just curious why you are choosing to look for:
/usr/local/jamf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300

instead of just

/usr/local/jamf/bin/jamf policy

I get this message if I try to interrupt:
/usr/local/jamf/bin/jamf policy -event CLIENT_CHECKIN -stopConsoleLogs

Would it better to look for just "jamf policy" so you catch more?  Is there a downside?  What if the binary gets hung during an inventory cycle?  Should we also be looking for other actions like recon?  

 


Testing my memory here... I think "/usr/local/jamf/bin/jamf policy -stopConsoleLogs -randomDelaySeconds 300" was what I was seeing every time we had an issue. 

Looks like it has changed to "/usr/local/jamf/bin/jamf policy -stopConsoleLogs -runOnQueue -randomDelaySeconds 300", so looking for "/usr/local/jamf/bin/jamf policy" might be a better option now.

It doesn't seem to be such a big issue now, I'm not seeing issues with softwareupdated anymore.


Forum|alt.badge.img
  • New Contributor
  • 1 reply
  • September 28, 2023

@jamesandre newbe here, thank you for this, I have been searching for a solution to this problem for a while now. I am trying to implement your solution as we have been running into this issue with about 30 or so macs not checking in and with the amount of developers we have, scheduled restarts are not a viable option.

During testing I am failing to get the LaunchDaemon to load. When using the command sudo /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist I am getting the error: Load failed: 5: Input/output error. 

I have verified that the .plist file and script are in the right places. Any ideas on what could be causing this?

 


Forum|alt.badge.img+14
  • Contributor
  • 29 replies
  • October 16, 2023
bsmithAP wrote:

@jamesandre newbe here, thank you for this, I have been searching for a solution to this problem for a while now. I am trying to implement your solution as we have been running into this issue with about 30 or so macs not checking in and with the amount of developers we have, scheduled restarts are not a viable option.

During testing I am failing to get the LaunchDaemon to load. When using the command sudo /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist I am getting the error: Load failed: 5: Input/output error. 

I have verified that the .plist file and script are in the right places. Any ideas on what could be causing this?

 


@jamesandre I'm seeing the same error as @bsmithAP : Load failed: 5: Input/output error 

Any solutions for this?


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • October 25, 2023

I'm just coming across this, because I'm also seeing a fair number of devices not checking in, even though the Macs are confirmed to be online.

I noticed a typo in your script. You define the variable for the log location as logLocation, but then in the function you are echoing out to a variable labeled $LOG

echo "$DATE" " $1" >> $LOG

Other than that, good work on this. I plan on doing some testing with it to see if it improves our situation.

Never mind! I see now that you define LOG by assigning it to $logLocation. All good!

As for those saying just reboot your Macs, well, yeah, that is ideal, but it's much harder to enforce in some environments than you might think. Things just aren't so cut and dry as that, so for now, this might help us out. Thanks again for posting it @jamesandre 


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • November 5, 2023
mm2270 wrote:

I'm just coming across this, because I'm also seeing a fair number of devices not checking in, even though the Macs are confirmed to be online.

I noticed a typo in your script. You define the variable for the log location as logLocation, but then in the function you are echoing out to a variable labeled $LOG

echo "$DATE" " $1" >> $LOG

Other than that, good work on this. I plan on doing some testing with it to see if it improves our situation.

Never mind! I see now that you define LOG by assigning it to $logLocation. All good!

As for those saying just reboot your Macs, well, yeah, that is ideal, but it's much harder to enforce in some environments than you might think. Things just aren't so cut and dry as that, so for now, this might help us out. Thanks again for posting it @jamesandre 


I hope it helps. I'm not able to edit the original post to update the script. I should have put it on GitHub... maybe one day.


Forum|alt.badge.img+4

I dont know why, but I am also getting error like @bsmithAP 
Load failed: 5: Input/output error


Forum|alt.badge.img+4

Expecting a LaunchAgents path since the command was ran as user. Got LaunchDaemons instead.
`launchctl bootstrap` is a recommended alternative.
Load failed: 5: Input/output error
Try running `launchctl bootstrap` as root for richer errors.


Forum|alt.badge.img+4

 dont know if I fixed the issue, but I dont have any errors any more. Can someone tell me if this is a good result of policy? 

Executing Policy Jamf Binary Restart

Running script Jamf binary Restart...

Script exit code: 0

Script result:


Forum|alt.badge.img+4
  • New Contributor
  • 1 reply
  • December 12, 2023
itinspectorio wrote:

Expecting a LaunchAgents path since the command was ran as user. Got LaunchDaemons instead.
`launchctl bootstrap` is a recommended alternative.
Load failed: 5: Input/output error
Try running `launchctl bootstrap` as root for richer errors.


For the "Load failed: 5: Input/output error" I found out the issue.
There's a typo on the LauncDaemon where:
"<key>Label</key>
<string>com.example.jamfrestart</string>"

needs to be:
"<string>com.example.jamfRestart</string>"
The "r" is lowercase and needs to be the uppercase "R".

 


Forum|alt.badge.img+4

@jamesandre Could you please help validate the latest process? As I understand there is issue with new MacOS to execute sudo /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

Did you try on Sonama and Ventura OS? 


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • January 23, 2024
itinspectorio wrote:

@jamesandre Could you please help validate the latest process? As I understand there is issue with new MacOS to execute sudo /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

Did you try on Sonama and Ventura OS? 


Yes, this is working on Sonoma, you can check the jamfRestart.log in Console. You will get the Load failed: 5: Input/output error if the Launch Daemon has already been loaded. 


Forum|alt.badge.img+8
  • Contributor
  • 149 replies
  • June 17, 2024
itinspectorio wrote:

Expecting a LaunchAgents path since the command was ran as user. Got LaunchDaemons instead.
`launchctl bootstrap` is a recommended alternative.
Load failed: 5: Input/output error
Try running `launchctl bootstrap` as root for richer errors.


Change that final line to:

launchctl bootstrap system "/Library/LaunchDaemons/com.example.jamfRestart.plist"

That should fix it.

Forum|alt.badge.img+8
  • Contributor
  • 149 replies
  • June 17, 2024

For anyone still looking to deploy this, I took what @MCfreiz put together and added some variables to make it a bit more adaptable. There are also some additional operations to do prep and post work. Other changes were made to bring the code up to compliance with current changes to MacOS.

#!/bin/bash ########################################################################################## # # Written by KClose # Based on original scripts by "JamesAndre" and "MCfreiz" # # This script simply writes out the required script and launchdaemon # ########################################################################################## ### VARIABLES ### scriptDir="/Library/Scripts/JamfAT" scriptFile="$scriptDir/jamfRestart.sh" daemonFile="/Library/LaunchDaemons/com.unt.at.jamfrestart.plist" ### MAIN SCRIPT ### # Check for Script Directory. if [[ ! -d "$scriptDir" ]]; then mkdir -p "$scriptDir" fi # Cleanup old files for recreation. if [[ -e "$scriptFile" ]]; then rm -f $scriptFile fi if [[ -e "$daemonFile" ]]; then launchctl bootout system $daemonFile rm -f $daemonFile fi # Write out the jamfRestart script. cat << 'EOF' > $scriptFile #!/bin/bash ### VARIABLES ### processRuntime=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy" | awk '{ print $3; }' | grep -o '.*[-]' | awk -F\\- '{print $1}') processCheck=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy" | awk '{ print $2; }') logLocation="/var/log/jamfRestart.log" ### FUNCTIONS ### scriptLogging(){ DATE=`date +%Y-%m-%d\\ %H:%M:%S` LOG="$logLocation" echo "$DATE" " $1" >> $LOG } ### MAIN SCRIPT ### if [ "${processRuntime}" = "" ]; then scriptLogging "JamfBinary has not run for more than 1 day" else scriptLogging "JamfBinary has run for ${processRuntime} days" scriptLogging "JamfBinary Process ID: ${processCheck}" scriptLogging "Quitting JamfBinary..." sudo kill -9 ${processCheck} fi exit 0 EOF # Set owenership and permissions on jamfRestart script. chmod 644 $scriptFile chown root:wheel $scriptFile # Write out LaunchDaemon. cat << EOF > $daemonFile <?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>$(basename $daemonFile | sed 's/.plist//')</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>$scriptFile</string> </array> <key>RunAtLoad</key> <false/> <key>StartInterval</key> <integer>86400</integer> </dict> </plist> EOF # Set ownership and permissions on LaunchDaemon. chmod 644 $daemonFile chown root:wheel $daemonFile # Load LaunchDaemon launchctl bootstrap system "$daemonFile"

JevermannNG
Forum|alt.badge.img+8
  • Valued Contributor
  • 136 replies
  • July 2, 2024
kacey3 wrote:

For anyone still looking to deploy this, I took what @MCfreiz put together and added some variables to make it a bit more adaptable. There are also some additional operations to do prep and post work. Other changes were made to bring the code up to compliance with current changes to MacOS.

#!/bin/bash ########################################################################################## # # Written by KClose # Based on original scripts by "JamesAndre" and "MCfreiz" # # This script simply writes out the required script and launchdaemon # ########################################################################################## ### VARIABLES ### scriptDir="/Library/Scripts/JamfAT" scriptFile="$scriptDir/jamfRestart.sh" daemonFile="/Library/LaunchDaemons/com.unt.at.jamfrestart.plist" ### MAIN SCRIPT ### # Check for Script Directory. if [[ ! -d "$scriptDir" ]]; then mkdir -p "$scriptDir" fi # Cleanup old files for recreation. if [[ -e "$scriptFile" ]]; then rm -f $scriptFile fi if [[ -e "$daemonFile" ]]; then launchctl bootout system $daemonFile rm -f $daemonFile fi # Write out the jamfRestart script. cat << 'EOF' > $scriptFile #!/bin/bash ### VARIABLES ### processRuntime=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy" | awk '{ print $3; }' | grep -o '.*[-]' | awk -F\\- '{print $1}') processCheck=$(ps -ax -o user,pid,etime,args | grep "/usr/local/[j]amf/bin/jamf policy" | awk '{ print $2; }') logLocation="/var/log/jamfRestart.log" ### FUNCTIONS ### scriptLogging(){ DATE=`date +%Y-%m-%d\\ %H:%M:%S` LOG="$logLocation" echo "$DATE" " $1" >> $LOG } ### MAIN SCRIPT ### if [ "${processRuntime}" = "" ]; then scriptLogging "JamfBinary has not run for more than 1 day" else scriptLogging "JamfBinary has run for ${processRuntime} days" scriptLogging "JamfBinary Process ID: ${processCheck}" scriptLogging "Quitting JamfBinary..." sudo kill -9 ${processCheck} fi exit 0 EOF # Set owenership and permissions on jamfRestart script. chmod 644 $scriptFile chown root:wheel $scriptFile # Write out LaunchDaemon. cat << EOF > $daemonFile <?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>$(basename $daemonFile | sed 's/.plist//')</string> <key>ProgramArguments</key> <array> <string>sh</string> <string>$scriptFile</string> </array> <key>RunAtLoad</key> <false/> <key>StartInterval</key> <integer>86400</integer> </dict> </plist> EOF # Set ownership and permissions on LaunchDaemon. chmod 644 $daemonFile chown root:wheel $daemonFile # Load LaunchDaemon launchctl bootstrap system "$daemonFile"

@kacey3 what are the macOS Version requirements? Thank you!


Forum|alt.badge.img+8
  • Contributor
  • 149 replies
  • July 8, 2024
JevermannNG wrote:

@kacey3 what are the macOS Version requirements? Thank you!


The main thing I added was "launchctl bootout system" to unload any previously existing Launch Daemons of the same name. This particular command line was first introduced in MacOS 10.11. Ideally, this script should be compatible with all current versions of MacOS (10.11 and beyond).

Another simple change I made was I made the grep command a bit more "flexible" as it seems like there are a couple of different outputs when jamf policy gets stuck. I also have the script check for existing scripts and launch daemons created by previous policies and delete them rather than overwriting them.

Lastly, I moved some of the script variables to the top, allowing admins to more easily customize the name and location of the script as well as the name of the Launch Daemon.


Forum|alt.badge.img+5
  • Contributor
  • 43 replies
  • February 15, 2025

Thanks for this post.
I've packaged the Launch Daemon and the script.
Correct me if I'm wrong, but Laund Daemons are triggered after a startup of the machine, right? So at that point it runs the script to check, right? But in that case the framework isn't up for more than one day.
You say :

"You can launch the LaunchDaemon with the command: /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

Do I need to set that command in a policy? But what if clients do not connect anymore than they won't run a policy, right? Or is there something else to trigger the scipt? Sorry, maybe I am not on the right track with my thoughts :-)


jamesandre
Forum|alt.badge.img+7
  • Author
  • Contributor
  • 59 replies
  • February 19, 2025
Musicmaker wrote:

Thanks for this post.
I've packaged the Launch Daemon and the script.
Correct me if I'm wrong, but Laund Daemons are triggered after a startup of the machine, right? So at that point it runs the script to check, right? But in that case the framework isn't up for more than one day.
You say :

"You can launch the LaunchDaemon with the command: /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

Do I need to set that command in a policy? But what if clients do not connect anymore than they won't run a policy, right? Or is there something else to trigger the scipt? Sorry, maybe I am not on the right track with my thoughts :-)


Use the updated script by kacey3 it looks like it will load itself when it gets deployed. 

If you deploy that script in a policy also tick on the "Network State Change" trigger as that runs as a seperate process and should install it on a "stuck" Mac. 


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • February 19, 2025
Musicmaker wrote:

Thanks for this post.
I've packaged the Launch Daemon and the script.
Correct me if I'm wrong, but Laund Daemons are triggered after a startup of the machine, right? So at that point it runs the script to check, right? But in that case the framework isn't up for more than one day.
You say :

"You can launch the LaunchDaemon with the command: /bin/launchctl load /Library/LaunchDaemons/com.example.jamfRestart.plist

Do I need to set that command in a policy? But what if clients do not connect anymore than they won't run a policy, right? Or is there something else to trigger the scipt? Sorry, maybe I am not on the right track with my thoughts :-)


@Musicmaker The LaunchDaemon has a StartInterval value of 86400 seconds, which is one day. So once the daemon is loaded, it stays "loaded" but will only run the job in the LaunchDaemon once per day. So it's not something that would only run after a restart. No need to worry about that.


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