Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
April 21, 2026

Faster FileInfo

In this issue:

  • GetFiles()
  • EnumerateFiles()
  • GetFileSystemInfos()
  • EnumerateFileSystemInfos()
  • Get-IOFolderSize
  • Summary

Last time I demonstrated a few .NET techniques for listing directories and sub-directories from a given folder. You might want to use these idea for your own scripting projects where you want a little more granular control over the process or want to eke out a little more performance. We can do a similar thing with files.

I'm sure you've run a command like this.

$a = dir c:\scripts -file

This took 221ms to get 4500 files. Let's look at an alternative.

GetFiles()

As before, we need a reference to the parent folder.

$folder = Get-Item C:\Scripts

Now we can use the GetFiles() method, which has similar overload definitions as GetDirectories().

PS C:\> $folder.GetFiles.OverloadDefinitions
System.IO.FileInfo[] GetFiles()
System.IO.FileInfo[] GetFiles(string searchPattern)
System.IO.FileInfo[] GetFiles(string searchPattern, System.IO.SearchOption searchOption)
System.IO.FileInfo[] GetFiles(string searchPattern, System.IO.EnumerationOptions enumerationOptions)

Getting files in the root directory only now only takes 65ms.

$b = $folder.GetFiles()

The contents of $a and $b are identical.

And as with directories, I can search on a pattern.

PS C:\> $folder.GetFiles("*.zip") | Measure-Object length -sum | Select-Object count,sum


Count       Sum
-----       ---
   20 283687.00

I can use a search option.

PS C:\> $folder.GetFiles("*.zip","AllDirectories") | Measure-Object length -sum | Select-Object count,sum


Count        Sum
-----        ---
   40 7852173.00

This took about 3 seconds compared to dir c:\scripts\*.zip -Recurse | measure length -sum | select count,sum which took over 31 seconds to complete!

Hmmm...I wonder how many files it had to process.

PS C:\> $all = $folder.GetFiles("*","AllDirectories")
PS C:\> $all.count
18310

Or I can get very granular with enumeration options.

PS C:\> $opt = [System.IO.EnumerationOptions]::new()
PS C:\> $opt.RecurseSubdirectories = $True
PS C:\> $opt.attributesToSkip+="SparseFile"
PS C:\> $opt.MaxRecursionDepth = 1
PS C:\> $opt

RecurseSubdirectories    : True
IgnoreInaccessible       : True
BufferSize               : 0
AttributesToSkip         : Hidden, System, SparseFile
MatchType                : Simple
MatchCasing              : PlatformDefault
MaxRecursionDepth        : 1
ReturnSpecialDirectories : False

Now to use it.

PS C:\> $c = $folder.GetFiles("*",$opt)
PS C:\> $c.count
6487
Want to read the full issue?
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.