Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get properties that ONLY have populated values?

How do I get properties that ONLY have populated values?

So for example if I run

Get-QADUser -Identity "SomeOne" -IncludeAllProperties

the output would of course include.. all properties, including those with and those without values. I want a listing of properties with values only. How is it done generally speaking?

This wouldn't be restricted to Quest Cmdlets, I only use Get-QADUser as an example.

like image 594
Andrew Stevens Avatar asked Nov 30 '22 15:11

Andrew Stevens


2 Answers

You could try using the built-in (hidden) property of PowerShell objects called PSObject, which includes a property called Properties, i.e. a list of all properties on the parent object.

Maybe easier with an example. Take Get-Process... a process can have many attributes (properties) with or without values. In order to get just the ones with values you do this:

(Get-Process | Select -First 1).PSObject.Properties | ?{$_.Value -ne $null} | FT Name,Value

Note that I limited this to just the first process returned by Get-Process. We then get all the properties defined on that object, filtering where Value is not null and then displaying just the Name and Value for those properties.

like image 65
Charlie Joynt Avatar answered Dec 06 '22 08:12

Charlie Joynt


To complement Charlie Joynt's helpful answer:

Below is convenience function Remove-NullProperties, which creates custom-object copies of its input objects populated with only the non-$null properties of the input objects.

Example use:

# Sample input collection, with 2 objects with different $null-valued
# properties.
$coll = [pscustomobject] @{ one = 'r1c1'; two = $null; three = 'r1c3' },
        [pscustomobject] @{ one = 'r2c1'; two = 'r2c2'; three = $null }

# Output copies containing only non-$null-valued properties.
# NOTE: The `ForEach-Object { Out-String -InputObject $_ }` part is solely
#       there to ensure that *all* resulting properties are shown.
#       With the default output, only the properties found on the FIRST
#       input object would be used in the output table.
$coll | Remove-NullProperties | 
  ForEach-Object { Out-String -InputObject $_ }

This yields the following - note how the respective null-valued properties were removed:

one  three
---  -----
r1c1 r1c3 


one  two 
---  --- 
r2c1 r2c2

Remove-NullProperties source code:

<#
.SYNOPSIS
Removes properties with $null values from custom-object copies of 
the input objects.

.DESCRIPTION
Note that output objects are custom objects that are copies of the input
objects with copies of only those input-object properties that are not $null.

CAVEAT: If you pipe multiple objects to this function, and these objects
        differ in what properties are non-$null-valued, the default output
        format will show only the non-$null-valued properties of the FIRST object.
        Use ... | ForEach-Object { Out-String -InputObject $_ } to avoid
        this problem.

.NOTES
Since the output objects are generally of a distinct type - [pscustomobject] -
and have only NoteProperty members, use of this function only makes sense
with plain-old data objects as input.

.EXAMPLE
> [pscustomobject] @{ one = 1; two = $null; three = 3 } | Remove-NullProperties

one three
--- -----
  1     3

#>
function Remove-NullProperties {

  param(
    [parameter(Mandatory,ValueFromPipeline)]
    [psobject] $InputObject
  )

  process {
    # Create the initially empty output object
    $obj = [pscustomobject]::new()
    # Loop over all input-object properties.
    foreach($prop in $InputObject.psobject.properties) {
      # If a property is non-$null, add it to the output object.
      if ($null -ne $InputObject.$($prop.Name)) {
        Add-Member -InputObject $obj -NotePropertyName $prop.Name -NotePropertyValue $prop.Value
      }
    }
    # Give the output object a type name that reflects the type of the input
    # object prefixed with 'NonNull.' - note that this is purely informational, unless
    # you define a custom output format for this type name.
    $obj.pstypenames.Insert(0, 'NonNull.' + $InputObject.GetType().FullName)
    # Output the output object.
    $obj
  }

}
like image 22
mklement0 Avatar answered Dec 06 '22 08:12

mklement0