Run PowerShell script from C# writing to input pipe

Hello,
I am trying to run a PowerShell script from C# (I have no control over what's in the script). The script may have a prompt like "Press enter to continue". So my goal is:
1. Get text output from the script (easy, many examples available)
3. If output contains "Press enter to continue", write a blank line to the running script's pipe to make it finish its job and quit
4. If output does contain that prompt, just let it exit by itself without sending any input
Note that commands in this PS script also try to get at script's file path, so I can't read script from file and pass it as text. It has to be executed as a script so it knows where it's located.
I have done this with .exes and batch files before. All you do in that case is process.StandardInput.WriteLine() which "types" enter into the input stream of script you are trying to control. But this does not work with Power Shell. How do I do this?
I have tried using PS object model like so:
using (Pipeline pipeline = runspace.CreatePipeline())
Command command = new Command(scriptPS, true, true);
   pipeline.Commands.Add(command);
   pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
   pipeline.Input.Write("\n");
   Collection<PSObject> psresults = pipeline.Invoke();   //...
But I get an error because the script prompts:
"A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related
commands from command types that do not support user interaction, such as Windows PowerShell workflows."
I also tried using Process, and running PowerShell with -File switch to execute the script, then write to StandardInput with C#. I get no errors then, but the input is ignored and doesn't make it to PowerShell.
Please help!

No man, what kind of answer is that? You should have left it unanswered rather than waste people's time like this. I already seen those links before I posted my question. They address the issue of specifying script parameters, but not
writing to the input pipe.
Fortunately I did figure this out by writing a custom script host for PowerShell. Anyone interested can read about this in detail on MSDN (fortunately simple material with samples you can copy paste as I did, so this solution takes little time to implement).
Implement PSHost interface. Nothing special here, just paste directly from MSDN sample and modify their SetShouldExit function definition to contain just a "return;". Here's the relevant link:
http://msdn.microsoft.com/en-us/library/windows/desktop/ee706559(v=vs.85).aspx
Implement PSHostUserInterface interface. This is the ticket to solving this problem
(see below). Here's the MSDN link:
http://msdn.microsoft.com/en-us/library/windows/desktop/ee706584(v=vs.85).aspx
Implement PSHostRawUserInterface. This may not be required (not sure) but I did anyway. Nearly a direct paste from MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/ee706601(v=vs.85).aspx
So, there are two PSHostUserInterface function implementations that are of particular interest. First is Prompt (read header comment to see why):
/// <summary>
/// When script attempts to get user input, we override it and give it input programmatically,
/// by looking up within promptInput's dictionary<string,string> or lineInput array.
/// PromptInput dictionary is mapped by input prompt (for example, return "" in response to "Press ENTER to continue")
/// LineInput is a regular array, and each time the script wants to prompt for input we return the next line in that array;
/// this works much like piping inputs from a regular text file in DOS command line.
/// </summary>
/// <param name="caption">The caption or title of the prompt.</param>
/// <param name="message">The text of the prompt.</param>
/// <param name="descriptions">A collection of FieldDescription objects that
/// describe each field of the prompt.</param>
/// <returns>Throws a NotImplementedException exception.</returns>
public override Dictionary<string, PSObject> Prompt(string caption, string message, System.Collections.ObjectModel.Collection<FieldDescription> descriptions)
Dictionary<string, PSObject> ret = new Dictionary<string, PSObject>();
foreach (FieldDescription desc in descriptions)
if (this.promptInput.Count != 0)
ret[desc.Name] = new PSObject(this.promptInput[desc.Name] + "\r\n");
else if (this.lineInput != null && this.currentLineInput >= 0 && this.currentLineInput < this.lineInput.Length)
ret[desc.Name] = new PSObject(this.lineInput[this.currentLineInput++] + "\r\n");
else
if (desc.DefaultValue == null)
ret[desc.Name] = new PSObject("\r\n");
else
ret[desc.Name] = new PSObject(desc.DefaultValue);
return ret;
Next is PromptForChoice. Here I opted to always return the default choice, but you could rewrite it to read from somewhere to "simulate" reading from input pipe just like the function above:
public override int PromptForChoice(string caption, string message, System.Collections.ObjectModel.Collection<ChoiceDescription> choices, int defaultChoice)
        return defaultChoice;
