问题
I am trying to get the source network address for an RDP connection to send an email when a user connects to the server. I have everything but the source address. My script is triggered by event 1149 in the RemoteConnectionManager Operational log. I only need to access either the event data or source address from the system.
$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)
Final script after excellent help by 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
Script to send logon email:
$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
}
回答1:
Updated Based on Comments
Looks like the source address for the connection is recorded as the 3rd property in event 1149. Properties are an object array of type [System.Diagnostics.Eventing.Reader.EventProperty[]]
which just means you have to access the sub-property .Value
.
An Example to get the last event:
$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
Since I'm not sure Get-WinEvent will guarantee chronological order the the Sort-Object
cmdlet is used. So it should result in the the last 1149 event. However, it doesn't guarantee it will be for the user that was returned by System.Security.Principal.WindowsIdentity]::GetCurrent().Name
. I don't know what kind of machine this is or under what circumstances the script will be run. For example if it's a multi-user system (implied by Terminal Server) I suspect there's an edge case where last event may not be for the current user.
So, I'm guessing that we should isolate the last event for that user. We can do that with one of these samples:
Option 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]
Option 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
In both cases $LastEvent
should have the last 1149 event for the current user. The first option has less sorting, because it is only sorting events for the specific user. you can use $LastEvent.SourceIP
for the email.
A secondary note: You don't need to use System.Net.Mail.SMTPClient. you can use Send-MailMessage combined with command splatting that might look like:
$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
Note: Above was also updated after your comments to take advantage of the newer revisions. Note:
.ToString('g')
results in date format like '6/30/2020 9:17 PM'
I'm not sure if the body or subject is exactly right, but you can work that out.
Let me know how it goes. Thanks.
来源:https://stackoverflow.com/questions/62664619/powershell-script-rdp-connection-data