Recursively count files in subfolders Recursively count files in subfolders powershell powershell

Recursively count files in subfolders


Something like this should work:

dir -recurse |  ?{ $_.PSIsContainer } | %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }
  • dir -recurse lists all files under current directory and pipes (|) the result to
  • ?{ $_.PSIsContainer } which filters directories only then pipes again the resulting list to
  • %{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count } which is a foreach loop that, for each member of the list ($_) displays the full name and the result of the following expression
  • (dir $_.FullName | Measure-Object).Count which provides a list of files under the $_.FullName path and counts members through Measure-Object

  • ?{ ... } is an alias for Where-Object

  • %{ ... } is an alias for foreach


Similar to David's solution this will work in Powershell v3.0 and does not uses aliases in case someone is not familiar with them

Get-ChildItem -Directory | ForEach-Object { Write-Host $_.FullName $(Get-ChildItem $_ | Measure-Object).Count}

Answer Supplement

Based on a comment about keeping with your function and loop structure i provide the following. Note: I do not condone this solution as it is ugly and the built in cmdlets handle this very well. However I like to help so here is an update of your script.

Function DirX($directory){    $output = @{}    foreach ($singleDirectory in (Get-ChildItem $directory -Recurse -Directory))    {        $count = 0         foreach($singleFile in Get-ChildItem $singleDirectory.FullName)        {            $count++        }        $output.Add($singleDirectory.FullName,$count)    }    $output | Out-String}

For each $singleDirectory count all files using $count ( which gets reset before the next sub loop ) and output each finding to a hash table. At the end output the hashtable as a string. In your question you looked like you wanted an object output instead of straight text.


Well, the way you are doing it the entire Get-ChildItem cmdlet needs to complete before the foreach loop can begin iterating. Are you sure you're waiting long enough? If you run that against very large directories (like C:) it is going to take a pretty long time.

Edit: saw you asked earlier for a way to make your function do what you are asking, here you go.

Function DirX($directory){    foreach ($file in Get-ChildItem $directory -Recurse -Directory )    {        [pscustomobject] @{        'Directory' = $File.FullName        'Count' = (GCI $File.FullName -Recurse).Count        }    }}DirX D:\

The foreach loop only get's directories since that is all we care about, then inside of the loop a custom object is created for each iteration with the full path of the folder and the count of the items inside of the folder.

Also, please note that this will only work in PowerShell 3.0 or newer, since the -directory parameter did not exist in 2.0