I am searching for a file in all the folders.
Copyforbuild.bat
is available in many places, and I would like to search recursively.
$File = "V:\Myfolder\**\*.CopyForbuild.bat"
How can I do it in PowerShell?
Use the Get-ChildItem cmdlet with the -Recurse
switch:
Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
cd V:\MyFolder
followed by ls -r -inc CopyForBuild.bat
Commented
Aug 14, 2014 at 21:57
ls -r -ea silentlycontinue -fo -inc "filename.txt" | % { $_.fullname }
I use this to find files and then have PowerShell display the entire path of the results:
dir -Path C:\FolderName -Filter FileName.fileExtension -Recurse | %{$_.FullName}
You can always use the wildcard *
in the FolderName
and/or FileName.fileExtension
. For example:
dir -Path C:\Folder* -Filter File*.file* -Recurse | %{$_.FullName}
The above example will search any folder in the C:\
drive beginning with the word Folder
. So if you have a folder named FolderFoo
and FolderBar
PowerShell will show results from both of those folders.
The same goes for the file name and file extension. If you want to search for a file with a certain extension, but don't know the name of the file, you can use:
dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}
Or vice versa:
dir -Path C:\FolderName -Filter FileName.* -Recurse | %{$_.FullName}
When searching folders where you might get an error based on security (e.g. C:\Users
), use the following command:
Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse -ErrorAction SilentlyContinue -Force
Here is the method that I finally came up with after struggling:
Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*
To make the output cleaner (only path), use:
(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname
To get only the first result, use:
(Get-ChildItem -Recurse -Path path/with/wildc*rds/ -Include file.*).fullname | Select -First 1
Now for the important stuff:
To search only for files/directories do not use -File
or -Directory
(see below why). Instead use this for files:
Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}
and remove the -eq $false
for directories. Do not leave a trailing wildcard like bin/*
.
Why not use the built in switches? They are terrible and remove features randomly. For example, in order to use -Include
with a file, you must end the path with a wildcard. However, this disables the -Recurse
switch without telling you:
Get-ChildItem -File -Recurse -Path ./bin/* -Include *.lib
You'd think that would give you all *.lib
s in all subdirectories, but it only will search top level of bin
.
In order to search for directories, you can use -Directory
, but then you must remove the trailing wildcard. For whatever reason, this will not deactivate -Recurse
. It is for these reasons that I recommend not using the builtin flags.
You can shorten this command considerably:
Get-ChildItem -Recurse -Path ./path*/ -Include name* | where {$_.PSIsContainer -eq $false}
becomes
gci './path*/' -s -Include 'name*' | where {$_.PSIsContainer -eq $false}
Get-ChildItem
is aliased to gci
-Path
is default to position 0, so you can just make first argument path-Recurse
is aliased to -s
-Include
does not have a shorthandGet-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat
Will also work
Filter using wildcards:
Get-ChildItem -Filter CopyForBuild* -Include *.bat,*.cmd -Exclude *.old.cmd,*.old.bat -Recurse
Filtering using a regular expression:
Get-ChildItem -Path "V:\Myfolder" -Recurse
| Where-Object { $_.Name -match '\ACopyForBuild\.[(bat)|(cmd)]\Z' }
Try this:
Get-ChildItem -Path V:\Myfolder -Filter CopyForbuild.bat -Recurse | Where-Object { $_.Attributes -ne "Directory"}
| Where-Object { !$_PSIsContainer }
to exclude folders
Commented
Jun 17, 2016 at 11:23
To add to @user3303020 answer and output the search results into a file, you can run
Get-ChildItem V:\MyFolder -name -recurse *.CopyForbuild.bat > path_to_results_filename.txt
It may be easier to search for the correct file that way.
On a Windows system: Search for all .py files in the 'c:\temp' dir and subdirs, type: dir -r *.py or dir *.py -r
On a *Nix (Linux / MacOs system: at the terminal type: find /temp -name *.py
This works fine for me.
Generally, robocopy is the fastest and simplest way for searching multiple files in parallel threads. It needs a quite good Powersell code with parallelism to beat that. Here is a link to an article I have written in the past with all the different options you have: Fastest way to find a full path of a given file via Powershell? Check the accepted answer for the best code.