Use PowerShell to List all directories that contain both File1 and File2

OK, here’s a task that’s supposedly very easy, but can get you raging due to the oddities of PowerShell formatting. How do we list all directories that have a particular set of files available? For the sake of simplicity, let’s just examine the case of two files and call them File1.txt and File2.txt. Remember, we need all directories that have BOTH of these files.

You can browse a gazillion examples online, all using different variations of the -Filter or -Include parameter of the Get-ChildItem cmdlet. Something like this for example:

dir C:\ -Include File1.txt, File2.txt -Recurse

which is equivalent to:

dir C:\ -Recurse| ? {$_.Name -eq "File1.txt" -or $.Name -eq "File2.txt" }

Note the damned -OR operator however. This returns ANY directory that has ANY of the files we are interested in, not only the directories that have BOTH of them. And since the comparison is done against each individual file, there’s no point in replacing the -OR with -AND operator.

On the other hand, the output already contains the information we are interested in – among the list of all directories that include any of the file names, there are some that include ALL of them. So the question is how to filter only those entries?

After banging my head against the keyboard for a while, this is the solution I came up with – use the Group-Object cmdlet and then use another filter to get the entries we need (in this case check whether the count of values is exactly 2):

dir C:\ -Include File1.txt, File2.txt -Recurse | Group Directory | ? {$_.Count -eq 2}

That’s the list of all directories that have both files we are querying for. As the format is again not very useful, you can get the Values (which returns the full System.IO.DirectoryInfo object) and for example sort by the Last Modified Date to get the newest/oldest directory:

(dir C:\ -Include File1.txt, File2.txt -Recurse | Group Directory | ? {$_.Count -eq 2}).Values | sort LastWriteTime -Descending | select -First 1 | select -ExpandProperty FullName

Man, that was exhausting exercise. Hope it helps someone 🙂

Do let me know if there’s an easier way to do this!

This entry was posted in PowerShell. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *