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:
- Remove the
Exclude
parameter from Get-ChildItem
.
- 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.