I wonder if you could help me being gods of the C# world and all!
I'm pretty new to C# and i think im a bit out of my depth, but i am trying to use C# to create a wpf that will ask the user for parameters and then pass these parameters to my script to perform an install.
At the moment i have it set to click a button to begin the install as that was requested (no idea why) so on button click i have the following.
string script = System.IO.File.ReadAllText(#"C:\my\script\path\script.ps1");
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.Runspace.SessionStateProxy.SetVariable("SiteCode", GlobalVariables.sitecode);
ps.AddScript(script);
ps.Invoke();
}
My first problem is i need to set the script file location using partially a variable that has been set earlier in the form
Now this i can probably do myself, but calling the powershell script and then setting variables that are used within the powershell script from variables that are declared in the C# form are a bit out of my depth, am i on the right line here? do i look like a complete idiot or should i go bang my head on a tree outside?
Thanks very much in advance for any help you can offer!
Related
I am trying to call PowerShell ISE Script from the C#.
I have command that I am running it on the PowerShell
. .\Commands.ps1; Set-Product -bProduct 'Reg' -IPPoint 'ServerAddress' -Location 'testlocation' -Terminal 3
Now I am trying to create the Command with the c# I have wrote some code Like this.
//Set Execution Policy to un restrict
powershell.AddCommand("Set-ExecutionPolicy");
powershell.AddArgument("unrestricted");
powershell.Invoke();
powershell.Commands.Clear();
powershell.AddScript("K:\\Auto\\Cases\\Location\\Commands.ps1", false);
powershell.AddArgument("Set-Product").AddParameter("bProduct ", "Reg").
AddParameter("IPPoint", "ServerAddress").
AddParameter("Location", "testlocation").AddParameter("Terminal", 3);
powershell.Invoke();
I can see its running fine. But its not updating values in my xml file. It suppose to update my values in file. When I try to run it with powershell It does run and works file. But c# code does not work.
Any hint or clue will be appreciated.
Mind the semicolon, so this is basically two statements:
1.) Dot-sourcing the script Commands.ps1
. .\Commands.ps1
2.) Invoking the cmdlet Set-Product
Set-Product -bProduct 'Reg' -IPPoint 'ServerAddress' -Location 'testlocation' -Terminal 3
So, you have to treat them as such. Also, AddScript expects code, not a file name.
powershell
// dot-source the script
.AddScript(#". 'K:\Auto\Cases\Location\Commands.ps1'")
// this is the semicolon = add another statement
.AddStatement()
// add the cmdlet
.AddCommand("Set-Product")
.AddParameter("bProduct", "Reg")
.AddParameter("IPPoint", "ServerAddress")
.AddParameter("Location", "testlocation")
.AddParameter("Terminal", 3)
// invoke all statements
.Invoke();
(Alternatively to AddStatement() you can of course split this up in two calls and call Invoke() twice.)
I'm trying to make a simple (or so i thought) app that will make it easier to launch .ps1 scripts, so that non-powershell savvy users can use them.
Here is how its supposed to look like
Now, i managed to figure out one part about running scripts:
private string RunPowershell_1(string skripta)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (string str in PowerShell.Create().AddScript(skripta).AddCommand("Out-String").Invoke<string>())
{
stringBuilder.AppendLine(str);
}
return stringBuilder.ToString();
}
But i would normally run scripts that require parameters, so i would like to be able to read list of parameters from the script i import, assign value to them and then run the scrip (output should go to either txtPreview or to a file).
Is there a way to do this?
If there is another (better) approach to this I'm all ears.
You can use this powershell command to get the list of parameters.
(get-command get-netadapter).Parameters
And this is how you can read its output in C#:
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript("...");
Collection<PSObject> output = ps.Invoke();
}
I know that I can get the commands that were defined initially by using something like:
Runspace rs = RunspaceFactory.CreateRunspace();
rs.InitialSessionsState.Commands
or in PowerShell itself:
[System.Management.Automation.Runspaces.Runspace]::DefaultRunspace.InitialSessionState.Commands
But this only represents the state before the runspace was created.
If I import a module (even by manually creating the session state object and using sesh.ImportPSModule() before the runspace is opened), none of those functions or cmdlets will show up in the list.
Same thing if I define a new function with .AddScript() or something.
Is there any way to get the current state of the runspace rather than just the initial state, from outside the runspace?
I thought about just invoking Get-Command from inside the runspace and returning the objects, but it seems.. wrong to me for some reason. I feel like I'm missing something simple here, and there should be a way to just look at the current state and what's defined in it.
Does the function PSProvider work for your needs?
Get-ChildItem function:
Runspace have SessionStateProxy property, which allows you to interact with Runspace SessionState:
$PowerShell = [PowerShell]::Create()
$PowerShell.AddScript{
function SomeFunction {}
function SomeOtherFunction {}
}.Invoke()
$PowerShell.Runspace.SessionStateProxy.InvokeCommand.GetCommands('*','Function',$true)
I have the following Windows batch command that works successfully from the Command Prompt: djoin /provision /domain /machineou /machine /savefile
I have been able to wrap this Windows command in a PowerShell command: Invoke-Expression [djoin command] and it works well when running it locally using PowerShell.
I am failing when I try to take the script in Step #2 and call it from a C# web application. I'm trying the following:
PowerShell ps = PowerShell.Create();
ps.addCommand("Invoke-Expression");
ps.AddArgument("<djoin command>");
The web page doesn't give me any errors and I'm stuck on this. Please let me know if you have any questions and thank you for your help.
If you really want to use the PowerShell engine to execute this, then do it this way:
using (var ps = PowerShell.Create())
{
ps.AddScript("djoin /provision /domain /machineou /machine /savefile");
var results = ps.Invoke();
foreach (var r in results)
{
// do something with r
}
}
Note: the use of Invoke-Expression is unnecessary. Also, as MethodMan suggests in his comment, you could just use System.Diagnostics.Process.Start().
I have a C# application that runs PowerShell scripts after reading them off database as strings. Assume script1, script2 and utilityfunctions are scripts read from database.
var rs = RunspaceFactory.CreateRunspace();
rs.Open();
var ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(utilityFunctions);
ps.AddScript(script1);
Is there anyway possible that I can call functions in utilityFuntions from script1? I have tried using $MyInvocation and go through its properties but did not find anything useful. When going through ps.Commands properties, I can of course see two items but when going through commands within the script, I cannot get to anything inside utilityFunctions. I guess I can read all scripts and concatenate them as string and only pass one script but I am just wondering if there is a way to do it without string concatenation.