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

Getting Git Size with PowerShell Retooled

Posted on January 30, 2019January 31, 2019

A few days ago I wrote about my experiences in designing a PowerShell function that reports on the size of the hidden .git folder. In that version of the function I decided to include a parameter that would permit the user to get the size pre-formatted as either KB, MB or GB. I thought long and hard about it as this really is not the best design pattern.  Still, I'm not the only one who likes the ability to get values formatted into a more user-friendly form. So let me show you a revision that I think better adheres to PowerShell scripting best practices, yet also provides the flexibility of data formatting.

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!

Extending a PowerShell Object

One of the things I appreciate about PowerShell is how easy it is to extend or modify an object type. This is because PowerShell has an extensible type system. Using the Update-TypeData cmdlet, it is very easy to add new properties to an object type. That is the approach I decided to take. I decided to keep my "base" object very simple and show the directory size in bytes. This means I removed all the code around the -As parameter.

#get the total size of all files in the .git folder
$stat = Get-Childitem -path $git -Recurse -File | Measure-Object -Property length -sum

#create the output
$obj = [PSCustomObject]@{
    Path  = $full
    Files = $stat.count
    Size  = $stat.sum
} #customobject

In order to extend a type you need to know the typename. When creating a PSCustomobject as I'm doing here, this will require a few extra steps to define an additional typename for the custom object. This is typically done with code like this:

#insert a new typename
$obj.psobject.typenames.insert(0, "gitSize")
#write object to the pipeline
$obj

Update

Thanks to a comment from Chris Warwick, there is an even better way to insert a type name that was introduced in PowerShell at some point and I missed it. Define a property called PSTypeName in the object itself.

$obj = [PSCustomObject]@{
    PSTypeName = "gitSize"
    Path       = $full
    Files      = $stat.count
    Size       = $stat.sum
} #customobject

It won't show in the object's output but it will be used for the typename. You can verify it by piping the object to Get-Member.

I could also have created a PowerShell class which would have baked in the typename from the beginning. But that is a bit more complicated than I what to get into here. Now for the fun stuff.

Exploiting Update-TypeData

My function will now write an object to the pipeline with a typename of gitSize. I decided that all of the other properties I might want to see were completely optional. To accomplish this I am going to use the Update-TypeData command  outside of the function. Since I would need to dot source the script file with the function anyway, I added these lines after the function definition.

Update-TypeData -TypeName gitSize -MemberType ScriptProperty -MemberName SizeKB -Value {$this.size / 1kb} -force
Update-TypeData -TypeName gitSize -MemberType ScriptProperty -MemberName SizeMB -Value {$this.size / 1mb} -force
Update-TypeData -TypeName gitSize -MemberType ScriptProperty -MemberName SizeGB -Value {$this.size / 1gb} -force
Update-TypeData -TypeName gitSize -MemberType NoteProperty -MemberName Computername -Value $env:COMPUTERNAME -force
Update-TypeData -TypeName gitSize -MemberType ScriptProperty -MemberName Date -Value {Get-Date} -force
Update-TypeData -TypeName gitSize -MemberType ScriptProperty -MemberName Name -Value {Split-Path -path $this.path -leaf} -force

I also added a few other properties I had been thinking about like Computername and Date. Yes, I could have defined many of these as part of the custom object in which case I would have used code like this:

$obj = [PSCustomObject]@{
    Path  = $full
    Files = $stat.count
    Size  = $stat.sum
    SizeKB = $stat.sum/1kb
    Computername = $env:computername
} #customobject

Regardless, I knew that by default I only wanted to see the path, number of files and size in bytes.  As things currently stand, when I run my function I'll get an object that displays everything. The solution is to use Update-TypeData and define a default set of properties.

#set default properties
Update-TypeData -TypeName gitSize -DefaultDisplayPropertySet "Path", "Files", "Size" -Force

When I run the function, which will write a gitSize object to the pipeline, I'll get the defaults.

Revised Get-GitSize with defined default properties

But all of the properties are there if I want them.

Viewing extended object properties

The Extended Function

I've left the original function up on Github. This version can be found here.

As before, you will need to save the file locally and dot source it into your PowerShell session. Now, I have some flexibility. I can either get the default output as I showed earlier or I can run code like this to utilize the additional properties.

Getting git size with PowerShell and additional properties Using a PowerShell Format File

Another approach I thought about, but didn't pursue, would be the use of a format.ps1xml file. This too would require me to define a typename. With this approach I would have had to create a specially formatted xml file that define table or list (usually these two) views. The views could include code to dynamically display data formatted as KB or MB. This is the type of thing done with process objects that you see when you run Get-Process. When you run Get-Process alone, PowerShell uses a defined table view for process objects that formats values. But it doesn't change the underlying object. Creating the xml file can be a bit tedious and I didn't want to go down that rabbit hole today. There certainly may be situations where you want to take advantage of both type and format extensions and hopefully we can revisit this topic in a future article.

PowerShell Scripting is a Process

In the mean time, take a look at the code. Consider the design process I went through. I write these articles as much for teaching you concepts and techniques as I do showing you a finished product. Although if you find it helpful, that's a bonus. Embrace and enjoy.


Behind the PowerShell Pipeline

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

4 thoughts on “Getting Git Size with PowerShell Retooled”

  1. Blanke says:
    January 30, 2019 at 11:32 am

    Nice solution. Thank you.

  2. Chris Warwick says:
    January 31, 2019 at 5:22 am

    Hi Jeff,

    You can just add a ‘PsTypeName’ property to your [PsCustomObject] rather than using $obj.psobject.typenames.insert(0, “gitSize”)

    So:

    $obj = [PSCustomObject]@{
    PsTypeName = ‘gitSize’
    Path = $full
    Files = $stat.count
    Size = $stat.sum
    SizeKB = $stat.sum/1kb
    Computername = $env:computername
    } #customobject

    Cheers,
    Chris

    1. Jeffery Hicks says:
      January 31, 2019 at 9:20 am

      Well that is much easier! This is one of those things that snuck in some earlier version that I missed while I kept using my “old-school” ways. Thanks for the tip.

  3. Pingback: Creating More Git PowerShell Tools • The Lonely Administrator

Comments are closed.

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