Я извлекаю данные инвентаризации из базы данных SQL, я хочу преобразовать их в JSON для дальнейшей обработки.
Существуют отдельные запросы для операционной системы, процессоров и приложений (Добавить и удалить информацию).
Для ОС обычно возвращается одна строка, для процессоров — одна или несколько строк, а для приложений обычно пара строк.
Извлечение данных делается так (эта часть работает нормально):
$deviceOperatingSystem = Invoke-Sqlcmd -ServerInstance $sqlServer -Database $sqlDatabase -Query $inventoryOperatingSystemQuery -credential $databaseCredentials -Variable $variables
$deviceProcessors = Invoke-Sqlcmd -ServerInstance $sqlServer -Database $sqlDatabase -Query $inventoryProcessorsQuery -credential $databaseCredentials -Variable $variables
$deviceApplications = Invoke-Sqlcmd -ServerInstance $sqlServer -Database $sqlDatabase -Query $inventoryApplicationsQuery -credential $databaseCredentials -Variable $variables
затем он передается в массив следующим образом:
$deviceInventoryOutput = @()
$deviceInventoryOutput += [PSCustomObject]@{
'OperatingSystem' = $deviceOperatingSystem
'Processors' = $deviceProcessors
'Applications' = $deviceApplications
}
и вывод выглядит так:
{
"OperatingSystem": {
"Caption": "Microsoft Windows 10 Enterprise",
"Version": "10.0.16299",
"BuildNumber": "16299",
"ServicePackMajorVersion": 0,
"Language": 1031
},
"Processors": {
"Name": "Intel(R) Core(TM) i3-6100U CPU @ 2.30GHz",
"Description": "Intel64 Family 6 Model 78 Stepping 3",
"Manufacturer": "GenuineIntel",
"NumberOfCores": 1,
"NumberOfLogicalCores": 1
},
"Applications": [
{
"Name": "IM.order",
"Publisher": "Ingram Micro Distribution GmbH",
"Version": "6.41.761.0"
},
{
"Name": "JTL-Wawi",
"Publisher": "JTL-Software-GmbH",
"Version": "1.2.3.7"
},...
}
принимающий API ожидает информацию для процессоров в виде массива, даже если есть только одна запись, поэтому мой пример должен выглядеть так:
{
"Processors": [{
"Name": "Intel(R) Core(TM) i3-6100U CPU @ 2.30GHz",
"Description": "Intel64 Family 6 Model 78 Stepping 3",
"Manufacturer": "GenuineIntel",
"NumberOfCores": 1,
"NumberOfLogicalCores": 1
}]
}
я пытался обернуть переменную процессора вот так
'Processors' = @($deviceProcessors)
но это мало помогло. Я также попытался инициализировать $deviceProcessors как массив, например:
$deviceProcessors = @()
$deviceProcessors += Invoke-Sqlcmd -ServerInstance $sqlServer -Database $sqlDatabase -Query $inventoryProcessorsQuery -credential $databaseCredentials -Variable $variables
но также, нет, не получилось.
$deviceProcessors.GetType() returns System.Data.DataRow
$deviceApplications.GetType() returns System.Object[]
Ожидаемый вывод должен иметь [] вокруг информации для процессоров, если из запроса возвращается только один результат.



Следующий фрагмент кода должен выполнить эту работу:
$deviceInventoryOutput = @()
$deviceInventoryOutput += [PSCustomObject]@{
'OperatingSystem' = $deviceOperatingSystem
'Processors' = $deviceProcessors
'Applications' = $deviceApplications
}
# possible additional `$deviceInventoryOutput += [PSCustomObject]@{…}` here
for ( $i = 0; $i -lt $deviceInventoryOutput.Count; $i++ ) {
foreach ( $aux in $( $deviceInventoryOutput[$i] |
Get-Member -MemberType NoteProperty ).Name ) {
if ( $deviceInventoryOutput[$i].$aux.Gettype().name -ne 'Object[]' ) {
$deviceInventoryOutput[$i].$aux = @($deviceInventoryOutput[$i].$aux)
}
}
}
$deviceInventoryOutput | ConvertTo-Json -Depth 2
@xBarns Правильно. Например, если кто-то собирает данные с более чем одного SQL-сервера…
Это прекрасно работает, один вопрос:
for ( $i = 0; $i -lt $deviceInventoryOutput.Count; $i++ ) {...}используется в случае, если в выводе более одного «устройства», верно?