无法在Azure Functions v2中运行PowerShell脚本

时间:2018-12-11 03:58:49

标签: azure powershell azure-functions

我正在尝试在Azure Functions v2中使用.NET Core编写Function App。使用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函数并添加以下代码段即可:

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。

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

1 个答案:

答案 0 :(得分:2)

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

解决方法是手动将程序集移动到输出目录bin。右键单击您的功能项目,然后单击Edit <FunctionProject>.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>

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