【问题标题】:Powershell script RDP connection dataPowershell 脚本 RDP 连接数据
【发布时间】:2020-06-30 19:12:11
【问题描述】:

我正在尝试获取 RDP 连接的源网络地址,以便在用户连接到服务器时发送电子邮件。除了源地址,我什么都有。我的脚本由 RemoteConnectionManager 操作日志中的事件 1149 触发。我只需要从系统中访问事件数据或源地址。

$SmtpClient = new-object system.net.mail.smtpClient
$MailMessage = New-Object system.net.mail.mailmessage
$SmtpClient.Host = "mail.scomage.com"
$mailmessage.from = ("BWAQBW@BWAServer.com")
$mailmessage.To.add("support@scomage.com")
$mailmessage.Subject = “BWAQB RDP”
$mailmessage.Body = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name + “ logged into BWA QB Server”
$smtpclient.Send($mailmessage)

在 Steven 的大力帮助下的最终脚本:

$LastEvent = Get-WinEvent -FilterHashtable `
    @{ LogName = "Microsoft-Windows-TerminalServices- 
RemoteConnectionManager/Operational"; Id = 1149} |
Select-Object *,
    @{ Name = 'UserName'; Expression = `
        { if ($_.Properties[0].Value) { $_.Properties[0].Value } else { "Administrator" } } },
    @{ Name = 'SourceIP'; Expression = { $_.Properties[2].Value } } |
Sort-Object TimeCreated |
Select-Object -Last 1

$MailParams = 
@{
    SmtpServer = "mail.scomage.com"
    From       = "BWAQBW@BWAServer.com"
    To         = "support@scomage.com"
    Subject    = "BWAQB RDP " + $LastEvent.UserName + " " + $LastEvent.SourceIP
    Body       = $LastEvent.UserName + " logged into BWA QB Server at " + `
    $LastEvent.TimeCreated.ToString('g') + " From: " + $LastEvent.SourceIP
}

Send-MailMessage @MailParams

发送登录电子邮件的脚本:

$Event = Get-WinEvent -FilterHashTable @{
    LogName='Security'; ID=4624; StartTime=$DateLess10; } |
    Where-Object{$_.Properties[8].Value -eq 10 } | 
    Sort-Object TimeCreated |
    Select-Object -Last 1 

if( $Event.Properties[8].Value -eq 10 )
{
    $MailParams = 
    @{
        SmtpServer = "mail.scomage.com"
        From       = "BWAQBW@BWAServer.com"
        To         = "support@scomage.com"
        Subject    = "BWAQB Remote Login " + $Event.Properties[5].Value + " " + $Event.Properties[18].Value
        Body       = $Event.Properties[5].Value + " logged into BWA QB Server at " + `
        $Event.TimeCreated.ToString('g') + " From: " + $Event.Properties[18].Value
    }
    Send-MailMessage @MailParams
}

