none
Select-String in Invoke-Command not working as expected RRS feed

  • Question

  • I am trying to analyse the on-demand scan logs produced by my McAfee anti-virus.  The following code works on in a local session, and in a psSession:
    $scanLog = gc $env:deflogdir\ondemandscanlog.txt
    $scanlog | Select-String 'Engine version' 
    

    However, the following code returns a whole lot of blank lines:

    $pc = 'server1'
    $sb ={
    $scanLog = gc $env:deflogdir\ondemandscanlog.txt
    $scanlog | Select-String 'Engine version' -AllMatches
    }
    write-host $pc -fore red
        try {
            icm -cn $pc -scr $sb 
            } # end try
        catch {
            Write-Host "Could not connect to $pc" -ForegroundColor red
            } # end catch
        
    
    

    I'd really like to get this working so that I can return just the results of the last scan, so I need Select-String to do its thing in an Invoke-Command scriptblock.

    Does anyone know why this is happening or how I can make it work properly?

     


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    Saturday, October 29, 2011 9:30 AM

Answers

  • Here is teh fix:

    $sb={cat c:\windows\windowsupdate.log|select-string "^2011-10-09"|select line}

    The issue is caused by the '$matches' collection.  It does not seem portable across sessions.  This is because it is an array of pointers into some objects stashed in memory.  When returned to a remote session it points to nothing for some reason so we get a list of null or zeros which show up as line feeds.

    Adding the select forces a simle object to be created containing the string.  This can be ported to a remote session.

    We can also just use the matches collection locally as it contains copies of the lines.l

    This also works:

    $sb={cat c:\windows\windowsupdate.log|select-string "^2011-10-09"}
    $job=Invoke-Command -script $sb -computer remote1 -AsJob
    wait-job $job
    $job|receive-job -keep | select line
    
    

    Use a select-string that you know returns info from your systems.  You may not have that date in your log.

     


    jv

    • Edited by jrv Saturday, October 29, 2011 1:11 PM
    • Marked as answer by Bigteddy Saturday, October 29, 2011 1:19 PM
    Saturday, October 29, 2011 1:09 PM

All replies

  • Have you tried this:

    gwmi AntiVirusProduct -name root/securitycenter -computer ws101 |
         select displayName,versionnumber,productUptoDate

     


    jv
    Saturday, October 29, 2011 11:25 AM
  • I haven't tried that, no.  But I don't need to know if it's up to date, I want to look at the results of the last scheduled scan.  I have worked around this, with the following code.  Perhaps that will make it clearer what I'm doing:

     

    $server = 'server3'
    $scanLogDir = icm -cn $server -scr {$env:deflogdir}
    $scanLogPath = "\\$server\c$" + ($scanLogDir | Split-Path -NoQualifier).toString()
    $scanLog = gc $scanLogPath\ondemandscanlog.txt
    $scanLogLastScan = $scanLog | Select-String 'Engine Version' | select -Last 1
    $start = $scanLogLastScan.lineNumber - 1
    $end = $scanLog.count -1 
    $scanLog[$start..$end] | Select-String -NotMatch 'Not scanned'
    

    I can't hard-code the path to the log, because it varies with Windows version.  So I have to use icm to get the path to the log file on the particular computer in question.

     

    In the code above, although it works, it depends on pulling the whole log file down the network, instead of just the section I'm looking for.

    If I could include all this code in an Invoke-Command, it would save network traffic and therefore make it faster, especially when run on a batch of computers.

     


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    • Edited by Bigteddy Saturday, October 29, 2011 11:55 AM
    Saturday, October 29, 2011 11:52 AM
  • But the status includes teh result of the last scheduled scan. It will be 'failed' if there are errors.

    McAfee has som COM objects that can be queried to display the scan stas like on the stats page.

    The log is easiest when read via the admin share.

     

     


    jv
    Saturday, October 29, 2011 12:09 PM
  • Yes, I get failed, but as you can see, I'm inquisitive, and I want to see the details, especially if there are detections on my servers.

    Yes, I can and do read the logs via the admin share, as you can see from the code I posted, but you are evading the question:  Why can't I use select-string in my icm scriptblock?


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    Saturday, October 29, 2011 12:13 PM
  • Just to add to this, I just used the McAfee log file example as a real-world example, but this question is more generic: 

    Why won't Select-String work properly in an Invoke-Command scriptblock?

    That's the title of this thread, and let's not focus on the exact log file I'm reading.  This could apply to other situations too.


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    Saturday, October 29, 2011 12:16 PM
  • Just to add to this, I just used the McAfee log file example as a real-world example, but this question is more generic: 

    Why won't Select-String work properly in an Invoke-Command scriptblock?

    That's the title of this thread, and let's not focus on the exact log file I'm reading.  This could apply to other situations too.


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"


    Ahh - thar's better.  Yee Ol' 'Select-String' problem.

    Didn't we decide that that was a bug and report it to the MS Connect site?

     


    jv
    Saturday, October 29, 2011 12:34 PM
  • Yes, I remember asking this question before, and I worked around it by Rich suggesting I use an admin share as I am doing.

    I think mj had an answer, but for the life of me, I can't remember or find the thread now.

    If someone else can verify this behaviour, I can report it to Connect, but not just based on my findings alone.


    [string](0..9|%{[char][int](32+("39826578840055658268").substring(($_*2),2))})-replace "\s{1}\b"
    Saturday, October 29, 2011 12:37 PM
  • Here is teh fix:

    $sb={cat c:\windows\windowsupdate.log|select-string "^2011-10-09"|select line}

    The issue is caused by the '$matches' collection.  It does not seem portable across sessions.  This is because it is an array of pointers into some objects stashed in memory.  When returned to a remote session it points to nothing for some reason so we get a list of null or zeros which show up as line feeds.

    Adding the select forces a simle object to be created containing the string.  This can be ported to a remote session.

    We can also just use the matches collection locally as it contains copies of the lines.l

    This also works:

    $sb={cat c:\windows\windowsupdate.log|select-string "^2011-10-09"}
    $job=Invoke-Command -script $sb -computer remote1 -AsJob
    wait-job $job
    $job|receive-job -keep | select line
    
    

    Use a select-string that you know returns info from your systems.  You may not have that date in your log.

     


    jv

    • Edited by jrv Saturday, October 29, 2011 1:11 PM
    • Marked as answer by Bigteddy Saturday, October 29, 2011 1:19 PM
    Saturday, October 29, 2011 1:09 PM