Como posso executar o PowerShell com o tempo de execução do .NET 4?

Estou atualizando um script do PowerShell que gerencia alguns assemblies do .NET. O script foi escrito para assemblies construídos com o .NET 2 (a mesma versão da estrutura com a qual o PowerShell é executado), mas agora precisa trabalhar com assemblies .NET 4 e .NET 2.

Como o .NET 4 suporta a execução de aplicativos criados em versões mais antigas da estrutura, parece que a solução mais simples é iniciar o PowerShell com o tempo de execução do .NET 4 quando precisar executá-lo em assemblies do .NET 4.

Como posso executar o PowerShell com o tempo de execução do .NET 4?

O PowerShell (o mecanismo) funciona bem no .NET 4.0. O PowerShell (o host do console e o ISE ) não, simplesmente porque foram compilados em versões mais antigas do .NET. Há uma configuração de registro que alterará o .NET framework carregado em todo o sistema , o que, por sua vez, permitirá que o PowerShell use as classs do .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 

Para atualizar apenas o ISE para usar o .NET 4.0, você pode alterar o arquivo de configuração ($ psHome \ powershell.exe.config) para ter um trecho como este:

 < ?xml version="1.0" encoding="utf-8"?>      

Você pode criar aplicativos .NET 4.0 que chamam o PowerShell usando a API do PowerShell (System.Management.Automation.PowerShell), mas essas etapas ajudarão a obter os hosts do PowerShell prontos para uso no .NET 4.0.


Remova as chaves do registro quando você não precisar mais delas. Essas são chaves para toda a máquina e migram forçadamente TODOS os aplicativos para o .NET 4.0, até mesmo aplicativos que usam .net 2 e .net 3.5


A melhor solução que encontrei está na postagem do blog Using Newer Version (s) of .NET with PowerShell . Isso permite que o powershell.exe seja executado com assemblies do .NET 4.

Simplesmente modifique (ou crie) $pshome\powershell.exe.config para que contenha o seguinte:

 < ?xml version="1.0"?>       

Notas adicionais de configuração rápida:

Locais e arquivos são um pouco dependentes da plataforma; no entanto, você terá uma visão inline de como fazer a solução funcionar para você.

  • Você pode encontrar a localização do PowerShell no seu computador executando cd $pshome na janela do Powershell (não funciona no prompt do DOS).
    • O caminho será algo como (exemplo) C:\Windows\System32\WindowsPowerShell\v1.0\
  • O nome do arquivo para colocar a configuração é: powershell.exe.config se o PowerShell.exe estiver sendo executado (crie o arquivo de configuração, se necessário).
    • Se o PowerShellISE.Exe estiver em execução, você precisará criar seu arquivo de configuração complementar como PowerShellISE.Exe.config

Por favor, tenha muito cuidado ao usar a abordagem de chave de registro. Estas são chaves para toda a máquina e migram forçadamente todas as aplicações para o .NET 4.0.

Muitos produtos não funcionam se migrados forçadamente e isso é um auxílio de teste e não um mecanismo de qualidade de produção. O Visual Studio 2008 e 2010, MSBuild , turbotax e uma série de sites, SharePoint e assim por diante não devem ser migrados.

Se você precisar usar o PowerShell com o 4.0, isso deve ser feito em uma base por aplicativo com um arquivo de configuração, você deve verificar com a equipe do PowerShell sobre a recomendação precisa. Isso provavelmente quebrará alguns comandos existentes do PowerShell.

Se você só precisar executar um único comando, bloco de script ou arquivo de script no .NET 4, tente usar os Arquivos de configuração de ativação do .NET 4 para iniciar apenas uma única instância do PowerShell usando a versão 4 do CLR.

Detalhes completos:

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

Um exemplo de módulo do PowerShell:

https://gist.github.com/882528

Aqui está o conteúdo do arquivo de configuração que eu usei para suportar os assemblies .NET 2.0 e .NET 4:

 < ?xml version="1.0" encoding="utf-8" ?>        

Além disso, aqui está uma versão simplificada do código compatível com o PowerShell 1.0 que usei para executar nossos scripts a partir dos argumentos de linha de comando passados:

 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 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; } } } 

