How to automate a file search

TL;DR How to automate a search for a filename on multiple systems.
Background
This lab exercise presupposes that one of your users Blue Falconed multiple other users by emailing them a file attachment containing sensitive data that should not have been released. The receiving users are busy with their normal day to day job and might not recall whether they saved the attachment. The Exchange administrators have already cleaned the inboxes, other administrators have checked the portal, file server, etc, but you need to be sure the file isn’t saved locally on any domain workstations.
The Problem
We need to search for a specific filename across a range of domain workstations, possibly hundreds of them. This would take far too long to do manually and it would be easy to miss one or two.
The Solution
We automate of course. There are a couple ways to skin this cat, but almost all roads lead to the ForEach loop.
We start this lab exercise by creating a file to look for. We will pick one of our VMs and put the file there in order to verify the search works:
Add-Content ‘\\BackupDC\C$\Users\mishky\Desktop\Backup.ps1’ -Value ‘Write-Host “Hello World!”’
We need a CSV file containing the ComputerNames we want to check. If we want to be safe and just check an entire group of computers we can do this by
(Get-ADComputer -Filter * -SearchBase “ou=Clients,dc=test,dc=local” -Properties *).CN | Out-File List.txt ; Rename-Item List.txt List.csv
A Privileged User account with elevated rights on the domain workstation OU will have to run this search. If the CSV list of systems to search was created with a regular user account then just save it in C:\Users\Public\Documents and ‘cd’ into that dir before running the search.
Search Method I, aka The Quick & Dirty Way
If we are just running this search ourselves and aren’t worried about accepting user input we can just put together a couple things from CW6 Google and get the job done:
$systems = Get-Content .\List.csv
ForEach($system in $systems)
{
Invoke-Command -ScriptBlock {Get-ChildItem -Path C:\Users\* -Filter Backup.ps1 -Recurse -ErrorAction SilentlyContinue} -ComputerName $system | Out-File .\Output.txt -Append
}

Search Method II
A slightly more refined way to run this search is to ask the user what the CSV list of ComputerNames is named and what the filename is they are checking for. This method also avoids creating a profile on the remote systems. It may also run a bit faster.
$File = Read-Host “What is the filename you are checking for?”
$List = Read-Host “What is your list of computers to check?”
$systems = Get-Content .\$List
ForEach($system in $systems)
{
Get-ChildItem -Path \\$system\C$\Users\* -Filter $File -Recurse -ErrorAction SilentlyContinue | Out-File .\OutputII.txt -Append
}

Computers & Users That ‘Pop Hot’
Either method will create a text file in the present working directory that will contain the details of any workstations that contained the file. As shown in the output from each method above, we also get the exact path and in 99% of cases we will also get the user’s SamAccountName who saved the file. This is due to the fact that Domain Users are only allowed to create files locally in C:\Users\<their SamAccountName> and C:\Users\Public. Most users however do not know or care about the Public folder.
We can then deal with those systems accordingly.
If you have any questions just message me on FB, LinkedIn, or my work email!
-Rich
References: