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

Emp*_*LII 232 .net powershell .net-4.0

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

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

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

小智 236

我发现的最佳解决方案是在博客文章中使用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> 
Run Code Online (Sandbox Code Playgroud)

其他快速设置说明:

位置和文件在某种程度上取决于平台; 但是,它将为您提供如何使解决方案适合您的内联要点.

  • 您可以cd $pshome 在Powershell窗口中执行,在计算机上找到PowerShell的位置(在DOS提示符下无效).
    • 路径会像(例子) C:\Windows\System32\WindowsPowerShell\v1.0\
  • 配置的文件名是:powershell.exe.config如果PowerShell.exe正在执行(如果需要,创建配置文件).
    • 如果PowerShellISE.Exe正在运行,那么您需要创建其配套配置文件PowerShellISE.Exe.config

  • 绝对是正确的方法.这只会改变Powershell的行为,而不是改变你机器上的所有其他.NET应用程序...... (23认同)
  • @JoshL - 在64位系统上,我发现.exe.config需要进入SysWOW64\WindowsPowershell(32位文件夹),即使你试图运行64位PowerShell.否则,您会收到"外部更改"错误. (12认同)
  • 我添加了一个如上所述的文件.但是,我无法再使用该文件运行PowerShell - 我收到错误"文件的卷已被外部更改,因此打开的文件不再有效." 有任何想法吗? (7认同)
  • 这很有效但会影响所有PowerShell.如果您只想要一些功能,请复制powershell文件夹,然后在那里编辑文件. (4认同)
  • powershell.exe.config需要在两个地方.... C:\ Windows\System32\WindowsPowerShell\v1.0 \和C:\ Windows\SysWOW64\WindowsPowerShell\v1.0 \ (4认同)
  • 您可能还想创建一个powershell_ise.exe.config文件(具有相同的内容). (2认同)

Sta*_*ing 147

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
Run Code Online (Sandbox Code Playgroud)

要仅更新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>
Run Code Online (Sandbox Code Playgroud)

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


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


  • 只是一个小建议.当您不再需要它们时删除注册表项.我只是花了很多时间试图找出为什么我无法构建一些我正在研究的.NET 3.5项目. (11认同)
  • 为了清楚起见,powershell.exe(控制台主机应用程序)本身是一个本机应用程序 - 不管理. (9认同)
  • 请注意,Microsoft强烈反对这样做:"虽然可以使用各种机制(例如为PowerShell创建配置文件或编辑注册表)强制PowerShell 2.0与.NET Framework 4.0一起运行,但这些机制不受支持且可以具有对其他PowerShell功能的负面影响,例如PowerShell远程处理和具有混合模式程序集的cmdlet." http://connect.microsoft.com/PowerShell/feedback/details/525435/net-4-0-assemblies-and-powershell-v2 Powershell 3.0对.NET 4.0有本机支持. (9认同)
  • 如果您正在进行多目标定位(即在VS2010中编写.NET 2.0应用程序),建议的注册表修改解决方案会产生令人讨厌的副作用.谨防. (7认同)
  • 我从上面想出了我的问题.在64位操作系统上运行时,必须将配置文件放在64位目录中.32位powershell可执行文件似乎从那里获得了很好的改变. (4认同)
  • @Kiquenet较新的.NET 4.5,.NET 4.5.1,.NET 4.5.2和.NET 4.6(将于2015年推出)都是.NET 4.0的__in-place replacements__.因此,如果您在安装相关的.NET Framework版本之前定位.NET 4.0,则会自动定位这些目标.版本号"4.0.30319"仍然适用于.NET 4.5和4.6. (3认同)

小智 28

使用注册表项方法时请非常小心.这些是计算机范围的密钥,并且可以将所有应用程序迁移到.NET 4.0.

如果不经过迁移,许多产品都不起作用,这是一种测试辅助工具,而不是生产质量机制.不应自动迁移Visual Studio 2008和2010,MSBuild,turbotax和大量网站,SharePoint等.

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


Jas*_*ome 26

如果您只需要在.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


Tim*_*wis 20

如果你仍然坚持使用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=
Run Code Online (Sandbox Code Playgroud)

这将允许您启动在.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
Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止最好的答案,因为它是一个非常本地化的变化,并且不会对系统进行任何持久的更改.好东西! (3认同)

Emp*_*LII 17

以下是我用于支持.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>
Run Code Online (Sandbox Code Playgroud)

另外,这是我用来从传入的命令行参数执行脚本的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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

除了上面显示的基本错误处理之外,我们还在trap脚本中注入一个语句以显示其他诊断信息(类似于Jeffrey Snover的Resolve-Error函数).


Jep*_*sen 10

其他答案来自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搜索链接)下载.

  • Windows Management Framework 4.0(它们与3.0类似)的系统要求是:Windows 7,Windows Embedded Standard 7,Windows Server 2008 R2,Windows Server 2012. (2认同)

小智 9

实际上,您可以使用.NET 4运行PowerShell,而不会影响其他.NET应用程序.我需要这样做才能使用新的HttpWebRequest"Host"属性,但是更改"OnlyUseLatestCLR"打破了Fiddler,因为它无法在.NET 4下使用.

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

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

将该键的值更改为所需的版本.请记住,虽然有些snapins可能不再加载,除非它们是.NET 4兼容的(WASP是唯一一个我遇到麻烦的,但我还是没有真正使用它).VMWare,SQL Server 2008,PSCX,Active Directory(Microsoft和Quest Software)和SCOM都运行良好.


Gra*_*day 7

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

请参阅选项2 - 自己托管Windows PowerShell

首先,添加对System.Management.AutomationMicrosoft.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
            );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jay*_*kul 6

正如另一个选择,最新的PoshConsole版本包括针对.NET 4 RC的二进制文件(它可以在RTM版本中正常工作),无需任何配置.