Tuesday, July 19, 2016

How to run multiple PowerShell commands in c# (including pre-environment commands like set-adserversettings -viewentireforest:$true)



This allows me to create a script in a string with multiple commands, it processes 1 command at a time and then creates a runspace in c# and runs all of the powershell commands. The amount of commands that you could put inline in the string is endless.


<pre lang="C#">string scriptText = @"$pw = convertto-securestring -AsPlainText -Force -String '<password>'; $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist '<domain>\<username>', $pw;  $session = new-pssession -ConfigurationName Microsoft.Exchange -ConnectionUri '<server url>/powershell' -credential $cred; import-pssession $session; Set-ExecutionPolicy bypass -confirm:$false -force; $pic = ([System.IO.File]::ReadAllBytes('" + <picture file name> + "')); set-userphoto -identity <username> -picturedata $pic -domaincontroller '<dc fqdn>' -confirm:$false;";

              
                runExchangeShellScript(scriptText);</pre>


<pre lang="C#">private string runExchangeShellScript(string scriptText)
        {
           
            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);
            RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
            runSpaceInvoker.Invoke(&quot;Set-ExecutionPolicy Unrestricted&quot;);

            // 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
            // &quot;Get-Process&quot; returns a collection of System.Diagnostics.Process instances.
            //pipeline.Commands.Add(&quot;Out-String&quot;);

            // execute the script
            Collection&lt;PSObject&gt; results = null;
            try
            {
                results = pipeline.Invoke();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.InnerException + &quot; - &quot; + ex.Message + &quot; - &quot; + ex.Source + &quot; - &quot; + ex.StackTrace + &quot; - &quot; + ex.TargetSite + &quot; - &quot; + ex.Data);
                return &quot;&quot;;
            }


            // 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 the results of the script that has
            // now been converted to text
            return stringBuilder.ToString();
        }</pre>