How to eliminate unvalued properties of an object when converting to JSON in Powershell

I have a piece of code that works, but I want to know if there is a better way to do this. So far, I could not find anything related. Here are the facts:

  • I have an object with n properties.
  • I want to convert this object to JSON using (ConvertTo-Json).
  • I do not want to include in JSON those properties of the object that are not evaluated.

Building an object (not very important):

$object = New-Object PSObject Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable" Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.." Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt" Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value "" 

The line where I need improvements (to filter out unvalued properties and not include them in JSON)

 # So I want to 'keep' and deliver to the JSON only the properties that are valued (first 3). $object | select -Property TableName, Description, AppArea, InitialVersion | ConvertTo-Json 

What this line provides:

 Results: { "TableName": "MyTable", "Description": "Lorem ipsum dolor..", "AppArea": "UserMgmt", "InitialVersion": null } What I want to obtain: { "TableName": "MyTable", "Description": "Lorem ipsum dolor..", "AppArea": "UserMgmt" } 

That I tried and works, but I don’t like it, because I have much more properties for processing:

 $JSON = New-Object PSObject if ($object.TableName){ Add-Member -InputObject $JSON -MemberType NoteProperty -Name TableName -Value $object.TableName } if ($object.Description){ Add-Member -InputObject $JSON -MemberType NoteProperty -Name Description -Value $object.Description } if ($object.AppArea){ Add-Member -InputObject $JSON -MemberType NoteProperty -Name AppArea -Value $object.AppArea } if ($object.InitialVersionCode){ Add-Member -InputObject $JSON -MemberType NoteProperty -Name InitialVersionCode -Value $object.InitialVersionCode } $JSON | ConvertTo-Json 
+9
source share
3 answers

Something like that?

 $object = New-Object PSObject Add-Member -InputObject $object -MemberType NoteProperty -Name TableName -Value "MyTable" Add-Member -InputObject $object -MemberType NoteProperty -Name Description -Value "Lorem ipsum dolor.." Add-Member -InputObject $object -MemberType NoteProperty -Name AppArea -Value "UserMgmt" Add-Member -InputObject $object -MemberType NoteProperty -Name InitialVersionCode -Value "" # Iterate over objects $object | ForEach-Object { # Get array of names of object properties that can be cast to boolean TRUE # PSObject.Properties - https://msdn.microsoft.com/en-us/library/system.management.automation.psobject.properties.aspx $NonEmptyProperties = $_.psobject.Properties | Where-Object {$_.Value} | Select-Object -ExpandProperty Name # Convert object to JSON with only non-empty properties $_ | Select-Object -Property $NonEmptyProperties | ConvertTo-Json } 

Result:

 { "TableName": "MyTable", "Description": "Lorem ipsum dolor..", "AppArea": "UserMgmt" } 
+10
source

helpful answer beatcracker offers an effective solution; let me complement it with a simplified version that takes advantage of PSv4 + features:

 # Sample input object $object = [pscustomobject] @{ TableName = 'MyTable' Description = 'Lorem ipsum dolor...' AppArea = 'UserMgmt' InitialVersionCode = $null } # Start with the list of candidate properties. # For simplicity we target *all* properties of input object $obj # but you could start with an explicit list as wellL # $candidateProps = 'TableName', 'Description', 'AppArea', 'InitialVersionCode' $candidateProps = $object.psobject.properties.Name # Create the filtered list of those properties whose value is non-$null # The .Where() method is a PSv4+ feature. $nonNullProps = $candidateProps.Where({ $null -ne $object.$_ }) # Extract the list of non-null properties directly from the input object # and convert to JSON. $object | Select-Object $nonNullProps | ConvertTo-Json 
+3
source

To do this, my profile has the following function. Advantage: I can pass it a collection of objects and remove null values ​​from all objects in the pipeline.

 Function Remove-Null { [cmdletbinding()] param( # Object to remove null values from [parameter(ValueFromPipeline,Mandatory)] [object[]]$InputObject, #By default, remove empty strings (""), specify -LeaveEmptyStrings to leave them. [switch]$LeaveEmptyStrings ) process { foreach ($obj in $InputObject) { $AllProperties = $obj.psobject.properties.Name $NonNulls = $AllProperties | where-object {$null -ne $obj.$PSItem} | where-object {$LeaveEmptyStrings.IsPresent -or -not [string]::IsNullOrEmpty($obj.$PSItem)} $obj | Select-Object -Property $NonNulls } } } 

Some examples of use:

 $AnObject = [pscustomobject]@{ prop1="data" prop2="moredata" prop5=3 propblnk="" propnll=$null } $AnObject | Remove-Null prop1 prop2 prop5 ----- ----- ----- data moredata 3 $ObjList =@ ( [PSCustomObject]@{ notnull = "data" more = "sure!" done = $null another = "" }, [PSCustomObject]@{ notnull = "data" more = $null done = $false another = $true } ) $objList | Remove-Null | fl #format-list because the default table is misleading notnull : data more : sure! notnull : data done : False another : True 
+1
source

Source: https://habr.com/ru/post/1233350/


All Articles