Offline Notifications?

clifhirtle
Contributor II

Absent an externally-facing JSS, anyone have an effective means for posting policy messages to your users when not on your network?

We're in midst of deferred FileVault rollout so I've created a daily message policy reminding our folks to logout to encrypt. However, most of our users travel and are not on network most of the time, which is preventing the reminder from triggering.

My initial thought was to leverage an offline policy for this, but I just noticed that's only available for policies executed ongoing and my notification is set to execute daily. Is there an alternate means to execute ongoing with a manual trigger every 24 hours (never done that)?

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

Yeah, that's why I was originally thinking the script checking FV2 status and firing off, or not, accordingly. Without some way to tell it not to execute your users will be nagged about something they already did. Not so good.

I would use a combo of the existing Smart Group, but put some logic in the script up front to check FileVault 2 status. Just off the top of my head...

#!/bin/sh

FV2Stat=$( fdesetup status | grep "On" )
if [[ "$FV2Stat" == "" ]]; then
      *do your messaging stuff here*
else
      exit 0
fi

Take a look at the man page for fdesetup. There's a isactive verb that will report exit status of 0 if on and 1 if off, or 2 if FileVault is "busy" which could mean its in the middle of encrypting or decrypting. In 10.9 Apple changed that command a little and you get somewhat different results with it. In 10.8 you had to do an echo $? to see the exit status. In 10.9 it now reports "true" or "false", but will still report the exit status.
Unfortunately, I've found that in 10.8 I could reliably tell if FileVault was deactivated with the isactive command, even before a reboot. Thats no longer the case in 10.9. It will still report true, even if a user completely disabled FileVault in the Preference Pane or from the command line.. Only after a reboot will it report correctly as "false"

So in short, the fdesetup status seems to be the most reliable way I've seen on both 10.8 and 10.9 to get the encryption state.

View solution in original post

11 REPLIES 11

mm2270
Legendary Contributor III

To get what you're looking for, one options would be to create and deploy a LaunchAgent or LaunchDaemon with a specific StartInterval or Calendar setting to run once per day, with a script as its ProgramArguments. Have the script check to see if FileVault is enabled, and if not, alert the user to log out to enable it. It should continue to do this as long as necessary. Once FileVault is enabled, you can have the script remove the Agent or Daemon and the script itself so it won't run anymore.

I'd recommend a LaunchDaemon for this so you can take advantage of the fdesetup command in the script (requires root to run under 10.8, but not in 10.9 interestingly) But you'll need to make sure the script checks to see if someone is logged in before trying to display a message, by checking the owner of console for example.

Does that help?

clifhirtle
Contributor II

Thanks @mm2270 that does sound like a workable approach. The reason I was asking about the manual trigger was that I had thought I heard of folks using a manual notification to trigger policies on some kind of custom interval other than the global every15 schedule. In the case I remember I thought they switched to everyHour, but it seemed possible it might be everyDay or something. Is that possible or am I just imagining things now?

clifhirtle
Contributor II

Found this older thread with a post from you @mm2270 about creating custom tasks and intervals using the hidden page at:

https://your.casper.server.com:8443/tasks.html

That appears to get me halfway there, since I can create a custom task to kick off daily and trigger a manual offline-enabled policy, yes? Or would the custom trigger not even fire unless the JSS could be reached?

https://jamfnation.jamfsoftware.com/featureRequest.html?id=506

mm2270
Legendary Contributor III

