Cannot run PowerShell scripts in Azure Functions v2 - azure

I'm trying to write a Function App using .NET Core in Azure Functions v2. When using the Microsoft.Powershell.SDK package from Nuget (required for .NET Core PowerShell runtime) I cannot get Visual Studio to copy the System.Management.Automation library to the bin with my Function App.
This results in the following error:
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.
I've reproduced this in an existing Azure Function and a new Solution by simply creating a Timer function and adding the following snippet:
PowerShell shell = PowerShell.Create();
IEnumerable<PSObject> result = shell.AddScript("Write-Output 'Hello, World!'").Invoke();
foreach(PSObject line in result)
{
log.LogInformation(line.ToString());
}
This works on a new Console App with the PowerShell Nuget installed, but when added to the Function App I get the error. I do notice that System.Management.Automation doesn't get put in the bin directory with a regular Console App but I'm not sure how to interpret this. I know it's a System library but I can't use it unless the Nuget is installed, so I don't know if this is a special case. In both scenarios I'm using v6.1.1 of the PowerShell Nuget.
Is this a known bug with Functions v2? Or am I missing something?

It's a known issue that Function can't load runtime assemblies([FunctionProject]\bin\Debug\netcoreapp2.1\bin\runtimes) correctly.
The workaround is to move assemblies to output dir bin manually. Right click on your function project and Edit <FunctionProject>.csproj. Add following items to achieve our goal.
<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>
Note that microsoft.management.infrastructure is set to win10-x86 on my side(Win10), you may need to change according to your pc platform. Assemblies are x86 as VS uses x86 Function CLi by default, we don't need to worry about it unless we need to work with x64.

Related

Could not load file or assembly 'Microsoft.Extensions.DependencyModel, Version=3.0.0.0 in Azure Functions App v3

I have a v3 queue-triggered function that has been working fine on my Windows 10 machine. This is how the .csproj file looks like:
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
I am not sure why I started getting the exception mentioned in the subject line, but the bottom line is that this function used to work well. This Stackoverflow post was not helpful to address the issue. Could it be due to upgrading the operating system to Windows 11? I did not run this function app immediately after migrating to Windows 11, so I cannot speak on that.
The full exception's stack trace is per below:
Could not load file or assembly 'Microsoft.Extensions.DependencyModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
at
Microsoft.Azure.Functions.Extensions.DependencyInjection.FunctionsStartup.Configure(WebJobsBuilderContext
context, IWebJobsBuilder builder) at
Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.ConfigureStartup(IWebJobsStartup
startup, WebJobsBuilderContext context, IWebJobsBuilder builder) in
C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line
162
Any idea on what the possible solution would be as it has become a roadblock?
To preserve specific version in order to avoid upgrading to a newer version which you could add this entry to csproj
<ItemGroup>
<FunctionsPreservedDependencies Include="Microsoft.Extensions.DependencyModel.dll" />
</ItemGroup>
You can try adding <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput> to the Function's project file.
like this:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
</PropertyGroup>

Azure function multiple output binding Extensions error

