windowspowershellget-childitem

Powershell Get-ChildItem: how to get everything with a given BaseName, both Files and Folders?


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:

  1. Get-ChildItem -Path ".\BaseName 1" -exclude *.lnk returns the content of the directory BaseName 1, which i don't want.
  2. 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.
  3. Get-ChildItem -Path ".\BaseName 1.*" -exclude *.lnk returns only BaseName 1.txt but not the directory BaseName 1, which i need.
  4. Get-ChildItem -Path "." -include "BaseName 1" -exclude *.lnk -recurse returns only the the directory BaseName 1, but not the BaseName 1.txt file
  5. Get-ChildItem -Path "." -include "BaseName 1*" -exclude *.lnk -recurse returns everything, but again, i don't want the content of the directory BaseName 1

What should i do?


Solution

  • 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):