Skip to main content
Solved

Log out after 30 minutes and delete files in user folders

  • October 20, 2025
  • 16 replies
  • 125 views

Forum|alt.badge.img+6

Hey,

I’ve tried looking for this all over and found some partial solutions that don’t really work so I wanted to ask here.

I’ve been asked to set up several iMacs to auto-log off or reboot after 30 minutes of inactivity AND (this is the kicker) delete all files on Desktop, Downloads, and Documents.

I found the Configuration Profile Login Window setting to auto log-off but I’ve seen that if people left unsaved documents over it doesn’t work. It seems to me some scripting is needed here and that’s still a weak spot for me so I’m putting this out to this community in the hopes of some help.

Thanks in advance!

Best answer by Chubs

 Something like this:

#!/bin/bash


cat << EOF > /usr/local/bin/forcelogout.sh
#!/bin/bash

log="/Library/Logs/Auto_Logout/Auto_Logout.log"

writelog() {
local log_file="/Library/Logs/Auto_Logout/Auto_Logoutlog"
echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$log_file"
}

mkdir -p "/Library/Logs/Auto_Logout"

lidClosed=\$(ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState | head -1 | awk '{print \$NF}')
if [[ "\$lidClosed" == "Yes" ]]; then
writelog "Lid has been closed while still logged in; logging out."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
else
writelog "Lid is not closed; exiting."
fi


