Run policy only when the user session is not locked

cbd4s
Contributor II

Hi,

I know we can check if the machine is logged on by a user or not. But just wondering if anyone knows a way to detect if that login session is locked or not?

The intention is to only run a policy under an active user login session (not locked by screensaver, display is not turned off)

Thanks in advance.

9 REPLIES 9

bvrooman
Valued Contributor

I have a script which checks this as part of the prerequisites to do some tasks (I'm actually looking for inactivity, but it's the same check). I haven't had anyone report issues, but obviously you'll want to test to make sure it does what you want. Here's the relevant line, which will return a 1 or 0:
pmset -g assertions | grep UserIsActive | grep -v pid | awk {'print $2'}

If the goal is to run a policy, the script could just call a custom policy trigger after evaluating the presence of user activity.

cbd4s
Contributor II

@bvrooman Thanks so much for the handy command line. I wish I was that skilled in scripting.

I've given it a test. Unfortunately, it doesn't look very promising. When I ssh into a machine which has been logged in and idle for a while and ran this command, it did initially return 0, as soon as I clicked the mouse which triggered the login prompt, it return became 1. But obviously the user hasn't really logged in yet as the machine is still locked.

mm2270
Legendary Contributor III

Try this code block. Customize what happens when the screen is not locked, such as calling a function.

## Get the name of the logged in user (Changed to a more reliable python method to get the current console user)
LOGGED_IN_USER=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");' | sed '/^$/d')

## Get the logged in user's UID
LOGGED_IN_UID=$(id -u "$LOGGED_IN_USER")

## This is a sanity check. If a user is logged in...
if [[ "$LOGGED_IN_USER" != "root" ]] || [[ "$LOGGED_IN_USER" != "" ]]; then
    ## Check to see if the screen is locked, or the screensaver is active.
    LOCKED_SCREEN_STATE=$(/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" /usr/bin/python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d' | grep "CGSSessionScreenIsLocked")
    ## If the LOCKED_SCREEN_STATE check is not empty, then the screensaver is on or the screen is locked
    if [[ ! -z "$LOCKED_SCREEN_STATE" ]]; then
        echo "A user is logged in to the Mac, but the screen is locked, or the screensaver is active."
        ## Do something different here since the screen was found to be locked
    else
        echo "A user is logged in to the Mac, and the screen is not locked. Continuing..."
        ## Do something here to continue with the script...
    fi
else
    echo "No user is logged into the Mac."
fi

bradtchapman
Valued Contributor II

Thank you @mm2270. Your scripts are the gifts that keep on giving.

L3nny5
New Contributor III

Is there a way to do this without python? 

sdagley
Esteemed Contributor II

@L3nny5 @arminBriegel has written the definitive article on determining the logged in user: https://scriptingosx.com/2020/02/getting-the-current-user-in-macos-update/

 

L3nny5
New Contributor III

Thanks. Yeah I know. But I'm talking about this part of the script:

LOCKED_SCREEN_STATE=$(/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" /usr/bin/python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d' | grep "CGSSessionScreenIsLocked")

sdagley
Esteemed Contributor II

Sorry, my parsing of the script stopped at the first occurrence of python. This may be relevant to determining CGSSessionScreenIsLocked's state: https://stackoverflow.com/questions/11505255/osx-check-if-the-screen-is-locked

 

mm2270
Legendary Contributor III

That's a good link, thanks for pointing to it @sdagley 

Back when I wrote my script above, there was no issue using python because it was still in vogue. Now that it's become more persona non grata these days, it makes sense to look for a more pure shell way of doing the same. The link you pointed to has a solution at the end of the page using ioreg. However, it seems the poster overcomplicated the solution. There's no need to call something like PlistBuddy into this. From what I can tell (and have partially tested), that CGSSessionScreenIsLocked key only shows up in the output when the screen is actually locked. Otherwise it's not present. So a simple grep for it from the ioreg output is enough to determine the state. Something like this seems to work.

 

#!/bin/zsh

screen_locked_check=$(/usr/sbin/ioreg -n Root -d1 -a | /usr/bin/grep "CGSSessionScreenIsLocked")

if [ "$screen_locked_check" ]; then
    /bin/echo "Locked"
else
    /bin/echo "Unlocked"
fi