Friday, May 25, 2007

PowerShell Get-ChildItem Traversal Order

I was playing with Get-ChildItem in PowerShell the other day, and I came across an interesting behavior with the –RECURSE switch. As a review, the –RECURSE switch tells Get-ChildItem to get all of the items at the specified path and in all child items within that path. So, for example,

PS> Get-ChildItem C:\Windows –RECURSE

would return all of the items in C:\Windows, and all of the items in all folders under C:\Windows recursively. This is similar to the Command Shell DIR /S command.

What’s interesting is that there is a difference in the recursive traversal order depending on whether the path is wildcarded or not. That is, the paths C:\Foo and C:\Foo\* return slightly different results when passed to Get-ChildItem –RECURSE. This is a change from DIR /S, where either path returns the same results.

So how do they differ? Let’s take a look at the command line results and see what we can see. First, a folder path without wildcards:


PS> dir foo –recurse


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo


Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/23/2007 1:52 PM <DIR> Bar
d---- 5/23/2007 1:55 PM <DIR> Baz
-a--- 5/23/2007 1:52 PM 26 readme.txt
-a--- 5/23/2007 1:51 PM 9 testfile.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar


Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/23/2007 1:53 PM <DIR> Beer
d---- 5/23/2007 1:54 PM <DIR> Wine
-a--- 5/23/2007 1:52 PM 31 Menu.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar\Beer


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:52 PM 15 Allagash.txt
-a--- 5/23/2007 1:52 PM 15 Belgian.txt
-a--- 5/23/2007 1:52 PM 15 DogFish Head.txt
-a--- 5/23/2007 1:53 PM 22 Swill.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar\Wine


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:54 PM 29 Australia.txt
-a--- 5/23/2007 1:54 PM 29 California.txt
-a--- 5/23/2007 1:54 PM 29 France.txt
-a--- 5/23/2007 1:54 PM 29 Hungary.txt
-a--- 5/23/2007 1:54 PM 29 Iceland.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Baz


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:52 PM 31 Menu.txt

Notice that the first items returned are the items in the folder foo, followed by a recursive traversal of the sub-folders in foo.
Now let’s try that again, wildcarding the path:

PS> dir foo\* -recurse


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar


Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/23/2007 1:53 PM <DIR> Beer
d---- 5/23/2007 1:54 PM <DIR> Wine
-a--- 5/23/2007 1:52 PM 31 Menu.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar\Beer


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:52 PM 15 Allagash.txt
-a--- 5/23/2007 1:52 PM 15 Belgian.txt
-a--- 5/23/2007 1:52 PM 15 DogFish Head.txt
-a--- 5/23/2007 1:53 PM 22 Swill.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Bar\Wine


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:54 PM 29 Australia.txt
-a--- 5/23/2007 1:54 PM 29 California.txt
-a--- 5/23/2007 1:54 PM 29 France.txt
-a--- 5/23/2007 1:54 PM 29 Hungary.txt
-a--- 5/23/2007 1:54 PM 29 Iceland.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo\Baz


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:52 PM 31 Menu.txt


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\foo


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 5/23/2007 1:52 PM 26 readme.txt
-a--- 5/23/2007 1:51 PM 9 testfile.txt

This time, notice that the first thing returned is a traversal of the first folder in foo, not the items in foo. In fact, it’s not until you get to the end of the output that you get any results from foo at all, and then only the items that are not themselves traversable.

I’m not 100% sure how to apply this information yet, but I suspect it will be useful to know it someday.

No comments: