How to find amount of time mstsc is used and by wh

2019-07-03 16:07发布

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?

4条回答
Animai°情兽
2楼-- · 2019-07-03 16:44

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)

查看更多
劳资没心,怎么记你
3楼-- · 2019-07-03 16:49

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
查看更多
干净又极端
4楼-- · 2019-07-03 16:57

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
}
查看更多
Fickle 薄情
5楼-- · 2019-07-03 16:58

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
查看更多
登录 后发表回答