This PowerShell module contains commands that make it easier to work with type extensions. Many of these commands are wrappers for built-in tools like Get-TypeData or Update-TypeData. This module should work in Windows PowerShell 5.1 and PowerShell 7.x. Although some of the sample type extensions require a Windows platform.
Installation
You can install the current release from the PowerShell Gallery:
Install-PSResource PSTypeExtensionToolsThe module contains these commands.
| Name | Alias | Synopsis |
|---|---|---|
| Add-PSTypeExtension | Set-PSTypeExtension,atex | Add a new type extension. |
| Export-PSTypeExtension | etex | Export type extensions to a file. |
| Get-PSType | Get the type name for a given object. | |
| Get-PSTypeDataPreview | Preview the type extension settings in a ps1xml file. | |
| Get-PSTypeExtension | gtex | Get selected type extensions. |
| Import-PSTypeExtension | itex | Import type extension definitions. |
| New-PSPropertySet | Create a new property set ps1xml file. |
Why You Want to Use This Module
Let's say you want to update a number object, but you have no idea what the type name is. Once you have read help for the commands in this module, you could run a PowerShell command like this:
123 | Get-PSType | Add-PSTypeExtension -MemberType ScriptProperty -MemberName SquareRoot -Value {[math]::Sqrt($this)}
Use $this to reference the object instead of $_. Now you can get the new property.
PS C:\> $x = 123 PS C:\> $x.SquareRoot 11.0905365064094
Once you know the type name, you can add other type extensions.
Add-PSTypeExtension -TypeName system.int32 -MemberType ScriptProperty -MemberName Squared -value {$this*$this} Add-PSTypeExtension -TypeName system.int32 -MemberType ScriptProperty -MemberName Cubed -value {[math]::Pow($this,3)} Add-PSTypeExtension -TypeName system.int32 -MemberType ScriptProperty -MemberName Value -value {$this} Add-PSTypeExtension -TypeName system.int32 -MemberType ScriptMethod -MemberName GetPercent -value {Param([int32]$Total,[int32]$Round=2) [math]::Round(($this/$total)*100,$round)}
Here's how it might look:
PS C:\> $x = 38 PS C:\> $x | select * SquareRoot Squared Cubed Value ---------- ------- ----- ----- 6.16441400296898 1444 54872 38 PS C:\> $x.GetPercent(50) 76 PS C:\> $x.GetPercent(100) 38 PS C:\> $x.GetPercent(110,4) 34.5455
Go GUI
As an alternative to the command-line, you can use the native Show-Command cmdlet to display a graphical interface.
Show-Command Add-PSTypeExtension
Clicking Run will insert this code at your prompt.
Add-PSTypeExtension -MemberName ToTitleCase -MemberType ScriptMethod -TypeName System.String -Value { (Get-Culture).TextInfo.ToTitleCase($this.ToLower())}
If you like this extension, you can export it and re-import it later.
Get Type Extensions
To see current type extensions, you can use Get-PSTypeExtension. You can choose to see all extensions or selected ones by member name. CodeProperty extensions are hidden by default.
PS C:\> Get-PSTypeExtension system.int32 TypeName: System.Int32 Name Type Value ---- ---- ----- SquareRoot ScriptProperty [math]::Sqrt($this) Squared ScriptProperty $this*$this Cubed ScriptProperty [math]::Pow($this,3) Value ScriptProperty $this GetPercent ScriptMethod Param([int32]$Total,[int32]$Round=2) [math]::Round(($this/$total)*100,$round)
If you always want these extensions, you would have to put the commands into your PowerShell profile script. Or you can export the extensions to a JSON or XML file. You can either export all members or selected ones, which is helpful if you are extending a type that already has type extensions from PowerShell.
Get-PSTypeExtension system.int32 | Export-PSTypeExtension -TypeName system.int32 -Path c:\work\int32-types.json
In your PowerShell profile scrip,t you can then re-import the type extension definitions.
Import-PSTypeExtension -Path C:\work\int32-types.json
Property Sets
New-PSPropertySet
In addition to custom properties, PowerShell also has the idea of a propertyset. This allows you to reference a group of properties with a single name.
Let's say you have loaded the sample 'System.IO.FileInfo` type extensions from this module.
Import-PSTypeExtension -Path $PSTypeSamples\fileinfo-extensions.json
You could write a command like this:
dir c:\work -file | Select-Object Name,Size,LastWriteTime,Age
Or you could create a custom property set. These have to be defined in ps1xml files. The New-PSPropertySet simplifies this process.
New-PSPropertySet -Typename System.IO.FileInfo -Name FileAge -Properties Name,Size,LastWriteTime,Age -FilePath d:\temp\FileInfo.types.ps1xml
I've included the file in the Samples folder.
PS C:\> Update-TypeData $PSTypeSamples\FileInfo.types.ps1xml PS C:\> dir c:\work -file | Select-Object FileAge Name Size LastWriteTime Age ---- ---- - ----------- --- a.dat 42 2/12/2024 5:36:55 PM 23.17:27:21 a.txt 14346 12/31/2023 9:10:15 AM 67.01:54:00 a.xml 171394 12/31/2023 12:15:44 PM 66.22:48:32 aa.ps1 28866 12/31/2023 9:13:16 AM 67.01:51:00 aa.txt 28866 12/31/2023 9:11:18 AM 67.01:52:58 about.json 16455 2/27/2024 10:11:03 AM 09.00:53:12 about_ADReportingTools 1688 3/4/2024 7:37:01 PM 03.15:27:14 b.csv 1273 11/13/2023 12:11:35 PM 114.22:52:40 ...
If your property set is using custom properties, you need to load them into your PowerShell session before you can use the property set.
Create ps1xml Files
The Export-PSTypeExtension command will also export extensions to a properly formatted .ps1xml file. This can be useful when building type extension files for a module where you want to use the traditional ps1xml form. You can also import these types of files with Update-TypeData with the -AppendPath or -PrependPath parameters.
When exporting to .ps1xml file, Export-PSTypeExtension has a dynamic parameter, Append. This allows you to combine multiple type extensions into a single file. If you intend to use a property set, create that file first. Then append your custom type extensions to that file.
Here's how this might look.
First, create a property set file.
New-PSPropertySet -Typename System.IO.FileInfo -Name TimeSet -Properties "Name","Length","CreationTime","LastWriteTime" -FilePath c:\work\file.types.ps1xml
I'll define a few type extensions.
Add-PSTypeExtension -TypeName System.IO.FileInfo -MemberType AliasProperty -MemberName Size -Value Length Add-PSTypeExtension -TypeName System.IO.FileInfo -MemberType ScriptProperty -MemberName ModifiedAge -Value {New-TimeSpan -Start $this.LastWriteTime -End (Get-Date)}
I'll even add a second property set to the same file using these new extensions.
Export-PSTypeExtension -TypeName System.IO.FileInfo -MemberName Size,ModifiedAge -Path c:\work\file.types.ps1xml -append
I'll end up with this file:
<?xml version="1.0" encoding="utf-8"?> <!-- This file was created with New-PSPropertySet from the PSTypeExtensionTools module which you can install from the PowerShell Gallery. Use Update-TypeData to append this file in your PowerShell session. Created 03/09/2024 15:27:56 --> <Types> <Type> <Name>System.IO.FileInfo</Name> <Members> <PropertySet> <Name>TimeSet</Name> <ReferencedProperties> <Name>Name</Name> <Name>Length</Name> <Name>CreationTime</Name> <Name>LastWriteTime</Name> </ReferencedProperties> </PropertySet> <PropertySet> <Name>Age</Name> <ReferencedProperties> <Name>Name</Name> <Name>Size</Name> <Name>LastWriteTime</Name> <Name>ModifiedAge</Name> </ReferencedProperties> </PropertySet> <AliasProperty> <Name>Size</Name> <ReferencedMemberName>Length</ReferencedMemberName> </AliasProperty> <ScriptProperty> <Name>ModifiedAge</Name> <GetScriptBlock>New-TimeSpan -Start $this.lastwritetime -End (Get-Date)</GetScriptBlock> </ScriptProperty> </Members> </Type> </Types>
In PowerShell, I can load this file and use it.
PS C:\> Update-TypeData c:\work\file.types.ps1xml PS C:\> Get-ChildItem -path c:\work\*.csv | Sort-Object -property size -Descending | Select Age Name Size LastWriteTime ModifiedAge ---- ---- ------------- ----------- updates.csv 4021821 11/14/2023 9:00:48 AM 115.06:45:35.2595780 part5.csv 7332 2/27/2024 6:10:11 PM 9.21:36:12.4672428 ipperf.csv 5008 11/4/2023 11:36:20 AM 125.04:10:03.4641251 localusers.csv 1480 2/27/2024 4:39:32 PM 9.23:06:51.7431393 b.csv 1273 11/13/2023 12:11:35 PM 116.03:34:48.0298279 foo.csv 1077 11/13/2023 12:40:04 PM 116.03:06:19.3069112 y.csv 524 11/19/2023 2:11:44 PM 110.01:34:39.0826388 yy.csv 524 12/1/2023 11:28:03 AM 98.04:18:20.7080948 c.csv 334 11/13/2023 11:58:15 AM 116.03:48:08.3898463 a.csv 0 12/1/2023 11:30:55 AM 98.04:15:27.9106911
I can put the Update-TypeData command in my PowerShell profile to always have these extensions. Or I could share the file.
Previewing Type Extensions
Depending on the file you are using to update type data, there are a few options to preview the type extensions before you import them. If you have exported settings to a JSON or XML file using Export-PSTypeExtension, you can use the Preview parameter of Import-PSTypeExtension command to see the type extensions before they are applied.
PS C:\> Import-PSTypeExtension $PSTypeSamples\stringtypes.json -Preview TypeName: System.String MemberType MemberName Value ---------- ---------- ----- AliasProperty Size Length ScriptMethod IsIPAddress $this -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" ScriptMethod Randomize ($this.ToCharArray() | get-random -Count $this.length) -join "" ScriptMethod Reverse for ($i=$this.length;$i -ge 0;$i--) {… ScriptMethod Reverse ($this.ToCharArray())[-1..-$this.length] -join "" ScriptProperty IsEmail $this -match '^\S+@([\w-]+)\.(com|edu|org|net)$' PS C:\> Import-PSTypeExtension $PSTypeSamples\measureinfo.xml -Preview TypeName: Microsoft.PowerShell.Commands.GenericMeasureInfo MemberType MemberName Value ---------- ---------- ----- ScriptProperty SumGB [math]::Round($this.sum/1gb,4) ScriptProperty SumKB [math]::Round($this.sum/1kb,4) ScriptProperty SumMB [math]::Round($this.sum/1mb,4)
The Get-PSTypeDataPreview command will display the type extensions in a ps1xml file. This is useful if you want to see what type extensions are defined in a file before you import them.
If you have a ps1xml file, you can use the Get-PSTypeDataPreview command to see the type extensions.
The default output uses custom formatting to display type extensions using ANSI color sequences. Or you can use the object directly.
PS C:\> $a = Get-PStypeDataPreview $PSTypeSamples\process.types.ps1xml PS C:\> $a | Select-Object * TypeName : System.Diagnostics.Process AliasProperty : {@{Name=Computername; Reference=MachineName}, @{Name=Started; Reference=StartTime}} NoteProperty : @{Name=Comment; Value=Type extended with PSTypeExtensionTools} ScriptProperty : @{Name=RunTime; Get=(Get-Date) - $this.StartTime; Set=} PropertySet : {@{Name=PSRun; Properties=System.Object[]}, @{Name=RunInfo; Properties=System.Object[]}} Path : C:\scripts\PSTypeExtensionTools\samples\process.types.ps1xml PS C:\> $a.PropertySet Name Properties ---- ---------- PSRun {ID, Name, WS, StartTime...} RunInfo {ID, Name, StartTime, RunTime...}
I Want to Try
You can find sample and demonstration type extension exports in the Samples folder. When you import the module, this location is saved to a global variable, $PSTypeSamples.
PS C:\> Get-ChildItem $PSTypeSamples Directory: C:\scripts\PSTypeExtensionTools\samples Mode LastWriteTime Length Name ---- ------------- ------ ---- a--- 10/11/2024 4:52 PM 762 cimlogicaldisk-extensions.json a--- 10/11/2024 4:32 PM 265 datetime-extensions.json a--- 10/11/2024 4:32 PM 490 eventlog-type.json a--- 6/24/2025 12:02 PM 2608 fileinfo-extensions.json a--- 6/24/2025 4:44 PM 728 fileinfo.types.ps1xml a--- 10/11/2024 4:32 PM 901 int32-types.json a--- 10/11/2024 4:32 PM 1318 measure-extensions.json a--- 6/24/2025 11:48 AM 1066 measureinfo.xml a--- 6/24/2025 11:33 AM 1176 msft_volume-extensions.json a--- 6/24/2025 1:56 PM 656 mydatetime.types.ps1xml a--- 6/24/2025 1:56 PM 444 process-types.xml a--- 6/24/2025 2:14 PM 1555 process.types.ps1xml a--- 10/11/2024 4:33 PM 944 README.md a--- 10/11/2024 4:32 PM 1246 stringtypes.json a--- 6/24/2025 11:30 AM 3024 vm-extensions.json PS C:\> Import-PSTypeExtension $PSTypeSamples\measure-extensions.json -Verbose VERBOSE: Starting: Import-PSTypeExtension VERBOSE: Importing file C:\scripts\PSTypeExtensionTools\samples\measure-extensions.json VERBOSE: Processing ScriptProperty : SumKB VERBOSE: Creating scriptblock from value VERBOSE: Performing the operation "Adding ScriptProperty SumKB" on target "Microsoft.PowerShell.Commands.GenericMeasureInfo". VERBOSE: Processing ScriptProperty : SumMB VERBOSE: Creating scriptblock from value VERBOSE: Performing the operation "Adding ScriptProperty SumMB" on target "Microsoft.PowerShell.Commands.GenericMeasureInfo". VERBOSE: Processing ScriptProperty : SumGB VERBOSE: Creating scriptblock from value VERBOSE: Performing the operation "Adding ScriptProperty SumGB" on target "Microsoft.PowerShell.Commands.GenericMeasureInfo". VERBOSE: Ending: Import-PSTypeExtension PS C:\> Get-ChildItem D:\VMDisks\ -file -recurse | Measure-Object -property length -sum | Select-Object Count,SumGB Count SumGB ----- ----- 4 50.2031
This project was first described at http://jdhitsolutions.com/blog/powershell/5777/a-powershell-module-for-your-type-extensions
There is an about help topic you can read:
help about_PSTypeExtensionTools



