Как запустить PowerShell с помощью среды выполнения .NET 4?

Я обновляю PowerShell script, который управляет некоторыми сборками .NET. script был написан для сборок, встроенных в .NET 2 (та же самая версия фреймворка, с которой работает PowerShell), но теперь ему необходимо работать с сборками .NET 4, а также с сборками .NET 2.

Так как .NET 4 поддерживает запуск приложений, созданных на основе старых версий фреймворка, кажется, что самое простое решение - запустить PowerShell со средой .NET 4, когда мне нужно запустить его с сборками .NET 4.

Как запустить PowerShell со средой .NET 4?

Ответ 1

PowerShell (движок) отлично работает в .NET 4.0. PowerShell (консольный хост и ISE) не просто потому, что они были скомпилированы против более старых версий .NET. Там параметр реестра, который будет изменяет платформу .NET, загруженную в системную область, что, в свою очередь, позволит PowerShell использовать классы .NET 4.0:

reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1

Чтобы обновить только ISE для использования .NET 4.0, вы можете изменить файл конфигурации ($ psHome\powershell_ise.exe.config), чтобы иметь такой фрагмент:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup>
      <supportedRuntime version="v4.0.30319" />
    </startup>
</configuration>

Вы можете создавать приложения .NET 4.0, которые вызывают PowerShell с помощью PowerShell API (System.Management.Automation.PowerShell), просто отлично, но эти шаги помогут получить доступ к встроенным в PowerShell хостам для работы в .NET 4.0.


Удалите ключи реестра, когда они вам больше не понадобятся. Это машинные ключи и принудительно переносят ВСЕ приложения в .NET 4.0, даже приложения с использованием .net 2 и .net 3.5


Ответ 2

Лучшее решение, которое я нашел, - в блоге Использование более новых версий .NET с PowerShell. Это позволяет powershell.exe работать со сборками .NET 4.

Просто измените (или создайте) $pshome\powershell.exe.config, чтобы он содержал следующее:

<?xml version="1.0"?> 
<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0.30319"/> 
        <supportedRuntime version="v2.0.50727"/> 
    </startup> 
</configuration> 

Дополнительные примечания по быстрой установке:

Расположение и файлы в некоторой степени зависят от платформы; Тем не менее, вы узнаете, как заставить решение работать на вас.

  • Вы можете найти расположение PowerShell на вашем компьютере, выполнив cd $pshome в окне Powershell (не работает из командной строки DOS).
    • Путь будет примерно таким (пример) C:\Windows\System32\WindowsPowerShell\v1.0\
  • Имя файла для конфигурации: powershell.exe.config, если выполняется ваш PowerShell.exe (создайте файл конфигурации, если это необходимо).
    • Если PowerShellISE.Exe запущен, вам нужно создать его конфигурационный файл как PowerShellISE.Exe.config

Ответ 3

Пожалуйста, будьте ОЧЕНЬ осторожны с использованием подхода к разделу реестра. Это ключи машинного интерфейса и автоматически переносят ВСЕ приложения в .NET 4.0.

Многие продукты не работают, если они переносятся автоматически, и это средство тестирования, а не механизм качества продукции. Visual Studio 2008 и 2010, MSBuild, turbotax и множество веб-сайтов, SharePoint и т.д. не должны быть автоматизированы.

Если вам нужно использовать PowerShell с 4.0, это должно быть сделано для каждого приложения с конфигурационным файлом, вы должны проверить с командой PowerShell точную рекомендацию. Вероятно, это приведет к поломке некоторых существующих команд PowerShell.

Ответ 4

Если вам нужна только одна команда, блок script или script в .NET 4, попробуйте использовать Файлы конфигурации активации .NET 4, чтобы запустить только один экземпляр PowerShell, используя версию 4 CLR.

Полная информация:

http://blog.codeassassin.com/2011/03/23/executing-individual-powershell-commands-using-net-4/

Пример модуля PowerShell:

https://gist.github.com/882528

Ответ 5

Если вы все еще застряли в PowerShell v1.0 или v2.0, вот мой вариант на Jason Stangroome отличный ответ.

Создайте powershell4.cmd где-то на своем пути со следующим содержимым:

@echo off
:: http://stackoverflow.com/questions/7308586/using-batch-echo-with-special-characters
if exist %~dp0powershell.exe.activation_config goto :run
echo.^<?xml version="1.0" encoding="utf-8" ?^>                 > %~dp0powershell.exe.activation_config
echo.^<configuration^>                                        >> %~dp0powershell.exe.activation_config
echo.  ^<startup useLegacyV2RuntimeActivationPolicy="true"^>  >> %~dp0powershell.exe.activation_config
echo.    ^<supportedRuntime version="v4.0"/^>                 >> %~dp0powershell.exe.activation_config
echo.  ^</startup^>                                           >> %~dp0powershell.exe.activation_config
echo.^</configuration^>                                       >> %~dp0powershell.exe.activation_config
:run
:: point COMPLUS_ApplicationMigrationRuntimeActivationConfigPath to the directory that this cmd file lives in
:: and the directory contains a powershell.exe.activation_config file which matches the executable name powershell.exe
set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=%~dp0
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe %*
set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=

Это позволит вам запустить экземпляр консоли powershell, работающей под .NET 4.0.

Вы можете увидеть разницу в моей системе, где у меня есть PowerShell 2.0, рассмотрев вывод следующих двух команд, запущенных из cmd.

C:\>powershell -ExecutionPolicy ByPass -Command $PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.5485
BuildVersion                   6.1.7601.17514
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1


