PowerShell find files by extension on multiple servers and export

Lingareddy Chandrakanth Reddy 1 Reputation point
2021-12-14T15:00:19.843+00:00

I wrote a script to find the particular file on windows servers based on Disks and exported that list to a .txt file for each server and drive.

I want to run the script for multiple servers and export all the list details in one CSV or excel file with the server name and the file location path as output.

My script is working as expected but it is giving the output for each server with drive name as a separated file and the output contains only the path, but i need to get the output in one single CSV file for all the servers with the entire file location path as well.

#Clearing the Host file
Clear-Host

#Get all the list of Servers
$Machines = get-content "C:\Scripts\Servers.txt"

#Get all the list of Disks to search
$Disks = get-content "C:\Scripts\Disks.txt"

#Lopping through specified servers
foreach ($Machine in $Machines) 
{
#Lopping through each Disks
    foreach ($Disk in $Disks) 
    {
        if (Test-Path \\$Machine\$Disk$) 
        {
            Write-Host Checking $Machine Disk $Disk -BackgroundColor DarkRed
            Get-ChildItem -Path \\$Machine\$Disk$\ -Filter log4j.jar -Recurse -Name -Force | Out-File "C:\Scripts\Output\$Machine $Disk.txt"
        }
    }
} 
Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Michael Taylor 60,161 Reputation points
    2021-12-14T15:13:36.337+00:00

    That's because you are calling Get-ChildItem in a foreach loop. And for each run you're placing it into a file based upon the machine/disk name for that iteration. If you want to put that into a single file then you need to use a single filename. Of course you could always merge the files later but I assume you want to skip that step.

    It is unclear to me whether you want a single file for each server or a single file overall. I'm going to assume a single file per server otherwise you have no easy way to know what server a set of files came from.

    Get-ChildItem ... | Out-File "C:\scripts\output\$Machine.txt -Append
    

    This runs each command but stores it into a single file based upon the matchine name. The append option has the output appended to the existing file so each time through the loop it just keeps adding the content. Of course if the file exists before the run then it'll append anyway. You likely don't want that so either ensure the file doesn't exist before you start running your foreach loop or add a datetime to the filename before you run it.


  2. Rich Matheisen 47,901 Reputation points
    2021-12-14T15:19:16.83+00:00

    See if this works for you:

    #Clearing the Host file
    Clear-Host
    
    #Get all the list of Servers
    $Machines = Get-Content "C:\Scripts\Servers.txt"
    
    #Get all the list of Disks to search
    $Disks = Get-Content "C:\Scripts\Disks.txt"
    
    #Looping through specified servers
    foreach ($Machine in $Machines) {
        #Looping through each Disk
        foreach ($Disk in $Disks) {
            if (Test-Path \\$Machine\$Disk$) {
                Write-Host Checking $Machine Disk $Disk -BackgroundColor DarkRed
                Get-ChildItem -Path \\$Machine\$Disk$\ -Filter log4j.jar -Recurse -Force | 
                    Select-Object @{n=Machine;e={$Machine}},@{n=Share;e={$Disk}}, FullName
            }
        }
    } Export-Csv C:Scripts\Output\SharesByMachine.csv -NoTypeInformation
    

  3. Leon Laude 86,026 Reputation points
    2021-12-15T15:59:19.47+00:00

    Hi @Lingareddy Chandrakanth Reddy ,

    If your goal is to find all Log4J vulnerabilities, it is not sufficient to simply search for files with the name of Log4j, this is described well in the Reddit post below:

    This will not catch all scenarios, such as when log4j is bundled inside of a JAR, therefore you should not be using this to find it. You need to find all .JAR files and look for the existence of the JndiLookup class. This check of yours would not have caught the base minecraft.jar file containing the original vector used to identify this vulnerability because the class was packaged inside of the file.

    This will find every existence under the given drive.

    gci 'C:\' -rec -force -include *.jar -ea 0 | `  
    foreach {select-string "JndiLookup.class" $_} | `  
    select -exp Path  
    

    Source:
    https://www.reddit.com/r/sysadmin/comments/rgektp/simple_log4j_search_cdir_log4j_as

    This is also mentioned in the following tweet:
    https://twitter.com/CyberRaiju/status/1469505677580124160

    You can the modify the script to run on all drives which are found under the host, and also modify to run on multiple servers.

    ----------

    If the reply was helpful please don't forget to upvote and/or accept as answer, thank you!

    Best regards,
    Leon

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.