I have an array with psocustomobjet like this :
$Data=@()
$Data = [PSCustomObject]@{
'RawMessage' = '123'
'MessageType' = 'String'
'Export' = ''}
$Data = [PSCustomObject]@{
'RawMessage' = '456'
'MessageType' = 'File'
'Export' = ''}
$Data = [PSCustomObject]@{
'RawMessage' = '789'
'MessageType' = 'String'
'Export' = ''}
If column "export" is empty, I would like to remove it to get the following result :
RawMessage MessageType
---------- -----------
123 String
456 File
789 String
My control seem good but I didn't manage to remove the column :
If ($Data.Export -NotLike $Null) {$Data.PSObject.Properties.Remove('Export')}
I tried a lot of commands but I keep with my column...
Thank for your help.
CodePudding user response:
Please accept mklement0's answer, as it gives you a good solution to accomplish what you asked for, and explains what was wrong with what you tried. I am only including this as a different way to iterate the array looking for empty values.
Since we can use If
to evaluate $true
if there is there is a non-zero/non-false value, and we can invert those results, we can pipe your array to Select-Object
and for the ExcludeProperty
parameter supply a subexpression that looks to see if anything has a value for "Export", and if nothing does then exclude that property.
$Data | Select * -ExcludeProperty $(if(!($Data.Export -ne '')){'Export'}) | Format-Table -AutoSize
This works because $Data.Export -ne ''
outputs the Export value of any object in the array that is not equal to ''. If nothing has a non-'' value then nothing is output and it evaluates as $null
, and If
equates $null
with $false
, so we precede it is !
(alias for -not
), and tell it that if not false, to output 'Export' to the -ExcludeProperty
parameter. Reading this answer makes it all seem very convoluted, but it works. Run it, then change the value of Export on any of the objects and try it again. It outputs like you want either way.
Or if you wanted to remove the property and not just output it you could lose the Format-Table
and capture the output in itself like this:
$Data = $Data|Select * -ExcludeProperty $(if(!($Data.Export -ne '')){'Export'})
CodePudding user response:
Since you want to remove the Export
property from individual objects objects where that value is ''
(the empty string), you must process them individually:
$Data | ForEach-Object {
if ('' -eq $_.Export) { $_.PSObject.Properties.Remove('Export') }
$_ # Output
}
The
ForEach-Object
cmdlet is one way to (in effect) loop (iterate) over the individual objects contained in your$Data
array, with each element reflected in the automatic$_
variable. Alternatively, especially for arrays already in memory, you may use theforeach
statement.Note that it is generally sufficient to test
[string]
values for''
(the empty string) in PowerShell, not also for$null
, because PowerShell doesn't store$null
in string values (see this answer for more information).- However, if you don't know the type of the property ahead of time and want to test for
$null
too, you can use the[string]::IsNullOrEmpty($_.Export)
- or, more simply -$_.Export -like ''
- However, if you don't know the type of the property ahead of time and want to test for
As for what you tried:
$Data
is an array of objects, and you mistakenly tried to remove the property from the array object rather than from the objects that make up its elements.
$Data.Export
, due to PowerShell's member-access enumeration feature, does act on the individual elements, but returns their .Export
property values as an array.
As such, you can use the following tests at the array level, but in order to modify the elements, you need to enumerate (iterate over) them and process each.
# Is at least *one* .Export value the empty string?
$Data.Export -contains ''
# Are *all* .Export values the empty string?
($Data.Export -eq '').Count -eq $Data.Count