I'm developing an Azure function through the portal,
My function is an HttpTrigger with httpResponse.
I add a TableStorage output binding and install its Extension (everything is fine).
I add a SendGrid output binding and install its Extension (the extension installer give me a message saying "it takes longer than expected" and seems to fail. Afterward, my function is broken.
I tried creating my bindings in reverse order (SendGrid then TableStorage). It now fails on TableStorage installation.
Any way to resolve this issue?
Thanks
It's a known issue that sometimes filesystem for Consumption plans reacts slow, e.g during extension installation with many file I/O operations.
The first suggestion is to delete the extensions and retry.
Stop Function app.
In portal, Platform features> App Service Editor.
Right click on bin folder and extensions.csproj, Delete.
Start Function app.
Delete existing output bindings and add them again to install extensions.
If this doesn't work, try to manually install the extensions.
Stop Function app.
In portal, Platform features> App Service Editor.
Right clik on the blank under WWWROOT, New File extensions.csproj then add content below.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<WarningsAsErrors />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.SendGrid" Version="3.0.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.2" />
<PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="1.0.*" />
</ItemGroup>
</Project>
Press Ctrl+Shift+C to open console, or click the second button Open Console from the bottom on the sidebar.
Input dotnet build extensions.csproj -o bin --no-incremental --packages D:\home\.nuget and wait for the command to finish.
Start Function app.

IIS WebDeploy using MS Build Fails with error MSB4044 -ConcatFullServiceUrlWithSiteName task

In setting up a Jenkins deployment job, I kept running into this error when trying to deploy a Visual Studio 2012 Web project via the command line.
error MSB4044: The "ConcatFullServiceUrlWithSiteName" task was not given a value for the required parameter "SiteAppName"
For reference, here are the parameters that I used:
/p:Configuration=Release /t:Rebuild /p:VisualStudioVersion=11.0 /p:PublishProfile="DeployToDevServer"
/p:DeployOnBuild=True /p:DeployTarget=MSDeployPublish
/P:AllowUntrustedCertificate=True /p:MSDeployPublishMethod=WMSvc
/p:MsDeployServiceUrl=https://devmachine.server.com:8172/MsDeploy.axd
/p:username=domainhere\adminuserhere /p:password=adminpasshere
Note: It would deploy just fine if I chose Publish... from inside the project.
After much googling, and finally comparing a project that would deploy with the one that wouldn't, I finally figured it out after I opened the .csproj files with a text editor and compared them.
In the project that worked, I found this section:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
And it had this line:
<DeployIisAppPath>Default Web Site/sitenamehere</DeployIisAppPath>
I added this same line to the non-working project, changed the sitename, and it worked.
Hope this helps someone else.
You could pass this DeployIisAppPath as parameter to Jenkins, like this:
p:DeployIisAppPath=Default Web Site/sitenamehere
This would allow you to have different sitenames on different machines. While in your example (with CSPROJ modification) you would be obliged to have one IIS site name on all target machines

TFS Deployment to Azure Error: cannot find ClientPerfCountersInstaller.exe

I configured our implementation to use the Azure Caching provider to maintain session state between all cloud instances like described here:
http://msdn.microsoft.com/en-us/library/windowsazure/gg185668.aspx
This created a new startup task on my csdef file that always fails with this error:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Windows Azure Tools\2.0\Microsoft.WindowsAzure.targets (987): CloudServices64 : Cannot find file named 'approot\bin\Microsoft.WindowsAzure.Caching\ClientPerfCountersInstaller.exe' for startup task Microsoft.WindowsAzure.Caching\ClientPerfCountersInstaller.exe install of role MyRole.Web.
The .exe in the nuget package and in the main folder is included in the source control that TFS uses for the deployment.
I found this previous question that addresses this same issue:
Azure Deployment Error: cannot find ClientPerfCountersInstaller.exe
But the accepted answer states to just delete the startup task that installs the .exe needed for the caching to take place.
Make sure the .exe is marked as CopyAlways so that it is copied to your \bin directory.
To do so, right click on the .exe in Visual Studio and select properties. Make sure it looks like this:
I had a similar issue with a dedicate cache worker role, but in my case the Microsoft.WindowsAzure.Caching folder never showed up in VisualStudio. In the end, I had to open the .csproj file for the worker role project and this:
<None Include="Microsoft.WindowsAzure.Caching\ClientPerfCountersInstaller.exe.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Microsoft.WindowsAzure.Caching\ClientPerfCountersInstaller.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Microsoft.WindowsAzure.Caching\PerformanceCounters.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
I put that within the same <ItemGroup> tag as the app.config file, and now it's deploying as it should.

RoleEnvironment initialization in Azure on IIS x64 bit throws an error

I created webservice that runs under IIS, and it is x64 bit. I deployed it with custom install script on Azure machine (ws2008 r2). I created custom app pool (64 bit, Managed pipeline mode: Classic, .net v2, with NetworkService account as service user). Everything seems to be configured correctly but when I try to run my application I get following error:
System.TypeInitializationException: The type initializer for 'Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment' threw an exception. ---> System.TypeInitializationException: The type initializer for '' threw an exception. ---> .ModuleLoadException: The C++ module failed to load while attempting to initialize the default appdomain.
I can run standalone win form application and this method works correctly. What is more when I switch app pool to 32 bit and I run my application then it fail (because it has x64 bit components), however later when switch back to x64 it works correctly, RoleEnvironment returns correct data.
Do you have any ideas what can I do wrong when it comes to configuration, so this module cannot be loaded in x64 bit version?
This may help. You can add a start-up task to your Windows Azure project's .csdef file to configure IIS to allow 32-bit modules in 64-bit applications.
In your Windows Azure project .csdef file:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition>
<WebRole ...>
...
<Startup>
<Task commandLine="ConfigureIIS.cmd" executionContext="elevated" taskType="simple" />
</Startup>
</WebRole>
</ServiceDefinition>
ConfigureIIS.cmd (all one line):
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.enable32BitAppOnWin64:true
I believe you would need to install VC++ x64 runtime in your Azure VM via startup task as some of the references you are using need VC++ run time.

Resources