2

Basically, I want to execute AZURE CLI command from my C# Azure function which is running in Linux environment.

I am currently taking approach of executing this command through running powershell script from C#.

I have tried PowerShell.Core which is cross platform version.

If I include Microsoft.PowerShell.Commands.Diagnostics and System.Management.Automation than it is able to initiate PowerShell instance but it requires PowerShell.SDK that is PowerShell runtime to be included.

If it is included than it works locally in windows but in Azure with Linux environment, it can not understand it. It gives 404 not found error for function.

Sample Code:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Threading;

namespace FunctionApp1
{
    public static class FunctionApp1
    {
        static ILogger logger;

        [FunctionName("FunctionApp1")]
        public static ActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            logger = log;
            log.LogInformation("C# HTTP trigger function processed a request.");
            try
            {
                using (PowerShell PowerShellInstance = PowerShell.Create())
                {
                    PowerShellInstance.AddScript("az --version");
                    log.LogInformation("PowerShell instance created.");

                    PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
                    outputCollection.DataAdded += outputCollection_DataAdded;
                    PowerShellInstance.Streams.Error.DataAdded += Error_DataAdded;

                    IAsyncResult result = PowerShellInstance.BeginInvoke<PSObject, PSObject>(null, outputCollection);
                    while (result.IsCompleted == false)
                    {
                        log.LogInformation("Waiting for pipeline to finish...");
                        Thread.Sleep(1000);
                    }
                    log.LogInformation("Execution has stopped. The pipeline state: " + PowerShellInstance.InvocationStateInfo.State);
                    foreach (PSObject outputItem in outputCollection)
                    {
                        log.LogInformation(outputItem.BaseObject.ToString());
                    }
                }
                log.LogInformation("execution completed.");
            }
            catch (Exception ex)
            {
                log.LogInformation("Error occured");
                log.LogError(ex.Message + ex.StackTrace);
            }
            finally
            {
                log.LogInformation("finally block completed.");
            }
            return new OkObjectResult("Success");
        }

        static void outputCollection_DataAdded(object sender, DataAddedEventArgs e)
        {               
            logger.LogInformation("Object added to output.");
        }
        
        static void Error_DataAdded(object sender, DataAddedEventArgs e)
        {                
            logger.LogInformation("An error was written to the Error stream!");
            Collection<ErrorRecord> error = ((System.Management.Automation.PSDataCollection<System.Management.Automation.ErrorRecord>)sender).ReadAll();
            foreach (var item in error)
            {
                logger.LogInformation(item.ToString());
            }
        }
    }
}
Finisher001
  • 455
  • 1
  • 5
  • 18
  • Does this answer your question? PowerShell will not run from Linux since it is windows only. [Run Azure CLI Commands from a Azure Function APP](https://stackoverflow.com/questions/59354593/run-azure-cli-commands-from-a-azure-function-app) – Murray Foxcroft Jul 14 '20 at 12:31
  • @MurrayFoxcroft PowerShell.Core is cross-platform – Pavel Anikhouski Jul 14 '20 at 12:36
  • @MurrayFoxcroft Azure CLI is directly not supported but I think we should be able to do it using Powershell. – Finisher001 Jul 14 '20 at 12:43
  • @PavelAnikhouski I have not tried using PowerShell.Core. I will try this – Finisher001 Jul 14 '20 at 12:43
  • 1
    I tried to use PowerShell.Core. There was progress but not success. I included Microsoft.PowerShell.Commands.Diagnostics using PowerShell-Core package source. It solved problem of intance creation but to execute script it also want PowerShell.SDK to be installed. If I include this then it works locally but Azure can not understand function. It gives 404 not found error for function. – Finisher001 Jul 14 '20 at 15:23
  • Please note that you don't need PowerShell to execute Azure CLI commands. Azure CLI has no dependency on PowerShell. – Anatoli Beliaev Jul 14 '20 at 17:37
  • @AnatoliBeliaev, yes I know. But is there any other approach to execute CLI commands through C# code in linux system? I am trying to use Linux bash, but it is not able to execute CLI commands. Any idea? – Finisher001 Jul 15 '20 at 06:13
  • May I know what requirement do you want to implement by CLI command ? – Hury Shen Jul 15 '20 at 06:36
  • @HuryShen Mounting File storage to function – Finisher001 Jul 15 '20 at 07:11
  • @Finisher001 I'm assuming you are using .NET Core, so you should be able to use the Process class to start an executable: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process?view=netcore-3.1. Using the PowerShell SDK just for that is way too heavy. You will also need to make sure Azure CLI is installed. – Anatoli Beliaev Jul 15 '20 at 08:07
  • @AnatoliBeliaev, yes you are right. I have tried that approach. But I don't know how to install Azure CLI in function. Tried to install at run time from bash command but it doesn't have the rights to install. – Finisher001 Jul 16 '20 at 09:42
  • @Finisher001 If you are using a custom container image, just install Azure CLI on your image. Otherwise, install Azure CLI on a Linux machine and copy the entire folder (normally /usr/bin/az) to your app. – Anatoli Beliaev Jul 16 '20 at 20:15
  • @AnatoliBeliaev that's next thing I am going to try. Thanks for suggestions. – Finisher001 Jul 17 '20 at 07:34

0 Answers0