我们的团队在地理上分散,许多虚拟机将由他们使用远程桌面连接。我想知道谁在访问远程桌面会话以及使用了多长时间。
我试图用powershell来做到这一点。我编写了一个脚本,用户将在其中使用 powershell 调用 mstsc。它将记录谁已登录以及何时登录。但我想知道有人从 mstsc 注销或断开 mstsc 的时间。有什么方法可以使用 powershell 在日志文件中捕获该信息。关闭可用于它的 mstsc 时是否会触发任何事件?
我们的团队在地理上分散,许多虚拟机将由他们使用远程桌面连接。我想知道谁在访问远程桌面会话以及使用了多长时间。
我试图用powershell来做到这一点。我编写了一个脚本,用户将在其中使用 powershell 调用 mstsc。它将记录谁已登录以及何时登录。但我想知道有人从 mstsc 注销或断开 mstsc 的时间。有什么方法可以使用 powershell 在日志文件中捕获该信息。关闭可用于它的 mstsc 时是否会触发任何事件?
我编写了一个基于Cassia的 PowerShell 模块 PSTerminalServices ( http://psterminalservices.codeplex.com ) 。这是一个示例命令输出:
PS> Get-TSSession | fl *
IPAddress :
State : Active
ApplicationName :
Local : False
RemoteEndPoint :
InitialProgram :
WorkingDirectory :
ClientProtocolType : Console
ClientProductId : 0
ClientHardwareId : 0
ClientDirectory :
ClientDisplay : Cassia.Impl.ClientDisplay
ClientBuildNumber : 0
Server : Cassia.Impl.TerminalServer
ClientIPAddress :
WindowStationName : Console
DomainName : homelab
UserAccount : homelab\shay
ClientName :
ConnectionState : Active
ConnectTime : 12/15/2011 2:47:02 PM
CurrentTime : 12/23/2011 4:35:21 PM
DisconnectTime :
LastInputTime :
LoginTime : 12/15/2011 3:11:58 PM
IdleTime : 00:00:00
SessionId : 1
UserName : shay
您可以使用Cassia获取 rdp 会话信息(可以定期记录到日志文件中)。
这是一个如何在 Powershell 中使用 cassia 的快速示例:
[reflection.assembly]::loadfile("d:\cassia.dll")
$manager = new-object Cassia.TerminalServicesManager
$server = $manager.GetRemoteServer("<name of your server>")
$server.open()
$server.getsessions()
它将返回如下内容(对于每个会话):
ClientDisplay : Cassia.Impl.ClientDisplay
ClientBuildNumber : 0
Server : Cassia.Impl.TerminalServer
ClientIPAddress :
WindowStationName :
DomainName : CONTOSO
UserAccount : CONTOSO\admin
ClientName :
ConnectionState : Disconnected
ConnectTime : 22/12/2011 19:02:00
CurrentTime : 23/12/2011 9:00:42
DisconnectTime : 22/12/2011 22:22:35
LastInputTime : 22/12/2011 22:22:35
LoginTime : 22/12/2011 10:40:21
IdleTime : 10:38:06.4220944
SessionId : 33
UserName : admin
如果您可以与服务器本身建立 RPC 连接,您可以使用QWinsta.exe查看谁在登录 TS,并使用RWinsta.exe远程关闭连接(请参阅远程管理终端服务会话)
我每 15 分钟运行一次这个函数,它依赖于模块 PSTerminalServices。基本上它的作用是,它会拉取最后一次有人 RDP 进入,然后将其存储在 XML 中,如果存在则覆盖旧值,如果当前没有人登录,则返回 XML 中的最新值。
Function Get-LastLogonTime
{
<#
.SYNOPSIS
Get-LastLogonTime returns the last date that someone logged on to a computer.
.DESCRIPTION
Get-LastLogonTime returns the last date that someone logged to a computer.
If admin rights are missing on the server it will return False.
.EXAMPLE
Get-LastLogonTime "nameofcomputer"
.NOTES
gets last access time from the user folder
.LINK
http://winfred.com
#>
Param(
[Parameter(Position=0, Mandatory=$true)]$ComputerName
)
$StoredRDPSessions = Import-Clixml "RDPSessions.xml"
$myobj = "" | select ComputerName, LastAccessedDate, UserName
$myobj.ComputerName = $ComputerName
$LastConnectedUser = Get-TSSession -ComputerName $ComputerName | where `
{
($_.WindowStationName -ne "Services") -and `
($_.State -ne "Listening") -and `
($_.WindowStationName -ne "Console")
} | sort-object -property LastAccessTime -Descending
if($LastConnectedUser -is [array])
{
$myobj.LastAccessedDate = $LastConnectedUser[0].ConnectTime
$myobj.UserName = $LastConnectedUser[0].UserName
}elseif($LastConnectedUser){
$myobj.LastAccessedDate = $LastConnectedUser.ConnectTime
$myobj.UserName = $LastConnectedUser.UserName
}else{
$myobj.LastAccessedDate = $Null
$myobj.UserName = "Unknown"
}
if(($myobj.LastAccessedDate) -and ($myobj.UserName))
{
$StoredRDPSession = $StoredRDPSessions | where {$_.ComputerName -eq $ComputerName}
if($StoredRDPSession)
{
if($myobj.LastAccessedDate -gt $StoredRDPSession.LastAccessedDate)
{
write-verbose "Newer LastAccessedDate, updating XML"
$StoredRDPSession.LastAccessedDate = $myobj.LastAccessedDate
$StoredRDPSession.UserName = $myobj.UserName
$StoredRDPSessions | Export-Clixml "RDPSessions.xml"
}
}else{
write-verbose "No Entry found Adding to XML"
$NewStoredRDPSessions = @()
$StoredRDPSessions | % {$NewStoredRDPSessions += $_}
$NewStoredRDPSessions += $myobj
$NewStoredRDPSessions | Export-Clixml "RDPSessions.xml"
}
}
if((!($myobj.LastAccessedDate)) -and $StoredRDPSessions)
{
write-verbose "no current session, pulling from stored XML"
$StoredRDPSession = $StoredRDPSessions | where {$_.ComputerName -eq $ComputerName}
if($StoredRDPSession)
{
$myobj.LastAccessedDate = $StoredRDPSession.LastAccessedDate
$myobj.UserName = $StoredRDPSession.UserName
}else{
write-verbose "Sadness, nothing stored in XML either."
}
}
write-verbose "Get-LastLogonTime $ComputerName - $($myobj.LastAccessedDate) - $($myobj.UserName)"
Return $myobj
}