locked
invoke-command not returning all results? RRS feed

  • Question

  • Hello,

    I am querying our domain controllers and reporting with powershell.  I am using ps remoting with the "invoke-command" cmdlet, but am not able to retrieve the full results back to my local session.

    example.

    $query = @'
    <QueryList>
      <Query Id="0" Path="Security">
        <Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (EventID=4727 or EventID=4728 or EventID=4729 or EventID=4730 or EventID=4731 or EventID=4732 or EventID=4733 or EventID=4734 or EventID=4735 or EventID=4737 or EventID=4754 or EventID=4755 or EventID=4756 or EventID=4757 or EventID=4758 or EventID=4764) and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]</Select>
      </Query>
    </QueryList>
    '@
    
    $domaincontrollers = @("dc1","dc4","dc2","dc3")
    
    $events = Invoke-Command -ComputerName $domaincontrollers -ScriptBlock {
        param($xmlquery)
        Get-WinEvent -FilterXml $xmlquery
        ####  Need to work out how to pass the properties back to the local session.
    } -ArgumentList $query -ErrorAction:SilentlyContinue


    above I am trying to collect the results into the $events variable.  I am able to see the event properties "TimeCreated", "Id", but I am not able to see the "properties" property which contains the bits I care about.  eg

    $events[0].Properties
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty

    If I was to run this same command using get-winevent -computername dc1 then it would return the result properly.

    example.

    $eventsDC1[0].Properties
    
    Value                                                     
    -----        
    CN=Joe Bloggs,OU=Staff,DC=domain,DC=net       
    S-1-5-21-***      
    SecurityGroupName           
    DOMAIN
    S-1-5-21-***
    S-1-5-21-***                         
    joe.bloggs
    DOMAIN
    107111233                

    , its only when I am using psremoting that I don't get back the full result..

    ?

    • Moved by Bill_Stewart Tuesday, March 1, 2016 11:51 PM Abandoned
    Tuesday, January 5, 2016 10:40 PM

Answers

  • I'm hoping I can help clarify things here a little.

    Invoke-Command -ComputerName server1,server2 -ScriptBlock { Get-WinEvent -FilterHashtable @{Logname='Application'} -MaxEvents 1 } | select -first 1 | select -expand Properties

    The above line returns System.Diagnostics.Eventing.Reader.EventProperty.

    Get-WinEvent -ComputerName server1,server2 -FilterHashtable @{Logname='Application'} -MaxEvents 1 | select -first 1 | select -expand Properties

    The above line will not execute, because Get-WinEvent does not support multiple computer names in the ComputerName parameter. I write this for example because you questioned why ajhstn wanted to use Invoke-Command.

    Get-WinEvent -ComputerName server1 -FilterHashtable @{Logname='Application'} -MaxEvents 1 | select -first 1 | select -expand Properties

    The above line returns values. Get-WinEvent can return Property values when executed on a client machine and supplied a ComputerName parameter for a remote server. However, it can only be executed on a single machine at a time.

    All of your examples were invoking Get-WinEvent against the execution machine's own event logs, which was not what ajhstn was asking. By itself, Get-WinEvent is obviously capable of taking care of remoting using -ComputerName; the problem seems to be the way that Invoke-Command is serializing results across the wire after executing Get-WinEvent locally on the target servers.

    On the surface, it appears as though the EventProperty class simply has no ToString() override on it, causing it to output the class name like any other .net class.

    • Marked as answer by ahdlstn Friday, March 4, 2016 1:38 AM
    Friday, March 4, 2016 1:27 AM

All replies

  • Before someone chimes in with the right answer, are you sure that's not just the script returning your results in a format you weren't expecting? It smells like PowerShell being overly helpful for your DC1 example and expanding the value because there's a single item.

    Have you tried executing the script with only DC1 listed in your array?

    Tuesday, January 5, 2016 10:49 PM
  • $events[0] | select -expand properties


    \_(ツ)_/

    Tuesday, January 5, 2016 11:01 PM
  • Why use remoting when Get-WinEvent has its own remoting.

    Get-WinEvent .... -ComputerName $computer


    \_(ツ)_/

    Tuesday, January 5, 2016 11:03 PM
  • Hi Alex,

    I tried the script with ONLY DC1 in the $domaincontrollers array variable.  It gave me the same results.

    PS C:\Users\me> $events | fl
    
    
    TimeCreated    : 06/01/2016 9:56:15 AM
    ProviderName   : Microsoft-Windows-Security-Auditing
    Id             : 4756
    Message        : 
    PSComputerName : DC1
    
    TimeCreated    : 06/01/2016 9:56:15 AM
    ProviderName   : Microsoft-Windows-Security-Auditing
    Id             : 4755
    Message        : 
    PSComputerName : DC1                                       
    
    PS C:\Users\me> $me[0].Properties
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    System.Diagnostics.Eventing.Reader.EventProperty
    
    
    

    Just for some more info, here is the type.

    $events[0]|gm
    
    
       TypeName: Deserialized.System.Diagnostics.Eventing.Reader.EventLogRecord

    Tuesday, January 5, 2016 11:06 PM
  • This also returns the object type only.
    PS C:\Users\me> $events[0] | select -ExpandProperty properties
    System.Diagnostics.Eventing.Reader.EventProperty

    Tuesday, January 5, 2016 11:08 PM
  • Oh! ok interesting. This may solve my problem. Ill read about this.
    Tuesday, January 5, 2016 11:08 PM
  • Ok, looking in help get-winevent, example 4 shows that I can foreach through an array of servers, but this is not "real" remoting right, eg it cannot simultaneous run on multiple or many servers..

    Foreach will work, but how do large companies with thousands of servers get around this?

    Tuesday, January 5, 2016 11:13 PM
  • Ok then look at it this way.

    PS C:\scripts> $x=get-winevent -FilterHashtable @{Logname='Application'} -MaxEvents 5|select properties
    PS C:\scripts> $x[0].Properties[0]

    Value
    -----
    LiveComm


    \_(ツ)_/

    Tuesday, January 5, 2016 11:25 PM
  • This still does not return a value.

    PS C:\Users\me> $events[0].Properties[0]
    System.Diagnostics.Eventing.Reader.EventProperty

    Do you think it has something to do with the session culture? I read it may only work for "en-US" although I have changed to this, but this doesn't resolve it..

    I guess I will need to use the foreach looping.

    Tuesday, January 5, 2016 11:41 PM
  • You did not do what I posted.

    PS C:\scripts> $x=get-winevent -FilterHashtable @{Logname='Application'} -MaxEvents 5|select properties
    PS C:\scripts> $x[0].Properties[0]

    You must use this method. If it still fails then you are missing Net updates.


    \_(ツ)_/

    Tuesday, January 5, 2016 11:59 PM
  • Hi JRV,

    Thank you for your help here.  Even using the FilterHashtable above instead of the FilterXml I still do not get any values for the "Properties" property.

    I will check for updates, otherwise I will use the parallel from workflows to achive what I want.

    eg. foreach -parallel  ($computer in $computers)

    Wednesday, January 6, 2016 12:36 AM
  • Correct conversion of the records is dependent on the version of net installed

    \_(ツ)_/

    Wednesday, January 6, 2016 12:41 AM
  • I'm hoping I can help clarify things here a little.

    Invoke-Command -ComputerName server1,server2 -ScriptBlock { Get-WinEvent -FilterHashtable @{Logname='Application'} -MaxEvents 1 } | select -first 1 | select -expand Properties

    The above line returns System.Diagnostics.Eventing.Reader.EventProperty.

    Get-WinEvent -ComputerName server1,server2 -FilterHashtable @{Logname='Application'} -MaxEvents 1 | select -first 1 | select -expand Properties

    The above line will not execute, because Get-WinEvent does not support multiple computer names in the ComputerName parameter. I write this for example because you questioned why ajhstn wanted to use Invoke-Command.

    Get-WinEvent -ComputerName server1 -FilterHashtable @{Logname='Application'} -MaxEvents 1 | select -first 1 | select -expand Properties

    The above line returns values. Get-WinEvent can return Property values when executed on a client machine and supplied a ComputerName parameter for a remote server. However, it can only be executed on a single machine at a time.

    All of your examples were invoking Get-WinEvent against the execution machine's own event logs, which was not what ajhstn was asking. By itself, Get-WinEvent is obviously capable of taking care of remoting using -ComputerName; the problem seems to be the way that Invoke-Command is serializing results across the wire after executing Get-WinEvent locally on the target servers.

    On the surface, it appears as though the EventProperty class simply has no ToString() override on it, causing it to output the class name like any other .net class.

    • Marked as answer by ahdlstn Friday, March 4, 2016 1:38 AM
    Friday, March 4, 2016 1:27 AM
  • Thank you for this clarification, very helpful.
    Friday, March 4, 2016 1:38 AM