Forum Discussion

dmarquesgn's avatar
dmarquesgn
Iron Contributor
Nov 07, 2022
Solved

Get-WinEvent FilterXPath options

Hi,

I'm kind of new to powershell and trying to generate an alert on RDP logons to certain machines by certain users. So I've found a nice code to do it, and tweak it a bit for what I need. But there's still one thing I couldn't do it, which is to filter by the user.
My code is this:

Invoke-Command -ComputerName servername {
$RDPAuths = Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' -FilterXPath '<QueryList><Query Id="0"><Select Path="Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational">*[System[(EventID=1149) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]</Select></Query></QueryList>'
[xml[]]$xml=$RDPAuths|Foreach{$_.ToXml()}
$EventData = Foreach ($event in $xml.Event)
{ New-Object PSObject -Property @{
TimeCreated = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'dd-MM-yyyy hh:mm:ss')
User = $event.UserData.EventXML.Param1
Domain = $event.UserData.EventXML.Param2
Client = $event.UserData.EventXML.Param3
}
} $EventData | FT
}

So this lists the RDP logons based on event id 1149, shows Time, User and IP from the connection, which is fine. But this lists all RDP connections and I want to filter only from 1 user.
How can I do that with FilterXPath?
Thanks

 

  • Hi dmarquesgn:

     

    Append this to filter by a specific username:

    and *[UserData[EventXML[@xmlns='Event_NS'][Param1='dmarquesgn']]]

     

    The full xpath filter will look like this:

    <QueryList><Query Id='0'><Select Path='Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'>*[System[(EventID=1149) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]] and *[UserData[EventXML[@xmlns='Event_NS'][Param1='dmarquesgn']]]</Select></Query></QueryList>

     

    Notes:

    1. I created variables for the filterxpath and username out to separate variables
    2. I replaced the Invoke-Command block with the "-ComputerName" parameter in the Get-WinEvent cmdlet.

     

    Here's the full script block:

    $computername = "servername"
    $username = "dmarquesgn"
    $FilterPath = "<QueryList><Query Id='0'><Select Path='Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'>*[System[(EventID=1149) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]] and *[UserData[EventXML[@xmlns='Event_NS'][Param1='{0}']]]</Select></Query></QueryList>" -f $username
    
    $RDPAuths = Get-WinEvent -ComputerName $computername -LogName 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' -FilterXPath $FilterPath
    
    [xml[]]$xml=$RDPAuths | Foreach { $_.ToXml() }
    
    $EventData = Foreach ($event in $xml.Event) {
        New-Object PSObject -Property @{
            TimeCreated = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'dd-MM-yyyy hh:mm:ss')
            User = $event.UserData.EventXML.Param1
            Domain = $event.UserData.EventXML.Param2
            Client = $event.UserData.EventXML.Param3
        }
    
    } $EventData | FT

     

5 Replies

  • plsfix's avatar
    plsfix
    Brass Contributor

    Hi dmarquesgn:

     

    Append this to filter by a specific username:

    and *[UserData[EventXML[@xmlns='Event_NS'][Param1='dmarquesgn']]]

     

    The full xpath filter will look like this:

    <QueryList><Query Id='0'><Select Path='Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'>*[System[(EventID=1149) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]] and *[UserData[EventXML[@xmlns='Event_NS'][Param1='dmarquesgn']]]</Select></Query></QueryList>

     

    Notes:

    1. I created variables for the filterxpath and username out to separate variables
    2. I replaced the Invoke-Command block with the "-ComputerName" parameter in the Get-WinEvent cmdlet.

     

    Here's the full script block:

    $computername = "servername"
    $username = "dmarquesgn"
    $FilterPath = "<QueryList><Query Id='0'><Select Path='Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational'>*[System[(EventID=1149) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]] and *[UserData[EventXML[@xmlns='Event_NS'][Param1='{0}']]]</Select></Query></QueryList>" -f $username
    
    $RDPAuths = Get-WinEvent -ComputerName $computername -LogName 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' -FilterXPath $FilterPath
    
    [xml[]]$xml=$RDPAuths | Foreach { $_.ToXml() }
    
    $EventData = Foreach ($event in $xml.Event) {
        New-Object PSObject -Property @{
            TimeCreated = (Get-Date ($event.System.TimeCreated.SystemTime) -Format 'dd-MM-yyyy hh:mm:ss')
            User = $event.UserData.EventXML.Param1
            Domain = $event.UserData.EventXML.Param2
            Client = $event.UserData.EventXML.Param3
        }
    
    } $EventData | FT

     

    • dmarquesgn's avatar
      dmarquesgn
      Iron Contributor
      Hi,

      Thanks for the help. It's exactly what I need.
      Only the -ComputerName parameter doesn't work, that's why I'm using Invoke-Command. When I use the -ComputerName I get this error:
      Get-WinEvent : The RPC server is unavailable
      When I use Invoke, there's no issue with it and runs fine.
      Thanks
      • dmarquesgn's avatar
        dmarquesgn
        Iron Contributor
        By the way, one other issue with this script.
        I want to generate an alert which will be sent by email with this information.
        But for that I need that the $EventData variable can be used outside the Invoke-Command, so I can concatenate the info from all servers and then sent it over email.
        How can I use the variable outside the Invoke-Command?

        Thanks

Resources