Suppose we have the following directory structure:
~dir00
|-> dir10
| |-> dir20
| |-> file1.txt
|-> dir11
|-> file2.txt
Now, suppose ~dir00 is the current directory. I would have expected the two commands get-childitem * -recurse
andget-childitem -recurse
to produce the same results. However, they do not. The behaviour of the second is what I would expect.
I am trying to write a small library of tools for use with our scripted processes. One tool I need to write is a tool to copy and backup sets of files. I get, as inputs, something that tells me what files/directories/etc. to copy. I have no way of knowing what the user may provide. They may provide a wild-card such as "*", they may provide a file name, they may provide the -recurse parameter, etc. etc. The inputs are fed to get-childitem. The inconsistency of the behaviour of get-childitem when the "path" is just "*" is a big problem. Why does get-childitem suddenly drop the first-level directories when fed a -path of "*" and the -recurse option? (Note that it only drops the first-level directories.) Is there any way I can prevent this odd behaviour?
Now, it gets more bizzare. If we put a file in the root directory, so the file structure becomes
~dir00
|-> dir10
| |-> dir20
| |-> file1.txt
|-> dir11
| |-> file2.txt
|-> file3.txt
then the directories are suddenly NOT dropped. To reproduce this, just execute the following script:
cd $Env:temp
mkdir dir00\dir10\dir20 | out-null
cd dir00
mkdir dir11 | out-null
echo 'hello world 1'>dir10\dir20\file1.txt
echo 'hello world 2'>dir11\file2.txt
$list1 = get-childitem -recurse
echo 'Results of get-childitem -recurse: '
$list1
echo ''
echo 'Number of items:'
$list1.length
echo ''
$list2 = get-childitem * -recurse
echo 'Results of get-childitem * -recurse: '
$list2
echo ''
echo 'Number of items:'
$list2.length
echo ''
echo "hello world 3">file3.txt
$list3 = get-childitem * -recurse
echo 'Results of get-childitem * -recurse: '
$list3
echo ''
echo 'Number of items:'
$list3.length
echo ''
This is because the path that you are feeding into Get-ChildItem is different.
When you execute:
Get-ChildItem -Recurse
You are saying the same as:
Get-ChildItem -Path . -Recurse
Or interpreted as: Get Child Item -Path starts at the current directory (dir00)
When you execute:
Get-ChildItem * -Recurse
You are saying, with the *, iterate through all items in the directory, feed those paths to Get-ChildItme, and then Recurse through those items. So the equivalent command that is executed is this:
$items = Get-ChildItem *
Get-ChildItem $items -Recurse
Which works out to:
Get-ChildItem -Path ./dir10 -Recurse
Get-ChildItem -Path ./dir11 -Recurse
Now, what you are seeing is an odd exception (or could be seen as a bug) to this behaviour, and it only happens in this case when you have a root directory that only contains folders and no files. If you create one file in the dir00:
echo 'hello world 1'>test1.txt
And then we execute
Get-ChildItem * -Recurse
It lists exactly the same as Get-ChildItem -Recurse
. So you will only get different results only when you have root directories with no files, only folders.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With