PowerShell Property Sets

tree11

What are PowerShell Property sets and how can they be used?

Property sets are named groups of properties for certain types that can be used through Select-Object. The property sets are defined in the *types*.ps1xml files that can be found in the $pshome directory. Most of the types have default property sets defined as DefaultDisplayPropertertySet within the PSStandardMembers MemberSet. Those determine the list of properties shown when an object of that type is output. An example:

$process = (Get-Process)[0]
$process.PSStandardMembers.DefaultDisplayPropertySet.ReferencedPropertyNames
$process | Format-List

screenShotPropertySet1

The list of default properties for a type can be modified by using Update-TypeData:

$process = (Get-Process)[0]
$typeName = $process.PSTypeNames[0]
Update-TypeData -TypeName $typeName -DefaultDisplayPropertySet Handles, Name, ID -Force
$process | Format-List

screenShotPropertySet

Some types have additional property sets defined that can be used with Select-Object:

Get-Process | select PSConfiguration -Last 5 | Format-Table -Auto

screenShotPropertySet2

The properties displayed when using the ‘PSConfiguration’ property set are defined in the types.ps1xml file but can be also accessed through Get-Member:

Get-Process | Get-Member -MemberType PropertySet

Property sets can also be added dynamically to any object instance by using Add-Member:

$ps = Get-Process
$ps | Add-Member -MemberType PropertySet 'Test' ('Path', 'Product', 'Company', 'StartTime')
$ps | select Test

Adding a property set to a type is unfortunately not as easy as just calling Update-TypeData, since the MemberType PropertySet is not supported:

$typeName = (Get-Process).GetType().FullName
Update-TypeData -TypeName $typeName -MemberType PropertySet -MemberName 'Test' -Value $props
Get-Process | select Test -First 5

screenShotPropertySet6

That does of course not mean it’s impossible, but it involves creating the appropriate type.ps1xml file ‘manually’:

function Add-PropertySet{
     <#    
    .SYNOPSIS
        Function to create property sets
    .DESCRIPTION
        Property sets are named groups of properties for certain types that can be used through Select-Object.
        The function adds a new property set to a type via a types.ps1xml file.
	.PARAM inputObject
		The object or collection of objects where the property set is added
	.PARAM propertySetName
		The name of the porperty set
	.EXAMPLE
		$fileName = dir | Add-PropertySet Testing ('Name', 'LastWriteTime', 'CreationTime')
        dir | Get-Member -MemberType PropertySet
        dir | select Testing
        #add this to the profile to have the property set available in all sessions
        Update-TypeData -PrependPath $fileName
	.EXAMPLE
		Get-Process | Add-PropertySet RAM ('Name', 'PagedMemorySize', 'PeakWorkingSet')
        Get-Process | select RAM
    #>
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        $inputObject,
    
        [Parameter(Mandatory=$true,Position=0)]
        $propertySetName,

        [Parameter(Mandatory=$true,Position=1)]
        $properties
    )
    $propertySetXML = "<Types>`n"
    $groupTypes = $input | group { $_.PSTypeNames[0] } -AsHashTable
    foreach ($entry in $groupTypes.GetEnumerator()) {
        $typeName = $entry.Key
        $propertySetXML += @"
    <Type>
        <Name>$typeName</Name>
        <Members>
            <PropertySet>
                <Name>$propertySetName</Name>
                <ReferencedProperties>
                    $($properties | foreach { 
                        "<Name>$_</Name>"    
                    })
                </ReferencedProperties>
            </PropertySet>
        </Members>
    </Type>
"@
    } 
    $propertySetXML += "`n</Types>"
    $xmlPath = Join-Path (Split-Path $profile.CurrentUserCurrentHost)  ($propertySetName + '.types.ps1xml')
    ([xml]$propertySetXML).Save($xmlPath)    
    Update-TypeData -PrependPath $xmlPath
    $xmlPath
}

With Add-PropertySet property sets can also be easily added to types:

Get-Process | Add-PropertySet RAM ('Name', 'PagedMemorySize', 'PeakWorkingSet')
Get-Process | select RAM -First 3 | Format-Table -Auto
Get-Process | Get-Member -MemberType PropertySet

screenShotPropertySet7

The property set is by default only available for the current PowerShell session. In order to have the property set available for every session the Update-TypeData call with the return value from the Add-PropertySet function (the types.ps1xml are created within the same directory as the profile and prefixed with the propertySetName) needs to be added to the profile:

#add this to your profile
Update-TypeData -PrependPath PATHRETURNEDFROMADD-PROPERTYSET

Add-PropertySet including full help can be download from my GitHub repository.

shareThoughts


photo credit: Happy Lazy Saturday via photopin (license)

Advertisements

I'd love to hear what you think

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s