C:\>powershell4.cmd -ExecutionPolicy ByPass -Command $PSVersionTable

Name                           Value
----                           -----
PSVersion                      2.0
PSCompatibleVersions           {1.0, 2.0}
BuildVersion                   6.1.7601.17514
CLRVersion                     4.0.30319.18408
WSManStackVersion              2.0
PSRemotingProtocolVersion      2.1
SerializationVersion           1.1.0.1

Ответ 6

Вот содержимое файла конфигурации, который я использовал для поддержки сборок .NET 2.0 и .NET 4:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <!-- http://msdn.microsoft.com/en-us/library/w4atty68.aspx -->
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" />
    <supportedRuntime version="v2.0.50727" />
  </startup>
</configuration>

Кроме того, это упрощенная версия совместимого с PowerShell 1.0 кода, который я использовал для выполнения наших скриптов из переданных в аргументе командной строки:

class Program {
  static void Main( string[] args ) {
    Console.WriteLine( ".NET " + Environment.Version );

    string script = "& " + string.Join( " ", args );
    Console.WriteLine( script );
    Console.WriteLine( );

    // Simple host that sends output to System.Console
    PSHost host = new ConsoleHost( this );
    Runspace runspace = RunspaceFactory.CreateRunspace( host );

    Pipeline pipeline = runspace.CreatePipeline( );
    pipeline.Commands.AddScript( script );

    try {
      runspace.Open( );
      IEnumerable<PSObject> output = pipeline.Invoke( );
      runspace.Close( );

      // ...
    }
    catch( RuntimeException ex ) {
      string psLine = ex.ErrorRecord.InvocationInfo.PositionMessage;
      Console.WriteLine( "error : {0}: {1}{2}", ex.GetType( ), ex.Message, psLine );
      ExitCode = -1;
    }
  }
}

В дополнение к основной обработке ошибок, показанной выше, мы также вводим инструкцию trap в script, чтобы отобразить дополнительную диагностическую информацию (похожую на Jeffrey Snover Resolve-Error).

Ответ 7

Другие ответы датируются до 2012 года, и они сосредоточены на "взломе" PowerShell 1.0 или PowerShell 2.0 в таргетинге на более новые версии .NET Framework и Common Language Runtime (CLR).

Однако, как было написано во многих комментариях, с 2012 года (когда пришел PowerShell 3.0) гораздо лучшее решение - это установить новейшую версию PowerShell. Он автоматически настроится на CLR v4.0.30319. Это означает, что .NET 4.0, 4.5, 4.5.1, 4.5.2 или 4.6 (ожидается в 2015 году), поскольку все эти версии заменяют друг друга на месте. Используйте $PSVersionTable или посмотрите Определить установленный поток версии PowerShell, если вы не уверены в своей версии PowerShell.

На момент написания последней версии PowerShell 4.0, и она может быть загружена с помощью системы управления Windows (ссылка для поиска Google).

Ответ 8

На самом деле вы можете запустить PowerShell с помощью .NET 4, не затрагивая другие .NET-приложения. Мне нужно было сделать это, чтобы использовать новое свойство хоста HttpWebRequest, однако изменение "OnlyUseLatestCLR" сломало Fiddler, поскольку это невозможно было использовать в .NET 4.

Разработчики PowerShell явно предвидели это, и они добавили раздел реестра, чтобы указать, какую версию Framework он должен использовать. Одна из незначительных проблем заключается в том, что перед тем, как изменить его, вам необходимо взять на себя управление ключом реестра, так как даже администраторы не имеют доступа.

  • HKLM:\Software\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (64-разрядная и 32-разрядная версия)
  • HKLM:\Software\Wow6432Node\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (32-разрядная версия на 64-битной машине)

Измените значение этого ключа на нужную версию. Имейте в виду, что некоторые snapins больше не могут загружаться, если они не совместимы с .NET 4 (WASP - это единственное, с чем я столкнулся, но на самом деле я его не использую). VMWare, SQL Server 2008, PSCX, Active Directory (Microsoft и Quest Software), и SCOM все работает нормально.

Ответ 9

Если вы не хотите изменять файлы реестра или app.config, альтернативный способ - создать простое консольное приложение .NET 4, которое имитирует то, что делает PowerShell.exe, и размещает PowerShell ConsoleShell.

См. Вариант 2 - Хостинг Windows PowerShell самостоятельно

Сначала добавьте ссылку на сборки System.Management.Automation и Microsoft.PowerShell.ConsoleHost, которые можно найти в разделе % programfiles%\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0

Затем используйте следующий код:

using System;
using System.Management.Automation.Runspaces;
using Microsoft.PowerShell;

namespace PSHostCLRv4
{
    class Program
    {
        static int Main(string[] args)
        {
            var config = RunspaceConfiguration.Create();
                return ConsoleShell.Start(
                config,
                "Windows PowerShell - Hosted on CLR v4\nCopyright (C) 2010 Microsoft Corporation. All rights reserved.",
                "",
                args
            );
        }
    }
}

Ответ 10

Как еще один вариант, последний выпуск PoshConsole включает в себя двоичные файлы, предназначенные для .NET 4 RC (которые отлично работают с релизом RTM) без какой-либо конфигурации.

Ответ 11

Просто запустите powershell.exe с переменной среды COMPLUS_version, для которой установлено значение v4.0.30319. Например, из cmd.exe или .bat файла:

set COMPLUS_version=v4.0.30319
powershell -file c:\scripts\test.ps1