Find string in Powershell scripts, bat files; multiple directories

I have this working script that will find my string within every ps1 file in a single directory.

$Path = "E:\Scripts\"
$Text = "MyString"
$PathArray = @()
$Results = "E:\temp\results.txt"


# This code snippet gets all the files in $Path that end in ".ps1".
Get-ChildItem $Path -Filter "*.ps1" |
Where-Object { $_.Attributes -ne "Directory"} |
ForEach-Object {
If (Get-Content $_.FullName | Select-String -Pattern $Text) {
$PathArray += $_.FullName
$PathArray += $_.FullName
}
}
Write-Host "Contents of ArrayPath:"
$PathArray | ForEach-Object {$_}

~ How do I get it to look in all sub-folders?

Get-ChildItem $Path -Filter "*.ps1" -Recurse

As shown in Example 3

Thank you grokkit

…but when I attempt to search now for a string in an .xml file (for which I know is there, as a test) it comes up empty, using -Recurse.

#$Path = "C:\"
$Path = "E:\AllScripts"
$Text = "DVD5"
$PathArray = @()
$Results = "E:\temp\results.txt"


# This code snippet gets all the files in $Path that end in ".xml".
Get-ChildItem $Path -Filter "*.xml" -Recurse |
Where-Object { $_.Attributes -ne "Directory"} |
ForEach-Object {
If (Get-Content $_.FullName | Select-String -Pattern $Text) {
$PathArray += $_.FullName
$PathArray += $_.FullName
}
}
Write-Host "Contents of ArrayPath:"
$PathArray | ForEach-Object {$_}

Your script runs fine in my testing…

Now I need to search for a keyword in a text file that could be on a set of DCs so I tried this:

$AllDCs = Get-Content .\AllDCs.txt
Invoke-Command -ScriptBlock {
Get-ChildItem -Path E:\, C:\ -Include *.ps1, *.xml, *.bat -Recurse | Select-String -Pattern DVD5
 } -ComputerName $AllDCs

…I put a small xml file with the text string DVD5 in it but the script is not finding it.

However, I tried this foreach and it did find my string:

foreach($DC in $AllDCs){
Get-ChildItem -Path E:\, C:\ -Include *.ps1, *.xml, *.bat -Recurse | Select-String -Pattern DVD5
}

…just not sure it’s efficient (about 30 DCs to search)

What am I missing? Also, will I be able to tell which server the result(s) are located?

This is a weird one… Check out the answer post here: https://social.technet.microsoft.com/Forums/scriptcenter/en-US/f5697b54-6256-4489-80e1-18b1a7d3cb56/selectstring-in-invokecommand-not-working-as-expected?forum=ITCG

Based on that, I was able to get this to work:

PS E:\> invoke-command -computername server01 -scriptblock {gci -path c:\temp\* -include *.txt | select-string -pattern 'COMP01' | select line }

Line                  PSComputerName RunspaceId
----                  -------------- ----------
CN= FedSrv.comp01.com server01      d7e2d108-150d-431f-82e0-75b249ec2289
OU=COMP01,            server01      d7e2d108-150d-431f-82e0-75b249ec2289

As to the efficiency and speed, that’s a longer discussion that includes a lot of questions. Can you multi-thread it? Do you have to look at all of those file types? Do you have to look at the entire file system? What kind of network are you on? How many results are you expecting from each DC? Etc, etc.

Based on the output of the above command, it looks like you could pull the computer name from the Invoke-Command output line. You could do this differently by piping the Invoke-Command to something like Select-Object:

Invoke-Command -computername $server -scriptblock {gci -path c:\temp\* -include *.txt | select-string -pattern $SearchString | select line } | Select-Object Line, PSComputerName

Or create a custom object:

$foundStrings = Invoke-Command -computername $server -scriptblock {gci -path c:\temp\* -include *.txt | select-string -pattern $SearchString | select line }
New-Object -TypeName PSObject -Property @{
     ComputerName = $server
     SearchString = $SearchString
     FoundStrings = $foundStrings
}

I read the article but even just trying to find a known string on the local box I’m on doesn’t return the string.

$SearchString = "Owner Before"
$AllDCs = Get-Content .\AllDCs.txt #only contains MYLOCALCOMPUTER as a test, which has a .ps1 file containing the string "Owner Before"
$foundStrings = Invoke-Command -computername $AllDCs -scriptblock {gci -path E:\ -include *.ps1 -Recurse | select-string -pattern $SearchString | select line }
New-Object -TypeName PSObject -Property @{
     ComputerName = $AllDCs
     SearchString = $SearchString
     FoundStrings = $foundStrings
}

output:

Cannot bind argument to parameter 'Pattern' because it is null.
    + CategoryInfo          : InvalidData: (:) [Select-String], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SelectStringCommand
    + PSComputerName        : MYLOCALCOMPUTER
 

ComputerName SearchString FoundStrings
------------ ------------ ------------
MYLOCALCOMPUTER Owner Before             

I don’t get it why you had double threads. Check out the answer in the other one:

https://powershell.org/forums/topic/find-string-exclude-folder-list-results/#post-184574

 

The requirements had changed