10

Using PowerShell I can get the directories with the following command:

Get-ChildItem -Path $path -Include "obj" -Recurse | `
    Where-Object { $_.PSIsContainer }

I would prefer to write a function so the command is more readable. For example:

Get-Directories -Path "Projects" -Include "obj" -Recurse

And the following function does exactly that except for handling -Recurse elegantly:

Function Get-Directories([string] $path, [string] $include, [boolean] $recurse)
{
    if ($recurse)
    {
        Get-ChildItem -Path $path -Include $include -Recurse | `
            Where-Object { $_.PSIsContainer }
    }
    else
    {
        Get-ChildItem -Path $path -Include $include | `
            Where-Object { $_.PSIsContainer }
    }
}

How can I remove the if statement from my Get-Directories function or is this a better way to do it?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Tim Murphy
  • 4,822
  • 4
  • 37
  • 47
  • 1
    Consider using -Filter instead of -Include unless you need to includ multiple items. For something like *.txt, -Filter can be significantly faster. Or you could always add both. – Keith Hill Jul 17 '10 at 16:51

3 Answers3

13

Try this:

# nouns should be singular unless results are guaranteed to be plural.
# arguments have been changed to match cmdlet parameter types
Function Get-Directory([string[]]$path, [string[]]$include, [switch]$recurse) 
{ 
    Get-ChildItem -Path $path -Include $include -Recurse:$recurse | `
         Where-Object { $_.PSIsContainer } 
} 

This works because -Recurse:$false is the same has not having -Recurse at all.

x0n
  • 47,695
  • 5
  • 84
  • 110
  • 1
    Thank you for the answer and the extra mile of fixing the function name and parameter declarations. Learnt more than I asked. – Tim Murphy Jul 17 '10 at 05:36
4

In PowerShell 3.0, it is baked in with -File -Directory switches:

dir -Directory #List only directories
dir -File #List only files
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
iraSenthil
  • 10,381
  • 6
  • 36
  • 47
2

The answer Oisin gives is spot on. I just wanted to add that this is skirting close to wanting to be a proxy function. If you have the PowerShell Community Extensions 2.0 installed, you already have this proxy function. You have to enable it (it is disabled by default). Just edit the Pscx.UserPreferences.ps1 file and change this line so it is set to $true as shown below:

GetChildItem = $true # Adds ContainerOnly and LeafOnly parameters 
                     # but doesn't handle dynamic params yet.

Note the limitation regarding dynamic parameters. Now when you import PSCX do it like so:

Import-Module Pscx -Arg [path to Pscx.UserPreferences.ps1]

Now you can do this:

Get-ChildItem . -r Bin -ContainerOnly
Keith Hill
  • 173,872
  • 36
  • 316
  • 347
  • Thanks for the reminder of PowerShell Community Extensions. I could have used it as a reference. As this is part of a build process I'll stick with what I've got because I don't want to add another dependency. – Tim Murphy Jul 18 '10 at 01:39