#powershell
#powershell
Вопрос:
У меня есть массив объектов, которые я считываю из таблицы SQL Invoke-SqlCmd
и которые выглядят следующим образом:
ARTIKEL_NR : 74.10095.00
ArtBeschrieb1_3 : Onyx RGB-Strip 14W/m 24V DC Samsung
KLASSE : LuXLED
SMB1 :
SMW1 :
SMN1 :
SMB2 : Leistung
SMW2 : 14 W/m
SMN2 :
SMB3 : Lichtfarbe
SMW3 : RGB;
Но с гораздо большим количеством свойств, около 80.
Теперь я хочу отфильтровать все пустые свойства, не указывая их явно. итак, приведенный выше пример должен быть таким в конце:
ARTIKEL_NR : 74.10095.00
ArtBeschrieb1_3 : Onyx RGB-Strip 14W/m 24V DC Samsung
KLASSE : LuXLED
SMB2 : Leistung
SMW2 : 14 W/m
SMB3 : Lichtfarbe
SMW3 : RGB;
Как я могу это сделать?
Я знаю, что могу использовать [string]::IsNullOrEmpty()
или [string]::IsNullOrWhiteSpace()
, однако я не знаю, как я могу проверить свойства, не перечисляя их явно — под этим я подразумеваю, например:
Where-Object { ![string]::IsNullOrEmpty($_.SMB1) -and ![string]::IsNullOrEmpty($_.SMW1) -and ... }
.., потому что мои пальцы буквально сломались бы, если бы мне пришлось печатать их все
Ответ №1:
У объектов вызывается psobject
набор элементов, который содержит свойства вашего объекта. Вы можете запустить $object.psobject.Properties
, чтобы увидеть объекты свойств. Для предоставленного вами объекта вы можете сделать что-то вроде следующего:
$object | Select ($object.psobject.Properties | Where Value).Name
Если у вас есть массив, содержащий объекты, каждый из которых может иметь разные свойства null, вы можете выполнить вышеуказанную фильтрацию для каждого объекта в массиве:
$array | Foreach-Object {
$_ | Select ($_.psobject.Properties | Where Value).Name
}
Этот параметр имеет оговорку, если первый объект в массиве имеет 4 или менее свойств, тогда отображением по умолчанию будет табличное представление. В табличном представлении будут отображаться только те свойства, которые соответствуют первому объекту. Так что, если $array[0]
содержит только SMB3
без нулевого значения, то $array[1]
будет отображаться только SMB3
и так далее. Это всего лишь проблема с отображением, поскольку фактические данные точны. Чтобы обойти это, вам нужно будет принудительно просмотреть список:
$array | Foreach-Object {
$_ | Select ($_.psobject.Properties | Where Value).Name
} | Format-List
Ответ №2:
Попробуйте следующее. С помощью сводного хэш-набора вы можете впоследствии повторно создать унифицированный массив, в противном случае некоторые свойства отсутствуют при использовании командлетов, упомянутых в моем скрипте.
$inputData = <your-sql-result>
<#
summary of all properties required for properly output the data afterwards,
when used with cmdlets like Out-GridView, Export-Csv, ConvertTo-Csv, etc
otherwise some properties are missing, because such cmdlets gets the properties only from first index
#>
$propertySummary = [System.Collections.Generic.HashSet[string]]::new()
$output = foreach ($item in $inputData) {
$newProperties = [ordered]@{}
foreach ($property in $item.psobject.properties) {
if (![string]::IsNullOrEmpty($property.Value)) {
$newProperties.Add($property.Name, $property.Value)
# add to summary
[void]$propertySummary.Add($property.Name)
}
}
[pscustomobject]$newProperties
}
# output with missing properties
$output | Out-GridView -Title 'Missing properties'
# correct output with all properties
$output | Select-Object -Property ([string[]]$propertySummary) | Out-GridView -Title 'Correct'