Почему вызов PowerShell из C # вызывает исключение System.Management.Automation.CommandNotFoundException? - PullRequest
5 голосов
/ 15 сентября 2010

Я использую этот 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;
    }

Для запуска этого скрипта:

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

Работает нормально на 32-битной ОС Windows 2003, но на 64-битной Windows 2008R2 я получаю эту ошибку:

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)

И у меня установлен Microsoft.SystemCenter.VirtualMachineManager. Сценарий также работает, если я вручную ввожу его в консоль power-shell на машине 2008R2.

Не могли бы вы помочь с любыми идеями о том, чего мне может не хватать?

Большое спасибо.

Ответы [ 2 ]

7 голосов
/ 15 сентября 2010

Это происходит из-за того, что метаданные оснастки powershell записываются в реестр. В вашем случае это означает, что информация о оснастке доступна только в 32-разрядном программном кусте в реестре. Обычно хитрость в том, чтобы сделать его доступным, состоит в том, чтобы использовать 64-битную версию .NET Framework installutil.exe (в каталоге framework64), чтобы зарегистрировать его, но иногда он 32-битный только по причине. Это может зависеть от 32-битных COM-объектов, которые недоступны в 64-битной среде.

Итак, у вас есть два подхода:

1) зарегистрировать оснастку для 64-разрядной версии с помощью installutil.exe / i (вряд ли будет работать)

или

2) нацелить ваш .NET exe на 32 бит только через свойства проекта VS (anycpu -> x86)

или

3) заверните свою работу в сценарий, как это: http://www.nivot.org/blog/post/2012/12/18/Ensuring-a-PowerShell-script-will-always-run-in-a-64-bit-shell

-Oisin

0 голосов
/ 10 августа 2018

Вот пример, который обрабатывает именованные параметры и работает для моих нужд. Оригинал был взят из ссылки в сообщении x0n. Смотрите связанный пост для получения дополнительной информации. Я выполняю этот сценарий из консольного приложения C #, имеющего сторонние зависимости от 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...