Posted on 11-26-2019 03:52 PM
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.
Posted on 11-27-2019 07:48 AM
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.
Posted on 11-27-2019 03:39 PM
@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.
Posted on 11-27-2019 04:49 PM
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
Posted on 03-17-2021 06:21 PM
Thank you @mm2270. Your scripts are the gifts that keep on giving.
Posted on 02-03-2022 05:37 AM
Is there a way to do this without python?
Posted on 02-03-2022 05:55 AM
@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/
Posted on 02-03-2022 06:00 AM
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")
02-03-2022 06:20 AM - edited 02-03-2022 06:21 AM
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
Posted on 02-03-2022 09:21 PM
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