Home QuickTipps Bug Why “Dir” in PowerShell 3.0 can be dog slow…
 

Why “Dir” in PowerShell 3.0 can be dog slow…

(…and why that’s actually not a bad thing, I’d like to add)

PowerShell 3.0 comes with a lot of changes, some of which aren’t very apparent at first. For example, in PowerShell 3.0, the widely used cmdlet Get-ChildItem (aka “Dir”) has changed tremendously. In most scenarios, it is now much more flexible and 2-3 times faster than in PowerShell 2.0. However, because of some of its new features, it can also slow down your scripts by minutes.

Better Usability

In PowerShell 3.0, Get-Childitem can recursively search for files in a very intuitive way. Have a look at these lines:

dir *.txt -ErrorAction SilentlyContinue
dir $env:windir\*.txt -Recurse -ErrorAction SilentlyContinue
dir $env:windir\*eula*.txt -Recurse -ErrorAction SilentlyContinue

Note: We added the parameter -ErrorAction┬áin these samples to suppress errors because in the windows folder, there are plenty of subfolders where you don’t have access.

In PowerShell 2.0, this was not possible. You always had to specify a path, and the file you were after had to be specified as a separate -Filter parameter. Else, recursion did not work.

Lee Holmes from the PowerShell team explained this new behavior. In PowerShell 3.0, Get-Childitem checks whether the path you specify points to a folder or to a file. If it is a file, the file is listed. If it does not exist, Get-ChildItem recursively enumerates its parent folder looking for files and folders with the child name. The algorithm used in PowerShell 3.0 is essentially the same used by cmd.exe.

The Price You Have To Pay

There is one pitfall though that can slow down your scripts considerably. If you specify a top-level folder that does not exist, as PowerShell MVP Kirk Munro points out, due to the new algorithm, Get-ChildItem now literally searches your entire hard drive.

You can easily reproduce this. Try this line:

dir c:\system32 -Recurse -ErrorAction SilentlyContinue

The path c:\system32 obviously does not exist. So PowerShell 3.0 now takes a look at the parent folder and recursively searches all top level folders, effectively searching your entire hard drive.

Obviously, this takes a very long time. The line will eventually find the folder system32 inside your windows folder, so even this extensive automatic search can be useful.

You just need to be aware of this new functionality. In PowerShell 2.0, Get-ChildItem would not have searched sibling folders, returning with an error momentarily.