Creating a GitHub Repository Tool - Part 4
I've come a long way with the project and the end is in sight. Hopefully, we can wrap up building my GitHub repository tool today. At this point, I have a PowerShell class-based tool with several functions for working with the GitHub repository data. I have a rich object.
PS C:\> $in[10]
Name : PSReleaseTools
Description : 🚢 A set of commands for working with PowerShell 7.x releases.
LastUpdate : 8/29/2024 9:07:55 AM
Visibility : Public
DefaultBranch : master
LatestReleaseName : PSReleaseTools_v1.12.0
LatestReleaseDate : 6/4/2022 10:08:49 AM
LastPush : 8/4/2024 4:57:03 PM
StargazerCount : 112
WatcherCount : 11
URL : https://github.com/jdhitsolutions/PSReleaseTools
DiskUsage : 3175
ID : MDEwOlJlcG9zaXRvcnk3ODA1NTc4NA==
InfoDate : 10/10/2024 3:21:25 PM
UpdateAge : 43.05:12:53.9554832
isReleased : True
ReleaseAge : 860.04:11:59.9556128
IsEmpty : False
Since last time, I've extended this object even further.
More Type Extensions
One thing I had to do was revised the type extension that defined the ReleaseAge
property. If the repository didn't have a release, the previous code was throwing an error. I revised the definition to check for a null value using the PowerShell 7 ternary operator.
Update-TypeData -TypeName GitHubRepoInfo -MemberType ScriptProperty -MemberName ReleaseAge -Value {
($Null -eq $this.LatestReleaseName) ? $null : (Get-Date) - $this.LatestReleaseDate
} -force
I also realized that I could make the object even easier to use. I might want to run a command like this:
$in | where {$_.Visibility -eq 'public' -AND $_.IsReleased} | Sort-Object ReleaseAge | Select-Object ReleaseAge,name,LatestReleaseName,description -first 5
I can simplify this by adding custom boolean properties indicating if the repository is public or private.
Update-TypeData -TypeName GitHubRepoInfo -MemberType ScriptProperty -MemberName IsPublic -Value { $this.Visibility -eq 'Public' } -Force
Update-TypeData -TypeName GitHubRepoInfo -MemberType ScriptProperty -MemberName IsPrivate -Value { $this.Visibility -eq 'Private' } -Force
With this, I can reduce the amount of typing.
$in | where {$_.IsPublic -AND $_.IsReleased} | Sort-Object ReleaseAge | Select-Object ReleaseAge,name,LatestReleaseName,description -first 5
When creating tools, and especially custom objects, find ways to reduce the friction in using them. Another good example is the use of alias
properties. I have a few properties that are good candidates. Here's an example:
$in | where IsPublic | Sort StargazerCount -Descending | Select-Object Name,StarGazerCount,WatcherCount -first 5
Yes, I know I could use wildcards. But an alias feels a little cleaner.
Update-TypeData -TypeName GitHubRepoInfo -MemberType AliasProperty -MemberName Stars -Value StargazerCount -Force
Update-TypeData -TypeName GitHubRepoInfo -MemberType AliasProperty -MemberName Watchers -Value WatcherCount -Force
Compare the difference.
$in | where IsPublic | Sort Stars -Descending | Select-Object Name,Stars,Watchers -first 5
Even better, the output uses the aliases.

Property Sets
At this point, here's what the object looks like.

Thinking again about ease of use, are there situations where the user might want to specify a subset of properties on a regular basis? I'm thinking the following is a core set of properties that I want to use repeatedly.
$in | Select LastUpdate,Name,Visibility,URL,Description -first 5 | Format-Table -Wrap
But I'm lazy. I don't want to have to remember to type these properties every time. Instead, I can create a property set.
If I don't plan on using custom formatting, I can define a default property set.
Update-TypeData -Typename GitHubRepoInfo -DefaultDisplayPropertySet LastUpdate,Name,Visibility,URL,Description -Force
This gives me a type of default formatting.
PS C:\> $in[0]
LastUpdate : 10/10/2024 1:52:05 PM
Name : PSGalleryReport
Visibility : Public
URL : https://github.com/jdhitsolutions/PSGalleryReport
Description : A set of reports in PDF and Markdown format about recently published and popular modules in the PowerShell Gallery. The reports are generated by a
GitHub Action. This is NOT a PowerShell module.
But I plan on defining custom formatting, and there are other groups of properties I think I want to bundle together to save typing.
$in | Select Name,LatestReleaseName,LatestReleaseDate,ReleaseAge,Url
$in | Select Name,Stars,Watchers,Url,Description
To define these as property sets, I need to use an XML file. This can't be done with Update-TypeData
. But let me make this easy for you. Install the PSTypeExtensionTools module from the PowerShell Gallery. I wrote a command called New-PSPropertySet that will create the XML file for you.
New-PSPropertySet -Typename GitHubRepoInfo -Name ReleaseInfo -Properties Name,LatestReleaseName,LatestReleaseDate,ReleaseAge,Url -FilePath .\GitHubRepoInfo.types.ps1xml