Объект PowerShell возвращает значение null

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

C # метод:

           public string RunScript( string contentScript, Dictionary<string, EntityProperty> parameters)
            {
                List<string> parameterList = new List<string>();
                foreach( var item in parameters )
                {
                    parameterList.Add( item.Value.ToString() );
                }
                PowerShell ps1 = PowerShell.Create();
               
                using( PowerShell ps = PowerShell.Create() )
                {
                    ps.AddScript( contentScript );
// in ContentScript I get "Get-RowAndPartitionKey" on debugging
                    ps.AddParameters( parameterList );//I get list of strings
                   
                    IAsyncResult async = ps.BeginInvoke();
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach( PSObject result in ps.EndInvoke( async ) )
// here i get result empty in ps.EndInvoke(async)
                    {
                        stringBuilder.AppendLine( result.ToString() );
                    }
                    return stringBuilder.ToString();
                }
            }
        }

Моя команда Powershell:

      public abstract class GetRowAndPartitionKey : PSCmdlet
    {
        [Parameter]
        public List<string> Properties { get; set; } = new List<string>();
    }

    [Cmdlet( VerbsCommon.Get, "RowAndPartitionKey" )]
    public class GetRowAndPartitionKeyCmd : GetRowAndPartitionKey

    {
        protected override void ProcessRecord()
        {
            string rowKey = string.Join( "_", Properties );
            string pKey = string.Empty;
            
            WriteObject( new
            {
                RowKey = rowKey,
                PartitionKey = pKey
            } );
        }
    }
}

Код после редактирования в соответствии с ответом, но все еще не работает (ошибка Drive C не найдена и Get-RowAndPartitionKey не распознан)

       using( PowerShell ps = PowerShell.Create() )
            {
               
                IAsyncResult async =
                 ps.AddCommand( "Import-Module" ).AddArgument( @"""C:\Users\Test\source\repos\Rest\Sert.Dataresr.PowerShell\bin\Debug\netcoreapp3.1\Sert.Dataresr.PowerShell.dll""" )
                    .AddStatement()
                    .AddCommand( contentScript ).AddParameter( "Properties","test" )
                    .BeginInvoke();

                StringBuilder stringBuilder = new StringBuilder();
                foreach( PSObject result in ps.EndInvoke( async ) )
                {
                    stringBuilder.AppendLine( result.ToString() );
                }
                return stringBuilder.ToString();
            }
        }

1 ответ

При использовании PowerShell SDK, если вы хотите передать параметры одной команде с .AddParameter() / / AddArgument(), используйте <tcode id="378755"></tcode>, нет

<tcode id="378756"></tcode>предназначен для передачи произвольных фрагментов кода PowerShell, который выполняется как блок сценария, в который параметры, добавленные с помощью .AddParameters() пройдены.

То есть ваш вызов эквивалентен & { Get-RowAndPartitionKey } <your-parameters>, и, как видите, ваша команда не получает значения параметров.

См. Этот ответ или дополнительную информацию.


Примечание. В качестве предварительного условия для вызова настраиваемого командлета вам, возможно, придется явно импортировать его модуль , что вы можете сделать:

  • либо: с отдельным синхронным Import-Moduleвызов выполнен заранее (для простоты я использую .AddArgument()здесь с позиционной передачей аргумента , который привязывается к -Nameпараметр (который также принимает пути )):

            ps1.AddCommand("Import-Module").AddArgument("<your-module-path-here>").Invoke();
    
  • или: как часть одного (в данном случае асинхронного) вызова - обратите внимание на обязательный .AddStatement() вызов для разделения двух команд:

            IAsyncResult async = 
      ps1.AddCommand("Import-Module").AddArgument("<your-module-path-here>")
        .AddStatement()
          .AddCommand("GetRowAndPartitionKey").AddParameter("Properties", parameterList)
              .BeginInvoke();
    

"<your-module-path-here>" относится к полному пути в файловой системе модуля, содержащего Get-RowAndPartitionKeyкомандлет; в зависимости от того, как реализован этот модуль, это либо путь к модуля каталога , его .psd1 манифест модуля или его .dll, если это отдельная сборка.

Для устранения этих вызовов:

  • Проверять ps1.HadErrors после .Invoke() / .EndInvoke() чтобы узнать, сообщили ли команды PowerShell о каких-либо (непрекращающихся) ошибках.

  • Перечислить ps1.Streams.Errors для проверки конкретных произошедших ошибок.

Другие вопросы по тегам