@clifhirtle][/url Honestly I'm not sure if creating a custom task will work in this instance. For one thing, it seems frowned upon by JAMF themselves, and not recommended. Second, I do think that the JSS would need to reachable to have the policy fire off on that alternate task trigger.

I guess you could give it a shot and see how or if it works.

Another approach that could work, but would be a little more complicated, would be to have the script being triggered on your regular everyX minute offline trigger, check the last time it ran, possible by looking in a log file, and if the difference between the last time and the current time hasn't been >= 24 hours, exit silently. While this would work, it would mean the offline policy will be actually running on all your Macs at every check in attempt by the jamf binary, even if the user doesn't see anything. Probably not a huge deal if the script is pretty lightweight, but its just something to keep in mind.

clifhirtle
Contributor II

Thanks Mike. Just tested out the custom trigger > offline script and it works! Frankly it sounds like these triggers work just about the same as what you're describing here with the local everyX script, since the standard every15 triggers (and any other customs you create) are always running, just whether they contact the JSS and can execute that is dependent on network connection. Either way, I think this will work for us, particularly since it will only likely be for a time-limited 2-3 week time period.

One gotcha: my current message script is scoped to a FileVault Needed smart group. If I use that to run an offline script, said script would likely continue to fire off even after the user encrypted since it has not yet updated uploaded its inventory and dropped out of the smart group within the JSS. Hmm...

mm2270
Legendary Contributor III

Yeah, that's why I was originally thinking the script checking FV2 status and firing off, or not, accordingly. Without some way to tell it not to execute your users will be nagged about something they already did. Not so good.

I would use a combo of the existing Smart Group, but put some logic in the script up front to check FileVault 2 status. Just off the top of my head...

#!/bin/sh

FV2Stat=$( fdesetup status | grep "On" )
if [[ "$FV2Stat" == "" ]]; then
      *do your messaging stuff here*
else
      exit 0
fi

Take a look at the man page for fdesetup. There's a isactive verb that will report exit status of 0 if on and 1 if off, or 2 if FileVault is "busy" which could mean its in the middle of encrypting or decrypting. In 10.9 Apple changed that command a little and you get somewhat different results with it. In 10.8 you had to do an echo $? to see the exit status. In 10.9 it now reports "true" or "false", but will still report the exit status.
Unfortunately, I've found that in 10.8 I could reliably tell if FileVault was deactivated with the isactive command, even before a reboot. Thats no longer the case in 10.9. It will still report true, even if a user completely disabled FileVault in the Preference Pane or from the command line.. Only after a reboot will it report correctly as "false"

So in short, the fdesetup status seems to be the most reliable way I've seen on both 10.8 and 10.9 to get the encryption state.

clifhirtle
Contributor II

Thanks Mike. I edited the script to have that FileVault status check a prior as you mention above and it appears to work just fine on my test machines. I'm not terribly worried about notifying users in-process of encryption, since all our Macs are on SSD drives, encrypting runs through quite fast, and I'm only notifying them 1x/day anyway. Thanks again for your help on this one. This provides a great template for future needs as well (custom trigger + offline script + local variable check = good balance of local-remote initiation/control).

clifhirtle
Contributor II

Ok I'm circling back around on this since a script I had working with code here has suddenly stopped waiting for user input from the jamfHelper tool and simply failing out with default response codes, which subsequently skips the conditional logout prompt. Assuming I'm missing something obvious here, as in perhaps jamfHelper cannot work with a multilevel if statement?

#!/bin/sh

#### Casper Encryption Reminder Dialog (Utility Style)
#### C. Hirtle with code/contributions from mm2270 
### Offline Discussion: https://jamfnation.jamfsoftware.com/discussion.html?id=9251 

#### Read in the parameters
mountPoint=$1
computerName=$2
username=$3

#### SET VARIABLES
title="Enable Encryption"

trigger="Enable-Encryption"

description="Encryption has been activated on your Mac, but requires a one time log out and password confirmation to enable. You may log out now or later, but this reminder will continue to appear daily until your Mac is encrypted.

You may continue to use your Mac as normal while encrypting. 

Click Encrypt to log out + confirm password now. Cancel to postpone until next log out."

icon="/System/Library/PreferencePanes/Security.prefPane/Contents/Resources/FileVault.icns"

button1="Encrypt"                 # "string" Creates button with label (default button)

button2="Cancel"              # "string" Creates button with label

dButton="1"                       # Sets default button to button1. Responds to "return"

cButton="2"

windowType="utility"          # [hud | utility | fs]

user=`ls -l /dev/console | cut -d " " -f 4`

FV2Stat=$( fdesetup status | grep "" )

### BEGIN SCRIPT

if [[ "$FV2Stat" == "On" ]]; then

    #### Script to trigger dialog with above variables
    response=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType "$windowType" -windowPosition "$windowPosition" -title "$title" -description "$description" -icon "$icon" -button1 "$button1" -button2 "$button2" -defaultButton "$dButton" -cancelButton "$cButton" -windowType "$windowType"`

    echo "response is $response"

    #### If user responds with default button run trigger policy

    if [ "$response" == "1" ]; then

        #### Logout the current user
        sudo -u $user osascript -e 'tell application "System Events" to log out'

    exit 0

    else

    # User chose to postpone

    exit 1

    fi

else

    exit 0

fi

mm2270
Legendary Contributor III

Hey @clifhirtle][/url][/url, I'm not certain if its the same issue some of us have run int but you might want to throw in the -startlaunchd flag at the end of your jamfHelper call. For some reason that seems to get around issues where the jamfHelper window exits with a default exit code, as if someone clicked a button even when no-one interacted with it.
I don't know why that happens, and its not consistent, but most times adding the -startlaunchd flag fixes it.

Give it a try.

Edit: I just noticed something odd in your script. Maybe I'm missing something, but these lines don't actually seem like they'd do what you want?

FV2Stat=$( fdesetup status | grep "" )

### BEGIN SCRIPT

if [[ "$FV2Stat" == "On" ]]; then

You're pulling the entire output of fdesetup status into the FV2Stat variable, which could be a multi line output like:

FileVault is On.
FileVault master keychain… etc

or

FileVault is Off.
Deferred enablement… etc

The if [[ "$FV2Stat" == "On" ]]; then test condition would seem to always fail since it can't equal "On" only, even if it actually is on. Am I not thinking of that right? If I'm right, you could change it to =~ instead, but I think gripping for the word "On' makes more sense and then testing if the variable is null or has a value.

clifhirtle
Contributor II

Looks like my entire grep logic and response codes were off or not specific enough. Here's the faster, better, more streamlined version in case others want to make use of:

#!/bin/sh

#### Casper Encryption Reminder Dialog (Utility Style)
#### C. Hirtle with code/contributions from mm2270 
### Offline Discussion: https://jamfnation.jamfsoftware.com/discussion.html?id=9251 

#### Read in the parameters
mountPoint=$1
computerName=$2
username=$3

#### SET VARIABLES

title="Enable Encryption"
trigger="Enable-Encryption"
icon="/System/Library/PreferencePanes/Security.prefPane/Contents/Resources/FileVault.icns"
button1="Encrypt"                 # "string" Creates button with label (default button)
button2="Cancel"              # "string" Creates button with label
dButton="1"                       # Sets default button to button1. Responds to "return"
cButton="2"
windowType="utility"          # [hud | utility | fs]
user=`ls -l /dev/console | cut -d " " -f 4`
FV2Stat=$( fdesetup status | grep "On" )
description="Encryption has been activated on your Mac, but requires a one time log out and password confirmation to enable. You may log out now or later, but this reminder will continue to appear daily until your Mac is encrypted.

You may continue to use your Mac as normal while encrypting. 

Click Encrypt to log out + confirm password now. Cancel to postpone until next log out."

### BEGIN SCRIPT

if [[ "$FV2Stat" == "FileVault is On." ]]; then

    #### Script to trigger dialog with above variables
    response=`/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType "$windowType" -windowPosition "$windowPosition" -title "$title" -description "$description" -icon "$icon" -button1 "$button1" -button2 "$button2" -defaultButton "$dButton" -cancelButton "$cButton" -windowType "$windowType"`

    echo "response is $response"

    #### If user responds with default button run trigger policy
    if [ "$response" == "0" ]; then
        #### Logout the current user
        sudo -u $user osascript -e 'tell application "System Events" to log out'
        exit 0
    else    
        exit 1      # User chose to postpone
    fi
else
    exit 0  
fi

mm2270
Legendary Contributor III

Ah, looks like you caught the same thing I did after taking another look. Glad you got it worked out. :)