How to print the result of a .ps1 in windows form? - c#

I'm creating a system for executing cascaded scripts. There will be a checklist and depending on the option that the user selects, he must execute these lines inside the powershell (.ps1). So that the user can follow the application status of the selected items, I want to print the execution status on the screen. I'm using C# the current command I'm using opens the powershell, and I don't want to make it available to the user.
Code
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
Command command = new Command(#"E:\Users\goku\Downloads\Baseline1.ps1");
pipeline.Commands.Add(command);
pipeline.Invoke();
runspace.Close();
Example
my idea is that this window opens to show the status and when it's done it closes automatically, I don't want to leave an exit button.
thank you if anyone can help.
I didn't find anything that would make it possible to print the result.

Related

C# - Utilize Quest active directory cmdlets for Powershell by calling PS script

C# code (Source):
private string RunScript(string scriptText)
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
// add an extra command to transform the script
// output objects into nicely formatted strings
// remove this line to get the actual objects
// that the script returns. For example, the script
// "Get-Process" returns a collection
// of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
Collection<psobject /> results = pipeline.Invoke();
// close the runspace
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
Powershell code
#Dummy code for example purpose
ASNP Quest*
#Example of cmdlet I want to use
$Users = Get-QADGroupMember -Identity $Group -Enabled
return $Users.count
As you can see, my goal is to call the script utilizing RunScript above in a Button_Click event in my WPF app. I've been able to correctly call the script but the call to Quest cmdlets clearly doesn't go trough as wanted since I would receive 0 in the above example.
TL;DR
Script is running correctly but calls to Quest cmdlets don't work since it return nothing (or 0 in the above example). Is there something I'm missing ?
EDIT
Important to note that the exact same script ran in Powershell returns the correct values. Calling it from C# don't.

Run Powershell from C#

I need to start a powershell script from C# and get the PSSSecurityException on pipeline.Invoke()
AuthorizationManager check failed.
My code:
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration))
{
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
Command scriptCommand = new Command(scriptfile);
pipeline.Commands.Add(scriptCommand);
pipeline.Invoke();
}
Questions
I suspect that I need to set PSCredential. But I can not promt for it, so I have to handle this in code. Can this be done in a secure way? (This was not the case)
Check out this SuperUser post: https://superuser.com/questions/106360/how-to-enable-execution-of-powershell-scripts
You probably just need to allow unsigned scripts to run. In the PS console, type the following:
set-executionpolicy remotesigned
Another resource echoes this: http://tgnp.me/2011/09/powershell-authorizationmanager-check-failed-resolution/
Give that a try and let me know what happens.
To capture the output from the script, try this:
Collection output = pipeline.Invoke();
foreach (PSObject psObject in output)
{
<here you can ToString the psObject for the output and write it line by line to your log>
}
The problem was that the script was placed on a share. To run scripts on this share I needed to add the share to Trusted Sites.

Adding a Batch/Powershell file to a compilation (Build) C# Powershell

I'm working on a c# project where i'm trying to run powershell scripts, output them to a CSV and read the CSV and output it to a Checked list box.
I've added a powershell file as a resource with Build Action 'Compile' and Copy to output directory 'Do Not Copy'.
The basic content of the file is :
Get-CimInstance -Query "SELECT * from Win32_Service where name LIKE 'sql%'" | select Name, State , StartMode | convertto-csv > proctest.csv
i try to access this file using this string
string ps_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\GetSvc.ps1";
The PS code i use is
RunspaceConfiguration runspaceconfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceconfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
Command mycommand = new Command(ps_path);
pipeline.Commands.Add(mycommand);
pipeline.Invoke();
runspace.Close();
This works fine during compilation but when i build an exe and try to run it, i get an error saying the GetSvc.ps1 file is not found.
How do i make the file a part of the build ?!
Make the build action for the script be Embedded Resource. Then take a look at lines 149-155 on how to extract the script inside the C# exe. In this example, I had zipped the script to compact it. If you skip that step then you can remove line 152 and in line 153 use stream instead of gZipStream.

Powershell command through C# code

I want to add through C# code Powershell command or script (what is correct?) variable declaration with default value stored in C# variable.
For example, in Powershell I typing following line
$user = 'Admin'
I want to add this line in C# code.
powershell.AddScript(String.Format("$user = \"{0}\"", userName));
or
powershell.AddCommand(String.Format("$user = \"{0}\"", userName));
I try with AddCommand() but it throws exception. I use PS 2.0.
According to this article How to run PowerShell scripts from C#, you will need something like this:
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(String.Format("$user = \"{0}\"", userName));
pipeline.Commands.AddScript("#your main script");
// execute the script
Collection<psobject> results = pipeline.Invoke();
// close the runspace
runspace.Close();
Also see Run Powershell-Script from C# Application question here on Stackoverflow.

Cannot invoke this function because the current host does not implement it c#

i know this is on this board, but im new, and nothing has really halped me, so i am hoping someone can provide some insight. i get the following error:
Cannot invoke this function because the current host does not implement it
here is my code
public static void runPowershellScript(string scriptName)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(scriptName);
pipeline.Invoke();
}
the variable i pass through is my script name, it doesnt have a problem.
You're probably using some functions which are host-specific, meaning that any process which hosts the PowerShell engine (e.g. the powershell.exe, powershell_ise.exe, your c# app) has to provide implementations for them.
In general, these would include the *-host functions (write-host, out-host, read-host), the transcript functions (start-transcript, stop-transcript), and some others.

Categories