Посторонние данные возвращаются из Invoke-Command

Я работаю с PowerShell для сбора данных из списка удаленных серверов, которые затем превращаю в объект JSON. Все работает нормально, но я получаю действительно странный вывод, который я не могу исключить.

Я пробовал передавать результаты Invoke-Command и исключать свойства. Я также пытался удалить элементы вручную из возвращенного хэш-файла, но, похоже, я не могу заставить их уйти.

Что мне не хватает?

РЕДАКТИРОВАТЬ:

Чтобы понять, что не так, вот упрощенный, но все еще неработающий скрипт:

$returnedServer = @{}
$pass = cat "C:\...\securestring.txt" | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "UserName",$pass
$s = @("xx.xxx.xxx.xxx","xx.xxx.xxx.xxx") 


foreach($server in $s)
{
    $returnedServer.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock 
{
1
}-credential $mycred | select -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName) 

$returnedServer| ConvertTo-Json

Что выводит:

{
"xx.xxx.xxx.xxx":  [
                       {
                           "value":  1,
                           "PSComputerName":  "xx.xxx.xxx.xxx",
                           "RunspaceId":  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                           "PSShowComputerName":  xxxx
                       }
                   ],
"xx.xxx.xxx.xxx":  [
                       {
                           "value":  1,
                           "PSComputerName":  "xx.xxx.xxx.xxx",
                           "RunspaceId":  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"",
                           "PSShowComputerName":  xxxx
                       }
                   ]
}

person DiscOH    schedule 13.03.2014    source источник


Ответы (4)


После некоторого тестирования кажется, что проблема заключается в типе объекта. Я смог заставить ваш тестовый скрипт работать, явно приведя возвращаемый результат.

$returnedServer = @{}
$pass = cat "C:\...\securestring.txt" | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "UserName",$pass
$s = @("xx.xxx.xxx.xxx","xx.xxx.xxx.xxx") 




foreach($server in $s)
{
  $returnedServer.$server += ,[int](Invoke-Command -ComputerName $server -ScriptBlock {1} -credential $mycred) 
}
$returnedServer| ConvertTo-Json
person mjolinor    schedule 13.03.2014
comment
Я либо неправильно интегрирую это решение, либо оно не работает для такого типа проблем. Я обновил вопрос, чтобы отразить это. - person DiscOH; 14.03.2014
comment
Это не ты. Я думаю, это потому, что это десериализованные объекты, и они ведут себя не так, как ожидалось. - person mjolinor; 14.03.2014

Вам нужно использовать Select-Object, чтобы ограничить результат только нужными свойствами. для отображения в выводе JSON:

$returnedServers.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock 
{
...$serverHash = various look ups and calculations...
$serverHash
} | select PropertyA, PropertyB, ...)

Чтобы получить более подробный ответ, вам нужно более подробно намного рассказать о «различных поисковых запросах и вычислениях», а также о фактическом преобразовании в JSON.

person Ansgar Wiechers    schedule 13.03.2014

Этот пост действительно старый, но спустя 6 лет я не смог найти приемлемого ответа, поэтому написал свой собственный.

$invokeCommandResults | ForEach-Object {
  $_.PSObject.Properties.Remove('PSComputerName')
  $_.PSObject.Properties.Remove('RunspaceId')
  $_.PSObject.Properties.Remove('PSShowComputerName')
}
person John Homer    schedule 16.05.2020

Вы можете попробовать это... вместо того, чтобы пытаться исключить посторонние значения свойств, просто будьте конкретными и "вызовите" или "захватите" те, которые вы хотите.

Совет по быстрому коду! Кстати, Invoke-Command -Computer $server -Scriptbock {command} можно значительно упростить, используя: icm $server {command}

Теперь, возвращаясь в строй...

Используя ваш исходный пост/пример, кажется, что вы пытаетесь использовать одно «значение», исключая все другие значения, то есть -ExcludeProperty (что очень разочаровывает).

Начнем с удаления и замены единственного раздела исключения:

select -ExcludeProperty PSComputerName,RunSpaceID,PSShowComputerName

Вместо этого попробуйте использовать одно из следующих действий:

1-й метод: использование модифицированной исходной команды...

  $returnedServer.$server += ,(Invoke-Command -ComputerName $server -ScriptBlock {1}-credential $mycred).value 

2-й метод: использование версии "icm"...

  $returnedServer.$server += ,(icm $server {1} -credential $mycred).value

По сути, вы «выбираете» нужные вам значения (по сравнению с исключением значений свойств, что, опять же, довольно неприятно, когда оно НЕ работает).


Связанные примеры:

Вот типичный системный вызов команды Powershell/WMIC:

icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}

Но что, если мне нужна только «версия» из глобуса объекта:

(icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}).version

Но подождите, теперь мне нужно только «lastbootuptime» из глобуса объекта:

(icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}).lastbootuptime

Нерешительно, я хочу быть более гибким:

$a=icm ServerNameGoesHere {Get-CimInstance -ClassName win32_operatingsystem}
$a.version
$a.lastbootuptime
$a.csname

(Имеет смысл?)

Удачи, ~PhilC

person user4817763    schedule 22.04.2015