【问题讨论】:

    标签: powershell remote-desktop


    【解决方案1】:

    根据评论更新

    看起来连接的源地址被记录为事件 1149 中的第三个属性。属性是 [System.Diagnostics.Eventing.Reader.EventProperty[]] 类型的对象数组,这意味着您必须访问子属性 .Value

    获取最后一个事件的示例:

    $LastEvent =
    Get-WinEvent -FilterHashtable @{ LogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"; Id = 1149} |
    Select-Object *,
        @{ Name = 'UserName'; Expression = { $_.Properties[0].Value } },
        @{ Name = 'SourceIP'; Expression = { $_.Properties[2].Value } } |
    Sort-Object TimeCreated |
    Select-object -Last 1
    

    由于我不确定 Get-WinEvent 是否会保证使用 Sort-Object cmdlet 的时间顺序。所以它应该导致最后一个 1149 事件。但是,它不保证它会用于System.Security.Principal.WindowsIdentity]::GetCurrent().Name 返回的用户。我不知道这是什么机器,也不知道脚本会在什么情况下运行。例如,如果它是一个多用户系统(由终端服务器暗示),我怀疑存在最后一个事件可能不适用于当前用户的极端情况。

    所以,我猜我们应该隔离该用户的最后一个事件。我们可以使用以下示例之一来做到这一点:

    选项 1:

    $NTUserName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    $UserName = $NTUserName.Split('\')[-1]
    
    $Events =
    Get-WinEvent -FilterHashtable @{ LogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"; Id = 1149} |
    Select-Object *,
        @{ Name = 'UserName'; Expression = { $_.Properties[0].Value } },
        @{ Name = 'SourceIP'; Expression = { $_.Properties[2].Value } } |
    Group-Object -Property UserName -AsHashTable -AsString
    
    $LastEvent = ($Events[$UserName] | Sort-Object TimeGenerated)[-1]
    

    选项 2:

    $NTUserName = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    $UserName = $NTUserName.Split('\')[-1]
    
    $LastEvent =
    Get-WinEvent -FilterHashtable @{ LogName = "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"; Id = 1149} |
    Select-Object *,
        @{ Name = 'UserName'; Expression = { $_.Properties[0].Value } },
        @{ Name = 'SourceIP'; Expression = { $_.Properties[2].Value } } |
    Where-Object{ $_.UserName -eq $UserName } |
    Sort-Object TimeCreated |
    Select-Object -Last 1
    

    在这两种情况下,$LastEvent 都应该有当前用户的最后一个 1149 事件。第一个选项的排序较少,因为它仅对特定用户的事件进行排序。您可以使用$LastEvent.SourceIP 发送电子邮件。

    次要说明:您不需要使用 System.Net.Mail.SMTPClient。您可以将 Send-MailMessage 与命令 splatting 结合使用,如下所示:

    $MailParams = 
    @{
        SmtpServer = "mail.scomage.com"
        From       = "BWAQBW@BWAServer.com"
        To         = "support@scomage.com"
        Subject    = "BWAQB RDP"
        Body       = $UserName + " logged into BWA QB Server at " + $LastEvent.TimeCreated.ToString('g') + " From: " + $LastEvent.SourceIP
    }
    
    Send-MailMessage @MailParams
    

    注意:以上内容也在您的 cmets 之后进行了更新,以利用较新的修订版。注意:.ToString('g') 的日期格式类似于 '6/30/2020 9:17 PM'

    我不确定正文或主题是否完全正确,但你可以解决。

    【讨论】:

    • 感谢您的回复!我是一个“老”人,在 DOS 中比在 PowerShell 中更舒服。 :) 我是否必须做任何特定的事情来确保选择从最近的事件 1149 中提取信息?另外,如果我理解正确,选择会将所有 1149 个事件都放在日志中。它们是否会像在事件查看器界面中显示的那样按日期降序排列?如果是这样,我如何访问第一个数组元素。抱歉听起来太天真了。我是许多不同语言的长期开发人员,只是不是 powershell。
    • 再次感谢您提供所有详细信息。我已经在问题的末尾发布了我的最终脚本。在您的帮助和一点谷歌搜索下,我的脚本完全符合我的需要。事实证明 System.Security.Principal.WindowsIdentity]::GetCurrent().Name 始终是管理员,因为计划任务以该 ID 运行。用户的连接速度不会那么快(只有 4 个用户),我需要担心得到错误的日志条目。
    • 我认为这是完美的工作,除了当用户 id 为空时,它并不总是管理员。当凭据保存在连接器中并且用户不必输入密码时,会导致空日志条目。我正在查看登录事件的安全日志,发现了我认为需要的内容,但我不知道如何按登录类型 10 过滤 get 事件。这些是远程登录,但它是 [8]属性数组。我可以按那个过滤吗?
    • 我很惊讶我会认为它无论如何都会记录用户名。我不知道有什么方法可以直接做到这一点,但是您可以在Get-WinEvent 命令之后添加| Where-Object{$_.Properties[8].Value -eq "UserName"。您还可以通过将StartTime = [DateTime] 添加到FilterHashtable 来限制搜索的深度。 help document 中的示例 #15 就是一个很好的例子。
    • 显然,由于脚本是由任务管理器启动的,并且它在管理员 ID 下运行,因此脚本运行的会话是管理员。我不知道为什么保存的用户没有出现在日志中。好老微软。显然,保存的凭据遵循不填充这些字段的不同逻辑路径。懒人编程!
    猜你喜欢
    • 1970-01-01
    • 2015-04-30
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多