IdleTimeSecs=\$(expr \$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/{print \$NF; exit}') / 1000000000)
IdleLimit="3600"
if [[ "\$IdleTimeSecs" -gt "\$IdleLimit" ]]; then
writelog "Idle limit reached. Loging out user."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
fi


exit 0



EOF


cat << EOF > /Library/LaunchAgents/com.apple.forcelogout.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.forcelogout</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/usr/local/bin/forcelogout.sh</string>
</array>
<key>StartInterval</key>
<integer>15</integer>
</dict>
</plist>
EOF

chmod 644 /Library/LaunchAgents/com.apple.forcelogout.plist
chown root:wheel /Library/LaunchAgents/com.apple.forcelogout.plist

/bin/launchctl load /Library/LaunchAgents/com.apple.forcelogout.plist

exit 0

 

16 replies

_Daley
Forum|alt.badge.img+6
  • Contributor
  • 27 replies
  • October 21, 2025

You can force a shutdown, ignoring unsaved files, with the following line: 

 	shutdown -r now

I’d recommend adding some kind of notification, either through a tool like SwiftDialog or with osascript, with an option to cancel the shutdown.


AJPinto
Forum|alt.badge.img+26
  • Legendary Contributor
  • 2803 replies
  • October 21, 2025

As ​@_Daley said you can use sudo shutdown -r now to force a reboot. MacOS will natively prevent reboots if there is unsaved work. However, also be aware macOS updates dont like to run if a user is not logged in so this could disrupt any overnight OS update workflows you have. As far as deleting the user files a simple script in a policy to loop through /Users and then loop through the contents of ~/Documents, ~/Desktop and ~/Downloads that runs on startup should accomplish what you are needing. Make sure to exempt your local admin account from this workflow as automating file deletion is very risky.


dsavageED
Forum|alt.badge.img+8
  • New Contributor
  • 173 replies
  • October 21, 2025

Get the username of the logged in user (say UserNm)

Set an idle timeout

Kill the loginwindow process

Delete /Users/UserNm

This would need to be a script ran as a daemon… I should have some example code, but not got the time to dig it out right now.


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 21, 2025

Sounds like you want/need authenticated guest mode.  If you’re using Entra MFA and PSSO, then this should be an option for you.


mvu
Forum|alt.badge.img+20
  • Jamf Heroes
  • 963 replies
  • October 22, 2025

Yeah, look into Guest account. Used this in school labs in the past and it works. 


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 22, 2025

Yeah, look into Guest account. Used this in school labs in the past and it works. 

There is the baked in Guest account - but you’ll want to test it.  It doesn’t log out inactive users.  We had to create a launchAgent to take care of that.  We were using it in the capacity of “guest mode” for iPads, so naturally we wanted an inactivity log out.


Forum|alt.badge.img+6
  • Author
  • Contributor
  • 36 replies
  • October 23, 2025

Get the username of the logged in user (say UserNm)

Set an idle timeout

Kill the loginwindow process

Delete /Users/UserNm

This would need to be a script ran as a daemon… I should have some example code, but not got the time to dig it out right now.

This sounds perfect. If you can find that example code that would be a huge help.


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • Answer
  • October 23, 2025

 Something like this:

#!/bin/bash


cat << EOF > /usr/local/bin/forcelogout.sh
#!/bin/bash

log="/Library/Logs/Auto_Logout/Auto_Logout.log"

writelog() {
local log_file="/Library/Logs/Auto_Logout/Auto_Logoutlog"
echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$log_file"
}

mkdir -p "/Library/Logs/Auto_Logout"

lidClosed=\$(ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState | head -1 | awk '{print \$NF}')
if [[ "\$lidClosed" == "Yes" ]]; then
writelog "Lid has been closed while still logged in; logging out."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
else
writelog "Lid is not closed; exiting."
fi


IdleTimeSecs=\$(expr \$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/{print \$NF; exit}') / 1000000000)
IdleLimit="3600"
if [[ "\$IdleTimeSecs" -gt "\$IdleLimit" ]]; then
writelog "Idle limit reached. Loging out user."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
fi


exit 0



EOF


cat << EOF > /Library/LaunchAgents/com.apple.forcelogout.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.forcelogout</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/usr/local/bin/forcelogout.sh</string>
</array>
<key>StartInterval</key>
<integer>15</integer>
</dict>
</plist>
EOF

chmod 644 /Library/LaunchAgents/com.apple.forcelogout.plist
chown root:wheel /Library/LaunchAgents/com.apple.forcelogout.plist

/bin/launchctl load /Library/LaunchAgents/com.apple.forcelogout.plist

exit 0

 


Forum|alt.badge.img+6
  • Author
  • Contributor
  • 36 replies
  • October 23, 2025

 Something like this:

#!/bin/bash


cat << EOF > /usr/local/bin/forcelogout.sh
#!/bin/bash

log="/Library/Logs/Auto_Logout/Auto_Logout.log"

writelog() {
local log_file="/Library/Logs/Auto_Logout/Auto_Logoutlog"
echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$log_file"
}

mkdir -p "/Library/Logs/Auto_Logout"

lidClosed=\$(ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState | head -1 | awk '{print \$NF}')
if [[ "\$lidClosed" == "Yes" ]]; then
writelog "Lid has been closed while still logged in; logging out."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
else
writelog "Lid is not closed; exiting."
fi


IdleTimeSecs=\$(expr \$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/{print \$NF; exit}') / 1000000000)
IdleLimit="3600"
if [[ "\$IdleTimeSecs" -gt "\$IdleLimit" ]]; then
writelog "Idle limit reached. Loging out user."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
fi


exit 0



EOF


cat << EOF > /Library/LaunchAgents/com.apple.forcelogout.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.forcelogout</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/usr/local/bin/forcelogout.sh</string>
</array>
<key>StartInterval</key>
<integer>15</integer>
</dict>
</plist>
EOF

chmod 644 /Library/LaunchAgents/com.apple.forcelogout.plist
chown root:wheel /Library/LaunchAgents/com.apple.forcelogout.plist

/bin/launchctl load /Library/LaunchAgents/com.apple.forcelogout.plist

exit 0

 

Thank you for this! This is only used for iMacs so the LidClosed part won’t be needed. I can just remove that section and the code will still work, yes?

I don’t need to delete the entire User folder, just the contents of the Desktop, Downloads and Documents subfolders. If I replace the line “rm -r /Users/Guest” with “rm -rf /Users/Library/Desktop/*” and include additional lines for the Downloads and Documents folders, would that work?

 


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 23, 2025

 Something like this:

#!/bin/bash


cat << EOF > /usr/local/bin/forcelogout.sh
#!/bin/bash

log="/Library/Logs/Auto_Logout/Auto_Logout.log"

writelog() {
local log_file="/Library/Logs/Auto_Logout/Auto_Logoutlog"
echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$log_file"
}

mkdir -p "/Library/Logs/Auto_Logout"

lidClosed=\$(ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState | head -1 | awk '{print \$NF}')
if [[ "\$lidClosed" == "Yes" ]]; then
writelog "Lid has been closed while still logged in; logging out."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
else
writelog "Lid is not closed; exiting."
fi


IdleTimeSecs=\$(expr \$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/{print \$NF; exit}') / 1000000000)
IdleLimit="3600"
if [[ "\$IdleTimeSecs" -gt "\$IdleLimit" ]]; then
writelog "Idle limit reached. Loging out user."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
fi


exit 0



EOF


cat << EOF > /Library/LaunchAgents/com.apple.forcelogout.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.forcelogout</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/usr/local/bin/forcelogout.sh</string>
</array>
<key>StartInterval</key>
<integer>15</integer>
</dict>
</plist>
EOF

chmod 644 /Library/LaunchAgents/com.apple.forcelogout.plist
chown root:wheel /Library/LaunchAgents/com.apple.forcelogout.plist

/bin/launchctl load /Library/LaunchAgents/com.apple.forcelogout.plist

exit 0

 

Thank you for this! This is only used for iMacs so the LidClosed part won’t be needed. I can just remove that section and the code will still work, yes?

I don’t need to delete the entire User folder, just the contents of the Desktop, Downloads and Documents subfolders. If I replace the line “rm -r /Users/Guest” with “rm -rf /Users/Library/Desktop/*” and include additional lines for the Downloads and Documents folders, would that work?

 

We wrote this to use on all devices - so it’s smart enough to know there isn’t a lid...and it gets rid of the entire profile - namely because you really should plan on removing the SSO tokens and stuff.  Just remove the whole profile and be done.


Forum|alt.badge.img+6
  • Author
  • Contributor
  • 36 replies
  • October 23, 2025

 Something like this:

#!/bin/bash


cat << EOF > /usr/local/bin/forcelogout.sh
#!/bin/bash

log="/Library/Logs/Auto_Logout/Auto_Logout.log"

writelog() {
local log_file="/Library/Logs/Auto_Logout/Auto_Logoutlog"
echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$log_file"
}

mkdir -p "/Library/Logs/Auto_Logout"

lidClosed=\$(ioreg -r -k AppleClamshellState -d 4 | grep AppleClamshellState | head -1 | awk '{print \$NF}')
if [[ "\$lidClosed" == "Yes" ]]; then
writelog "Lid has been closed while still logged in; logging out."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
else
writelog "Lid is not closed; exiting."
fi


IdleTimeSecs=\$(expr \$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/{print \$NF; exit}') / 1000000000)
IdleLimit="3600"
if [[ "\$IdleTimeSecs" -gt "\$IdleLimit" ]]; then
writelog "Idle limit reached. Loging out user."
osascript -e 'tell application "loginwindow" to «event aevtrlgo»'
rm -r /Users/Guest
fi


exit 0



EOF


cat << EOF > /Library/LaunchAgents/com.apple.forcelogout.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.forcelogout</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/usr/local/bin/forcelogout.sh</string>
</array>
<key>StartInterval</key>
<integer>15</integer>
</dict>
</plist>
EOF

chmod 644 /Library/LaunchAgents/com.apple.forcelogout.plist
chown root:wheel /Library/LaunchAgents/com.apple.forcelogout.plist

/bin/launchctl load /Library/LaunchAgents/com.apple.forcelogout.plist

exit 0

 

Thank you for this! This is only used for iMacs so the LidClosed part won’t be needed. I can just remove that section and the code will still work, yes?

I don’t need to delete the entire User folder, just the contents of the Desktop, Downloads and Documents subfolders. If I replace the line “rm -r /Users/Guest” with “rm -rf /Users/Library/Desktop/*” and include additional lines for the Downloads and Documents folders, would that work?

 

We wrote this to use on all devices - so it’s smart enough to know there isn’t a lid...and it gets rid of the entire profile - namely because you really should plan on removing the SSO tokens and stuff.  Just remove the whole profile and be done.

Works for me! One last (possibly stupid) question: do we just deploy this script to the machines in question once or does this have to be deployed on a recurring basis? Thank you again!


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 23, 2025

It’s a one and done.  We run it at post-enrollment and it sits on the box.


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 23, 2025

But as always TEST TEST TEST!


Forum|alt.badge.img+6
  • Author
  • Contributor
  • 36 replies
  • October 23, 2025

But as always TEST TEST TEST!

Absolutely! Especially with a script that wipes a profile! Thank you once again! You’ve saved me a lot of grief!


Chubs
Forum|alt.badge.img+20
  • Jamf Heroes
  • 241 replies
  • October 23, 2025

Make sure to change this section: 

IdleLimit="3600"

To your desired time.  I sure didn’t write that to be malleable as it was a knee-jerk solution to a problem that needed to be fixed the same day lol.


Forum|alt.badge.img+6
  • Author
  • Contributor
  • 36 replies
  • October 23, 2025

Make sure to change this section: 

IdleLimit="3600"

To your desired time.  I sure didn’t write that to be malleable as it was a knee-jerk solution to a problem that needed to be fixed the same day lol.

Yes I saw that but thanks for the reminder!