8

I am trying to make a powershell script which will count all the .xml files in directories & subdirectories and list the value + path.

So far I have done the this:

Get-ChildItem -Path c:/test -recurse -include *.xml

Which is close to what I want but without the actual files names, just the folder paths and counts.

This is what I am getting:

>     Directory: C:\test\A_Sub-folder
> Mode                LastWriteTime     Length Name
> ----                -------------     ------ ----
> -a---        27/11/2015     11:29          0 AA.xml
> 
>     Directory: C:\test 
> Mode                LastWriteTime     Length Name
> ----                -------------     ------ ----
> -a---        27/11/2015     11:29          0 BB.xml
> -a---        27/11/2015     11:29          0 CC.xml
> -a---        27/11/2015     11:29          0 DD.xml

And I'm trying to get this ( or similar):

 >  Directory: C:\test\A_Sub-folder
 > 1
 >  Directory: C:\test 
 > 3

The plan is to run this script on each root drive (some drives have around 5k .xml files, so I am not sure how this will affect performance.)

Edit:

This works perfectly for subfolders but for some reason it doesn't work under root drive directories (eg. e:/). I'm trying to exclude \windows and \program files but it doesn't work. Is there any way of excluding root directories in the search?

Script so far:

$excludedPaths = @("E:\Windows", "E\Program Files", "E:\Program Files (x86)", "E:\MSSQL", "E:\MSSQL11.MSSQLSERVER");
$pathtocount = Read-Host -Prompt 'Input path to count xml files'
Get-ChildItem -Path $pathtocount -recurse -include *.xml | Where-Object { $excludedPaths -notcontains $_.Directory } | Group-Object -Property Directory | Sort-Object count
daelas
  • 183
  • 1
  • 1
  • 6

1 Answers1

15
Get-ChildItem -Path c:/test -recurse -filter *.xml | Group-Object -Property Directory

And to get a nicer table, you could add -NoElement to Group-Object.

To exclude some directories, try:

$excludedPaths = @("Windows", "Program Files", "Program Files (x86)");
$searchPaths = Get-ChildItem -Path C:\ -Directory | Where-Object { $excludedPaths -notcontains $_.name }
Get-ChildItem -Path $searchPaths -recurse -filter *.xml | Group-Object -Property Directory

Update: According to Get-ChildItem documentation, -filter is more efficient than -include when you only filter for one pattern. (If you filter for more patterns, -filter doesn't work and you have to use -include)

For excluding whole subtrees:

  • -exclude doesn't work, because it is applied to each file, it doesn't prune the whole tree, and it seems the filter is only matched to the filename, not the directory
  • your Where-Object doesn't work because $_.Directory returns nothing (not sure why, I haven't found any documentation)
  • Even if looking at another property ($_.FullName seems to do what you intend), this would only remove the directory itself, not paths starting with the directory. You would need to do a string-prefix-match (using -imatch or -ilike) against each string in the filter-set
Joey
  • 344,408
  • 85
  • 689
  • 683
Rolf Rander
  • 3,221
  • 20
  • 21
  • Yours was better than mine. :) – Nate Dec 04 '15 at 16:12
  • 1
    @Nate Don't be discouraged, you made a good effort in your answer, it just wasn't quite right. Keep trying, it's good to see newer people posting answers! :) Plus, it's amazing how much you can learn just figuring out other people's issues. Sometimes it leads to great new perspectives on problems and helps solve issues you come across on your own. – TheMadTechnician Dec 04 '15 at 16:15
  • Brilliant! Exactly what I wanted! Cheers guys :) – daelas Dec 04 '15 at 16:27
  • @TheMadTechnician Psh, I ain't scrrd. :P – Nate Dec 04 '15 at 16:45
  • @Rolf Rander This works perfectly for subfolders but for some reason it doesn't work under root drive directories (eg. e:/). Is it a powershell bug? See OP. – daelas Dec 09 '15 at 12:03
  • What doesn't work? Don't you get any results, or is it the filtering of certain directories? – Rolf Rander Dec 09 '15 at 12:21
  • I do get results, but with the excluded directories specified in $excludedPaths (windows, program files, etc.). This is when I run this under e:\ or c:\ drive. If I run this in c:\test it does excludes the specified directories. – daelas Dec 09 '15 at 14:08
  • Of course; running a recursive search for files under c:\test won't find any files in c:\windows. I believe your results is because of your trouble filtering results and not a specific feature of running the script from root. – Rolf Rander Dec 09 '15 at 14:10
  • I'm running the recursive search under 'c:\' excluding 'c:\windows' directory but I still get 'c:\windows' in my results. – daelas Dec 09 '15 at 14:15
  • 1
    As I have outlined in the update to my answer, filtering (pruning) subtrees from Get-ChildItem turns out to be quite complicated, it doesn't work how one would think it does, and it doesn't give you any speedup (all subdirectories are searched anyway). I think specifying which directories you want to search is easier than specifying which to exclude. – Rolf Rander Dec 09 '15 at 14:18
  • what about not to include sub-directories in counting? – rickyProgrammer Feb 28 '19 at 06:12
  • @rickyProgrammer you want to count the number of xml-files in a directory without recursing? – Rolf Rander Feb 28 '19 at 06:57
  • i want to count the number of xml files without counting xml files inside sub directories – rickyProgrammer Feb 28 '19 at 07:10
  • @rickyProgrammer just remove the "recurse"-flag – Rolf Rander Feb 28 '19 at 07:11
  • i did, and just make -File -include *.txt but the result is 0 count. – rickyProgrammer Feb 28 '19 at 07:18
  • please see this and give advice. https://stackoverflow.com/questions/54916917/powershell-script-to-count-txt-files-only-in-a-directory – rickyProgrammer Feb 28 '19 at 07:23