如何使用。net 4运行时运行PowerShell ?

我正在更新一个管理一些. net程序集的PowerShell脚本。该脚本是为在。net 2(与PowerShell运行的框架相同版本)上构建的程序集编写的,但现在需要使用。net 4程序集以及。net 2程序集。

由于. net 4支持运行基于旧版本框架构建的应用程序,因此似乎最简单的解决方案是在需要针对. net 4程序集运行PowerShell时,使用。net 4运行时启动PowerShell。

如何使用。net 4运行时运行PowerShell ?

130882 次浏览

PowerShell(引擎)在。net 4.0下运行良好。PowerShell(控制台主机和伊势)没有,因为它们是根据旧版本的。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,你可以更改配置文件($ phome \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)构建调用PowerShell的。net 4.0应用程序,但是这些步骤将有助于使PowerShell主机在。net 4.0下工作。


当您不再需要注册表项时,请删除它们。这些是机器范围内的键,强制将所有应用程序迁移到。net 4.0,甚至包括使用。net 2和。net 3.5的应用程序


下面是我用来支持。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语句来显示额外的诊断信息(类似于Jeffrey Snover的Resolve-Error函数)。

就像另一个选项一样,最新的PoshConsole版本包含了针对net 4 RC的二进制文件(它可以在RTM版本中正常工作),无需任何配置。

请谨慎使用注册表项方法。这些是机器范围的键,强制将所有应用程序迁移到net 4.0。

如果强制迁移,许多产品不能工作,这是一种测试辅助,而不是一种生产质量机制。Visual Studio 2008和2010,MSBuild, turbotax,以及大量的网站,SharePoint等等不应该被自动化。

如果您需要使用PowerShell 4.0,这应该在每个应用程序的基础上使用配置文件完成,您应该与PowerShell团队核实准确的建议。这可能会破坏一些现有的PowerShell命令。

实际上,你可以让PowerShell使用。net 4 没有来影响其他。net应用程序。我需要这样做来使用新的HttpWebRequest“Host”属性,然而改变“OnlyUseLatestCLR”破坏了Fiddler,因为它不能在。net 4下使用。

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

  • \Software\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion(64位及32位)
  • \Software\Wow6432Node\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion(32位在64位机器上)

将该键的值更改为所需的版本。请记住,一些snapin可能不再加载,除非它们与。net 4兼容(WASP是我唯一遇到过麻烦的一个,但我实际上并不使用它)。VMWareSQL Server 2008, PSCX, 活动目录 (Microsoft和追求软件)和SCOM都可以正常工作。

如果你不想修改注册表或app.config文件,另一种方法是创建一个简单的。net 4控制台应用程序,它模仿PowerShell.exe的功能并托管PowerShell ConsoleShell。

看到选项2 -自己托管Windows PowerShell

首先,添加对System.Management.AutomationMicrosoft.PowerShell.ConsoleHost程序集的引用,它们可以在微软% programfiles % \引用程序集\ \ 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
);
}
}
}

我找到的最好的解决方案是在博客文章使用更新版本的。net with PowerShell .NET。这允许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>

另外,快速设置注意事项:

位置和文件多少依赖于平台;然而,将为您提供如何使解决方案为您工作的内联要点。

    你可以通过执行cd $pshome 在Powershell窗口(不能从DOS提示符中工作)来找到PowerShell在你的计算机上的位置。
    • Path将类似于(example) C:\Windows\System32\WindowsPowerShell\v1.0\
    • 李< / ul > < / >
    • 如果正在执行PowerShell.exe,则将配置放入的文件名为:powershell.exe.config(如果需要,则创建配置文件)。
      • 如果PowerShellISE.Exe正在运行,那么你需要创建它的配套配置文件PowerShellISE.Exe.config
      • 李< / ul > < / >

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

详情:

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

PowerShell模块示例:

https://gist.github.com/882528

其他的答案都是2012年以前的,它们都集中在“黑客”上。PowerShell 1.0或PowerShell 2.0针对。net框架和公共语言运行时(CLR)的新版本。

然而,正如在许多评论中所写的那样,自2012年(PowerShell 3.0问世)以来,更好的解决方案是安装最新版本的PowerShell。它将自动以CLR v4.0.30319为目标。这意味着。net 4.0、4.5、4.5.1、4.5.2或4.6(预计在2015年),因为所有这些版本都是彼此的替代版本。如果您不确定PowerShell版本,请使用$PSVersionTable或查看确定安装的PowerShell版本线程编辑:哪个.NET版本是我的PowerShell脚本使用?< / em >

在撰写本文时,PowerShell的最新版本是4.0,它可以是随Windows管理框架下载(谷歌搜索链接)

如果您还停留在PowerShell 1.0或2.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=

这将允许您启动在。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
只要运行powershell.exe,将COMPLUS_version环境变量设置为v4.0.30319。 例如,从cmd.exe或.bat-file:

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