Объект 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
для проверки конкретных произошедших ошибок.