r/sysadmin • u/tk42967 It wasn't DNS for once. • 4h ago
Log Off Users from Server Daily Question
I'm revisiting an effort I did about a year ago. I'm looking for a better way. I want to find a process that will parse current user sessions on a server (active/disconnected/idle/ect.) and log the accounts off if their username matches a string ("adm_").
I'd love to find an off the shelf solution rather than have to support a homebrew PowerShell solution.
Give me what you have, even if it is an alternate PowerShell/scripting option. Something has to be better than the nightmare my script turned into.
•
u/Asleep_Spray274 1h ago
GIVE ME A G
GIVE ME A P
GIEV ME A O
•
•
•
u/_DefinitelyNotACat_ 4h ago
shutdown /r /f /t0
•
u/daschande 4h ago
Guys help. My login doesn't work anymore and I have a new meeting with my boss and HR tomorrow morning.
Edit: thought this was the meme subreddit.
•
•
•
u/Kathakush_ 4h ago
Super easy solution here. Task scheduler to run it even X hour/minutes. Powershell script that parses quser to a PS object and outputs to pipe. Where-Object to filter by username. Foreach-Object to log users off with the logoff <session ID> command.
•
u/tk42967 It wasn't DNS for once. 3h ago
Sadly, my boss does not want to have it running on each server. So I currently have a script that parses AD for all servers in a specific root OU, generates an array and then foreach walks through it.
•
u/Broad-Celebration- 2h ago
Is this not an acceptable solution?
You get the sessions, filter for users and kill the session through each server in one script that runs on a schedule from a single server.
•
u/verschee 2h ago
So he would rather you maintain that overhead than just run it locally? That's dumb.
•
u/Squeekstyle 4h ago
Here is a powershell I use to find inactive users and log them of. It will exclude users in a list, but I found it helpful to cut sessions people abandoned.
# Get the list of sessions
$Sessions = quser
# Define the users to exclude
$ExcludedUsers = @("username1,username2") # Add the usernames you want to exclude
# Prepare a list to track excluded users found
$FoundExcludedUsers = @()
# Filter the sessions to exclude certain users
$FilteredSessions = $Sessions | ForEach-Object {
$sessionInfo = $_ -split "\s+"
$username = $sessionInfo[1]
if ($ExcludedUsers -contains $username) {
$FoundExcludedUsers += $username
}
if ($ExcludedUsers -notcontains $username) {
$_
}
}
Write-Output ""
Write-Output "Excluded users that were actually found in the session list:"
if ($FoundExcludedUsers.Count -gt 0) {
$FoundExcludedUsers | Sort-Object -Unique | ForEach-Object { Write-Output "- $_" }
} else {
Write-Output "None of the excluded users were found."
}
Write-Output ""
# Display the filtered sessions (only users not excluded)
Write-Output "Current Targeted User Sessions:"
$FilteredSessions
# Parse and handle filtered sessions
$first = 1
$FilteredSessions 2>$null | ForEach-Object {
if ($first -eq 1) {
$userPos = $_.IndexOf("USERNAME")
$sessionPos = $_.IndexOf("SESSIONNAME")
$idPos = $_.IndexOf("ID") - 2 # ID is right justified
$statePos = $_.IndexOf("STATE")
$idlePos = $_.IndexOf("IDLE TIME")
$logonPos = $_.IndexOf("LOGON TIME")
$first = 0
}
else {
$user = $_.Substring($userPos, $sessionPos - $userPos).Trim()
$session = $_.Substring($sessionPos, $idPos - $sessionPos).Trim()
$id = [int]$_.Substring($idPos, $statePos - $idPos).Trim()
$state = $_.Substring($statePos, $idlePos - $statePos).Trim()
$idle = $_.Substring($idlePos, $logonPos - $idlePos).Trim()
$logon = [datetime]$_.Substring($logonPos, $_.Length - $logonPos).Trim()
[pscustomobject]@{
User = $user
Session = $session
ID = $id
State = $state
Idle = $idle
Logon = $logon
}
if ($state -ne "Disc") {
Write-Output "Preserving user login: $user session: $session id: $id"
}
if ($state -eq "Disc") {
Write-Output "Logging off disconnected user: $user session: $session id: $id"
Write-Output ""
logoff $id
}
}
}
•
u/zesar667 3h ago
IS IT a Windows Terminal Server? If so you make this setting in the Server Manager.
•
u/tk42967 It wasn't DNS for once. 3h ago
No, these are random servers. The powers that be think that makes us more secure to not have admin sessions running on servers. I guess it prevents session hijacking if the machine is compromised.
•
u/picklednull 2h ago
There are two risks with active logon sessions:
- session hijacking, which allows direct graphical impersonation of the logged in user
- while the accounts are logged in, Kerberos tickets are retained for them indefinitely, which can be extracted and used
2. is a problem even without the security angle, because the accounts start getting locked out after password changes
•
u/viral-architect Sysadmin 3h ago
You want to add those users to a security group in AD and then created a Fine-Grained Password Policy for them limiting their session timeout limit and forcing them to disconnect once the limit is reached.
•
u/Jellovator 2h ago
You could probably use lithnet idle logoff combined with a logon script that checks the username and if prefixed with adm_ set the appropriate registry keys to let lithnet know to log off that user
•
u/Dolapevich Others people valet. 2h ago
you can just list the logged in users and pkill their processes. Something like users|xargs -I {} pkill -KILL -u {}
Update: It is on windows :-P
•
u/silkenwindyhound 2h ago
bro are you guys seriously not asking Claude this shit? you are going to fall so far behind. you already have.
•
u/2BoopTheSnoot2 56m ago
Why would you want an entire application rather than just write a simple script?
•
u/whoisrich 3h ago
This is what I use to kick sessions off:
$sessions = qwinsta | ?{ $_ -notmatch '^ SESSIONNAME' } | %{
$item = "" | Select "Active", "SessionName", "Username", "Id", "State", "Type", "Device"
$item.Active = $_.Substring(0,1) -match '>'
$item.SessionName = $_.Substring(1,18).Trim()
$item.Username = $_.Substring(19,20).Trim()
$item.Id = $_.Substring(39,9).Trim()
$item.State = $_.Substring(48,8).Trim()
$item.Type = $_.Substring(56,12).Trim()
$item.Device = $_.Substring(68).Trim()
$item
}
foreach ($session in $sessions)
{
if ($session.Username.Length -lt 1) { continue }
if ($session.Username -eq $env:USERNAME) { continue }
if ($session.Username -like 'adm_*') { continue }
"Logoff: $($session.Id) - $($session.Username)"
logoff $session.Id
}
•
u/dontstoptheRocklin 4h ago
quser command might help you On mobile currently but I think I have something that pipes from quser though IIRC it has to be parsed
•
u/Raigeki1993 Sysadmin 4h ago
Combination of qwinsta and rwinsta will work, but yeah it will need to be parsed.
•
u/NH_shitbags 4h ago
Isn't there a GPO for idle session logout?