Thursday, December 1, 2011

PowerShell - count folders in folders

Counting the number of files in a directory is easy
(dir).Count
Here's a more complex example that I will break down, like a tutorial. Unlike the previous example, this is taking advantage of the object oriented nature of PowerShell. You should understand about_pipelines before you continue reading

The problem
An invoice scanning system uploads files to a file server. The directory structure is the following.
\\server\files\<country_code-invoices>\<date>\<invoice_id></invoice_id></date></country_code-invoices>

Here's an German invoice folder scanned on December 1st 2011
\\server\files\DE-invoices\2011-12-01\2ad52000-32d5-4d72-925a-98ac442d2381

The question is : "How many invoices have been created every day by country ?" . The output has to be a table to be analyzed with Excel.

The proposed solution

Get all the country folders
dir \\server\files\*-invoices
For each (% is the operator) country folder ($_ is the pipeline object), display only its name
dir \\server\files\*-invoices | %{$_.Name}
#
Display the date folders for each country
dir \\server\files\*-invoices | %{dir $_}
#
We'll store the country name in $country, to use it later as we bring it up the pipeline.
dir \\server\files\*-invoices | %{$country=$_.Name}
#


Now it's getting a bit tricky.We'll put a pipeline inside a pipeline!
Because we need to process each date folder in each country folder.

  • For Each country folder display its name
  • For Each date folder in a country folder display its name
  • For Each date folder, count the number of folders it contains

Display the country name and the date folder

dir \\server\files\*-invoices | %{$country=$_.Name;dir $_ |%{Write-Host $country $_.Name}}
#
outputs
DE-invoices 2011-12-01
DE-invoices 2011-11-30
etc..

Display the folder count
dir \\server\files\*-invoices | %{$country=$_.Name;dir $_ |%{Write-Host $country $_.Name (dir $_).count}}
#


outputs

DE-invoices 2011-12-01 5
DE-invoices 2011-11-30 18
etc..

The result can now be imported as CSV file ,using the space character as the separator.