3

I have been looking around here but unable to get specifics on implementing this PowerShell cmdlet in C#. I attempted the following but failed to get it to compile and run.

The cmdlet I would like to run in PowerShell from C#:

Restart-Computer -Computername (Get-Content C:\machineslist.txt) -Credential Administrator -Force

Here is my humble attempt:

PowerShell ps = PowerShell.Create();
ps.AddCommand("Restart-Computer");
ps.AddParameter("-ComputerName");
ScriptBlock filter2 = ScriptBlock.Create("(Get-Content C:\\machineslist.txt)");
ps.AddParameter("FilterScript2", filter2);
ps.AddParameter("-Credential");
ps.AddArgument("Administrator");
//not sure how to add password
ps.AddParameter("-Force");
foreach (PSObject result in ps.Invoke())
{
    Console.WriteLine(
        "{0,-24}{1}",
        result.Members["Length"].Value,
        result.Members["Name"].Value);
} // End foreach
3
  • 1
    What was the error on compile? Commented Nov 18, 2016 at 10:37
  • Also, take a look at this implementation: blogs.msdn.microsoft.com/kebab/2014/04/28/… Commented Nov 18, 2016 at 10:39
  • - is not a part of parameter name. Commented Nov 18, 2016 at 14:07

1 Answer 1

1

To make this code snippet to compile and run, you will first need to reference the System.Management.Automation assembly (located under C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0).

  • You do not need a ScriptBlock as it increases complexity, it's easier to just add the script with AddScript.

  • You do not need to prefix parameters with -

  • To pass credentials you can use PSCredential. Normally you would provide a secure string, you can translate a string into a secure string using NetworkCredential as an helper.

  • You will need to handle errors as well, but this is out of scope for this question!

Enjoy :-)

using System;
using System.Management.Automation;
using System.Net;
using System.Security;

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            PowerShell ps = PowerShell.Create();

            ps.AddScript("Get-Content C:\\machineslist.txt");

            ps.AddCommand("Restart-Computer");

            SecureString secureString = new NetworkCredential("", "Password").SecurePassword;
            PSCredential psc = new PSCredential("Administrator", secureString);
            ps.AddParameter("Credential", psc);

            ps.AddParameter("Force");

            // Simulation only
            ps.AddParameter("WhatIf");

            var results = ps.Invoke();

            foreach (var error in ps.Streams.Error)
            {
                Console.WriteLine(error);
            }

            foreach (PSObject result in results)
            {
                Console.WriteLine(result);
                //Console.WriteLine("{0,-24}{1}", result.Members["Length"].Value, result.Members["Name"].Value);
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your help, Cebe. I tried to run the code but I ran into "Computer name Computer cannot be resolved with the exception: One or more errors occurred." The machineslist.txt just contain a list of ip addresses. I tried names too but it does not work. Not sure what is missing. I have also tried ps.AddArgument("computerName"). Any ideas? Thanks.
Getting a bit out of scope there :) Is there a header in your machineslist.txt ? because it literally says it tries to reach a computer named "Computer". You should get the same error message when running the native Powershell statement. BTW, you could add a -WhatIf parameter to do a dry run.
nope, there is no header. just a text file containing ip addresses in column format. It can be just 1 ip too. I had tried with one too but still ran into same thing. It ran perfect in Powershell though.
I am still troubleshooting. Problem is ps.AddScript("Get-Content C:\\machineslist.txt"). Still trying to figure how to make this work. If I use ps.AddParameter("ComputerName", "x.x.x.x") without addscript, it works.
Sorry, my code sample was wrong. It's actually not possible to combine a command and a script the way I previously did; the new code sample is equivalent to Get-Content C:\machineslist.txt | Restart-Computer -Credential Administrator -Force -WhatIf That is, we pipe the output of Get-Content to Restart-Computer. Should work now!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.