Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Objects are the answer

Posted on July 1, 2010July 1, 2010

As I usually do, I was helping out in the forums at ScriptingAnswers.com. A member had several variables that he wanted to show as a group. As is almost always the case, the answer in PowerShell is object. I talk about this all the time in classes, conferences and online chitchat. Let me offer up a script that demonstrates how objects are the answer.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

My business need was to report on files found in a given folder or path. I wanted to get a breakdown of file types showing me the number of each type, their total size and their percentage of all files by count and size.

#requires -version 2.0            

Param([string]$path="$env:userprofile\documents")            

if (Test-Path -path $path) {
    write-host "Collecting file information for $path" `
   -ForegroundColor Green            

    $files=dir  $path -recurse -errorAction "SilentlyContinue" |
     where {-not $_.PSIsContainer}
    $stats=$files | Measure-Object -Property Length -sum
    $grouped=$files | group -property Extension            

    foreach ($group in $grouped) {
        #measure the total size of each file type
        $measure=$group.group | measure-object -Property length -sum            

        #calculate % of total size
        $perSize="{0:P4}" -f ($measure.sum/$stats.sum)            

        #calculate % of total number
        $perTotal="{0:P4}" -f ($measure.count/$stats.count)            

        #write a custom object to the pipeline
        new-object psobject -Property @{
            Extension=$group.name
            Total=$group.count
            TotalSizeMB=[Math]::Round($measure.sum/1mb,2)
            PercentTotal=$perTotal
            PercentSize=$perSize
            Files=$group.group
        }
    } #foreach
} #if test-path
else {
    Write-Warning "Failed to find $path"
}

The script takes a path as a parameter but defaults to your documents folder. Get-Childitem retrieves all files. I’m setting the –errorAction parameter to silentlycontinue to avoid the annoying error messages you get when trying to read protected system folders. The collection of files are then grouped by extension. Each group is then analyzed.

At this point I have a number of pieces of information to display. In a VBScript I would have most like written some message to the screen for each file type. Technically I could do the same thing here but why? Using New-Object I create a new object with properties for all my data. The objects written to the pipeline can be manipulated just like any other object. Let me check my C: drive.

PS C:\> $c=c:\scripts\filestats.ps1 “c:\”

Hmmm…how many different file types are on my computer?

PS C:\> $c.count
1897

Which file types are taking the most space?

PS C:\> $c | sort totalsizeMB -desc | select -first 10 -property * -ExcludeProperty Files | format-table -auto

TotalSizeMB PercentTotal Total Extension PercentSize

----------- ------------ ----- --------- -----------

115692.94 0.0637 %        90 .vmdk     57.8050 %

19559.24 0.0219 %        31 .iso      9.7726 %
14375.12 0.0014 %         2 .vdi      7.1824 %

12440.64 14.8798 %    21018 .dll      6.2159 %
6972.15 2.4778 %      3500 .exe      3.4836 %
6190.48 0.0064 %         9 .wim      3.0930 %

2884.98 0.1373 %       194 .CAB      1.4415 %

2672.56 0.0021 %         3 .m4v      1.3353 %

1424.91 0.0042 %         6 .sav      0.7119 %
1202.12 0.0092 %        13 .mp4      0.6006 %

My custom object even includes a property, files, which itself is a collection of objects. For example, what are the .vdi files?

PS C:\> $c | where {$_.extension -eq ".vdi"} | select -ExpandProperty Files

Directory: C:\VirtualBox\Exchange

Mode                LastWriteTime     Length Name
----                    -------------     ------ ----
-a---         6/29/2010   1:58 PM 1507336243 ExchangeHDD.vdi

Directory: C:\VirtualBox\R2

Mode                LastWriteTime     Length Name
----                    -------------     ------ ----
-a---         6/21/2010   9:34 PM      41472 ExchangeStore.vdi

The bottom line is that having objects offers tremendous possibilities. So the next time you’re working on a PowerShell problem, know that objects are the answer.

My script was intended as a demonstration but if you’d like a copy


Behind the PowerShell Pipeline
download it here.

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d