DEP Enrollment - Confirming user is fully logged in

tuinte
Contributor III

Preface: Maybe I'm missing something obvious...

For DEP deployments, we have an Enrollment Complete policy that waits until a user is logged in to throw up a splash page and custom triggers our big config policy to then do the configuring we want, then it reboots, etc. Here's the logic in the Enrollment Complete script that confirms the user is logged in before kicking off the config:

#!/bin/bash
until [[ $LoggedInUser != "_mbsetupuser" && $LoggedInUser != "loginwindow" ]]; do
LoggedInUser=$(defaults read /Library/Preferences/com.apple.loginwindow.plist lastUserName)
sleep 1
done
echo "$LoggedInUser has logged in, beginning configuration..."

The issue is that the login process begins immediately after the Create User screen, thereby updating LoggedInUser to pass the until loop. This would be fine, but following Create User is the Choose a Time Zone screen. So sometimes, if a user doesn't pick a Time Zone quickly enough, the splash screen comes up over the Choose a Time Zone screen. A number of our policies then fail because the user isn't really fully logged in.

I'm assuming I can solve this with another condition in the until loop. Any ideas what would be the most reliable check to ensure the Choose Your Time Zone page has completed? I thought about [[ $(systemsetup -gettimezone) != "America/Los Angeles" ]], as that's the default, but we, of course, have a Los Angeles office.

There's got to be something, though, I can latch onto here, right?

Appreciate any help in advance.

M

2 ACCEPTED SOLUTIONS

mbezzo
Contributor III

Hi,
We check for the 501 user to be logged in, loop on that until they are, and then start a loop waiting for the dock process to exist. Once that is running, then we know we can launch stuff:

dockStatus=$(pgrep -x Dock)
log "Waiting for Desktop"
while [ "$dockStatus" == "" ]; do
  log "Desktop is not loaded. Waiting."
  sleep 2
  dockStatus=$(pgrep -x Dock)
done

Maybe that'll help?

Good luck!
Matt

View solution in original post

sepiemoini
Contributor III
Contributor III

Yup! I'm using a similar approach to what @mbezzo has shared above. In short, I think a while-loop will do the trick as this allows for the "ideal conditions" to be present before going forward. Here's what I've got:

# While-loop used to detect if a standard user is logged on

while true
do
    loggedinuser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
    if [[ "$loggedinuser" = "root" ]] || [[ "$loggedinuser" = "_mbsetupuser" ]] || [[ "$loggedinuser" = "loginwindow" ]]; then
        sleep 10
    else
        break
    fi
done

sleep 5

With that said, I really like the idea of looking for the dock process rather than a non-root, -_mbsetupuser or -longinwindow user to be logged onto the computer. Here's how I'd modify it to work a bit in our environment.

dockStatus=$(pgrep -x Dock)

echo "Waiting for Desktop..."

while [[ "$dockStatus" == "" ]]
do
  echo "Desktop is not loaded. Waiting."
  sleep 5
  dockStatus=$(pgrep -x Dock)
done

sleep 5
loggedinuser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
echo "$loggedinuser has successfully logged on! The Dock appaears to be loaded with PID $dockStatus."

View solution in original post

7 REPLIES 7

mbezzo
Contributor III

Hi,
We check for the 501 user to be logged in, loop on that until they are, and then start a loop waiting for the dock process to exist. Once that is running, then we know we can launch stuff:

dockStatus=$(pgrep -x Dock)
log "Waiting for Desktop"
while [ "$dockStatus" == "" ]; do
  log "Desktop is not loaded. Waiting."
  sleep 2
  dockStatus=$(pgrep -x Dock)
done

Maybe that'll help?

Good luck!
Matt

sepiemoini
Contributor III
Contributor III

Yup! I'm using a similar approach to what @mbezzo has shared above. In short, I think a while-loop will do the trick as this allows for the "ideal conditions" to be present before going forward. Here's what I've got:

# While-loop used to detect if a standard user is logged on

while true
do
    loggedinuser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
    if [[ "$loggedinuser" = "root" ]] || [[ "$loggedinuser" = "_mbsetupuser" ]] || [[ "$loggedinuser" = "loginwindow" ]]; then
        sleep 10
    else
        break
    fi
done

sleep 5

With that said, I really like the idea of looking for the dock process rather than a non-root, -_mbsetupuser or -longinwindow user to be logged onto the computer. Here's how I'd modify it to work a bit in our environment.

