I need to generate a configuration file for our Pro/Engineer CAD system. I need a recursive list of the folders from a particular drive on our server. However I need to EXCL
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 | ...
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.
may be in your case you could reach this with the following:
mv excluded_dir ..\
ls -R
mv ..\excluded_dir .
I know this is quite old - but searching for an easy solution, I stumbled over this thread... If I got the question right, you were looking for a way to list more than one directory using Get-ChildItem. There seems to be a much easier way using powershell 5.0 - example
Get-ChildItem -Path D:\ -Directory -Name -Exclude tmp,music
chaos
docs
downloads
games
pics
videos
Without the -Exclude clause, tmp and music would still be in that list. If you don't use -Name the -Exclude clause won't work, because of the detailed output of Get-ChildItem. Hope this helps some people that are looking for an easy way to list all directory names without certain ones.
The simplest short form to me is something like:
#find web forms in my project except in compilation directories
(gci -recurse -path *.aspx,*.ascx).fullname -inotmatch '\\obj\\|\\bin\\'
And if you need more complex logic then use a filter:
filter Filter-DirectoryBySomeLogic{
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
$fsObject,
[switch]$exclude
)
if($fsObject -is [System.IO.DirectoryInfo])
{
$additional_logic = $true ### replace additional logic here
if($additional_logic){
if(!$exclude){ return $fsObject }
}
elseif($exclude){ return $fsObject }
}
}
gci -Directory -Recurse | Filter-DirectoryBySomeLogic | ....
The exclusion pattern should be case-insensitive, so you shouldn't have to specify every case for the exclusion.
That said, the -Exclude
parameter accepts an array of strings, so as long as you define $archive
as such, you should be set.
$archive = ("*archive*","*Archive*","*ARCHIVE*");
You also should drop the trailing asterisk from $folder
- since you're specifying -recurse
, you should only need to give the top-level folder.
$folder = "T:\Drawings\Design\"
Fully revised script. This also changes how you detect whether you've found a directory, and skips the Foreach-Object
because you can just pull the property directly & dump it all to the file.
$folder = "T:\Drawings\Design\";
$raw_txt = "T:\Design Projects\Design_Admin\PowerShell\raw.txt";
$search_pro = "T:\Design Projects\Design_Admin\PowerShell\search.pro";
$archive = ("*archive*","*Archive*","*ARCHIVE*");
Get-ChildItem -Path $folder -Exclude $archive -Recurse | where {$_.PSIsContainer} | select-Object -expandproperty FullName |out-file $search_pro
#For brevity, I didn't define a function.
#Place the directories you want to exclude in this array.
#Case insensitive and exact match. So 'archive' and
#'ArcHive' will match but 'BuildArchive' will not.
$noDirs = @('archive')
#Build a regex using array of excludes
$excRgx = '^{0}$' -f ($noDirs -join ('$|^'))
#Rather than use the gci -Recurse option, use a more
#performant approach by not processing the match(s) as
#soon as they are located.
$cmd = {
Param([string]$Path)
Get-ChildItem $Path -Directory |
ForEach-Object {
if ($_.Name -inotmatch $excRgx) {
#Recurse back into the scriptblock
Invoke-Command $cmd -ArgumentList $_.FullName;
#If you want all directory info change to return $_
return $_.FullName
}
}
}
#In this example, start with the current directory
$searchPath = .
#Start the Recursion
Invoke-Command $cmd -ArgumentList $searchPath