Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
April 17, 2026

Directory Diving

In this issue:

  • DirectoryInfo Methods
  • GetDirectories()
    • SearchPattern
    • SearchOptions
    • EnumerationOptions
  • EnumerateDirectories()
  • Summary

I expect that for many of you PowerShell is an easy to use tool because it isn't difficult to find and run a cmdlet to achieve a particular goal. Cmdlets are typically well documented and have a set of parameters to fine-tune the command's behavior. Cmdlets and functions abstract a lot of the .NET Framework so that you can use PowerShell without having to be a .NET developer.

However, as you gain experience, you'll encounter situations where you need to forego the cmdlet and dive into the deep end of .NET. You don't always have to rely on a cmdlet or function. Should the need arise, you can create code that utilizes the underlying .NET voodoo. This allows you to have more granular control of an operation. I want to dive into some of that today with the file system.

Normally, we can use Get-ChildItem.

PS C:\> Get-ChildItem c:\scripts -Directory | Measure | Select count

Count
-----
  189

Easy to use, and the cmdlet offers several parameters to control how the command runs. But there is always overhead with a cmdlet; a trade-off for ease of use. If we are willing to do the work, we can eke out a little more performance. This will be more noticeable with larger directories.

DirectoryInfo Methods

When I run Get-ChildItem on a location, I am implicitly creating aSystem.IO.DirectoryInfo` object. This class offers a few methods that we can take advantage of.

PS C:\> $folder = Get-Item C:\Scripts
PS C:\> Get-TypeMember $folder.GetType().Fullname -MemberType method | Where {$_.name -match "(Directories)|(file)"}

   Type: System.IO.DirectoryInfo

Name                     MemberType ResultType       IsStatic IsEnum
----                     ---------- ----------       -------- ------
EnumerateDirectories     Method     IEnumerable`1
EnumerateFiles           Method     IEnumerable`1
EnumerateFileSystemInfos Method     IEnumerable`1
GetDirectories           Method     DirectoryInfo[]
GetFiles                 Method     FileInfo[]
GetFileSystemInfos       Method     FileSystemInfo[]

> You will see different results when using Windows PowerShell.

Today I want to focus on the directory-related methods.

GetDirectories()

The GetDirectories() method will give you results identical to running Get-ChildItem -directory. The method has several overloaded definitions you can use.

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

The basic syntax will get all top-level directories

PS C:\> $folder.GetDirectories() | Measure | Select Count

Count
-----
  189
  ```

<h3 id="searchpattern">SearchPattern</h3>

You can limit your search to specific directories with a search pattern string. This parameter will accept wildcards.

```powershell
PS C:\&gt; $folder.GetDirectories("psworkitem")

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
l----           3/16/2026 12:28 PM                PSWorkItem

PS C:\&gt; $folder.GetDirectories("*work*")

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
l----           3/16/2026 12:28 PM                PSWorkItem
l----           4/10/2026  8:15 PM                putting-powershell-work
l----           10/7/2025  8:40 AM                Workflow

A simple wildcard search is the best you can do to filter results.

SearchOptions

The basic method is to get top-level directories. But another syntax option uses a search option. As you can see in the syntax this is System.IO.SearchOption object. I find it easiest to use my Get-TypeMember command.

PS C:\&gt; Get-TypeMember System.IO.SearchOption

   Type: System.IO.SearchOption

Name             MemberType ResultType             IsStatic IsEnum
----             ---------- ----------             -------- ------
AllDirectories   Field      System.IO.SearchOption     True
TopDirectoryOnly Field      System.IO.SearchOption     True
GetType          Method     Type
HasFlag          Method     Boolean
ToString         Method     String

This looks simple enough. I can explicitly search for top-level directories only.

PS C:\&gt; $folder.GetDirectories("*work*","TopDirectoryOnly")

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
l----           3/16/2026 12:28 PM                PSWorkItem
l----           4/10/2026  8:15 PM                putting-powershell-work
l----           10/7/2025  8:40 AM                Workflow

Or search the entire tree.

PS C:\&gt; $folder.GetDirectories("*work*","AllDirectories") | Select fullname

FullName
--------
C:\Scripts\PSWorkItem
C:\Scripts\putting-powershell-work
C:\Scripts\Workflow
C:\Scripts\Workflow\Workflow Samples - CTP1
C:\Scripts\Workflow\Workflow Samples - Deep Dive
C:\Scripts\GitDevTest\.github\workflows
C:\Scripts\jdhitsolutions\.github\workflows
C:\Scripts\PSGalleryReport\.github\workflows
C:\Scripts\tips\.github\workflows

You will need to supply a search pattern, when using a search option. Make your default the wildcard.

PS C:\&gt; $folder.GetDirectories("*","AllDirectories") | Measure | Select count

Count
-----
 5985

By the way, this took 570ms.

Using Get-ChildItem yields slightly different results in about 580ms.

PS C:\&gt; dir c:\scripts -Directory -Recurse | Measure | select Count

Count
-----
 1313

The GetDirectories() method will also get hidden and system folders. You can control this behavior with the third syntax option.

EnumerationOptions

The last syntax uses an EnumerationOptions object.

PS C:\&gt; Get-TypeMember System.IO.EnumerationOptions

   Type: System.IO.EnumerationOptions

Name                     MemberType ResultType     IsStatic IsEnum
----                     ---------- ----------     -------- ------
GetType                  Method     Type
AttributesToSkip         Property   FileAttributes            True
BufferSize               Property   Int32
IgnoreInaccessible       Property   Boolean
MatchCasing              Property   MatchCasing               True
MatchType                Property   MatchType                 True
MaxRecursionDepth        Property   Int32
RecurseSubdirectories    Property   Boolean
ReturnSpecialDirectories Property   Boolean
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.