Search code examples
powershellget-childitem

Get-ChildItem with specific properties, but still grouped by (sub)folder


I have written this bit of PowerShell code to get a listing of files meeting the type criteria shown below:

Get-ChildItem -Path 'C:\Program Files\Common Files' -Recurse -Include *.exe, *.bat, *.com, *.cmd, *.dll

This is part of the result:

Directory: C:\Program Files\Common Files\VMware\Drivers\vmci\sockets\Win8

Mode                 LastWriteTime         Length Name                                                                                                                        
----                 -------------         ------ ----                                                                                                                        
-a----        10/23/2022  12:23 AM          31120 vsocklib_x64.dll                                                                                                            
-a----        10/23/2022  12:23 AM          26512 vsocklib_x86.dll                                                                                                            
-a----        10/23/2022  12:23 AM           2048 vsockver.dll                                                                                                                

    Directory: C:\Program Files\Common Files\VMware\Drivers\vmxnet3\Win8

Mode                 LastWriteTime         Length Name                                                                                                                        
----                 -------------         ------ ----                                                                                                                        
-a----         11/3/2022   7:53 AM           2048 vmxnet3ver.dll                                                                                                              

I like that it breaks the results down by subdirectory. However, I want to specify certain properties to be shown.

When I change the code to this:

Get-ChildItem -Path 'C:\Program Files\Common Files' -Recurse -Include *.exe, *.bat, *.com, *.cmd, *.dll -ErrorAction Ignore |
    Select-Object -Property LastWriteTime, Length, @{N='Owner';E={$_.GetAccessControl().Owner}}, Name

I get the following result:

LastWriteTime            Length Owner                       Name                             
-------------            ------ -----                       ----                             
10/21/2019 11:28:34 PM   464232 NT AUTHORITY\SYSTEM         ac.activclient.gui.diagtoolrc.dll
10/21/2019 11:28:50 PM    31080 NT AUTHORITY\SYSTEM         ac.diag.hidproductsrc.dll        
10/21/2019 11:28:52 PM    33120 NT AUTHORITY\SYSTEM         ac.diag.systemrc.dll             
10/22/2019 6:35:46 PM    133032 NT AUTHORITY\SYSTEM         ac.activclient.gui.diagtool.exe  
10/21/2019 11:28:46 PM   266568 NT AUTHORITY\SYSTEM         ac.cext.dll                      
10/21/2019 11:28:50 PM    76648 NT AUTHORITY\SYSTEM         ac.diag.hidproducts.dll          
10/21/2019 11:28:50 PM   104792 NT AUTHORITY\SYSTEM         ac.diag.system.dll               
10/21/2019 11:29:36 PM   177512 NT AUTHORITY\SYSTEM         ac.winext.settingsapi.dll        
10/21/2019 11:29:44 PM   236880 NT AUTHORITY\SYSTEM         aclogu64.dll                     
10/21/2019 11:29:50 PM   215376 NT AUTHORITY\SYSTEM         aiwinextu.dll                    
1/8/2022 4:04:34 AM      367616 NT SERVICE\TrustedInstaller InkDiv.dll                       
1/8/2022 4:04:34 AM     1979392 NT SERVICE\TrustedInstaller InkObj.dll                       
1/8/2022 4:05:17 AM      383488 NT SERVICE\TrustedInstaller InputPersonalization.exe         
1/8/2022 4:05:17 AM       43520 NT SERVICE\TrustedInstaller IpsMigrationPlugin.dll

The directory info is gone! How can I specify desired properties of the files I retrieve, but keep them separated by subdir, instead of all bunched up together in one list?


Solution

  • You're looking for grouping for display purposes, which Format-Table can provide via the -GroupBy parameter:

    # -GroupBy DirectoryName groups the display output by shared
    # .DirectoryName values
    Get-ChildItem -Path 'C:\Program Files\Common Files' -Recurse -Include *.exe, *.bat, *.com, *.cmd, *.dll -ErrorAction Ignore |
      Format-Table -GroupBy DirectoryName -Property LastWriteTime, Length, @{N='Owner';E={$_.GetAccessControl().Owner}}, Name
    

    Note that - unlike when you use Select-Object - the output is only usable for display.