我如何使用.NET 4运行时运行PowerShell?

我正在更新pipe理一些.NET程序集的PowerShell脚本。 该脚本是针对.NET 2(PowerShell运行的框架的相同版本)构build的程序集编写的,但现在需要使用.NET 4程序集以及.NET 2程序集。

由于.NET 4支持运行针对较旧版本框架构build的应用程序,因此似乎最简单的解决scheme是在需要运行.NET 4程序集的情况下运行.NET 4运行时的PowerShell。

我如何使用.NET 4运行时运行PowerShell?

PowerShell(引擎)在.NET 4.0下运行良好。 PowerShell(控制台主机和ISE )不是,只是因为它们是针对旧版本的.NET编译的。 有一个registry设置将会改变系统加载的.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,可以将configuration($ psHome \ powershell_ise.exe.config)文件更改为像这样的块:

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

您可以使用PowerShell API(System.Management.Automation.PowerShell)来构build调用PowerShell的.NET 4.0应用程序,但这些步骤将有助于让现成的PowerShell主机在.NET 4.0下工作。


当您不再需要它们时,移除registry项。 这些是机器范围的密钥,强制将所有应用程序迁移到.NET 4.0,甚至是使用.net 2和.net 3.5的应用程序


我发现的最佳解决scheme是在PowerShell中使用.NET的较新版本进行博客文章。 这允许powershell.exe与.NET 4程序集一起运行。

只需修改(或创build) $pshome\powershell.exe.config ,使其包含以下内容:

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

另外,快速安装说明:

位置和文件与平台有关; 但是会给你一个如何使解决scheme为你工作的内联要点。

  • 您可以通过在PowerShell窗口中执行cd $pshome来findPowerShell在您的计算机上的位置(在DOS提示符下不起作用)。
    • path将会像(例子) C:\Windows\System32\WindowsPowerShell\v1.0\
  • 如果您的PowerShell.exe正在执行(如果需要创buildconfiguration文件),configuration文件的文件名是: powershell.exe.config
    • 如果PowerShellISE.Exe正在运行,则需要将其配套文件创build为PowerShellISE.Exe.config

请使用registry键方法非常小心。 这些是机器范围内的密钥,并将所有应用程序强制迁移到.NET 4.0。

许多产品如果被迫迁移就不起作用,这是一种testing援助,而不是一种生产质量机制。 Visual Studio 2008和2010, MSBuild ,turbotax和一大堆网站, SharePoint等不应该被自动化。

如果您需要使用PowerShell 4.0,则应该使用configuration文件在每个应用程序的基础上完成此操作,您应该向PowerShell团队确认具体的build议。 这很可能会破坏一些现有的PowerShell命令。

如果您只需要在.NET 4中执行单个命令,脚本块或脚本文件,请尝试使用.NET 4中的激活configuration文件,以使用CLR的版本4仅启动一个PowerShell实例。

全部细节:

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

一个PowerShell模块的例子:

https://gist.github.com/882528

这里是我用来支持.NET 2.0和.NET 4程序集的configuration文件的内容:

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

除了上面显示的基本error handling外,我们还在脚本中注入一个trap语句来显示其他诊断信息(类似于Jeffrey Snover的“ 解决错误”function)。

如果你仍然停留在PowerShell v1.0或v2.0上,这里是我对Jason Stangroome的出色答案的变化。

在path上的某个位置创build一个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= 

这将允许您启动在.NET 4.0下运行的powershell控制台实例。

通过检查从cmd运行的以下两个命令的输出,您可以在我的系统上看到与PowerShell 2.0不同的地方。

 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 

实际上,您可以使用.NET 4运行PowerShell 而不影响其他.NET应用程序。 我需要这样做来使用新的HttpWebRequest“主机”属性,但是改变“OnlyUseLatestCLR”打破了Fiddler,因为在.NET 4下无法使用它。

PowerShell的开发人员显然预见到了这种情况,他们添加了一个registry项来指定它应该使用哪个版本的Framework。 一个小问题是,在更改registry项之前,您需要获得registry项的所有权,因为即使是pipe理员也无法访问。

  • HKLM:\ Software \ Microsoft \ Powershell \ 1 \ PowerShellEngine \ RuntimeVersion(64位和32位)
  • HKLM:\ Software \ Wow6432Node \ Microsoft \ Powershell \ 1 \ PowerShellEngine \ RuntimeVersion(64位机器上的32位)

将该键的值更改为所需的版本。 请记住,一些pipe理单元可能不再加载,除非它们与.NET 4兼容(WASP是我唯一遇到的问题,但是我并没有真正使用它)。 VMWare , SQL Server 2008 ,PSCX, Active Directory (Microsoft和Quest Software )和SCOM都可以正常工作。

其他答案来自2012年以前,他们专注于将“PowerShell 1.0”或“PowerShell 2.0”“黑客入侵”,瞄准更新版本的.NET Framework和公共语言运行时(CLR)。

然而,正如许多评论中所写,自2012年以来(当PowerShell 3.0出现时),更好的解决scheme是安装最新版本的PowerShell 。 它会自动定位到CLR v4.0.30319 。 这意味着.NET 4.0,4.5,4.5.1,4.5.2或4.6(预计在2015年),因为所有这些版本都是相互replace的。 使用$PSVersionTable或者如果您不确定PowerShell版本,请参阅确定已安装的PowerShell版本线程 。

在撰写本文时,最新版本的PowerShell是4.0,可以使用Windows Management Framework(Googlesearch链接)下载 。

如果您不想修改registry或app.config文件,另一种方法是创build一个简单的.NET 4控制台应用程序,它可以模拟PowerShell.exe执行的操作并托pipePowerShell ConsoleShell。

请参阅选项2 – 自己托pipeWindows PowerShell

首先,添加一个对System.Management.AutomationMicrosoft.PowerShell.ConsoleHost程序集的引用,该程序集可以在%programfiles%\ Reference Assemblies \ Microsoft \ WindowsPowerShell \ v1.0下find

然后使用下面的代码:

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

就像另一种select一样,最新的PoshConsole版本包含了针对.NET 4 RC的二进制文件(在RTM版本上工作正常),没有任何configuration。