Reputation: 1351
I have below command and it returns me null object . When I run the command separately in PowerShell window I get the right result. Below is my PowerShell method which is calling the command and the also the PowerShell command which I have defined. I am basically looking to return a string value. Please let me know what wrong am I doing?
C# method:
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() );
}
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();
}
}
}
My Powershell GetRowAndPartitionKey
cmdlet definition, which the code above is trying to call:
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
} );
}
}
}
Upvotes: 1
Views: 1012
Reputation: 437953
When using the PowerShell SDK, if you want to pass parameters to a single command with .AddParameter()
/ .AddParameters()
/ AddArgument()
, use .AddCommand()
, not .AddScript()
.AddScript()
is for passing arbitrary pieces of PowerShell code that is executed as a script block to which the parameters added with .AddParameters()
are passed.
That is, your invocation is equivalent to & { Get-RowAndPartitionKey } <your-parameters>
, and as you can see, your Get-RowAndPartitionKey
command therefore doesn't receive the parameter values.
See this answer or more information.
Note: As a prerequisite for calling your custom Get-RowAndPartitionKey
cmdlet, you may have to explicitly import the module (DLL) that contains it, which you can do:
either: with a separate, synchronous Import-Module
call executed beforehand (for simplicity, I'm using .AddArgument()
here, with passes an argument positionally, which binds to the -Name
parameter (which also accepts paths)):
ps.AddCommand("Import-Module").AddArgument(@"<your-module-path-here>").Invoke();
or: as part of a single (in this case asynchronous) invocation - note the required .AddStatement()
call to separate the two commands:
IAsyncResult async =
ps.AddCommand("Import-Module").AddArgument(@"<your-module-path-here>")
.AddStatement()
.AddCommand("GetRowAndPartitionKey").AddParameter("Properties", parameterList)
.BeginInvoke();
"<your-module-path-here>"
refers to the full file-system path of the module that contains the Get-RowAndPartitionKey
cmdlet; depending on how that module is implemented, it is either a path to the module's directory, its .psd1
module manifest, or to its .dll
, if it is a stand-alone assembly.
Alternative import method, using the PowerShell SDK's dedicated .ImportPSModule()
method:
This method obviates the need for an in-session Import-Module
call, but requires extra setup:
.ImportPSModule()
on it to import the module.PowerShell.Create()
var iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[] { @"<your-module-path-here>" });
var ps = PowerShell.Create(iss);
// Now the PowerShell commands submitted to the `ps` instance
// will see the module's exported commands.
Caveat: A PowerShell
instance reflects its initial session state in .Runspace.InitialSessionState
, but as a conceptually read-only property; the tricky part is that it is technically still modifiable, so that mistaken attempts to modify it are quietly ignored rather than resulting in exceptions.
To troubleshoot these calls:
Check ps.HadErrors
after .Invoke()
/ .EndInvoke()
to see if the PowerShell commands reported any (non-terminating) errors.
Enumerate ps.Streams.Errors
to inspect the specific errors that occurred.
See this answer to a follow-up question for self-contained sample code that demonstrates these techniques.
Upvotes: 3