Powershell 如何确定mstsc的使用时间以及由谁使用?

Powershell 如何确定mstsc的使用时间以及由谁使用?,powershell,powershell-2.0,rdp,mstsc,Powershell,Powershell 2.0,Rdp,Mstsc,我们的团队地理位置分散,许多虚拟机将由他们使用远程桌面连接。我想知道谁正在访问远程桌面会话,以及它被使用了多长时间 我试着用powershell来做。我编写了一个脚本,其中用户将使用powershell调用mstsc。它将记录谁已登录以及何时登录。但我想知道何时有人从mstsc注销或断开mstsc。是否有任何方法可以使用powershell在日志文件中捕获该信息。关闭mstsc时是否会触发任何可用于该事件的事件?您可以使用该事件获取rdp会话信息(可以定期记录到日志文件中) 下面是一个如何在Po

我们的团队地理位置分散,许多虚拟机将由他们使用远程桌面连接。我想知道谁正在访问远程桌面会话,以及它被使用了多长时间

我试着用powershell来做。我编写了一个脚本,其中用户将使用powershell调用mstsc。它将记录谁已登录以及何时登录。但我想知道何时有人从mstsc注销或断开mstsc。是否有任何方法可以使用powershell在日志文件中捕获该信息。关闭mstsc时是否会触发任何可用于该事件的事件?

您可以使用该事件获取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()

如果您可以与服务器本身建立RPC连接,您可以使用它来查看谁正在登录TS并远程关闭连接()

我编写了一个构建在其上的PowerShell模块PSTerminalServices()。 以下是命令输出示例:

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

我每15分钟运行一次此功能,它依赖于模块PSTerminalServices。基本上,它所做的是,它提取上一次有人输入RDD的时间,然后将其存储在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
}
函数Get LastLogonTime
{
Param(
[参数(位置=0,必需=true)]$ComputerName
)
$StoredRDPSessions=Import Clixml“RDPSessions.xml”
$myobj=”“|选择计算机名称、LastAccessedDate、用户名
$myobj.ComputerName=$ComputerName
$LastConnectedUser=Get-TSSession-ComputerName$ComputerName |其中`
{
($\.WindowsStationName-ne“服务”)-和`
($州-ne“监听”)-和`
($\.WindowsStationName-ne“控制台”)
}|排序对象-属性LastAccessTime-降序
if($LastConnectedUser-is[array])
{
$myobj.LastAccessedDate=$LastConnectedUser[0]。连接时间
$myobj.UserName=$LastConnectedUser[0]。用户名
}elseif($LastConnectedUser){
$myobj.LastAccessedDate=$LastConnectedUser.ConnectTime
$myobj.UserName=$LastConnectedUser.UserName
}否则{
$myobj.LastAccessedDate=$Null
$myobj.UserName=“未知”
}
if($myobj.LastAccessedDate)-和($myobj.UserName))
{
$StoredRDPSession=$StoredRDPSessions |其中{$\.ComputerName-eq$ComputerName}
if($StoredRDPSession)
{
if($myobj.LastAccessedDate-gt$storedRDSession.LastAccessedDate)
{
编写详细的“更新的LastAccessedDate,更新XML”
$StoredRDPSession.LastAccessedDate=$myobj.LastAccessedDate
$StoredRDPSession.UserName=$myobj.UserName
$StoredRDPSessions |导出Clixml“RDPSessions.xml”
}
}否则{
详细写入“未找到添加到XML的条目”
$NewStoredRDPSessions=@()
$StoredRDPSessions |%{$NewStoredRDPSessions+=$|}
$NewStoredRDPSessions+=$myobj
$NewStoredRDPSessions |导出Clixml“RDPSessions.xml”
}
}
if((!($myobj.LastAccessedDate))-和$storedRDSessions)
{
编写详细的“无当前会话,从存储的XML中提取”
$StoredRDPSession=$StoredRDPSessions |其中{$\.ComputerName-eq$ComputerName}
if($StoredRDPSession)
{
$myobj.LastAccessedDate=$storedRDSession.LastAccessedDate
$myobj.UserName=$StoredRDPSession.UserName
}否则{
写详细的“悲伤,也没有任何XML存储。”
}
}
详细编写“获取LastLogonTime$ComputerName-$($myobj.LastAccessedDate)-$($myobj.UserName)”
返回$myobj
}

我尝试执行该操作,但出现以下错误。我也搜索了那个链接,但没有有用的信息。使用“0”参数调用“Open”时出现异常:“RPC服务器不可用”位于D:\My_Scripts\Mstsc monitor.ps1:4 char:13+$server.Open是否替换为服务器的主机名?我在服务器的地名中使用了IP地址。请检查是否可以在端口445上远程登录服务器
Telnet 445
谢谢你的提示。那个港口关闭了。我用另一台打开了端口的机器进行了验证。它运行良好我经常使用这个模块(基本上与OP需要它的原因相同,以了解我的VM的使用模式),我可以强烈推荐它。@Shay Levy:我收到了这个错误。使用“0”参数调用“Open”时出现异常:“RPC服务器不可用”。端口445已打开,但仍在使用。@Winfred:我可以知道如何使用它吗?我的意思是,你会每天晚上用ip地址列表执行,然后找出今天是否使用了这些机器吗?或者如何确定使用模式?如果您愿意,我可以单独问一个问题。中间是否有防火墙?您能否验证目标上的端口445上是否有侦听服务?
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
}