none
Scan for file and report back if it exists RRS feed

  • Question

  • Hello,

    I am new to scripting and trying to find a way to search for a supposed virus file named wsr[any two numbers]zt32.dll on a large group of computers. I'm not sure how or where to use Get-ChildItem -Path C:\Users -Filter ?zt32.dll -Recurse | export-csv C:\scripts\output\test.csv in this script. 

    The below script keeps erroring out when I try messing with the Test-Path options and I'm not sure where to use Get-ChildItem or whatever to get this working. Thanks

    ##########################################################
    # Edit these variables to fit your enviroment
    ##########################################################
    # Set file to be tested for, put everything after c:\
    # “c:\Users\Default” is the example path
    $filetofind = ‘wsr*zt32.dll ‘
    # Hostnames TXT Location
    $hostnamestxt = ‘C:\scripts\computernames.txt‘
    # Destination file for Online Machines
    $onlinetxt = ‘C:\scripts\output\Machines_with_file.txt‘
    # Destination file for Offline Machines
    $offlinetxt = ‘C:\scripts\output\Offline_Machines.txt‘

    ##########################################################
    # Begin Executing Script – Do Not Edit Below This Line
    ##########################################################
    $computers = get-content “$hostnamestxt”

    write-host “———————————————-”
    write-host “Scanning hostnames from $hostnamestxt…”
    write-host “———————————————-”

    foreach($computer in $computers)
    {
    ping -n 1 $computer >$null
    if($lastexitcode -eq 0)
    {
    if(test-path “\\$computer\c:\users\* -include $filetofind”)
    {
    echo “$computer” | Out-File -Append “$onlinetxt”
    write-host “File FOUND on $computer”
    }
    else
    {write-host “File NOT found on $computer”}
    }
    else
    {
    echo “$computer” | Out-File -Append “$offlinetxt”
    write-host “$computer is OFFLINE/DID NOT RESPOND TO PING”
    }
    }
    write-host “———————————————-”
    write-host “Script has completed please check output.”
    write-host “Hosts with file output location – $onlinetxt”
    write-host “Hosts that were unpingable output location – $offlinetxt”
    write-host “———————————————-”


    • Edited by MarcGel Tuesday, January 28, 2014 9:54 PM
    Tuesday, January 28, 2014 9:53 PM

Answers

  • Try the code now.

    # Set file to be tested for, put everything after c:\ # "c:\Users\Default" is the example path $filetofind = 'wsr*zt32.dll' # Hostnames TXT Location $hostnamestxt = 'C:\scripts\computernames.txt' # Destination file for Online Machines $onlinetxt = 'C:\scripts\Output\Machines_with_file.txt' # Destination file for Offline Machines $offlinetxt = 'C:\scripts\Output\Offline_Machines.txt' ########################################################## # Begin Executing Script – Do Not Edit Below This Line ########################################################## $computers = get-content $hostnamestxt write-host "———————————————-" write-host "Scanning hostnames from $hostnamestxt…" write-host "———————————————-" foreach($computer in $computers) { if(Test-Connection -ComputerName $computer -Count 2 -Quiet) { $g = get-childitem \\$computer\c$\user\* -recurse -ErrorAction silentlycontinue |? {$_.name -match "wsr[0-9][0-9]zt32.dll"} if($g -ne $NULL) { foreach($f in $g) {  Write-Output "$($f.name) File FOUND on following $($f.Directoryname) in $computer"  | Out-File -Append $onlinetxt write-host "File found on $computer" } } else { write-host "File NOT found on $computer"

    } } else { Write-Output "$computer is OFFLINE/DID NOT RESPOND TO PING" | Out-File -Append $offlinetxt } } write-host "———————————————-" write-host "Script has completed please check output." write-host "Hosts with file output location – $onlinetxt" write-host "Hosts that were unpingable output location – $offlinetxt" write-host "———————————————-"

    -Prashanth



    • Edited by Prashanth Jayaram Wednesday, January 29, 2014 7:45 PM
    • Marked as answer by MarcGel Wednesday, January 29, 2014 8:55 PM
    Wednesday, January 29, 2014 7:40 PM
  • I am new to scripting and trying to find a way to search for a supposed virus file named wsr[any two numbers]zt32.dll on a large group of computers.

    Don't use a script. Use an enterprise anti-malware tool.

    Bill

    • Marked as answer by MarcGel Wednesday, January 29, 2014 10:33 PM
    Wednesday, January 29, 2014 9:51 PM
    Moderator

All replies

  • First we get rid of most of the noise in the script and fix the logic errors.  Test-Pth will not work for what you are doing.

    Param(
        $filetofind 'wsr*zt32.dll'
        $hostnamestxt='C:\scripts\computernames.txt‘
        $onlinetxt='C:\scripts\output\Machines_with_file.txt'
        $offlinetxt='C:\scripts\output\Offline_Machines.txt'
    )
    
    $computers = get-content $hostnamestxt
    
    foreach($computer in $computers){
        if(Test-Connection $computer -Count 1 -q){
            $files= Get-ChildItem \\$computer\c$\users\$filetofind" -recurse
            if($files){
                $computer | Out-File -Append $onlinetxt
                write-host "File FOUND on $computer"
            }else{
                write-host “File NOT found on $computer”
            }
        }else{
            $computer| Out-File -Append $offlinetxt
            write-host "$computer is OFFLINE/DID NOT RESPOND TO PING"
        }
    }
    

    Place in file and run.

    As before you need to consider not just pasting things together without understanding how each piece works.  This will help you to learn WIndows technologies and to learn how to write a script.


    ¯\_(ツ)_/¯

    Tuesday, January 28, 2014 10:16 PM
  • # Set file to be tested for, put everything after c:\
    # "c:\Users\Default" is the example path
    $filetofind = 'wsr*zt32.dll'
    # Hostnames TXT Location
    $hostnamestxt = 'C:\scripts\computernames.txt'
    # Destination file for Online Machines
    $onlinetxt = 'C:\scripts\output\Machines_with_file.txt'
    # Destination file for Offline Machines
    $offlinetxt = 'C:\scripts\output\Offline_Machines.txt'
    
    ##########################################################
    # Begin Executing Script – Do Not Edit Below This Line
    ##########################################################
    $computers = get-content "$hostnamestxt"
    
    write-host "———————————————-"
    write-host "Scanning hostnames from $hostnamestxt…"
    write-host "———————————————-"
    foreach($computer in $computers)
    {
    ping -n 1 $computer >$null
    if($?)
    {
    $g=get-childitem \\$computer\c$\users\*.dll -recurse |? {$_.name -match "wsr[0-9][0-9]zt32.dll"}
    
    if($?)
    {
    echo "$computer" | Out-File -Append "$onlinetxt"
    write-host "File FOUND on $computer"
    }
    else
    {write-host "File NOT found on $computer"}
    }
    else
    {
    echo "$computer" | Out-File -Append "$offlinetxt"
    write-host "$computer is OFFLINE/DID NOT RESPOND TO PING"
    }
    }
    write-host "———————————————-"
    write-host "Script has completed please check output."
    write-host "Hosts with file output location – $onlinetxt"
    write-host "Hosts that were unpingable output location – $offlinetxt"
    write-host "———————————————-"
    

    --Prashanth

    Tuesday, January 28, 2014 10:18 PM
  • Try to add correct indenting to you scripts and learn to not put quotes around everything.  Be careful of smart quotes.  When you copy things from some web sites the quotes are smart quotes.  They will not work correctly in scripts.

    Smart quotes are quotes that look like they are backwards.

    Here is a comparison:

    write-host “File NOT found on $computer”

    write-host "File NOT found on $computer"

    Can you see the difference?


    ¯\_(ツ)_/¯

    Tuesday, January 28, 2014 10:20 PM
  • Note also that you should not use the DOS command ping.  Use Test-Connection.  It is what was  provided for this situation.


    ¯\_(ツ)_/¯

    Tuesday, January 28, 2014 10:22 PM
  • Thanks for the tips. It doesn't seem to be working though? Missing ')'? 

    Also, I tried Prashanth's which seems to work and it says it's finding the file but I need more info. How would I append the path and the filename to the Machines_with_file.txt? Thanks
    • Edited by MarcGel Tuesday, January 28, 2014 10:50 PM
    Tuesday, January 28, 2014 10:46 PM
  • One more chance.

    Here is a very simplified version.  It will likely fail because your knowledge of Windows does not know abounthow the file system works.  When you get the next error look real close at what it says.

    Also the above issue was started because I failed to remove all of the smart quotes.

    function FindFile( $computer ){
        $filetofind='wsr*zt32.dll'
        $onlinetxt='C:\scripts\output\Machines_with_file.txt'
        $offlinetxt='C:\scripts\output\Offline_Machines.txt'
        if(Test-Connection $computer -Count 1 -q){
            $files= Get-ChildItem "\\$computer\c$\users\$filetofind" -recurse
            if($files){
                $computer | Out-File -Append $onlinetxt
                write-host "File FOUND on $computer"
            }else{
                write-host “File NOT found on $computer”
            }
        }else{
            $computer| Out-File -Append $offlinetxt
            write-host "$computer is OFFLINE/DID NOT RESPOND TO PING"
        }
    }
    
    #$hostnamestxt='C:\scripts\computernames.txt‘
    #foreach($comp in (Get-Content $hostnames){
        FindFile $env:computername 
    #}
    This is set to only scan the local machine.  Make this work first.


    ¯\_(ツ)_/¯

    Tuesday, January 28, 2014 11:20 PM
  • Thanks, I believe you are saying that my wildcard * isn't the right choice there? Sure, that makes sense. No file found on my local machine. Prashanth's solution works but I would like to append the full path and found file name to the Machines_with_file.txt , right now it only puts in there the $computer name.
    Tuesday, January 28, 2014 11:56 PM
  • What you are in effect doing is asking others to write your script for you.  The last post gives you everything but you need to take the time to learn the basics of PowerShell.

    Read the forum guidelines.  You can't just keep begging until we give you what you want.  This is not a free consulting forum or a place to get free scripting.  It is a forum for technical people who use scripting in their jobs or who are learning how to write scripts.

    Start by taking advantage of the free learning resources.  Learn the basics of Windows and scripting.  Even if you ony kew the basics of Windows file system technology you would easily see why what you have been doing is not realistic.


    ¯\_(ツ)_/¯

    Wednesday, January 29, 2014 12:12 AM
  • This is as simple as we can make this for you:

    function FindFile( $computer ){
        if(Test-Connection $computer -Count 1 -q){
            $files= Get-ChildItem "\\$computer\c$\users\wsr*zt32.dll" -recurse -ea 0
            if($files){
                $files |           
                    ForEach-Object{
                        New-Object PsObject -Property @{Computer=$computer;FilePath="$_"} 
                    }
            }else{
                write-host “File NOT found on $computer” 
            }
        }else{
            write-host "$computer is OFFLINE/DID NOT RESPOND TO PING"
        }
    }
    FindFile $env:computername 
    

    If you cannot understand how this works or how to manage it in your environment then I recommend hiring a consultant to work with you to get your task done.

    You can very easily learn this if you were to take the time and put in the effort.


    ¯\_(ツ)_/¯

    Wednesday, January 29, 2014 12:15 AM
  • # Set file to be tested for, put everything after c:\
    # "c:\Users\Default" is the example path
    $filetofind = 'wsr*zt32.dll'
    # Hostnames TXT Location
    $hostnamestxt = 'C:\scripts\computernames.txt'
    # Destination file for Online Machines
    $onlinetxt = 'C:\scripts\output\Machines_with_file.txt'
    # Destination file for Offline Machines
    $offlinetxt = 'C:\scripts\output\Offline_Machines.txt'
    
    ##########################################################
    # Begin Executing Script – Do Not Edit Below This Line
    ##########################################################
    $computers = get-content "$hostnamestxt"
    
    write-host "———————————————-"
    write-host "Scanning hostnames from $hostnamestxt…"
    write-host "———————————————-"
    foreach($computer in $computers)
    {
    ping -n 1 $computer >$null
    if($?)
    {
    $g=get-childitem \\$computer\c$\users\*.dll -recurse |? {$_.name -match "wsr[0-9][0-9]zt32.dll"}
        if($g -ne $NULL)
        {
            foreach($f in $g)
            {
            echo "$f.name File FOUND $computer" | Out-File -Append "$onlinetxt"
            }
        }
        else
        {
            write-host "File NOT found on $computer"}
        }
    
    else
    {
    write-host "$computer is OFFLINE/DID NOT RESPOND TO PING" | Out-File -Append "$offlinetxt"
    }
    }
    
    write-host "———————————————-"
    write-host "Script has completed please check output."
    write-host "Hosts with file output location – $onlinetxt"
    write-host "Hosts that were unpingable output location – $offlinetxt"
    write-host "———————————————-"
    

    Try this code. 

    -Prashanth

    Wednesday, January 29, 2014 2:58 PM
  • Again I asked why are you using old DOS commands in PowerShell?  Why try to revert PowerShell to a DOS batch file?  It only makes the problem harder to solve.

    This is old DOS badly converted o PowerShell

    echo "$f.name File FOUND $computer" | Out-File -Append "$onlinetxt"

    That is redundant and shows a complete lack of understand of PowerShell.  It is something moved from DOS..  It also won't work because of the object reference.

    "$($f.name) File FOUND $computer" | Out-File -Append $onlinetxt

    Again - placing quotes around everything is unnecessary and will cause issues under some circumstances.  You need to not do things superstitiously.

    Note that we need parens here.


    ¯\_(ツ)_/¯


    • Edited by jrv Wednesday, January 29, 2014 3:14 PM
    Wednesday, January 29, 2014 3:13 PM
  • I am trying this one but it doesn't find the file on my local drive? Since the file can have names similar to this "wsr[0-9][0-9]zt32.dll" and may be hidden, is this why the script fails to find the file? I have created the file as wsr21zt32.dll with random text in the file, but this script doesn't find it? Sorry, as I said, I am not good at scripting and am trying to learn here. I understand basic concepts and can follow what you are trying to do here, but I don't understand why it doesn't find the file. 
    Wednesday, January 29, 2014 5:19 PM
  • Thanks Prashanth, tried this but now the file is not found. Your other version found the file? Why would that be? I'm not sure I see the difference?
    Wednesday, January 29, 2014 5:29 PM
  • # Set file to be tested for, put everything after c:\ # "c:\Users\Default" is the example path $filetofind = 'wsr*zt32.dll' # Hostnames TXT Location $hostnamestxt = 'C:\scripts\computernames.txt' # Destination file for Online Machines $onlinetxt = 'C:\scripts\Output\Machines_with_file.txt' # Destination file for Offline Machines $offlinetxt = 'C:\scripts\Output\Offline_Machines.txt' ########################################################## # Begin Executing Script – Do Not Edit Below This Line ########################################################## $computers = get-content $hostnamestxt write-host "———————————————-" write-host "Scanning hostnames from $hostnamestxt…" write-host "———————————————-" foreach($computer in $computers) { if(Test-Connection -ComputerName $computer -Count 2 -Quiet) { $g = get-childitem \\$computer\c$\test\* -recurse -ErrorAction silentlycontinue |? {$_.name -match "wsr[0-9][0-9]zt32.dll"} if($g -ne $NULL) { foreach($f in $g) {  Write-Output "$($f.name) File FOUND on following $($f.Directoryname) in $computer"  | Out-File -Append $onlinetxt write-host "File found on $computer" } } else { write-host "File NOT found on $computer"

    } } else { Write-Output "$computer is OFFLINE/DID NOT RESPOND TO PING" | Out-File -Append $offlinetxt } } write-host "———————————————-" write-host "Script has completed please check output." write-host "Hosts with file output location – $onlinetxt" write-host "Hosts that were unpingable output location – $offlinetxt" write-host "———————————————-"

    Try this

    --Prashanth





    Wednesday, January 29, 2014 6:18 PM
  • Thanks Prashanth, this appears to be working better as it is taking much longer to return results (still has not finished), however I am getting errors and I'm not certain still that the script is finding the file and returning a positive result;

    Get-ChildItem : Could not find a part of the path '\\AU-BJM2-PC2\c$\users\DEJ1\My Documents'.
    At C:\Scripts\scanfile5.ps1:23 char:17
    + $g=get-childitem <<<<  \\$computer\c$\users\* -recurse |? {$_.name -match "wsr[0-9][0-9]zt32.dll"}
        + CategoryInfo          : ReadError: (\\AU-BJM2-PC2\c$\users\DEJ1\My Documents:String) [Get-ChildItem], DirectoryNotFoundException
        + FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand


    Wednesday, January 29, 2014 7:01 PM
  • Try the code now.

    # Set file to be tested for, put everything after c:\ # "c:\Users\Default" is the example path $filetofind = 'wsr*zt32.dll' # Hostnames TXT Location $hostnamestxt = 'C:\scripts\computernames.txt' # Destination file for Online Machines $onlinetxt = 'C:\scripts\Output\Machines_with_file.txt' # Destination file for Offline Machines $offlinetxt = 'C:\scripts\Output\Offline_Machines.txt' ########################################################## # Begin Executing Script – Do Not Edit Below This Line ########################################################## $computers = get-content $hostnamestxt write-host "———————————————-" write-host "Scanning hostnames from $hostnamestxt…" write-host "———————————————-" foreach($computer in $computers) { if(Test-Connection -ComputerName $computer -Count 2 -Quiet) { $g = get-childitem \\$computer\c$\user\* -recurse -ErrorAction silentlycontinue |? {$_.name -match "wsr[0-9][0-9]zt32.dll"} if($g -ne $NULL) { foreach($f in $g) {  Write-Output "$($f.name) File FOUND on following $($f.Directoryname) in $computer"  | Out-File -Append $onlinetxt write-host "File found on $computer" } } else { write-host "File NOT found on $computer"

    } } else { Write-Output "$computer is OFFLINE/DID NOT RESPOND TO PING" | Out-File -Append $offlinetxt } } write-host "———————————————-" write-host "Script has completed please check output." write-host "Hosts with file output location – $onlinetxt" write-host "Hosts that were unpingable output location – $offlinetxt" write-host "———————————————-"

    -Prashanth



    • Edited by Prashanth Jayaram Wednesday, January 29, 2014 7:45 PM
    • Marked as answer by MarcGel Wednesday, January 29, 2014 8:55 PM
    Wednesday, January 29, 2014 7:40 PM
  • Although this works, it appears to be very slow. Also, the Offline machines are not getting logged. Is there a way to speed this up? I am reading about how gci is slow over UNC, but I'm going to have to research this more. Thanks


    • Edited by MarcGel Wednesday, January 29, 2014 9:31 PM
    Wednesday, January 29, 2014 8:57 PM
  • I am new to scripting and trying to find a way to search for a supposed virus file named wsr[any two numbers]zt32.dll on a large group of computers.

    Don't use a script. Use an enterprise anti-malware tool.

    Bill

    • Marked as answer by MarcGel Wednesday, January 29, 2014 10:33 PM
    Wednesday, January 29, 2014 9:51 PM
    Moderator
  • Although this works, it appears to be very slow. Also, the Offline machines are not getting logged. Is there a way to speed this up? I am reading about how gci is slow over UNC, but I'm going to have to research this more. Thanks


    This makes the third time you have demanded someone custom build a solution for you.  You need to step back and think about what you are doing.  The solution was provided as you asked for it.  You lack of technical experience led you to ask fot a now unworkable solution so you are asking for more free consulting and a new solution.

    As Bill has pointed out this should be done with AV software as just finding the fiole will accomplish nothing.  If your system is infected you need to rake more aggressive steps and you should not be trying to write a scripted solution for this kind of thing aunless you have the technical sjkills to understand what it is you are doing.

    All remote scan methods are very slow.  To do a local scan requires emoting to be installed and that you know how to use it,  Once remoting is installed a single line will get you the file existence.  Adding an AsJob will get you concurrent scanning.  You will need to learn how to use PowerShell and WMF remoting to proceed with this.  An AV scanner 2would be more valuable and it would protect you in the future.

    Also as I posted before this is a very weak construct for file scanning on a network.

    $g = get-childitem \\$computer\c$\user\* -recurse -ErrorActionsilentlycontinue |? {$_.name -match "wsr[0-9][0-9]zt32.dll"}

    The following will be much faster.

    $g = get-childitem \\$computer\c$\user\* -Include wsr*zt32.dll -recurse -ErrorActionsilentlycontinue


    ¯\_(ツ)_/¯

    Wednesday, January 29, 2014 10:34 PM