简体   繁体   中英

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

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.

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

Here's an example that handles named parameters and worked for my needs. Original was taken from the linked option in x0n's post. See the linked post for additional details. I'm executing this script from a C# console application that has 3rd party dependencies on x86.

param([string[]]$listOfVMNames, [string]$userName, [string]$resourceGroupName, [int]$waitForJob)
if ($pshome -like "*syswow64*") {
    & (join-path ($pshome -replace "syswow64", "sysnative") powershell.exe) -file `
        (join-path $psscriptroot $myinvocation.mycommand) -listOfVMNames (,$listOfVMNames) -userName $userName -resourceGroupName $resourceGroupName -waitForJob $waitForJob
    exit
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM