Reputation: 2184
I'm trying to learn how to call PS cmdlets from C#, and have come across the PowerShell class. It works fine for basic use, but now I wanted to execute this PS command:
Get-ChildItem | where {$_.Length -gt 1000000}
I tried building this through the powershell class, but I can't seem to do this. This is my code so far:
PowerShell ps = PowerShell.Create();
ps.AddCommand("Get-ChildItem");
ps.AddCommand("where-object");
ps.AddParameter("Length");
ps.AddParameter("-gt");
ps.AddParameter("10000");
// Call the PowerShell.Invoke() method to run the
// commands of the pipeline.
foreach (PSObject result in ps.Invoke())
{
Console.WriteLine(
"{0,-24}{1}",
result.Members["Length"].Value,
result.Members["Name"].Value);
} // End foreach.
I always get an exception when I run this. Is it possible to run the Where-Object cmdlet like this?
Upvotes: 24
Views: 19396
Reputation: 52410
Length
, -gt
and 10000
are not parameters to Where-Object
. There is only one parameter, FilterScript
at position 0, with a value of type ScriptBlock
which contains an expression.
PowerShell ps = PowerShell.Create();
ps.AddCommand("Get-ChildItem");
ps.AddCommand("where-object");
ScriptBlock filter = ScriptBlock.Create("$_.Length -gt 10000")
ps.AddParameter("FilterScript", filter)
If you have more complex statements that you need to decompose, consider using the tokenizer (available in v2 or later) to understand the structure better:
# use single quotes to allow $_ inside string
PS> $script = 'Get-ChildItem | where-object -filter {$_.Length -gt 1000000 }'
PS> $parser = [System.Management.Automation.PSParser]
PS> $parser::Tokenize($script, [ref]$null) | select content, type | ft -auto
This dumps out the following information. It's not as rich as the AST parser in v3, but it's still useful:
Content Type ------- ---- Get-ChildItem Command | Operator where-object Command -filter CommandParameter { GroupStart _ Variable . Operator Length Member -gt Operator 1000000 Number } GroupEnd
Hope this helps.
Upvotes: 23