Private/Add-ObjectDetail.ps1
function Add-ObjectDetail { <# .SYNOPSIS Decorate an object with - A TypeName - New properties - Default parameters .DESCRIPTION Helper function to decorate an object with: - A TypeName - New properties - Default parameters This breaks the 'do one thing' rule from certain perspectives... The goal is to decorate an object all in one shot This abstraction simplifies decorating an object, with a slight trade-off in performance. For example: 10,000 objects, add a property and typename: Add-ObjectDetail: ~4.6 seconds Add-Member + PSObject.TypeNames.Insert: ~3 seconds .INPUTS System.Management.Automation.PSObject[] .INPUTS System.Management.Automation.PSObject .NOTES - Troy Lindsay - Twitter: @troylindsay42 - GitHub: tlindsay42 .EXAMPLE # # Create an object to work with $object = [PSCustomObject] @{ First = 'Cookie' Last = 'Monster' Account = 'CMonster' } #Add a type name and a random property Add-ObjectDetail -InputObject $object -TypeName 'ApplicationX.Account' -PropertyToAdd @{ AnotherProperty = 5 } # First Last Account AnotherProperty # ----- ---- ------- --------------- # Cookie Monster CMonster 5 #Verify that get-member shows us the right type $object | Get-Member # TypeName: ApplicationX.Account ... .EXAMPLE # # Create an object to work with $object = [PSCustomObject] @{ First = 'Cookie' Last = 'Monster' Account = 'CMonster' } # Add a random property, set a default property set so we only see two props by default Add-ObjectDetail -InputObject $object -PropertyToAdd @{ AnotherProperty = 5 } -DefaultProperties 'Account', 'AnotherProperty' # Account AnotherProperty # ------- --------------- # CMonster 5 #Verify that the other properties are around $object | Select-Object -Property '*' # First Last Account AnotherProperty # ----- ---- ------- --------------- # Cookie Monster CMonster 5 .LINK https://tlindsay42.github.io/PSRyver/Private/Add-ObjectDetail/ .LINK https://github.com/tlindsay42/PSRyver/blob/master/PSRyver/Private/Add-ObjectDetail.ps1 .LINK http://ramblingcookiemonster.github.io/Decorating-Objects/ .LINK http://blogs.microsoft.co.il/scriptfanatic/2012/04/13/custom-objects-default-display-in-powershell-30/ .FUNCTIONALITY PowerShell Language #> [CmdletBinding( HelpUri = 'https://tlindsay42.github.io/PSRyver/Private/Add-ObjectDetail/' )] [OutputType( [Void] )] [OutputType( [PSObject] )] [OutputType( [PSObject[]] )] param ( # Specifies the object(s) to decorate. [Parameter( Mandatory = $true, Position = 0, ValueFromPipeline = $true )] [ValidateNotNullOrEmpty()] [PSObject[]] $InputObject, <# Typename to insert. This will show up when you use Get-Member against the resulting object. #> [Parameter( Position = 1 )] [String] $TypeName, <# Add these NoteProperties. Format is a hashtable with Key (Property Name) = Value (Property Value). Example to add a One and Date property: -PropertyToAdd @{ One = 1 Date = ( Get-Date ) } #> [Parameter( Position = 2 )] [Hashtable] $PropertyToAdd = @{}, # Change the default properties that show up [Parameter( Position = 3 )] [ValidateNotNullOrEmpty()] [Alias( 'dp' )] [String[]] $DefaultProperties = @(), # Whether to pass the resulting object on. [Parameter( Position = 4 )] [Boolean] $PassThru = $true ) begin { $function = $MyInvocation.MyCommand.Name Write-Verbose -Message ( "Beginning: '${function}' with ParameterSetName '$( $PSCmdlet.ParameterSetName )' and Parameters: " + ( $PSBoundParameters | Remove-SensitiveData | Format-Table -AutoSize | Out-String ) ) if ( $PSBoundParameters.ContainsKey( 'DefaultProperties' ) ) { # define a subset of properties $splat = @{ TypeName = 'System.Management.Automation.PSPropertySet' ArgumentList = 'DefaultDisplayPropertySet', $DefaultProperties } $ddps = New-Object @splat $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]] $ddps } } process { foreach ( $object in $InputObject ) { switch ( $PSBoundParameters.Keys ) { 'PropertyToAdd' { foreach ( $key in $PropertyToAdd.Keys ) { #Add some noteproperties. Slightly faster than Add-Member. $splat = @{ TypeName = 'System.Management.Automation.PSNoteProperty' ArgumentList = $key, $PropertyToAdd[$key] } $object.PSObject.Properties.Add( ( New-Object @splat ) ) } } 'TypeName' { #Add specified type [Void] $object.PSObject.TypeNames.Insert( 0, $TypeName ) } 'DefaultProperties' { # Attach default display property set $splat = @{ InputObject = $object MemberType = 'MemberSet' Name = 'PSStandardMembers' Value = $PSStandardMembers } Add-Member @splat } } if ( $PassThru ) { $object } } } end { Write-Verbose -Message "Ending: '${function}'." } } |