当我在
qwinsta /server:somesrv
中运行 cmd
命令时,我可以获得登录到特定 Windows 服务器的所有当前 RDP 会话的列表。
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console 0 Conn wdcon
rdp-tcp 65536 Listen rdpwd
rdp-tcp#594 tom1 1 Active rdpwd
rdp-tcp#595 bob1 2 Active rdpwd
是否可以从Powershell在远程服务器上获取这样的列表,以便数据可以在其他地方使用?
有多种选择:
qwinsta
的输出解析为对象。 简单的解决方案。请参阅下面的示例Cassia.DLL
.Net 包装器访问 qwinsta
在后台运行的本机 API。这是 TS 模块使用的类。 更困难,但好处是可以根据您的需求进行定制。Cassia.DLL
使用 P/Invoke 访问的本机方法(wtsapi32.dll
、kernel32.dll
、winsta.dll
)。 困难且过于复杂。qwinsta 的 PowerShell 包装器
function Get-TSSessions {
param(
$ComputerName = 'localhost'
)
$output = qwinsta /server:$ComputerName
if ($null -eq $output) {
# An error occured. Abort
return
}
# Get column names and locations from fixed-width header
$columns = [regex]::Matches($output[0],'(?<=\s)\w+')
$output | Select-Object -Skip 1 | Foreach-Object {
[string]$line = $_
$session = [ordered]@{}
for ($i=0; $i -lt $columns.Count; $i++) {
$currentColumn = $columns[$i]
$columnName = $currentColumn.Value
if ($i -eq $columns.Count-1) {
# Last column, get rest of the line
$columnValue = $line.Substring($currentColumn.Index).Trim()
} else {
$lengthToNextColumn = $columns[$i+1].Index - $currentColumn.Index
$columnValue = $line.Substring($currentColumn.Index, $lengthToNextColumn).Trim()
}
$session.$columnName = $columnValue.Trim()
}
# Return session as object
[pscustomobject]$session
}
}
Get-TSSessions -ComputerName "localhost" | Format-Table -AutoSize
SESSIONNAME USERNAME ID STATE TYPE DEVICE
----------- -------- -- ----- ---- ------
services 0 Disc
console Frode 1 Active
#This is objects, so we can manipulate the results to get the info we want. Active sessions only:
Get-TSSessions -ComputerName "localhost" | Where-Object State -eq 'Active' | Format-Table -AutoSize SessionName, UserName, ID
SESSIONNAME USERNAME ID
----------- -------- --
console Frode 1
我曾经使用过 Terminal Services PowerShell 模块(现在位于 codeplex 存档中),但那是两年前的事了。我无法把手放在它上面,但它在 gitshub 或其他嵌入了
QWinsta/RmWinsta
的网站上也存在一个功能。
我自己做的,但我想你会理解的
function seans ($server)
{
function path1 ($server, $user)
{
if ((Test-Path -Path "\\$server\c$\users\$user") -eq $true)
{
"\\$server\c$\users\$user"
}
elseif ((Test-Path -Path ("\\$server\d$\users\$user")) -eq $true)
{
"\\$server\d$\users\$user"
}
else
{
"\\$server\e$\users\$user"
}
}
$seans = qwinsta /server:$server | ForEach-Object { $_.Trim() -replace "\s+", "," } | ConvertFrom-Csv
$seans = $seans | select-object @{ Name = "User"; Expression = { $_.username } },
@{ Name = "Id"; Expression = { $_.id } },
@{ Name = "Status"; Expression = { $_.state } },
@{ Name = "Path"; Expression = { $null } }
$seans = $seans | Where-object -Property status -eq "Active"
$seans | foreach-object { $_.path = path1 $server $_.user }
$seans
}