Além do tratamento de erros básico mostrado acima, nós também injetamos uma instrução trap no script para exibir informações de diagnóstico adicionais (semelhante à function Resolver-Erro de Jeffrey Snover).

Se você ainda está preso no PowerShell v1.0 ou v2.0, aqui está minha variação da excelente resposta de Jason Stangroome.

Crie um powershell4.cmd em algum lugar em seu caminho com o seguinte conteúdo:

 @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.^ >> %~dp0powershell.exe.activation_config echo. ^ >> %~dp0powershell.exe.activation_config echo. ^ >> %~dp0powershell.exe.activation_config echo. ^ >> %~dp0powershell.exe.activation_config echo.^ >> %~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= 

Isso permitirá que você ative uma instância do console do PowerShell que está sendo executado no .NET 4.0.

Você pode ver a diferença no meu sistema em que tenho o PowerShell 2.0 examinando a saída dos dois comandos a seguir executados a partir do 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 

As outras respostas são anteriores a 2012, e elas se concentram em “hackear” o PowerShell 1.0 ou o PowerShell 2.0 para direcionar versões mais recentes do .NET Framework e do Common Language Runtime (CLR).

No entanto, como foi escrito em muitos comentários, desde 2012 (quando o PowerShell 3.0 veio), uma solução muito melhor é instalar a versão mais recente do PowerShell . Ele irá automaticamente segmentar o CLR v4.0.30319 . Isso significa que o .NET 4.0, 4.5, 4.5.1, 4.5.2 ou 4.6 (esperado em 2015), já que todas essas versões são substituições no local umas das outras. Use $PSVersionTable ou consulte o tópico Determinar a versão do PowerShell instalada se você não tiver certeza da sua versão do PowerShell.

No momento desta publicação, a versão mais recente do PowerShell é 4.0 e pode ser baixada com o Windows Management Framework (link de pesquisa do Google) .

Na verdade, você pode obter o PowerShell para executar usando o .NET 4 sem afetar outros aplicativos .NET. Eu precisava fazer isso para usar a nova propriedade “Host” do HttpWebRequest, mas alterar o “OnlyUseLatestCLR” quebrou o Fiddler, já que ele não pode ser usado no .NET 4.

Os desenvolvedores do PowerShell obviamente previram que isso acontecesse e adicionaram uma chave do Registro para especificar qual versão do Framework ele deveria usar. Um pequeno problema é que você precisa apropriar-se da chave do registro antes de alterá-la, pois nem os administradores têm access.

  • HKLM: \ Software \ Microsoft \ PowerShell \ 1 \ PowerShellEngine \ RuntimeVersion (64 bits e 32 bits)
  • HKLM: \ Software \ Wow6432Node \ Microsoft \ PowerShell \ 1 \ PowerShellEngine \ RuntimeVersion (32 bits na máquina de 64 bits)

Altere o valor dessa chave para a versão necessária. Tenha em mente que alguns snapins podem não ser mais carregados a menos que sejam compatíveis com o .NET 4 (o WASP é o único com o qual eu tive problemas, mas eu realmente não o uso de qualquer maneira). O VMWare , o SQL Server 2008 , o PSCX, o Active Directory (Microsoft e Quest Software ) e o SCOM funcionam bem.

Se você não quiser modificar os arquivos do registro ou app.config, uma maneira alternativa é criar um aplicativo de console simples do .NET 4 que imita o que o PowerShell.exe faz e hospeda o ConsoleShell do PowerShell.

Veja Opção 2 – Hospedando o Windows PowerShell você mesmo

Primeiro, adicione uma referência aos assemblies System.Management.Automation e Microsoft.PowerShell.ConsoleHost , que podem ser encontrados em % programfiles% \ Reference Assemblies \ Microsoft \ WindowsPowerShell \ v1.0

Em seguida, use o seguinte código:

 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 ); } } } 

Assim como outra opção, a última versão do PoshConsole inclui binários direcionados ao .NET 4 RC (que funcionam bem em relação à versão RTM) sem qualquer configuração.