根据空闲时间注销断开连接的用户会话

Logoff Disconnected user sessions based on IDLE time

我已经编写了一个 PS 脚本来查找在远程服务器上具有断开连接的 RDP 会话的任何用户,并且我得到了用户@Theo 的帮助以完成它。

现在添加到我的脚本中,如果空闲时间超过 1 天,我想注销断开连接的用户。

这对我们实现目标有很大帮助

代码

## 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
}

然后需要将.IdleTime属性倒转回整数,判断用户是否闲置超过1天:

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)
    }
}

要将其添加到您现有的代码中,只需更新最终的 if(..){..} else{..} 以包含:

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
}