I am struggling to find a way to execute a multi-line and multi-statement PowerShell script in C# in such a way, that all the results will be available from the Invoke() method. It appears that the commands added by PowerShell.AddScript are always pipelined together . But I would like them to be read, parsed and executed as multiple statements with all of the results of the individual statements being written to the output .
Is that possible?
What I do now:
using PowerShell powerShell = PowerShell.Create();
powerShell.AddCommand("Set-ExecutionPolicy").AddArgument("Unrestricted").AddParameter("Scope", "CurrentUser").AddStatement();
powerShell.AddScript(@"multiple powershell statements
on multiple rows, some of them writing to output"); //No intermediate results will be logged or printed as the script is added as a single pipeline
powerShell.AddScript("$?"); //This is to echo the execution status of the last command into results
var results = powerShell.Invoke();
The results collection contains only one result, and that is the echo of the last $? statement which I then query to find out pass/fail information. I also query Error stream but that is not relevant to the question.
The problem is: I receive the PowerShell script as a user input and therefore cannot modify it and add as statements. I was thinking about adding the script line by line, but it will break possible multiline pipelines, codeblocks etc. So to reach the result I want I would need to parse the script myself which sounds quite complex. Is there any elegant solution to receive all the results from Invoke() and most importantly, add a complex script from user input without it being crushed together as a single pipeline, feeding results of one command to another?
Simply use string concatenation to append the $?
statement to the statements received, preceded by a ;
(statement separator):
powerShell.AddScript(@"multiple powershell statements
on multiple rows, some of them writing to output" + ";$?");
That way, all statements are submitted as a single script [block] (piece of PowerShell code).
Successive .AddScript()
calls aren't cumulative - the last one "wins".
Alternatively, append .AddStatement()
to each .AddScript()
call , analogously to how you're already doing for the .AddCommand()
call that changes the execution policy.
However, it's more efficient to pass only a single piece of PowerShell code, using a single .AddScript()
call , as shown above.
Finally, the obligatory security warning :
I receive the PowerShell script as a user input
Unless you check and potentially sanitize the input first, only execute it if you trust the source.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.