How can I exclude multiple folders using Get-ChildItem -exclude? How can I exclude multiple folders using Get-ChildItem -exclude? powershell powershell

How can I exclude multiple folders using Get-ChildItem -exclude?


My KISS approach to skip some folders is chaining Get-ChildItem calls. This excludes root level folders but not deeper level folders if that is what you want.

Get-ChildItem -Exclude folder1,folder2 | Get-ChildItem -Recurse | ...
  • Start excluding folders you don't want
  • Then do the recursive search with non desired folders excluded.

What I like from this approach is that it is simple and easy to remember. If you don't want to mix folders and files in the first search a filter would be needed.


I'd do it like this:

Get-ChildItem -Path $folder -r  | ? { $_.PsIsContainer -and $_.FullName -notmatch 'archive' }

Note that -notmatch accepts a Regular Expression:

https://docs.microsoft.com/powershell/module/microsoft.powershell.core/where-object#parameters


I apologize if this answer seems like duplication of previous answers. I just wanted to show an updated (tested through POSH 5.0) way of solving this. The previous answers were pre-3.0 and not as efficient as modern solutions.

The documentation isn't clear on this, but Get-ChildItem -Recurse -Exclude only matches exclusion on the leaf (Split-Path $_.FullName -Leaf), not the parent path (Split-Path $_.FullName -Parent). Matching the exclusion will just remove the item with the matching leaf; Get-ChildItem will still recurse into that leaf.

In POSH 1.0 or 2.0

Get-ChildItem -Path $folder -Recurse  |           ? { $_.PsIsContainer -and $_.FullName -inotmatch 'archive' }

Note: Same answer as @CB.

In POSH 3.0+

Get-ChildItem -Path $folder -Directory -Recurse  |           ? { $_.FullName -inotmatch 'archive' }

Note: Updated answer from @CB.

Multiple Excludes

This specifically targets directories while excluding leafs with the Exclude parameter, and parents with the ilike (case-insensitive like) comparison:

#Requires -Version 3.0[string[]]$Paths = @('C:\Temp', 'D:\Temp')[string[]]$Excludes = @('*archive*', '*Archive*', '*ARCHIVE*', '*archival*')$files = Get-ChildItem $Paths -Directory -Recurse -Exclude $Excludes | %{     $allowed = $true    foreach ($exclude in $Excludes) {         if ((Split-Path $_.FullName -Parent) -ilike $exclude) {             $allowed = $false            break        }    }    if ($allowed) {        $_    }}

Note: If you want your $Excludes to be case-sensitive, there are two steps:

  1. Remove the Exclude parameter from Get-ChildItem.
  2. Change the first if condition to:
    • if ($_.FullName -clike $exclude) {

Note: This code has redundancy that I would never implement in production. You should simplify this quite a bit to fit your exact needs. It serves well as a verbose example.