obs0lete
obs0lete

Reputation: 179

Count the numbers of subfolders and .exe files inside those subfolders

Sorry for the long post, trying to be as detailed as I can.

My folder structure looks like this:

C:\1\2\3\4\5\6\file.exe

What I am trying to accomplish is to count the number of folders that exist in folder 6, then group them by the time they were created. I am also trying to count the number of instances that file.exe exists in those folders.

So for example, folder C:\1\2\3\4\5 contains the following sub-folders which were created at the time shown below::

a 12:00 AM
b 12:00 AM
c 1:00 AM
d 1:00 AM
e 2:00 AM
...

Of those folders, a and b contain file.exe.

What my expected output then should be is:

Time     Count Hit
----     ----- ---
12:00 AM     2   2
1:00 AM      2   0
2:00 AM      1   0

Time represents the time of the folders, Count is the number of folders created at that time and Hit is the number of instances of file.exe in the C:\1\2\3\4\5\6\ path of the folders created at that time.

So for another example, at 12:00 AM, there were 2folders created and inside of those two folders there are subfolders containing 2 instances of file.exe. Make sense?

I am having a problem with counting the instances of file.exe. When I run my script, it does group the folders, and gives me the time created and the number at that time but it does not give me the count of the instances of file.exe and I'm not sure what I'm doing wrong. This is the code I am using:

Get-ChildItem "C:\1\2\3\4\5" | `
        Sort-Object -Property LastWriteTime | `
        Select-Object @{Name = "Date"; Expression = { $_.LastWriteTime.ToString('h:mm tt') }}, `
        @{Name = "Hit"; Expression = { (Get-ChildItem "C:\1\2\3\4\5" -Recurse -Filter "*.png").Count}} | `
        Group-Object Date | Select-Object @{Name = "Time"; Expression = { $_.Name }} , Count, Hit

What I get is

Time     Count Hit
----     ----- ---
12:00 AM     2   
1:00 AM      2   
2:00 AM      1   

Any ideas? If you need more clarification, please let me know!

Upvotes: 1

Views: 238

Answers (1)

zett42
zett42

Reputation: 27756

Group-Object outputs objects with members Name, Count and Group only. To access the properties from the output of the cmdlet piped into Group-Object (except the property specified as argument for Group-Object), you need to access the Group property, which is an array of all grouped objects. So you need another calculated property for Hit.

Try this:

Get-ChildItem "C:\1\2\3\4\5" -Directory |
    Sort-Object -Property LastWriteTime |
    Select-Object @{Name = "Date"; Expression = { $_.LastWriteTime.ToString('h:mm tt') }},
                  @{Name = "Hit"; Expression = { ($_ | Get-ChildItem -Recurse -File -Filter "*.png").Count}} |
    Group-Object Date | 
    Select-Object @{Name = "Time"; Expression = { $_.Name }}, Count, 
                  @{Name = "Hit"; Expression = { ($_.Group | Measure-Object -Property Hit -sum).sum }}

The expression calculates the sum of the hit property of all elements of the Group array.

Another issue was that you are using the same path for both Get-ChildItem calls, so you are actually searching for *.png multiple times using the same path. Of course this results in incorrect counts. I've fixed that by specifying $_ as the path, which is the folder found by the first Get-ChildItem.

Also I've added -Directory to the top-level Get-ChildItem and -File to the nested Get-ChildItem. Propably won't make a difference in the result, but I think it makes the code clearer. It better expresses the intentions.

Upvotes: 1

Related Questions