如何使用 qwinsta 命令获取 RDP 断开连接的会话

发布于 2025-01-09 03:44:51 字数 2234 浏览 0 评论 0原文

我编写了一个 PS 脚本来查找在远程服务器上断开连接的 RDP 会话的任何用户,我得到了我想要的确切输出,但是,使用 qwinsta 查询我还想获取用户登录时间和 IDOL 时间的详细信息,但我无法使用 Qwinsta 命令查询。

如果我尝试使用查询用户,我的脚本中会出现错误,提示未找到用户。请帮助实现输出。

我写的剧本。

代码

## Clear Host Console
Clear-Host

## Define Variable for Server Count
$z = 0

##Set Default Script Location
Set-Location -Path "C:\Users\Desktop\Active or Disc users"

## Check if the old Report file exists or not
#$checkrep = Test-Path ".\Reports\RDP_Disconnected_Users_Report.html" 

## Provide List of Servers to Check for the Disconnected user session
$Servers = Get-Content ".\Servers\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"

## Define Array for Storing the User sessions
$openSessions = @()

## Loop through each server to find the User Disconnected session
Foreach ($ServerName 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)

## Add the servers if you want to exclude any
$ExcludedServers = "EXCLUDESRV01", "EXCLUDESRV02", "EXCLUDESRV03"
If ($ExcludedServers -notcontains $ServerName)
{
#$user = quser | where {($_.User -ne "") -and ($_.Username -ne "Administrator")}
Write-Host "Getting session information for $ServerName"
$sessions = qwinsta /server $ServerName| ?{ $_ -notmatch '^ SESSIONNAME' } | %{
$item = "" | Select "ServerName", "Username", "Id", "State"
$item.ServerName = $ServerName
#$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.IdleTime = $_.Substring().Trim()
$item.LogonTime = $_.Substring().Trim()
$item
}
$openSessions += $sessions | where { ($_.Username -ne "") -and ($_.Username -ne "Administrator") -and ($_.State -ne "Active")}
}
Else { Write-Host "Skipping named computer $ServerName" -ForegroundColor Green}
}

$openSessions | Export-Csv "$exportFile" -NoTypeInformation

I have written a PS script to find any user who has a disconnected RDP session on remote servers, I am getting the exact output as I want but, using qwinsta query I want to get the details of user Logon Time and IDOL time as well, but I am unable to query that using Qwinsta command.

If I try with Query user I am getting an error in my script saying no user has been found. Please help to achieve the output.

The script I have written.

Code

## Clear Host Console
Clear-Host

## Define Variable for Server Count
$z = 0

##Set Default Script Location
Set-Location -Path "C:\Users\Desktop\Active or Disc users"

## Check if the old Report file exists or not
#$checkrep = Test-Path ".\Reports\RDP_Disconnected_Users_Report.html" 

## Provide List of Servers to Check for the Disconnected user session
$Servers = Get-Content ".\Servers\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"

## Define Array for Storing the User sessions
$openSessions = @()

## Loop through each server to find the User Disconnected session
Foreach ($ServerName 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)

## Add the servers if you want to exclude any
$ExcludedServers = "EXCLUDESRV01", "EXCLUDESRV02", "EXCLUDESRV03"
If ($ExcludedServers -notcontains $ServerName)
{
#$user = quser | where {($_.User -ne "") -and ($_.Username -ne "Administrator")}
Write-Host "Getting session information for $ServerName"
$sessions = qwinsta /server $ServerName| ?{ $_ -notmatch '^ SESSIONNAME' } | %{
$item = "" | Select "ServerName", "Username", "Id", "State"
$item.ServerName = $ServerName
#$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.IdleTime = $_.Substring().Trim()
$item.LogonTime = $_.Substring().Trim()
$item
}
$openSessions += $sessions | where { ($_.Username -ne "") -and ($_.Username -ne "Administrator") -and ($_.State -ne "Active")}
}
Else { Write-Host "Skipping named computer $ServerName" -ForegroundColor Green}
}

$openSessions | Export-Csv "$exportFile" -NoTypeInformation

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还给你自由 2025-01-16 03:44:51

您可以使用辅助函数来获取所有远程会话详细信息(无论是否活动),并过滤掉您想要在输出中出现的内容。

按照这里的要求,不仅是函数,而且是对代码的完全重写:

function Get-RemoteSessions {
    [CmdletBinding()]
    param(
        [string[]]$ComputerName = 'localhost'
    )
    foreach ($Computer in $ComputerName) {
        Write-Verbose "Getting session information for $Computer"
        # create an object to fill in later
        $obj = "" | Select-Object UserName, @{Name = 'ComputerName'; Expression = {$Computer}}, 
                                  SessionName, ID, State, IdleTime, LogonTime, Error
        try {
            quser /server:$Computer 2>&1 | Select-Object -Skip 1 | ForEach-Object {
                $items = $_.Trim() -split '\s{2,}'
                $obj.UserName = $items[0].TrimStart(">")
                # If session is disconnected different fields will be selected
                if ($items[2] -like 'Disc*') {
                    $obj.SessionName = $null
                    $obj.Id          = $items[1]
                    $obj.State       = $items[2]
                    # IdleTime displays the number of minutes that have elapsed since the last keyboard or 
                    # mouse input from a session. Its format is number-of-days + hours:minutes
                    $obj.IdleTime    = $items[3]
                    $obj.LogonTime   = $items[4..($items.GetUpperBound(0))] -join ' '
                }
                else {
                    $obj.SessionName = $items[1]
                    $obj.Id          = $items[2]
                    $obj.State       = $items[3]
                    $obj.IdleTime    = $items[4]
                    $obj.LogonTime   = $items[5]
                }
                # 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
        }
    }
}

## Clear Host Console
Clear-Host

$ExcludedServers = 'EXCLUDESRV01', 'EXCLUDESRV02', 'EXCLUDESRV03'
## Read the list of Servers excluding the ones in $ExcludedServers
$Servers = Get-Content -Path 'C:\Users\Desktop\Active or Disc users\Servers\Servers.txt' | 
           Where-Object { $ExcludedServers -notcontains $_ }

# get all remote sessions on all servers
$allSessions = Get-RemoteSessions -ComputerName $Servers -Verbose

# filter the open sessions from the $allRemoteUsers
$openSessions = $allSessions| Where-Object {$_.Username -ne 'Administrator' -and $_.State -notlike 'Disc*'}
# and do the same for the disconnected sessions
$disconnected = $allSessions | Where-Object {$_.Username -ne 'Administrator' -and $_.State -like 'Disc*' }

## Define Path for the Out File and make sure the path for the output file exists
$reportPath = 'C:\Users\Desktop\Active or Disc users\Out'
$null = New-Item -Path $reportPath -ItemType Directory -Force

if (@($openSessions).Count) {
    # write a file for the open sessions
    $outFile = Join-Path -Path $reportPath -ChildPath ('RDP_Connected_Users_{0:yyyyMMdd}.csv' -f (Get-Date))
    $openSessions | Export-Csv -Path $outFile -NoTypeInformation
}
else {
    Write-Host "No open user sessions found"
}

if (@($disconnected).Count) {
    # and another for the disconnected sessions
    $outFile = Join-Path -Path $reportPath -ChildPath ('RDP_DisConnected_Users_{0:yyyyMMdd}.csv' -f (Get-Date))
    $disconnected | Export-Csv -Path $outFile -NoTypeInformation
}
else {
    Write-Host "No disconnected sessions found"
}

You could use a helper function to get all remote session details, active or not and filter out the ones you want in your output.

As requested here not only the function, but a complete rewrite of your code:

function Get-RemoteSessions {
    [CmdletBinding()]
    param(
        [string[]]$ComputerName = 'localhost'
    )
    foreach ($Computer in $ComputerName) {
        Write-Verbose "Getting session information for $Computer"
        # create an object to fill in later
        $obj = "" | Select-Object UserName, @{Name = 'ComputerName'; Expression = {$Computer}}, 
                                  SessionName, ID, State, IdleTime, LogonTime, Error
        try {
            quser /server:$Computer 2>&1 | Select-Object -Skip 1 | ForEach-Object {
                $items = $_.Trim() -split '\s{2,}'
                $obj.UserName = $items[0].TrimStart(">")
                # If session is disconnected different fields will be selected
                if ($items[2] -like 'Disc*') {
                    $obj.SessionName = $null
                    $obj.Id          = $items[1]
                    $obj.State       = $items[2]
                    # IdleTime displays the number of minutes that have elapsed since the last keyboard or 
                    # mouse input from a session. Its format is number-of-days + hours:minutes
                    $obj.IdleTime    = $items[3]
                    $obj.LogonTime   = $items[4..($items.GetUpperBound(0))] -join ' '
                }
                else {
                    $obj.SessionName = $items[1]
                    $obj.Id          = $items[2]
                    $obj.State       = $items[3]
                    $obj.IdleTime    = $items[4]
                    $obj.LogonTime   = $items[5]
                }
                # 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
        }
    }
}

## Clear Host Console
Clear-Host

$ExcludedServers = 'EXCLUDESRV01', 'EXCLUDESRV02', 'EXCLUDESRV03'
## Read the list of Servers excluding the ones in $ExcludedServers
$Servers = Get-Content -Path 'C:\Users\Desktop\Active or Disc users\Servers\Servers.txt' | 
           Where-Object { $ExcludedServers -notcontains $_ }

# get all remote sessions on all servers
$allSessions = Get-RemoteSessions -ComputerName $Servers -Verbose

# filter the open sessions from the $allRemoteUsers
$openSessions = $allSessions| Where-Object {$_.Username -ne 'Administrator' -and $_.State -notlike 'Disc*'}
# and do the same for the disconnected sessions
$disconnected = $allSessions | Where-Object {$_.Username -ne 'Administrator' -and $_.State -like 'Disc*' }

## Define Path for the Out File and make sure the path for the output file exists
$reportPath = 'C:\Users\Desktop\Active or Disc users\Out'
$null = New-Item -Path $reportPath -ItemType Directory -Force

if (@($openSessions).Count) {
    # write a file for the open sessions
    $outFile = Join-Path -Path $reportPath -ChildPath ('RDP_Connected_Users_{0:yyyyMMdd}.csv' -f (Get-Date))
    $openSessions | Export-Csv -Path $outFile -NoTypeInformation
}
else {
    Write-Host "No open user sessions found"
}

if (@($disconnected).Count) {
    # and another for the disconnected sessions
    $outFile = Join-Path -Path $reportPath -ChildPath ('RDP_DisConnected_Users_{0:yyyyMMdd}.csv' -f (Get-Date))
    $disconnected | Export-Csv -Path $outFile -NoTypeInformation
}
else {
    Write-Host "No disconnected sessions found"
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文