Ошибка PowerShell?Не удается передать свойство ComputerName в Get-Service (смешивание по значению и свойству) - PullRequest
0 голосов
/ 13 мая 2018

Похоже, ошибка, нет? В этом случае PowerShell преобразует хеш-таблицу в строку '@ {computername = comp001}' и пытается использовать ее с -Name (ByValue) вместо -ComputerName (ByPropertyName). Даже PS 6 делает это. Трубопровод до Get-Service -Name * работает нормально.

PS C:\> [pscustomobject]@{computername='comp001'} | get-service
get-service : Cannot find any service with service name '@{computername=comp001}'.
At line:1 char:45
+ [pscustomobject]@{computername='comp001'} | get-service
+                                             ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{computername=comp001}:String) 
[Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : 
NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Похоже на ошибку, нет?

Не ошибка как таковая, но неожиданное следствие разработки параметров командлета Get-Service:

Прикрепление атрибута ValueFromPipeline к параметру, набранному [string] / [string[]] или [object] / [object[]] (или [psobject] / [psobject[]]), приводит к привязке этого параметра к любому конвейерувведите , возможно в дополнение к привязке к другим параметрам - , если этот параметр не связан с аргументом командной строки , который является вашим -Name *обходной путь делает.

  • Причина в том, что экземпляры любого типа данных могут быть преобразованы в [string] / получены из [object] ([psobject]), вызывая любой объект ввода, независимо от типа, для привязки к этому параметру.

Вкратце: проблема здесь не в том, что [pscustomobject]@{computername='comp001'} не привязано к -ComputerName - на самом деле равно - это то, что это также связано с -Name, неизменно.
PowerShell связыватель параметров фундаментально связывает входные данные конвейера с всеми подходящими параметрами , а не только с одним.

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

Поведение теперь также обсуждается на GitHub .


Примечание:

Как указывает js2010 (OP), it можно осмысленно комбинироватьатрибуты ValueFromPipeline и ValueFromPipelineByPropertyName в параметре single , как это делает Get-Service, но обратите внимание на ограничения:

  • It работает только для параметра , а не , набираемого [object] или [psobject] / [object[]] или [psobject[]] (такой параметр неизменно связывает все по значению никогдас учетом свойств ).

    • Если типом является [string] или [string[]], свойства имеют значение сначала красный, но у вас не может быть дополнительных параметров привязки к конвейеру , потому что это представляет исходную проблему: параметр [string] / [string[]] будет неизменно также bind.
  • Тип свойства входного объекта, соответствующего имени параметра, должен либо соответствовать типу параметра, либо, по крайней мере, быть конвертируемым , чтобы быть связанным.

Вот пример команды, которая привязывает тот же сервис к -Name сначала как строка, а затем как объект со свойством .Name:
'rpcss', [pscustomobject] @{ Name = 'rpcss' } | Get-Service

0 голосов
/ 13 мая 2018

Когда вы отправляете полный объект в Get-Service, у него есть только две опции для привязки: Name и InputObject, которые являются параметрами, которые принимают ByValue конвейерный ввод.К сожалению, ваш объект не в той форме, в которой он понимает.

Вы можете увидеть, что делает PowerShell, запустив этот Trace-Command:

Trace-Command -Name ParameterBinding -PSHost -Expression {[pscustomobject]@{ComputerName='comp001'} | Get-Service}

Как вы говорите, способ обойти этодолжен предоставить значение для -Name, поэтому оно не пытается связать его:

[pscustomobject]@{ComputerName='comp001'} | Get-Service -Name *

Еще раз, вы можете использовать Trace-Command, как указано выше, чтобы убедиться, что онотеперь счастлив связать '*' с -Name, затем он продолжает связывать дополнительные параметры, такие как -ComputerName.

В документации PowerShell ( about_Parameters ) говорится:

Когда параметр имеет значение «True (по значению)», Windows PowerShell пытается связать любые переданные по конвейеру значения с этим параметром, прежде чем он попытается другими методами интерпретировать команду.

...