Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does invoking PowerShell from C# throw a System.Management.Automation.CommandNotFoundException?

Tags:

c#

powershell

I'm using this c#:

    public bool RunPowershell(string script)
    {
        RunspaceConfiguration runspaceConfig = RunspaceConfiguration.Create();

        using (Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfig))
        {
            runspace.Open();

            using (RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace))
            {
                scriptInvoker.Invoke(script);
            }
        }

        return true;
    }

To run this script:

      Add-PSSnapin -name Microsoft.SystemCenter.VirtualMachineManager
      $vmm = Get-VMMServer -ComputerName "VmmComputerName"

It works ok on a Windows 2003 32bit OS, but on a Windows 2008R2 64bit, I get this error:

System.Management.Automation.CommandNotFoundException: The term 'Get-VMMServer' 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.
at System.Management.Automation.CommandDiscovery.LookupCommandInfo(String commandName, CommandOrigin commandOrigin)
at System.Management.Automation.CommandDiscovery.LookupCommandProcessor(String commandName, CommandOrigin commandOrigin, Nullable`1 useLocalScope)
at System.Management.Automation.CommandFactory._CreateCommand(String commandName, CommandOrigin commandOrigin, Nullable`1 useLocalScope)
at System.Management.Automation.ExecutionContext.CreateCommand(String command)
at System.Management.Automation.CommandNode.CreateCommandProcessor(Int32& index, ExecutionContext context)
at System.Management.Automation.CommandNode.AddToPipeline(PipelineProcessor pipeline, ExecutionContext context)
at System.Management.Automation.PipelineNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.AssignmentStatementNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList,     ExecutionContext context)

And, I have got Microsoft.SystemCenter.VirtualMachineManager installed. The script also works if I manually type it in to the power-shell console on the 2008R2 machine.

Can you please help on any ideas for what I might be missing?

Thanks very much.

like image 667
Scott Langham Avatar asked Sep 15 '10 15:09

Scott Langham


1 Answers

This occurs because powershell snap-in metadata is recorded in the registry. In your case, this means that the snap-in info is only available in the 32 bit software hive in the registry. Normally the trick to make it available is to use the 64 bit version of the .NET framework's installutil.exe (in the framework64 directory) to register it, but sometimes it's 32 bit only for a reason. It may be depending on 32 bit COM objects that are not available in a 64 bit environment.

So you have two approaches:

1) register the snap-in for 64 bit by using installutil.exe /i (unlikely to work)

or

2) target your .NET exe for 32 bit only via VS project properties (anycpu -> x86)

or

3) wrap your work up in a script like this: http://www.nivot.org/blog/post/2012/12/18/Ensuring-a-PowerShell-script-will-always-run-in-a-64-bit-shell

-Oisin

like image 161
x0n Avatar answered Oct 13 '22 00:10

x0n