dockStatus=$(pgrep -x Dock)

echo "Waiting for Desktop..."

while [[ "$dockStatus" == "" ]]
do
  echo "Desktop is not loaded. Waiting."
  sleep 5
  dockStatus=$(pgrep -x Dock)
done

sleep 5
loggedinuser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
echo "$loggedinuser has successfully logged on! The Dock appaears to be loaded with PID $dockStatus."

NGuedes
New Contributor III

Hi,

I actually was also using this method, but it can still run for the user "root".
I read elsewhere it is better to get the loggedinuser variable using:
 - loggedinuser=$(stat -f%Su /dev/console

instead of:
- loggedinuser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')

 

Even so, my variable sometimes get the value "root" so I think your 1st suggestion should work better than the 2nd.
Since it makes sure the variables not root, _mbsetupuser or loginwindow, it should work better.

Best regards!


tuinte
Contributor III

Waiting for the dock does it. Thanks one million.

@sepiemoini : Your while loop is basically the same as what we were using. I'm surprised you weren't running into the same thing as us. Though, maybe you have your machines skipping the Time Zone screen.

Either way, lookin' good now. Thanks for the assist.

nvandam
Contributor II

I'm doing the same (waiting for dock) to kick off our enrollment policies, but the problem that I am still running into is the computer doesn't finish enrolling in JAMF fully before leaving the setup assistant and getting to the desktop. We use 802.1x and the computer re-authenticates when leaving setup assistant, thus loses a network connection and the enrollment is hosed. If i check jamf.log it usually shows that it's creating the management account, but that will stay that way until I intervene. Running a sudo jamf manage seems to fix it, but we use a zero touch deployment and can't be doing that to fix those. The consensus from other admins I've asked is to use an open WiFi for Mac enrollments or have the user enroll at home.

Tirillo
New Contributor II

Hi all,

I know it is an old post but I still get a tons of errors when enrolling through DEP.

I have a similar loop setup to keep waiting until a real user logs in, however I still get a lot of errors as the networkStatechange trigger triggers by itself (I have no policies on the trigger, but I can't really control that trigger).
After the errors the process eventually resumes (generally) and the rest of the installation goes through.
However the list of /bin errors is really annoying.

Does anyone know if it is possible to prevent that set of errors?
I'm on jamf 10.4.1-t1525267633 (cloud).

Below a part of the jamf.log

Thu May 31 06:01:49 MacBook Pro jamf[800]: Checking for policies triggered by "enrollmentComplete" for user "_mbsetupuser"...
Thu May 31 06:01:52 MacBook Pro jamf[800]: Executing Policy 00 Please wait
Thu May 31 06:01:52 MacBook Pro jamf[787]: Network state changed, checking for policies...
Thu May 31 06:01:56 Daniel...s MacBook Pro jamf[947]: Checking for policies triggered by "networkStateChange" for user "_mbsetupuser"...
Thu May 31 06:02:01 Daniel...s MacBook Pro jamf[1075]: Error executing command: ( "/usr/bin/defaults", export, "/Library/Preferences/com.jamfsoftware.jamf", "-"
)
Thu May 31 06:02:01 Daniel...s MacBook Pro jamf[1075]: Error executing command: ( "/usr/bin/uname", "-m"
)
Thu May 31 06:02:01 Daniel...s MacBook Pro jamf[1075]: Error executing command: ( "/usr/bin/defaults",

...............................

"/usr/bin/defaults", export, "/Library/Preferences/com.jamfsoftware.jamf", "-"
)
Thu May 31 06:02:08 Daniel...s MacBook Pro jamf[1159]: Checking for policies triggered by "remediation" for user "daniel.sadowski"...
Thu May 31 06:02:09 MacBook Pro jamf[787]: Network state changed, checking for policies...
Thu May 31 06:02:13 Daniel...s MacBook Pro jamf[1159]: Executing Policy 04 EnableCurrentUserforMDM
Thu May 31 06:02:13 Daniel...s MacBook Pro jamf[1274]: Checking for policies triggered by "networkStateChange" for user "daniel.sadowski"...

jmahlman
Valued Contributor

I had some trouble making sure that it ran every time in every circumstance so I decided to make a launchDaemon for my DEP process (outlined here) . Hopefully it's useful to some.

My Launch Daemon script does the above checks, but it won't run at all until the user is fully logged in.