'PowerShell Get-ChildItem on folder that does not exist behaves different with the -recurse flag

I am testing a Power Shell script to clean out a folder and I noticed some unexpected (to me) behavior when i used the - recurse flag

I have read the help files and done some searching but cant find an explanation for what is happening here.

Consider these 3 Power Shell commands:

 Get-ChildItem -Path  C:\folderThatDoesNotExist -recurse

 Get-ChildItem -Path  C:\folderThatDoesNotExist\ -recurse

 Get-ChildItem -Path  C:\folderThatDoesNotExist\* -recurse

The first command appears to search all of C:\ and there are a bunch of access denied errors for folders outside C:\folderThatDoesNotExist (eg c:\windows)

The second errors out with c:\f does not exist

The third errors out with c:\folderThatDoesNotExist\ not found

I expected all 3 to give an error of c:\folderThatDoesNotExist\ Path not found. Why do the first 2 give different errors?



Solution 1:[1]

1st command: Get-ChildItem -Path C:\folderThatDoesNotExist -recurse

You're seeing an unfortunate nod to cmd.exe's dir command, where the last path component of the -Path argument is interpreted as a pattern to be searched for on all levels of the subtree hierarchy - even when that last component doesn't contain wildcard characters such as * and ?.

This highly problematic behavior is discussed in GitHub issue #5699.

To avoid it, use -LiteralPath instead of -Path.
Caveat: user3608068 reports that this doesn't help in PowerShell v4 (and possibly all lower versions).


2nd command: Get-ChildItem -Path C:\folderThatDoesNotExist\ -recurse

The behavior is more sensible - an error occurs - but the error message complains about only part of the path, C:\f.

This is in itself a bug, but a harmless one (if you omit -Recurse, the error message quotes the correct, full path).


3rd command: Get-ChildItem -Path C:\folderThatDoesNotExist\* -recurse

This command exhibits the expected behavior: C:\folderThatDoesNotExist is correctly interpreted as a directory path that doesn't exist (whose child elements are being requested with wildcard *), and the error message correctly reflects that.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1