Posted on 09-26-2013 07:40 PM
Hi,
i set update inventory every day for each device and i have set extension attribute (device uptime) that also will be collect during update inventory.
I have set policy that will trigger a notification if the device uptime is more than 5days. the problem is, and maybe only my concern and think too much; :) ; how can i make the policy run AFTER update inventory every day?
i tried to figure out in smart group: Last inventory update, not sure how to set that.
Anyone please?
Solved! Go to Solution.
Posted on 09-27-2013 06:53 AM
I think maybe you are over thinking this a little :)
Instead of using an EA to populate a Smart Groups that in turn triggers a policy, why not just combine all this into one policy that would do this-
Run a script that is a combination of your EA and your messaging script. High level, have the script do-
• Check UPTIME on the Mac
• If UPTIME is equal to or greater than x number of days (5?) then display message about being up too long to the user (with something like jamfHelper, cocoaDialog, etc)
• if UPTIME is less than x number of days, exit silently
Have the above run once per day on the every 15 trigger. This way you can be 100% certain that no-one would ever see a message about their Mac being up too long unless it really was. Having the script run on the Mac will gather accurate information and then take an action.
Does this make sense? I think you should forget about unnecessarily complicating this, personally.
If you wanted to make your script somewhat flexible, you could set up a parameter, $4, to pass a value to check for down to the script. In other words, if you decided later you wanted to check for 6 days or greater, just change the value for uptime days being passed to the script. No need to rewrite it and re-upload the script.
Lastly, to answer your question about recon for an extension attribute only, no, there is no way to do this. There are at least 2 Feature Requests asking for this though, and they're popular requests, but as of right now it doesn't look like it will make its way into the product. So you're not alone in wanting to do that.
Posted on 09-30-2013 07:51 AM
I think to make this work, you'll need to adjust your uptime script. Though its cool that it provides a human readable format for the computer uptime, it might be a little tricky to use it in a script that checks for a greater than / less than value and then takes action. What I think would work better is to just get the days value as an integer, or you could go with hours as well. Whichever makes the most sense.
Here's a modified version of an uptime script I'm using as an EA. I changed this up a little because in my version I calculate a number with some decimal points using bc (bash calculator) In your case it can simply get a single numeric value for days up, so something like "4" or "10" or whatever. Later in the script we can do a simple test to see if the returned number is equal to or greater than a defined threshold.
#!/bin/sh
daysVal="86400"
hrsVal="3600"
## Get uptime in seconds from sysctl
secUp=$( sysctl kern.boottime | awk '{print $5}' | sed 's/,//' )
## Get epoch time in seconds
epochTime=$( date +%s )
## Calculate adjusted uptime for computer
adjTime=$(( $epochTime - $secUp ))
## Calculate uptime in hours and days
DaysUp=$(( $adjTime / $daysVal ))
HrsUp=$(( $adjTime / $hrsVal ))
echo "Days Up: $DaysUp
Hours Up: $HrsUp"
So using something like this, how about a script like so-
#!/bin/bash
daysVal="86400"
## Get uptime in seconds from sysctl
secUp=$( sysctl kern.boottime | awk '{print $5}' | sed 's/,//' )
## Get epoch time in seconds
epochTime=$( date +%s )
## Calculate adjusted uptime for computer
adjTime=$(( $epochTime - $secUp ))
## Calculate uptime in hours and days
DaysUp=$(( $adjTime / $daysVal ))
if [[ "$DaysUp" -ge 5 ]]; then
/usr/bin/osascript <<-EOF
with timeout of 200 seconds
tell application "Finder"
activate
set question to display dialog "This computer has not been shut down or restarted for more than a week. Please shut down or restart the computer by clicking on Shut Down or Restart." with title "System Event by Andres Cheah, MCM" buttons {"Shut Down", "Restart", "Cancel"} with icon stop
set answer to button returned of question
if answer is equal to "Shut Down" then
set question to display dialog "This computer will shut down in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
shut down
end if
if answer is equal to "Restart" then
set question to display dialog "This computer will restart in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
restart
end if
if answer is equal to "Cancel" then
return
end if
end tell
end timeout
EOF
else
exit 0
fi
This is just slapped together more or less, so I haven't really tested this. You'll need to do that, especially when called from a policy.
Edit: to give credit where credit is due, I learned the sysctl kern.boottime trick to get the Mac's boot time from a post by Zachary Smith @acidprime here: https://jamfnation.jamfsoftware.com/discussion.html?id=4058. Just wanted to mention that.
Posted on 09-26-2013 08:08 PM
If all you are doing is triggering a notification, my suggestion is to create a Smart Group with your criteria, and set it to Send Email Notification on Change.
When the Update Inventory policy runs, the machines matching the Smart Group criteria will be automatically added which will cause an email notification to be sent.
Posted on 09-26-2013 08:16 PM
Hi Blake
no, what i mean, in the policy (uptime), i have make a script that will trigger display dialog to the user.
so, i just wanted to know, is there a way to make sure that the policy run AFTER update inventory run first?
because i wanted the inventory update first, then extension attribute i set is up-to-date and smart group has accurate information and can run the policy (uptime)..
Posted on 09-26-2013 09:41 PM
Okay, then I think your best bet is to first trigger an inventory update from your script with```
sudo jamf recon
Then use the JSS API to get the updated information with```
curl -s -u API_USER:API_PASS https://your.jss.com:8443/JSSResource/computers/name/COMPUTER_NAME/subset/groups_accounts&extension_attributes
If the machine was removed from the smart group during this recon, exit the script. If not, you now have accurate information you can display to your users.
Posted on 09-26-2013 10:07 PM
Wait, why not just rely on the regular check in cycle to do this for you? If you already have a Smart Group that the Macs fall into or out of based on the value returned in your EA, once they submit their daily inventory, if they fall into the group, just setup your messaging policy with the every 15 trigger and once per day execution, and scoped to that Smart Group. Assuming you use Every 15 minutes as the check in, the next cycle, which would be between 15 - 20 minutes later at most, will run the policy and make the message come up.
Its not immediately after inventory submission, but its fairly close. What's 15 minutes between friends/policies? :)
The only possible issue with this approach, and perhaps the gist of what your concern is, is that its possible users would see the message about long uptime even after they restarted their Mac recently, if the Mac hasn't submitted new inventory. One way you might get around that would be a policy that simply recons a Mac with the Startup trigger. So if they reboot, it should recon, drop into/out of the group and thus wouldn't run the other message policy if it didn't need to.
Posted on 09-26-2013 11:22 PM
Hi msblake,
thanks, but it too complicated for me :))
Hi mm2270,
Yeah, that what i'm concern about. It is good idea to do another recon on startup trigger, i never do that, is it will slow down startup process? Or, can i do recon for specific extension attribute? It would be great if can do that.
thanks.
Posted on 09-27-2013 06:53 AM
I think maybe you are over thinking this a little :)
Instead of using an EA to populate a Smart Groups that in turn triggers a policy, why not just combine all this into one policy that would do this-
Run a script that is a combination of your EA and your messaging script. High level, have the script do-
• Check UPTIME on the Mac
• If UPTIME is equal to or greater than x number of days (5?) then display message about being up too long to the user (with something like jamfHelper, cocoaDialog, etc)
• if UPTIME is less than x number of days, exit silently
Have the above run once per day on the every 15 trigger. This way you can be 100% certain that no-one would ever see a message about their Mac being up too long unless it really was. Having the script run on the Mac will gather accurate information and then take an action.
Does this make sense? I think you should forget about unnecessarily complicating this, personally.
If you wanted to make your script somewhat flexible, you could set up a parameter, $4, to pass a value to check for down to the script. In other words, if you decided later you wanted to check for 6 days or greater, just change the value for uptime days being passed to the script. No need to rewrite it and re-upload the script.
Lastly, to answer your question about recon for an extension attribute only, no, there is no way to do this. There are at least 2 Feature Requests asking for this though, and they're popular requests, but as of right now it doesn't look like it will make its way into the product. So you're not alone in wanting to do that.
Posted on 09-29-2013 06:43 PM
Hi @mm2270
brilliant! anyone know how to script combination between check uptime and notifcation?
uptime script:
#! /bin/sh
# if $4 from `uptime` is "mins," then the system has been up for less than an hour.
# We set $timeup to the output of $3, appending only "m".
timechk=`uptime | awk '{ print $4 }'`
if [ $timechk = "mins," ]; then
timeup=`uptime | awk '{ print $3 "m" }'`
# if $4 is "days," then we generate a readable string from $3, $4, and $5;
elif [ $timechk = "days," ]; then
timeup=`uptime | awk '{ print $3 $4 " " $5 }' | sed 's/days,/d/g' | sed 's/:/h /g' | sed 's/,/m/g'`
# otherwise, generate a readable string from $3.
else
timeup=`uptime | awk '{ print $3 }' | sed 's/:/h /g' | sed 's/,/m/g'`
fi
echo "<result>$timeup</result>"
and this notification script:
#!/bin/bash
VARIABLE=$(/usr/bin/osascript <<-EOF
with timeout of 200 seconds
tell application "Finder"
activate
set question to display dialog "This computer has not been shut down or restarted for more than a week. Please shut down or restart the computer by clicking on Shut Down or Restart." with title "System Event by Andres Cheah, MCM" buttons {"Shut Down", "Restart", "Cancel"} with icon stop
set answer to button returned of question
if answer is equal to "Shut Down" then
set question to display dialog "This computer will shut down in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
shut down
end if
if answer is equal to "Restart" then
set question to display dialog "This computer will restart in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
restart
end if
if answer is equal to "Cancel" then
return
end if
end tell
end timeout
EOF)
exit 0
If anyone help will be appreciate. thanks
Posted on 09-30-2013 07:51 AM
I think to make this work, you'll need to adjust your uptime script. Though its cool that it provides a human readable format for the computer uptime, it might be a little tricky to use it in a script that checks for a greater than / less than value and then takes action. What I think would work better is to just get the days value as an integer, or you could go with hours as well. Whichever makes the most sense.
Here's a modified version of an uptime script I'm using as an EA. I changed this up a little because in my version I calculate a number with some decimal points using bc (bash calculator) In your case it can simply get a single numeric value for days up, so something like "4" or "10" or whatever. Later in the script we can do a simple test to see if the returned number is equal to or greater than a defined threshold.
#!/bin/sh
daysVal="86400"
hrsVal="3600"
## Get uptime in seconds from sysctl
secUp=$( sysctl kern.boottime | awk '{print $5}' | sed 's/,//' )
## Get epoch time in seconds
epochTime=$( date +%s )
## Calculate adjusted uptime for computer
adjTime=$(( $epochTime - $secUp ))
## Calculate uptime in hours and days
DaysUp=$(( $adjTime / $daysVal ))
HrsUp=$(( $adjTime / $hrsVal ))
echo "Days Up: $DaysUp
Hours Up: $HrsUp"
So using something like this, how about a script like so-
#!/bin/bash
daysVal="86400"
## Get uptime in seconds from sysctl
secUp=$( sysctl kern.boottime | awk '{print $5}' | sed 's/,//' )
## Get epoch time in seconds
epochTime=$( date +%s )
## Calculate adjusted uptime for computer
adjTime=$(( $epochTime - $secUp ))
## Calculate uptime in hours and days
DaysUp=$(( $adjTime / $daysVal ))
if [[ "$DaysUp" -ge 5 ]]; then
/usr/bin/osascript <<-EOF
with timeout of 200 seconds
tell application "Finder"
activate
set question to display dialog "This computer has not been shut down or restarted for more than a week. Please shut down or restart the computer by clicking on Shut Down or Restart." with title "System Event by Andres Cheah, MCM" buttons {"Shut Down", "Restart", "Cancel"} with icon stop
set answer to button returned of question
if answer is equal to "Shut Down" then
set question to display dialog "This computer will shut down in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
shut down
end if
if answer is equal to "Restart" then
set question to display dialog "This computer will restart in 3 minutes. Please save anything you are working on." with title "System Event by Andres Cheah, MCM" buttons {"OK"} with icon stop
delay 120
restart
end if
if answer is equal to "Cancel" then
return
end if
end tell
end timeout
EOF
else
exit 0
fi
This is just slapped together more or less, so I haven't really tested this. You'll need to do that, especially when called from a policy.
Edit: to give credit where credit is due, I learned the sysctl kern.boottime trick to get the Mac's boot time from a post by Zachary Smith @acidprime here: https://jamfnation.jamfsoftware.com/discussion.html?id=4058. Just wanted to mention that.
Posted on 09-30-2013 05:45 PM
hi @mm2270
thanks for your brilliant idea and script. i will test it in our environment.