Командлет говорит, что параметр не может быть получен: выражение должно быть читаемым

В моем командлете есть команда Get-Deal, которая будет получать значение из конвейера:

[Cmdlet(VerbsCommon.Get, "Deal")]
public class GetDealCmdlet : InsightBaseCmdlet
{
    private List<Object> _legalentities = new List<Object>();
    [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,ValueFromPipelineByPropertyName = true)]
    public List<Object> Legalentity { set { _legalentities = value; } } 


    protected override void ProcessRecord() {...}
}

Он отлично работает, если я передал список строк или других типов. Однако, если я передал объект, созданный в Search-Deal:

foreach (...)
{
    PSObject dealValue = new PSObject();
    dealValue.Properties.Add(new PSNoteProperty(Legalentity,Convert.ToInt32($deal.Properties["LegalEntityID"].Value.ToString())));
    dealValue.Properties.Add(new PSNoteProperty("Name",deal.Properties["name"].Value.ToString()));
    WriteObject(dealValue);
}

Я получаю сообщение об ошибке:

Вход конвейера не может быть обработан, так как невозможно получить значение по умолчанию для параметра «Законность». Исключение при получении «Легальности»: выражение должно быть читаемым. Имя параметра: выражение.

Я уверен, что search-Deal работает нормально, потому что

$a = Search-Deal name 

работает. И давая:

Get-Deal $a

возвращает точный результат, который я хочу.

Однако

$a | Get-Deal 

тоже будет ошибкой.

РЕДАКТИРОВАТЬ: используя

Trace-Command -Name ParameterBinding -Expression { Search-Deal JL | Get-Deal } -PSHost

Я нашел следующее:

CALLING BeginProcessing 
BIND PIPELINE object to parameters: [Get-Deal] 
PIPELINE object TYPE = [System.Management.Automation.PSCustomObject] 
RESTORING pipeline parameter's original values 
BIND PIPELINE object to parameters: [Out-Default] 
PIPELINE object TYPE = [System.Management.Automation.ErrorRecord] 
Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION 
BIND arg [Pipeline input cannot be processed because the default value of parameter 'LegalEntity' cannot be retrieved. Exception getting "LegalEntity": "Expression must be readable Parameter name: expression"] 

Поэтому я думаю, что что-то не так с конвейером, передающим объекты.

Спасибо за любую помощь!


person jamesdeath123    schedule 08.04.2013    source источник


Ответы (2)


Способ работы конвейера PowerShell предотвратит такой сценарий. Вместо передачи всего списка - он будет передавать элементы один за другим. Чтобы этого не произошло, вы можете использовать унарную запятую:

, $a | Get-Deals

Однако мое предложение (как пользователя PowerShell): не делайте этого, если у вас нет очень веской причины. Вместо этого принимайте/записывайте отдельные объекты. Это более естественно и должно избавить будущего пользователя от тех же печалей, которые у вас есть сейчас (на самом деле совсем наоборот - я бы ожидал, что будет возвращен поток объектов, а не одиночное «раздувание»;))

Также: рекомендуется называть командлеты существительными в единственном числе. Даже если вы обычно ожидаете большего (Get-Process, Get-Service, Get-ChildItem...)

person BartekB    schedule 08.04.2013
comment
Переименовано в единственное число :) Чтобы быть более конкретным, Search-Deal записывает объект в цикле: foreach (){PSObject DealValue = new PSObject(); ... WriteObject(dealValue);} поэтому он передает один объект за раз. также Get-Deal может принимать список (который сохраняет возможность передавать переменную списка в параметр вместо конвейерной обработки, как показано), но в случае с конвейером, я думаю, он берет один объект за раз из предыдущего цикла. Я пытался, $a | Get-Deals, но, похоже, не работает... - person jamesdeath123; 09.04.2013
comment
Должно быть, я неправильно прочитал это в первый раз. В любом случае: я бы проверил Trace-Command -Name ParameterBinding - очевидно, что-то в связывателе параметров вызывает эту проблему, поэтому может быть полезна дополнительная информация о трассировке. Я вижу свойство, которое соответствует параметру в объекте вывода Search-Deal, возможно, это вызывает эту проблему? И последнее, но не менее важное: я вижу $deal внутри ToInt32, разве не должно быть deal вместо этого...? - person BartekB; 09.04.2013
comment
$deal — это еще один объект PSObject, идентификатор которого Search-deal получает и передает в конвейер как свойство DealValue. Я как бы делаю это $deal, чтобы определить, что это переменная :) Я не знаком с Trace-Command, и я использовал: Trace-Command -Name ParameterBinding {Search-Deal JL | Get-Deal} и выдается та же ошибка. Не могли бы вы сказать мне, как мне использовать Trace-Command? Кроме того, Вы упомянули свойство, которое соответствует параметру в объекте вывода Search-Deal, и это может вызвать проблему. Я попытался переименовать имя параметра в Get-Deal, но здесь это мало помогает. - person jamesdeath123; 09.04.2013
comment
Как вы думаете, когда я передаю PSObject в Get-Deal, командлет не распознает PSObject, поскольку он ожидает List‹PSObject›? - person jamesdeath123; 09.04.2013
comment
Хорошо, вы здесь разработчик, я просто вижу, что $deal используется в одном свойстве, а deal — в другом. Что касается трассировки: вам нужно куда-то направить вывод, -PSHost для начала, например. Trace-Command -Name ParameterBinding -Expression { Search-Deal | Get-Deal } -PSHost. Причина? Если тип входного объекта совпадает с типом параметра - он будет использован. Чем если есть свойство с таким же именем, как параметр, оно будет привязано вторым. Наконец, входной объект будет преобразован в тип, ожидаемый параметром. С трассировкой вы должны быть в состоянии сказать, когда она так сильно терпит неудачу. - person BartekB; 10.04.2013
comment
ВЫЗОВ BeginProcessing ПРИВЯЗАТЬ объект PIPELINE к параметрам: [Get-Deal] TYPE объекта PIPELINE = [System.Management.Automation.PSCustomObject] ВОССТАНОВЛЕНИЕ исходных значений параметров конвейера BIND PIPELINE объекта к параметрам: [Out-Default] PIPELINE object TYPE = [System.Management .Automation.ErrorRecord] Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION BIND arg [Ввод конвейера не может быть обработан, поскольку невозможно получить значение параметра LegalEntity по умолчанию. Исключение при получении LegalEntity: выражение должно быть читаемым Имя параметра: выражение] - person jamesdeath123; 10.04.2013
comment
Trace-Command говорит мне, что находит какую-то ошибку: PIPELINE object TYPE = [System.Management.Automation.ErrorRecord], но я понятия не имею, что это такое и как это можно исправить... - person jamesdeath123; 10.04.2013

Оказалось, что публичный список Legalentity { set { _legalentities = value; } } отсутствует геттер.

хотя я действительно не знаю причину этого, добавление get {return xxx } устранит ошибку.

Тогда ошибка имеет смысл. В основном это говорит о том, что вам нужно добавить геттер:

Вход конвейера не может быть обработан, так как невозможно получить значение по умолчанию для параметра «Законность». Исключение при получении «Легальности»: выражение должно быть читаемым. Имя параметра: выражение.

person jamesdeath123    schedule 11.04.2013