Posted on 03-14-2014 04:29 PM
I recently applied a policy to a Smart Group that installs some software and then restarts the computers. Checking the logs, I see the software installed properly but no mention of reboot on any so I am thinking that shutdown or restart doesn't get logged? If not, wondering if there is a custom attribute or something else that I could use to track uptime or last shutdown/restart on these computers or even all managed clients?
Solved! Go to Solution.
Posted on 03-14-2014 05:34 PM
Last Reboot
#!/bin/bash
lastReboot=`who -b | awk '{print $3" "$4}'`
echo "<result>"$lastReboot"</result>"
exit 0
Uptime in Hours
#!/bin/sh
DAYS="days,"
HRS=" hrs"
DAYScheck=$(uptime | awk {'print $4'})
if [ $DAYScheck = "$DAYS" ]; then
result=$(uptime | awk {'print $3.$4.$5'} | sed 's/,/ /g' | sed 's/d/ d/g')
echo "<result>$result$HRS</result>"
else
result=$(uptime | awk {'print $3'} | sed 's/,//g')
echo "<result>$result$HRS</result>"
fi
exit
Hope that helps.
Posted on 03-14-2014 05:34 PM
Last Reboot
#!/bin/bash
lastReboot=`who -b | awk '{print $3" "$4}'`
echo "<result>"$lastReboot"</result>"
exit 0
Uptime in Hours
#!/bin/sh
DAYS="days,"
HRS=" hrs"
DAYScheck=$(uptime | awk {'print $4'})
if [ $DAYScheck = "$DAYS" ]; then
result=$(uptime | awk {'print $3.$4.$5'} | sed 's/,/ /g' | sed 's/d/ d/g')
echo "<result>$result$HRS</result>"
else
result=$(uptime | awk {'print $3'} | sed 's/,//g')
echo "<result>$result$HRS</result>"
fi
exit
Hope that helps.
Posted on 03-14-2014 05:54 PM
Works perfectly! Thx @jhbush1973
Posted on 03-15-2014 11:03 PM
I'm trying to put this is as an Extension Attribute but it doesn't display the result. Any ideas?
Posted on 03-16-2014 05:57 AM
Run recon on your test machine, should see it then
Posted on 03-16-2014 08:21 AM
Correct. As with any Extension Attribute that gets populated from inventory, you won't see anything until your Macs begin submitting new inventory and run the script. It actually brings up an important point on something like an "uptime" EA. The information will only be as good as the last inventory date, which could be only minutes before or as much as a day before (or more) depending on your setup. Just something to keep in mind.
Posted on 03-17-2014 12:26 AM
@mm2270 That's great info! I had overlooked on the update inventory policy we have set up. I've edited it to get the results on a more timely manner. Now I realize that it wasn't a scripting issue
Thanks!
Posted on 03-17-2014 08:23 AM
Just wanted to post an alternative Last Reboot EA. This one will output it in a date format that can be used in a "Date format" Extension Attribute the way Casper expects it to be. So you could use a search like "Before" or "After" a certain date, or something like "In the last X days" and it should work.
#!/bin/bash
echo "<result>$(date -jf "%s" "$(sysctl kern.boottime | awk -F'[= |,]' '{print $6}')" +"%Y-%m-%d %T")</result>"
Posted on 04-19-2014 06:13 AM
@mm2270 Many thanks, this is exactly what I was in need of, after the tenth syntax error I remember someone, like you, had probably already found a good (and working) method for this! :) Thanks!
Posted on 02-09-2016 06:57 PM
Love it, @mm2270. Thanks.
Posted on 06-15-2016 11:16 AM
you helped me out with this twice now @TomDay
Posted on 10-13-2016 04:15 PM
Hah; I'm getting some responses like " 6 days 46 hours". Anybody have any idea why that's happening?
Posted on 10-14-2016 06:41 AM
Not trying to be snarky, but @ken.cieszykowski What result are you trying to get? Sounds like an uptime report to me.
Posted on 10-14-2016 07:13 AM
Well, unless he lives on another planet, I'd say that the "46 Hours" bit is the part that's head scratching, y'know ;-)
Sounds like a math problem to me, but I haven't looked close enough to see why they would be.
Posted on 10-14-2016 07:17 AM
@mm2270 Don't mind me. I've been doing some wood working lately and breathing in a large amount of chemicals from staining furniture. I read that and my brain said 46 minutes... Maybe I should open a window here... Moving along now...
Posted on 01-03-2017 01:36 PM
Hah, thanks for explaining @mm2270
I'm trying to set some Smart Groups based on this extension; but the hours report > 24 is difficult.
Basically, I changed the EA to be an integer; and then set the criteria of the group to be "System Uptime" is more than 30. Running into a wall here since it's pulling things such as '31 hours' into the group, and so on.
Please let me know if anybody has any advice or can help with this!
Cheers
Posted on 01-26-2017 05:44 PM
I also use sysctl
to track this, or at least I found it the easiest to parse. Parsing uptime
or last reboot
was a bit more of a pain to covert into something you can return a value of just days to.
bash example:
sysctl kern.boottime | awk '{ print $5 }' | sed 's/,//g'
that will return epoch time since reboot in bash
Then compare it to current epoch time with date "+%s"
Python example might be:
#get last reboot epoch time
>>> import subprocess
>>> cmd = ['sysctl', '-h', 'kern.boottime']
>>> ps = subprocess.check_output(cmd)
>>> output = ps.strip().split()[4].replace(',','')
>>> print output
1485380162
# get current epoch time in Python
>>> import time
>>> epoch = int(time.time())
>>> print epoch
1485480972
I personally like the epoch time stamps because they are easier to do the math in my opinion then just divide by 86400 to get seconds into days conversion. As you can see I recently rebooted so the current epoch time is not too far off the output of sysctl
which is expected. Python will return 0 if it is less than one (like a fraction or float). Looks like bash internals also return 0 if the result is less than 1. If you are living in the future and actually have Python 3.x deployed to your Mac fleet I think Python actually has a built in uptime
module
bash internal division example:
echo $(( 6000 / 86400 ))
0
-Tom
Posted on 10-25-2017 02:43 PM
This is not my code but was from the CCA class. I know this was already answered but this was more elegant and you can change the data type to be Date which looks better :)
#!/bin/bash
# Find the last time reboot time
# sysctl -a lists all values for the kernel state
# A specific key can be specified
# sysctl kern.boottime lists the last time the computer was boot time in human format and epoch time. Neither are appropriate for the JSS
#######################################
# Print the boottime, capturing the fifth field (awk uses white space as default field separator), removing the trailing comma
#######################################
boottime=$(sysctl kern.boottime | awk '{print $5}' | tr -d ,)
#######################################
# The date command will list the current date, set system time, or reformat dates
# Time can be formatted with + for example the following will show the date in the format of YEAR-MONTH-DATE
# date +%Y-%m-%d
#
# The date command can be set to format one date to another, the syntax is as follows:
# date -jf %s $DATETOFORMAT +$NEWFORMAT
#
# To change epoch time 1492527424 (2017 April 18, 10:57:04 A.M.) to a format acceptable for the JSS:
#
# date -jf %s 1492527424 +%F %T
# The j flag says do not try to set the date, this allows you to use the -f flag in addition to the + option to convert one date format to another
# %s is the input format (epoch time), followed by the time to convert and the output format
#######################################
# Format the boottime for the JSS
#######################################
formattedTime=$(date -jf %s "$boottime" +%F %T)
#######################################
# To return a value to the JSS in Extension Attributes it must be wrapped in result tags
#######################################
echo "<result>$formattedTime</result>"
#######################################
# A list of the formatting options for the date command
# %% a literal %
# %a locale's abbreviated weekday name (e.g., Sun)
# %A locale's full weekday name (e.g., Sunday)
# %b locale's abbreviated month name (e.g., Jan)
# %B locale's full month name (e.g., January)
# %c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
# %C century; like %Y, except omit last two digits (e.g., 21)
# %d day of month (e.g, 01)
# %D date; same as %m/%d/%y
# %e day of month, space padded; same as %_d
# %F full date; same as %Y-%m-%d
# %g last two digits of year of ISO week number (see %G)
# %G year of ISO week number (see %V); normally useful only with %V
# %h same as %b
# %H hour (00..23)
# %I hour (01..12)
# %j day of year (001..366)
# %k hour ( 0..23)
# %l hour ( 1..12)
# %m month (01..12)
# %M minute (00..59)
# %n a newline
# %N nanoseconds (000000000..999999999)
# %p locale's equivalent of either AM or PM; blank if not known
# %P like %p, but lower case
# %r locale's 12-hour clock time (e.g., 11:11:04 PM)
# %R 24-hour hour and minute; same as %H:%M
# %s seconds since 1970-01-01 00:00:00 UTC
# %S second (00..60)
# %t a tab
# %T time; same as %H:%M:%S
# %u day of week (1..7); 1 is Monday
# %U week number of year, with Sunday as first day of week (00..53)
# %V ISO week number, with Monday as first day of week (01..53)
# %w day of week (0..6); 0 is Sunday
# %W week number of year, with Monday as first day of week (00..53)
# %x locale's date representation (e.g., 12/31/99)
# %X locale's time representation (e.g., 23:13:48)
# %y last two digits of year (00..99)
# %Y year
# %z +hhmm numeric timezone (e.g., -0400)
# %:z +hh:mm numeric timezone (e.g., -04:00)
# %::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
# %:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)
# %Z Time Zone (EDT)
Posted on 10-26-2017 04:24 PM
Just to add an alternate method to the discussion,
JSS Formatted in one command by pulling from the start time of PID 1 (launchd)
date -jf '%a %b %d %T %Y' "`ps -p 1 -o lstart=`" +%F %T
Posted on 10-30-2017 10:58 AM
I wrote ours slightly different in case anyone has a use for it:
#!/bin/bash
FORMAT_OF_TIME="`uptime | awk '{print $4}' | sed 's/,//g'`"
case $FORMAT_OF_TIME in
days )
CURRENT_UPTIME="`uptime | awk '{print $3 "days"}'`"
;;
mins )
CURRENT_UPTIME="`uptime | awk '{print $3 "mins"}'`"
;;
secs )
CURRENT_UPTIME="`uptime | awk '{print $3 "secs"}'`"
;;
* )
CURRENT_UPTIME="`uptime | awk '{print $3}' | sed 's/,//g' | awk -F ':' '{print $1 "hrs", $2 "mins"}'`"
;;
esac
PROCESSED_UPTIME="${CURRENT_UPTIME} (Last checked: `date`)"
echo "<result>${PROCESSED_UPTIME}</result>"
exit 0