我正在更新管理某些.NET程序集的PowerShell脚本。该脚本是为基于.NET 2(PowerShell运行时使用的框架的相同版本)构建的程序集编写的,但是现在需要与.NET 4程序集以及.NET 2程序集一起使用。
由于.NET 4支持运行针对较早版本的框架构建的应用程序,因此似乎最简单的解决方案是在需要针对.NET 4程序集运行时使用.NET 4运行时启动PowerShell。
如何在.NET 4运行时中运行PowerShell?
我正在更新管理某些.NET程序集的PowerShell脚本。该脚本是为基于.NET 2(PowerShell运行时使用的框架的相同版本)构建的程序集编写的,但是现在需要与.NET 4程序集以及.NET 2程序集一起使用。
由于.NET 4支持运行针对较早版本的框架构建的应用程序,因此似乎最简单的解决方案是在需要针对.NET 4程序集运行时使用.NET 4运行时启动PowerShell。
如何在.NET 4运行时中运行PowerShell?
Answers:
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>
您可以很好地构建使用PowerShell API(System.Management.Automation.PowerShell)调用PowerShell的.NET 4.0应用程序,但是这些步骤将有助于使内置的PowerShell主机在.NET 4.0下工作。
当您不再需要注册表项时,请删除它们。这些是计算机范围的密钥,可将所有应用程序强制迁移到.NET 4.0,甚至包括使用.net 2和.net 3.5的应用程序
我发现的最佳解决方案是在博客文章《使用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窗口中执行来找到PowerShell在计算机上的位置(在DOS提示符下不起作用)。
C:\Windows\System32\WindowsPowerShell\v1.0\
powershell.exe.config
如果PowerShell.exe
正在执行(如果需要,请创建配置文件)。
PowerShellISE.Exe
正在运行,则需要创建其配套配置文件,如下所示PowerShellISE.Exe.config
请非常小心使用注册表项方法。这些是计算机范围的密钥,可以将所有应用程序强制迁移到.NET 4.0。
如果强行迁移,许多产品将无法工作,这是一种测试辅助手段,而不是生产质量机制。Visual Studio 2008和2010,MSBuild,turbotax和许多网站,SharePoint等不应自动迁移。
如果需要在4.0中使用PowerShell,则应在每个应用程序的基础上使用配置文件来完成此操作,您应向PowerShell团队咨询确切的建议。这可能会破坏一些现有的PowerShell命令。
如果仅需要在.NET 4中执行单个命令,脚本块或脚本文件,请尝试使用.NET 4中的激活配置文件来使用CLR版本4仅启动PowerShell的单个实例。
详细信息:
http://blog.codeassassin.com/2011/03/23/executing-individual-powershell-commands-using-net-4/
示例PowerShell模块:
如果您仍然使用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=
这将允许您启动在.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 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函数)。
其他答案来自2012年之前,它们的重点是“攻击” PowerShell 1.0或PowerShell 2.0,以定位较新版本的.NET Framework和公共语言运行时(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版本”线程。
在撰写本文时,PowerShell的最新版本是4.0,可以通过Windows Management Framework(Google搜索链接)下载。
实际上,您可以使PowerShell在不影响其他.NET应用程序的情况下使用.NET 4运行。我需要这样做才能使用新的HttpWebRequest“ Host”属性,但是更改“ OnlyUseLatestCLR”破坏了Fiddler,因为在.NET 4中无法使用。
PowerShell的开发人员显然预见到了这种情况,他们添加了一个注册表项来指定应使用的Framework版本。一个小问题是,您需要在更改注册表项之前就拥有它的所有权,因为即使管理员也没有访问权限。
将该键的值更改为所需的版本。请记住,尽管某些管理单元可能无法加载,除非它们与.NET 4兼容(WASP是我遇到的唯一问题,但我还是不真正使用它)。VMWare,SQL Server 2008,PSCX,Active Directory(Microsoft和Quest Software)和SCOM都可以正常工作。
如果您不想修改注册表或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
);
}
}
}
作为另一个选择,最新的PoshConsole版本包含针对.NET 4 RC的二进制文件(与RTM版本兼容),无需任何配置。