I have this directory/file structure:
S:\My Folder\BaseName 1\
S:\My Folder\BaseName 1\BaseName 1 1.lnk
S:\My Folder\BaseName 1\BaseName 1 1.txt
S:\My Folder\BaseName 1.lnk
S:\My Folder\BaseName 1.txt
S:\My Folder\BaseName 2\
S:\My Folder\BaseName 2\BaseName 2 1.lnk
S:\My Folder\BaseName 2\BaseName 2 1.txt
S:\My Folder\BaseName 2.lnk
S:\My Folder\BaseName 2.txt
I have a script that seeks for *.lnk files in directorys and then should handle any other file/folder with the same BaseName of the *.lnk found.
When the script parses *S:\My Folder* it finds BaseName 1.lnk and BaseName 2.lnk
Now I need to find all the child-items in S:\My Folder (and only there, not in the subfolders) with the same BaseNames, so I need to find both the BaseName 1 folder and the BaseName 1.txt file.
But i'm unable to do it:
Get-ChildItem -Path ".\BaseName 1" -exclude *.lnk
returns the content of the directory BaseName 1, which i don't want.Get-ChildItem -Path ".\BaseName 1*" -exclude *.lnk
returns only BaseName 1.txt and the content of the directory BaseName 1, which i don't want.Get-ChildItem -Path ".\BaseName 1.*" -exclude *.lnk
returns only BaseName 1.txt but not the directory BaseName 1, which i need.Get-ChildItem -Path "." -include "BaseName 1" -exclude *.lnk -recurse
returns only the the directory BaseName 1, but not the BaseName 1.txt fileGet-ChildItem -Path "." -include "BaseName 1*" -exclude *.lnk -recurse
returns everything, but again, i don't want the content of the directory BaseName 1What should i do?
Use Get-Item
rather than Get-ChildItem
:
Get-Item -Path '.\BaseName 1*' -Exclude *.lnk
More stringently (given that the above would also match .\BaseName 11
, for instance):
# Add -ErrorAction Ignore to silence a potential error if no
# item literally named 'BaseName 1' exists.
Get-Item -Path '.\BaseName 1', '.\BaseName 1.*' -Exclude *.lnk
As for what you tried:
# !! Includes the *child* items of dir. 'BaseName 1', due to use of -Exclude
Get-ChildItem -Path ".\BaseName 1*" -Exclude *.lnk
Leaving aside that Get-Item
is also conceptually the better choice, since you're not looking for child items of what the wildcard expression ".\BaseName 1*"
matches, the behavior you've observed when combining Get-ChildItem
with -Exclude
is certainly surprising (observed in Windows PowerShell v5.1 and PowerShell (Core) 7 as of v7.5.0):
By default, a directory matched by wildcard is reported as itself rather than reporting its child items (the latter always happens if you use a literal name).
The addition of -Exclude
surprisingly implicitly modifies this behavior to report the children and applying the exclusion to them.
If -Include
is used, the behavior becomes downright buggy:
In addition to unexpectedly triggering reporting of the children, as with -Exclude
, the pattern is first matched against the item name itself, and if it doesn't match, the children are not matched.
E.g., Get-ChildItem foo* -Include *.txt
never matches anything, because *.txt
cannot match whatever directory names foo*
resolved to.
A summary of all problematic -Include
/ -Exclude
behaviors can be found in the bottom section of this answer.