0

I have written an application that installs Windows Roles and Features using the Powershell API. It works just fine in Windows 2008 R2, but nothing happens in Windows 2012; the program just moves on as if everything happened just fine, but nothing is installed.

I've tried making the program .NET v4.5 (it was .NET v2.0), but that didn't help. I've been all over Google about this and I can't find a solution that works. In fact, most say to use the sort of implementation that works in Windows 2008 R2. Here is my code:

        public bool runPowerShell(string command, string args)
    {
        mLogger myLogger = mLogger.instance;  //How I log stuff in my application.
        bool done = false; //default Return value.
        const string path = @"C:\\XMPLogs\\Roles and Features"; //Where Powershell output will go.

        //Make sure Powershell log directory is there.
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);

        //Start a new Powershell instance.
        PowerShell powershell = PowerShell.Create();
        System.Collections.ObjectModel.Collection<PSObject> output = new System.Collections.ObjectModel.Collection<PSObject>();
        StringBuilder strBuilder = new StringBuilder(); //Used to examine results (for testing)
        powershell.AddScript(@"Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted");
        powershell.AddScript(@"Import-Module ServerManager");
        //powershell.Invoke();

        powershell.AddScript(command + " " + args);
        try
        {

            output = powershell.Invoke();

            // Construct a StringBuilder to examine the output of Invoke()
            foreach (PSObject obj in output)
                strBuilder.AppendLine(obj.ToString());

            // Show the StringBuilder to see results (always empty!)
            MessageBox.Show(strBuilder.ToString());
            done = true;
        }
        catch (Exception ex)
        {
            string test = ex.ToString();
            MessageBox.Show(test);
            myLogger.output("ERRO", "PowerShell command " + command
                + "failed to run with arguments \"" + args + "\".  Message:  " + ex.ToString());
            done = false;
        }

        powershell.Dispose();
        return done;
    }

I would call the method like this:

runPowerShell("add-windowsfeature", "-name FS-FileServer -logpath \"c:\\XMPLogs\\Roles and Features\\File Services.log\"");

The "output" object never has any data in it nor does the log file. So, I have no idea what is going on. I do know if I take the two parameters in the method call and enter them into a Powershell prompt manually, the install runs flawlessly.

Can anyone see what I'm doing wrong with this implementation on Windows Server 2012?

Thank you.

breusshe
  • 59
  • 1
  • 15

1 Answers1

0

It's hard to know what is the real problem here, without more information. Perhaps you're not running your application as an administrator and therefore aren't allowed to add windows features?

However, PowerShell differs between terminating errors (which would block the execution and throw an exception, which should make your code enter the catch statement) and non-terminating errors (which are just written to the error stream and will not enter your catch statement).

You can read more about this if you run Get-Help Write-Error, Get-Help about_Throw and Get-Help about_Try_Catch_Finally.

I'm guessing your powershell command results in a non-terminating error. To find out whether a non terminating error has occured or not, you could check the powershell.HadErrors property and to get the error messages you can read the powershell.Streams.Error property.

This should probably help you in finding out what errors are occuring and hopefully help you solve your problem.

Robert Westerlund
  • 4,750
  • 1
  • 20
  • 32
  • That did help, thank you. I now know my errors. However, I'm wondering what I should look at to correct them. Basically, the modules I'm trying to run as stated as not being found. However, like I stated in my original post, I can open Powershell command prompt and run these commands manually with no issues. See my next comment for an example. – breusshe Apr 02 '14 at 18:59
  • [INFO]: [04/02/2014 13:56:54 -05:00] - ***Installing .NET v3.5.1 Feature*** [ERRO]: [04/02/2014 13:56:54 -05:00] - add-windowsfeature -name NET-Framework-Core -logpath "c:\XMPLogs\Roles and Features\.NET v3.5.1.log" The specified module 'ServerManager' was not loaded because no valid module file was found in any module directory. [ERRO]: [04/02/2014 13:56:54 -05:00] - add-windowsfeature -name NET-Framework-Core -logpath "c:\XMPLogs\Roles and Features\.NET v3.5.1.log" – breusshe Apr 02 '14 at 19:02
  • The term 'add-windowsfeature' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. – breusshe Apr 02 '14 at 19:02
  • I know ServerManager and add-windowsfeature exist. I can use them. What can't the Powershell API find them in my C# code? I'm running the application with elevated privileges, so it shouldn't be an access rights issue. – breusshe Apr 02 '14 at 19:04
  • Found the answer. I had to compile the code as x64 only. More information on what was happening at this link: [Powershell commands from C# 'the term is not recognizes as cmdlet'](http://stackoverflow.com/questions/20272931/powershell-commands-from-c-sharp-the-term-is-not-recognizes-as-cmdlet?rq=1) – breusshe Apr 02 '14 at 20:13
  • Thanks, Robert for your input. Getting my log errors known to me made all the difference. – breusshe Apr 02 '14 at 20:15