Search code examples
powershellcmdget-winevent

PowerShell vs CMD same command having different results


The following command for a Get-WinEvent command works:

PowerShell:

Get-WinEvent -FilterHashtable @{Logname=’application’;StartTime="2018-04-20 00:00:00";EndTime="2018-04-20 23:59:59"}

CMD:

powershell.exe -noprofile -command "Get-WinEvent -FilterHashtable @{Logname=\"application\";StartTime=\"2018-04-18 17:42:56\";EndTime=\"2018-04-19 17:43:01\"}"

The problem I'm facing is that when I try to pipe the results to get a specific RecordID, it works in PowerShell:

Get-WinEvent -FilterHashtable @{Logname=’application’;StartTime="2018-04-20 00:00:00";EndTime="2018-04-20 23:59:59"} | ? {$_.RecordId -eq 293116} | Select Message

When I try to add the same thing to my cmd call, it returns no results:

powershell.exe -noprofile -command "Get-WinEvent -FilterHashtable @{Logname=\"application\";StartTime=\"2018-04-18 17:42:56\";EndTime=\"2018-04-19 17:43:01\"} | ? {$RecordId -eq 293116} | Select Message"

I've already tried replacing the ? with Where-Object and -property to rule out an issue with CMD characters being misinterpreted. I feel like I'm missing something obvious here.


Solution

  • I was able to resolve this.

    Because I was going from SQL to CMD to PowerShell, there were some characters that were being interpreted in a way I wasn't expecting and no message was returned. Ultimately I was able to write this stored procedure that will call a specific machine from the SQL host using xp_cmdshell that will give you the event viewer logs for a specific time range.

    I've also put an override for number of records to avoid it running for a long time. This is the content of the stored procedure:

            if object_id('tempdb..#result') IS NOT NULL
            drop table #result
        create table #result
            ([ID] int
            ,[Timegenerated] datetime
            ,[EntryType] varchar(max)
            ,[Source] varchar(max)
            ,[Message] nvarchar(max)
            )
    
        if object_id('tempdb..#temp') IS NOT NULL
            drop table #temp
        create table #temp
            ([output] nvarchar(max))
    
        Declare @command nvarchar(1000)
        Set @command = 'powershell.exe -noprofile -command "Get-WinEvent -FilterHashtable @{Logname=''application'';StartTime='''+@StartTime+''';EndTime='''+@EndTime+'''} -MaxEvents ' + @topEvents + '| % {\"$($_.RecordId)`t$($_.TimeCreated)`t$($_.ProviderName)`t$($_.LevelDisplayName)\"}"'
    
        Insert Into #temp
            exec xp_cmdshell @command
    
        Delete from #temp where [output] is null
    
        Declare @fullstring nvarchar(max)
        While (Select COUNT(*) from #temp) > 0
        BEGIN
            Select TOP 1 @fullstring = [output] from #temp
            Insert Into #result
            SELECT TOP 1 dbo.F_ExtractSubString([output], 1, '    ') AS ID,
                    dbo.F_ExtractSubString([output], 2, '    ') AS TimeGenerated,
                    dbo.F_ExtractSubString([output], 3, '    ') AS EntryType,
                    dbo.F_ExtractSubString([output], 4, '    ') AS Source,
                    Null
            FROM   #temp
            Delete From #temp where [output] = @fullstring
        END
    
        Declare @IDSearch nvarchar(100), @messageString NVARCHAR(MAX)
        While (Select COUNT(*) from #result Where #result.[Message] is null) > 0
        BEGIN
            Select Top 1 @IDSearch = ID from #result Where #result.[Message] is null
    
            Set @command = 'powershell.exe -noprofile -command "Get-WinEvent -FilterHashtable @{Logname=''application'';StartTime='''+@StartTime+''';EndTime='''+@EndTime+'''} | ? {$_.RecordId -eq ' + @IDSearch + '} | % {\"$($_.Message)`r`n\"}'
    
            Insert Into #temp
                exec xp_cmdshell @command
    
            Set @messageString = STUFF(
                                (   SELECT ',' + CONVERT(NVARCHAR(Max), [output])
                                    FROM #temp
                                    FOR xml path('')
                                )
                                , 1
                                , 1
                                , '')
    
            Update #result Set [Message] = @messageString Where ID = @IDSearch
    
            TRUNCATE TABLE #temp
        END
    
        Select * from #result