【问题标题】:Cannot run PowerShell scripts in Azure Functions v2无法在 Azure Functions v2 中运行 PowerShell 脚本
【发布时间】:2018-12-11 03:58:49
【问题描述】:

我正在尝试在 Azure Functions v2 中使用 .NET Core 编写函数应用程序。当使用来自 Nuget 的 Microsoft.Powershell.SDK 包(.NET Core PowerShell 运行时需要)时,我无法让 Visual Studio 将 System.Management.Automation 库与我的 Function App 一起复制到 bin。

这会导致以下错误:

System.Private.CoreLib: Exception while executing function: Function1. TestPowershellInFunction: Could not load file or assembly 'System.Management.Automation, Version=6.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified. System.Private.CoreLib: Could not load the specified file.

我在现有的 Azure 函数和新的解决方案中重现了这一点,只需创建一个 Timer 函数并添加以下 sn-p:

PowerShell shell = PowerShell.Create();
IEnumerable<PSObject> result = shell.AddScript("Write-Output 'Hello, World!'").Invoke();

foreach(PSObject line in result)
{
    log.LogInformation(line.ToString());
}

这适用于安装了 PowerShell Nuget 的新控制台应用程序,但添加到函数应用程序时出现错误。我确实注意到 System.Management.Automation 没有使用常规控制台应用程序放入 bin 目录中,但我不确定如何解释这一点。我知道它是一个系统库,但除非安装了 Nuget,否则我不能使用它,所以我不知道这是否是一种特殊情况。在这两种情况下,我都使用 PowerShell Nuget 的 v6.1.1。

这是 Functions v2 的已知错误吗?还是我错过了什么?

【问题讨论】:

    标签: azure powershell azure-functions


    【解决方案1】:

    已知issue 函数无法正确加载运行时程序集([FunctionProject]\bin\Debug\netcoreapp2.1\bin\runtimes)。

    解决方法是将程序集手动移动到输出目录bin。右键单击您的函数项目和Edit &lt;FunctionProject&gt;.csproj。添加以下项目以实现我们的目标。

     <PropertyGroup>
        <SDKVersion>6.1.1</SDKVersion>
        <SDKPlatform>win-x86</SDKPlatform>
      </PropertyGroup>
    
      <ItemGroup>
        <None Include="
          $(USERPROFILE)\.nuget\packages\system.directoryservices\4.5.0\runtimes\win\lib\netcoreapp2.0\System.DirectoryServices.dll;
          $(USERPROFILE)\.nuget\packages\system.management\4.5.0\runtimes\win\lib\netcoreapp2.0\System.Management.dll;
          $(USERPROFILE)\.nuget\packages\system.management.automation\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\System.Management.Automation.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.management.infrastructure\1.0.0\runtimes\win10-x86\lib\netstandard1.6\Microsoft.Management.Infrastructure.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Management.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.utility\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Utility.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.diagnostics\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Diagnostics.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.sdk\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.SDK.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.security\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Security.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.coreclr.eventing\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.CoreCLR.Eventing.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.consolehost\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.ConsoleHost.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.markdownrender\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.MarkdownRender.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.wsman.runtime\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Runtime.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.wsman.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Management.dll;
          ">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
      </ItemGroup>
      <Target Name="CopyRuntimeToBin" AfterTargets="Build">
        <Copy SourceFiles="
          $(USERPROFILE)\.nuget\packages\system.directoryservices\4.5.0\runtimes\win\lib\netcoreapp2.0\System.DirectoryServices.dll;
          $(USERPROFILE)\.nuget\packages\system.management\4.5.0\runtimes\win\lib\netcoreapp2.0\System.Management.dll;
          $(USERPROFILE)\.nuget\packages\system.management.automation\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\System.Management.Automation.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.management.infrastructure\1.0.0\runtimes\win10-x86\lib\netstandard1.6\Microsoft.Management.Infrastructure.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Management.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.utility\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Utility.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.commands.diagnostics\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Commands.Diagnostics.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.sdk\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.SDK.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.security\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.Security.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.coreclr.eventing\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.CoreCLR.Eventing.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.consolehost\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.ConsoleHost.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.powershell.markdownrender\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.PowerShell.MarkdownRender.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.wsman.runtime\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Runtime.dll;
          $(USERPROFILE)\.nuget\packages\microsoft.wsman.management\$(SDKVersion)\runtimes\$(SDKPlatform)\lib\netstandard2.0\Microsoft.WSMan.Management.dll;
          " DestinationFolder="$(OutputPath)\bin" />
      </Target>
    

    注意我这边microsoft.management.infrastructure设置为win10-x86(Win10),你可能需要根据你的电脑平台进行更改。程序集是 x86,因为 VS 默认使用 x86 Function CLi,除非我们需要使用 x64,否则我们不需要担心它。

    【讨论】:

    • 可能有点为时过早,但现在我得到了一个类似的错误——尽管是不同版本的 PowerShell (4.0.0.0): "{System.TypeInitializationException: The type initializer for 'System.Management .Automation.LanguagePrimitives' 抛出异常。---> System.IO.FileNotFoundException: 无法加载文件或程序集 'System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'。系统找不到指定文件。”当我尝试加载 MSOnline 模块时会发生这种情况,所以我是否正确地假设该模块存在 PowerShell 版本不匹配?
    • @CoryGehr 对不起,我的遗漏,尝试分两部分添加$(USERPROFILE)\.nuget\packages\system.management\4.5.0\runtimes\win\lib\netcoreapp2.0\System.Management.dll
    • 冒着不断出现一连串问题的风险,您如何包含这些项目有什么规律吗?我有另一个 FileNotFound:无法加载文件或程序集“System.DirectoryServices,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”。该系统找不到指定的文件。变得有点多 - 我是否需要继续尝试并将这些添加到我的 csproj 中的 Copy SourceFiles 直到它们停止?
    • 我添加了 $(USERPROFILE)\.nuget\packages\system.directoryservices\4.5.0\runtimes\win\lib\netcoreapp2.0\System.DirectoryServices.dll;它现在可以工作了,谢天谢地,这是最后一个。我相信我现在走在正确的轨道上 - 谢谢!
    • @CoryGehr 很高兴你克服了它,我同意你的观点,我们可能不得不根据错误来修复它。我注意到 PSSDK 引用了其他一些程序集,它们的运行时程序集没有移动到bin,我们也不包括它们。所以我们是否遇到问题取决于我们的代码在内部引用了哪些程序集。这根本不是一个理想的解决方案,但在 Azure 团队解决问题之前,我们可能不得不依赖它。
    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2019-05-05
    • 2019-08-17
    相关资源
    最近更新 更多