I have written a PS script to find any user who has a disconnected RDP session on remote servers and I got help from user @Theo to get it finished.
Now add on to my script, I want to Log off the disconnected users if the IDLE time is more than 1 day.
This will help us a lot for me to achieve the things
CODE
## Clear Host Console
Clear-Host
## Define Variable for Server Count
$z = 0
##Set Default Script Location
Set-Location $PSScriptRoot
## Provide List of Servers to Check for the Disconnected user session
$Servers = Get-Content ".\Servers\DA_Servers.txt"
## Get Servers Count
$count = $Servers.count
## Define Date for the Out file
$dt = Get-Date -Format yyyyMMdd
$Date = Get-Date
## Define Path for the Out File
$exportFile = ".\Out\RDP_DisConnected_Users.csv"
## Create a Function to list all user sessions from Remote Servers
function Get-RemoteUsers {
## Loop through each server to find the User session
foreach ($Computer in $Servers) {
#initiate counter for showing progress
$z = $z + 1
# Start writing progress
Write-Progress -Activity "Processing Server: $z out of $count servers." -Status " Progress" -PercentComplete ($z/$Servers.count*100)
$obj = "" | Select-Object @{Name = 'ServerName'; Expression = {$Computer}}, UserName, ID, State, IdleTime, LogonTime
try {
quser /server:$Computer 2>&1 | Select-Object -Skip 1 | ForEach-Object {
$items = $_.Trim() -split '\s{2,}'
$obj.UserName = $items[0]
# If session is disconnected different fields will be selected
if ($items[2] -like 'Disc*')
{
$obj.Id = $items[1]
$obj.State = $items[2]
$obj.IdleTime = $items[3]
$obj.LogonTime = $items[4..($items.GetUpperBound(0))] -join ' '
}
else {
$obj.Id = $items[1]
$obj.State = $items[2]
$obj.IdleTime = $items[3]
$obj.LogonTime = $items[4]
}
# reformat the IdleTime property
$obj.IdleTime = '{0} days, {1} hours, {2} minutes' -f ([int[]]([regex]'^(?:(\d+)\+)?(\d+):(\d+)').Match($obj.IdleTime).Groups[1..3].Value | ForEach-Object { $_ })
# output the object
$obj
}
}
catch {
#$obj.Error = $_.Exception.Message
#$obj
}
}
}
## Filter the results to find out the disconnected users
$allRemoteUsers = Get-RemoteUsers $Servers
$disconnectedUsers = $allRemoteUsers | Where-Object {$_.State -like 'disc*' }
if (@($disconnectedUsers).Count) {
#output on screen
$disconnectedUsers | Format-Table -AutoSize
# output to Csv
$disconnectedUsers | Export-Csv "$exportFile" -NoTypeInformation
}
else {
Write-Host "No disconnected users found" -BackgroundColor Red
}
You then need to reverse the .IdleTime
property back to integer numbers to determine if the user has been idle for more than 1 day:
foreach ($item in $disconnectedUsers) {
# read back the values for Days, Hours and Minutes from the formatted string
$d, $h, $m = [int[]]([regex]'(\d+) days, (\d+) hours, (\d+) minutes').Match($item.IdleTime).Groups[1..3].Value
if ($d -gt 1 -or ($d -eq 1 -and ($h -gt 0 -or $m -gt 0))) {
# been idle for more than 1 day, so logoff the user here
Write-Host "Logging off $($item.UserName) from computer $($item.ServerName).."
logoff $item.Id /SERVER:$($item.ServerName)
# or use: rwinsta $item.Id /SERVER:$($item.ServerName)
}
}
To add that to your existing code, just update the final if(..){..} else{..}
to include that:
if (@($disconnectedUsers).Count) {
#output on screen
$disconnectedUsers | Format-Table -AutoSize
# output to Csv
$disconnectedUsers | Export-Csv "$exportFile" -NoTypeInformation
# next, loop through the disconnected user connections and test if there are idle connections older than 1 day
# if so then log them off
foreach ($item in $disconnectedUsers) {
# read back the values for Days, Hours and Minutes from the formatted string
$d, $h, $m = [int[]]([regex]'(\d+) days, (\d+) hours, (\d+) minutes').Match($item.IdleTime).Groups[1..3].Value
if ($d -gt 1 -or ($d -eq 1 -and ($h -gt 0 -or $m -gt 0))) {
# been idle for more than 1 day, so logoff the user here
Write-Host "Logging off $($item.UserName) from computer $($item.ServerName).."
logoff $item.Id /SERVER:$($item.ServerName)
# or use: rwinsta $item.Id /SERVER:$($item.ServerName)
}
}
}
else {
Write-Host "No disconnected users found" -BackgroundColor Red
}