Last but not least, here's a ReadLine implementation (again read header comment):
/// <summary>
/// If the LineInput is set, "read" the next line from line input string array, incrementing line pointer/// </summary>
/// <returns>The characters that are entered by the user.</returns>
public override string ReadLine()
if (this.lineInput != null && this.currentLineInput >= 0 && this.currentLineInput < this.lineInput.Length)
return this.lineInput[this.currentLineInput++];
else
return Console.ReadLine();
Both are exposed as properties:
/// <summary>
/// Gets or sets the input pipe override
/// </summary>
public string Input
get
return string.Join("\n", this.lineInput);
set
if (value != null)
this.lineInput = value.Split('\n');
this.currentLineInput = 0;
else
this.lineInput = null;
/// <summary>
/// Gets or sets input pipe override for named prompts
/// </summary>
public Dictionary<string, string> PromptInput
get
return this.promptInput;
set
this.promptInput = value;
And finally, here's how the whole shebang is used:
/// <summary>
/// Runs a powershell script, with input pipe arguments
/// </summary>
/// <param name="script">Path of the script to execute, or script text</param>
/// <param name="inline">Whether or not to execute script text directly, or execute script from path</param>
/// <param name="unrestricted">Whether or not to set unrestricted execution policy</param>
/// <param name="parameters">Parameters to pass to the script command line</param>
/// <param name="inputOverride">Input to pass into the script's input pipe</param>
/// <param name="inputOverrideName">Input to pass into the script's input pipe, to each prompt by label</param>
/// <returns>Output lines</returns>
public static string PowerShell(string script, bool inline, bool unrestricted = false, Dictionary<string, string> parameters = null, string inputOverride = null, Dictionary<string, string> inputOverrideByName = null)
string output = null;
ScriptHost host = new ScriptHost();
(host.UI as ScriptHostUserInterface).Input = inputOverride;
(host.UI as ScriptHostUserInterface).PromptInput = inputOverrideByName;
using (Runspace runspace = RunspaceFactory.CreateRunspace(host))
runspace.Open();
if (unrestricted)
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
using (Pipeline pipeline = runspace.CreatePipeline())
if (inline)
pipeline.Commands.AddScript(script);
else
Command command = new Command(script, true, true);
foreach (KeyValuePair<string, string> param in parameters)
command.Parameters.Add(param.Key, param.Value);
pipeline.Commands.Add(command);
pipeline.Commands.Add("Out-String");
pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
Collection<PSObject> psresults = pipeline.Invoke();
var sb = new StringBuilder();
foreach (PSObject obj in psresults)
sb.AppendLine(obj.ToString());
output = sb.ToString();
pipeline.Dispose();
runspace.Close();
return (host.UI as ScriptHostUserInterface).Output + "\r\n" + output;
As you can see, I also did some magic with the .Output property. That just accumulates lines of text output by the script in every WriteXXX function implemented in your custom PSHostUserInterface. The end result of all this, is that if you have a script
that has prompts, choices or reads from standard input, you can execute the script within the context of your custom script host written as above, to control precisely what strings are passed to it in response to prompts.
 

Similar Messages

  • Run Powershell script from Scheduled Task as "NT Authority \ SYSTEM"

    Hello, dear Colleagues.
    Cannot make Powershell script from Scheduled Task as "NT Authority \ System"
    Action: Start a program - 
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "C:\script.ps1"
    The matter is that script is working, moreover if to run Task with Domain Account it works too.
    Checked Run with highest privileges, changed "Configure for" field, tried different arguments (-noprofile, -noexit, -executionpolicy bypass, -command, -file,") - no luck.
    Didn't you try to make it work with SYSTEM account?
    Thanks.

    Hi fapq,
    Try this link task schedulers
    Note
    To identify tasks that run with system permissions, use a verbose query (/query/v). In a verbose query display of a system-run task, the Run As User field has a value of NT AUTHORITY\SYSTEM and
    the Logon Mode field has a value of Background only.
    Naveen Basati

  • Run PowerShell Script from a Event Receiver

     Hi,
    Just looking around on the net for some documentation for running a PowerShell script via an Event Receiver. We want to be able to make changes to the script and not change anything in the ER.
    Sadly using a workflow isn't an option here.
    Looking for websites that give some examples really, or if anyone has done this.
    Regards
    If this is helpful please mark it so. Also if this solved your problem mark as answer.

    Hi TemPart:
    string cmdArg = “C:\\Scripts\\test.ps1″;
    Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(cmdArg);
    Collection [PSObject] results = pipeline.Invoke(); // please Update [] bracket with less then and greater then bracket
    runspace.Close();
    Had to modify this slightly:
    string cmdArg = “Powershell.exe -file C:\\Scripts\\test.ps1″;
    Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(cmdArg);
    Collection [PSObject] results = pipeline.Invoke(); // please Update [] bracket with less then and greater then bracket
    runspace.Close();
    If this is helpful please mark it so. Also if this solved your problem mark as answer.

  • Run powershell script from context menu

    Hi guys!
    I do not know if what I'm going to
    ask you is achievable.
    This is what I want:
    when I click with the right mouse button
    a file, possibly with certain extensions,
    the context menu appears, and
    here I would to create an
    object that can run the script that I have created
    and assign as an argument the selected file.
    It would also be necessary that such an object is
    similar to the"send to" button.
    Browsing the net I had found the
    script to create such an object, however,
    I have no idea on how to implement it
    and then how to run my script.
    Thanks

    Hi jrv!
    Initially, I will try to follow your suggestion but I'd prefer to use some automation, possibly related to powershell as required, because i must do this thing on many computers.
    Thanks
    A
    Y((ou would do that with Group Policy as it is just a registry update.
    ¯\_(ツ)_/¯

  • Run Powershell Script from Server

    I am new to MDT so please forgive me.  I am looking for a way for the MDT server to run a script locally after a server has been deployed.  I saw you can do something similar where you use remoting in the task sequence.  That is not
    allowed or enabled in my environment.  Is there any way for the MDT server to know it is done then it runs a script?

    The unattend file has several locations that scripts could be run from, either in the specialize pass or oobeSystem pass. 
    http://technet.microsoft.com/en-us/library/cc748874(v=ws.10).aspx -- this also gives you some demos on how to create your own unattend, though most basic settings are handled by
    MDT.
    You could also look into utilizing the run and runonce keys -
    http://msdn.microsoft.com/en-us/library/aa376977%28v=vs.85%29.aspx

  • Issue with running powershell script in pssessions

    Hi Everyone,
    I am trying to run powershell script from remote machine using below commands
    C:\Users\user>"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
    -command "$s= New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri
    http://Exchservername/PowerShell/ -Authentication Kerberos ; Import-PSsession $s; "C:\Failback.ps1"
    and Below is the failback.ps1.
    $mbxs = Get-MailboxDatabase | Sort Name
    ForEach($mbx in $mbxs)
    $MBdb=$mbx.Name $ServerHosting=$mbx.Server.Name
    if($mbx.activationPreference.value -eq 1)
    If ($ServerHosting -ne $ActivationPreference.Key.Name) 
    Move-ActiveMailboxDatabase $MBdb -ActivateOnServer $ActivationPreference.Key.Name -confirm:$False 
    Below is what i am getting.

    What is your question?  Are you pointing out the yellow text?  This is normal, and appears every time EMS is opened.
    I should also point out that Microsoft provides a script to re-balance databases, if that's what you're trying to accomplish:
    You can use the RedistributeActiveDatabases.ps1 script to balance the active mailbox databases copies across a DAG. This script moves databases between their copies in an attempt to have an equal number of mounted databases on each server in DAG. If required,
    the script also attempts to balance active databases across sites.
    https://technet.microsoft.com/en-us/library/dd335158(v=exchg.141).aspx
    Mike Crowley | MVP
    My Blog --
    Baseline Technologies

  • Does Forefront Endpoint Protection 2010 block powershell scripts from running?

    Hi all,
    I have a task that runs a Powershell script on a set schedule on a particular machine.  It has failed to run and I thought 1 of the potential reasons would be that FEP 2010 blocks the Powershell script from being run.  Does FEP 2010 do that?  If so, where can I find the setting to allow Powershell scripts (or VB scripts or Java scripts) to be run by my task?
    Thanks for your help in advance.
    Howard Lee - Microsoft

    If the script detect as malicious , FEP will block it, otherwise it won't block normal and safe PowerShell scripts. You may take a look at event viewer and see whether it being blocked or detect as malicious code by FEP or not.

  • Can we execute a Powershell script from the Javascript?

    Hi,
    I have a certain requirement to add a Custom ribbon button in document library and there was a powershell script to be run for the selected item in the library.
    I have struck with executing a Powershell script from the javascript function.
    Can anyone please suggest me if this was achievable
    Thanks, Swaroop Vuppala

    Hi Swaroop,
    To execute server side code in a custom ribbon button script, using application page is a common way to do this, besides, you can also use a page dialog, which is similar with application page but display as model dialog, another way is javascript
    _dopostback and delegate control, the following article contains detailed information about this, please refer to it for more information:
    Invoke server side code on SharePoint ribbon click:
    http://sharepointnadeem.blogspot.in/2012/07/invoke-server-side-code-on-sharepoint.html
    Thanks,
    Qiao Wei
    TechNet Community Support

  • Running  sql scripts from different directory

    Hi
    I have sql scripts in different directories as follows:
    D:\myapp\sql
    - load.sql
    - init.sql
    D:\myapp\sql\schema
    -users.sql
    -structure.sql
    D:\myapp\sql\populate\
    - data1.sql
    - data2/sql
    load.sql call all the other scripts as below:
    @init.sql
    @schema\users.sql
    @schema\structure.sql
    @populate\data1.sql
    @populate\data2.sql
    All my scripts run correctly when I run load.sql from D:\myapp\sql on comand prompt.
    I need a way to run this script from a different directory say D:\ or C:\
    I am writing a installer which will execute from a different directory.
    Right now I get a file not found error for scripts within schema an populate folder.
    Please let me know how can I make this work from a different directory.
    Thanks
    kelvin

    Hi peter. i think you cannot run files spread across different locations.
    --the method which u specified always looks to the defined path                                                                                                                                                                                                                                                                                       

  • Passing parameters with spaces to SCCM Run PowerShell Script task

    I am working on an OS deployment task sequence in SCCM 2012 R2 with several Run PowerShell Script tasks.  Most of them run fine, but I am having trouble with the one I need to pass parameters to.
    The parameters I need to pass are:
    -ComputerOU "ou=All Workstations,dc=contoso,dc=com" -GroupDN "cn=Group1,ou=All Groups,dc=contoso,dc=com"
    I have that line (with actual DNs) entered in Parameters of the task.
    But when the script runs on the target machine, the values of the parameters in the script are truncated at the spaces.  $ComputerOU is set to "ou=All" and $GroupDN is set to "cn=Group1,ou=all"
    What syntax should I be using the Parameters field of the Task in order to properly pass PowerShell parameter string values that include spaces?
    Tim Curwick
    MadWithPowerShell.com

    Thank you, TC, but I am not calling the parameters from within PowerShell.
    The parameters are in the settings of a task sequence task to be used by the task to launch a script.  The syntax I am using would be correct for use within PowerShell or from a command line or batch script, but SCCM appears to be doing some parsing
    before or while it is passing them to the script, possibly dropping the quotes which causes mishandling of the spaces in the string values.
    Historically, it is always challenging to give one application parameters to pass to another application, and the required syntax can get quite tricky when the two application handle quotes or spaces differently, or when the parent application wants to parse
    something intended to be passed on as is to the child application.
    I'm sure someone has already figured out what the syntax needs to be for doing this with an SCCM 'Run PowerShell Script" task, it's just one of those issues that is hard to Google effectively.
    Any other ideas?
    Tim Curwick
    MadWithPowerShell.com

  • Execute powershell script from ssis?

    Hi,
    I was trying to use the execute process task to kick off a powershell script.  However, nothing happens when I run in debug (the component turns yellow and stays yellow).  Any idea if what I am trying to do is possible and the proper way to configure
    it?
    btw, I am using powershell for the remoting capabilites.  I need to execute a bat file on a remote server which runs a process in a legacy program. 
    Update:  When I name the ps1 script file in the executable window, it opens it in notepad.  This would be like the default if you double clicked the file.
    Mark

    To run a PowerShell Script from SSIS package. Add a "Execute Process Task" in SSIS and use the following command text.
    This works just great, plus the "-ExecutionPolicy ByPass" switch will take care of any server script policies.
    C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe
    -ExecutionPolicy ByPass -command ". 'L:\Powershell_Script\Script1.ps1' 'param1' 'param2'"
    Regards
    Deepak

  • Execute a powershell script from a windows store apps

    Hello Everybody !
    I'd like to launch a powershell script from a windows store apps.
    In fact the purpose is install a windows store apps from an other windows store apps.
    Any ideas?
    Thanks

    If it's a sideloaded LOB application, you can do this using a brokered component:
    http://blogs.msdn.com/b/wsdevsol/archive/2014/04/14/cheat-sheet-for-using-brokered-windows-runtime-components-for-side-loaded-windows-store-apps.aspx
    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.
    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined
    objects and unknown namespaces.

  • Valid sesion for run jython script from a plan

    If I run a cr_clij script i have to do
    app.execStr('udb.login -u user -p password') once and do not produce the login information anymore.
    It is possible to do the same with the sessionID, if I run the script from a plan on the BUI? Or do I have to add the '-s sessionID' option to all clui commands?
    Thanks

    Hi TemPart:
    string cmdArg = “C:\\Scripts\\test.ps1″;
    Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(cmdArg);
    Collection [PSObject] results = pipeline.Invoke(); // please Update [] bracket with less then and greater then bracket
    runspace.Close();
    Had to modify this slightly:
    string cmdArg = “Powershell.exe -file C:\\Scripts\\test.ps1″;
    Runspace runspace = RunspaceFactory.CreateRunspace();
    runspace.Open();
    Pipeline pipeline = runspace.CreatePipeline();
    pipeline.Commands.AddScript(cmdArg);
    Collection [PSObject] results = pipeline.Invoke(); // please Update [] bracket with less then and greater then bracket
    runspace.Close();
    If this is helpful please mark it so. Also if this solved your problem mark as answer.

  • How can i run unix script from my apex page

    how can i run unix script from my apex page and take the output of unix script as a hidden variable and display it on the report region of that page

    I had a requirement to run a Fortran program against some data that woudl be extracted from the database after the user set up their filtering criteria and made some additional input. SInce the program was to complex to conver to PL/SQL, we decided to try and invoke it from Apex. This is how I did it.
    1. I followed the steps in Tim Archer's excellent article "Oracle External Procedure to Run Host Commands" (http://www.timarcher.com/?q=node/9). If the link does nto work, google the article's title.
    Using this steps I created a function which accepts any OS command, including calling my own shell scripts, and runs them. I called my PL/SQL function "shell" instead of "USF_RUN_HOST_CMD " as Tim did in his example (step 9).
    2. In Apex,
    a. I created a button to run my shell command. (I named it P2_RUN_SHELL)
    b. I created a PL/SQL process whose source looks as follows:
    shell('/home/ackness/scripts/cr_xcf_file.sh > /tmp/cr_scfp_file.log');
    and which was conditioned on the the button P2_RUN_SHELL.
    It works like a charm.
    Note: since you can run your own scripts using this method, you can encapsulate a series of commands in a UNIX shell script and invoke that script from Apex. This allows you to be able to test or run you commands from the command line as well as Apex and makes it easier to develop/debug/enhance the scripts in the future.
    Ackness

  • IDCS5-win. Error while running a script from indesign(not via estk)

    Hi all,
    After running the script from indesign, I get following error
    ASSERT '(engine->getDebugFlags() & ScScript::kExtendedErrors) == ScScript::kExtendedErrors' in ..\..\..\source\components\script\javascript\JavaScriptRunner.cpp at line 412 failed.
    ..\..\..\source\components\script\javascript\JavaScriptRunner.cpp (412)
    any idea about this?
    The script runs fine when run from ES tool kit.
    Thanks

    Hi,
    My colleague found the problem. We were using extendables library and we still haven't figured out what was actually happening, but removing it solved the problem.

Maybe you are looking for

  • Set variable date in a procedure with current month and previous month

    Hi guys, I need to set two date range in one procedure. The date should be @datefrom the third day of the current month @dateto the seventh day of the current month @datefrom-1 the third day of the previous month @dateto-1 the seventh day of the prev

  • 2 problems, iPod nano battery depleted and not recognized by Windows, help!

    Earlier this morning. At first when I connected the usb to the computer I got the screen in the nano that said "apple.com/ipod/support" or something like that, with the folder/exclamation mark icon. It was charging but I disconnected it cause I had t

  • How do I install PS from CS 4 discs?

    Ok, this may be the dumbest question of the day. I have student version of CS 4 with three discs - App 2, Content and Learning. I put each of the first two in the CD drive and it spins but no install message. I look at the top files: AUTORUN & an ico

  • OS X 10.3.9 and Toast 5.2.3

    Switched systems on my PowerMac G4 from OS 9.2.2 to OS X 10.3.9 and Toast 5.2.1 (and 5.2.3) "unexpectedly quits" when accessing the CD drive. These Toast versions are supposed to be good with both systems. I have tried everything I can think of - re-

  • Group-Role Mapping OBIEE 11.1.1.6

    Scenario: I have created some groups in console. Let the groups be A, B, C and D. Now I want to create a role call it Manager and map A,B, C and D groups to Manager role in EM. And then give permissions (like Dashboard access) on Manager role. Issue: