问题
Our team has geographically dispersed and many virtual machine will be connected by them using remote desktop. I would like to find who is accessing a remote desktop session and how long it is being used.
I tried to do it with powershell. I wrote a script where user will invoke mstsc using powershell. It will log who has logged in and when he logged. But i would like to find when some one log off from mstsc or disconnect mstsc . Is there any way to capture that information in log file using powershell. Whether any event will be triggered while closing mstsc which could be used for it?
回答1:
I wrote a PowerShell module,PSTerminalServices (http://psterminalservices.codeplex.com), that is built on Cassia. Here's a sample command output:
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
回答2:
You could use Cassia to get rdp session information (which could be periodically logged to a log file).
Here's a quick example of how to use cassia in Powershell:
[reflection.assembly]::loadfile("d:\cassia.dll")
$manager = new-object Cassia.TerminalServicesManager
$server = $manager.GetRemoteServer("<name of your server>")
$server.open()
$server.getsessions()
It will return something like this (for every session):
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
回答3:
If you can establish an RPC connexion with the server itself you can use QWinsta.exe to see who is logon a TS and RWinsta.exe to remote close a connexion (see Managing Terminal Services Sessions Remotely)
回答4:
I run this function once per 15 minutes, it relies on Module PSTerminalServices. Basically what it does, is it pulls the last time someone RDPed in, then stores it in an XML, overwritting an older value if it exists, if no one is currently logged on, it returns the latest value from the XML instead.
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
}
来源:https://stackoverflow.com/questions/8612863/how-to-find-amount-of-time-mstsc-is-used-and-by-whom