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 shorthand