Запустить сценарий PowerShell / команду CLI из функции C# Azure с системой Linux - PullRequest
0 голосов
/ 14 июля 2020

По сути, я хочу выполнить команду AZURE CLI из моей C# Azure функции, которая работает в среде Linux.

В настоящее время я использую подход к выполнению этой команды через запуск PowerShell скрипт из C#.

Я пробовал PowerShell.Core, который является кроссплатформенной версией.

Если я включу Microsoft.PowerShell.Commands.Diagnostics и System.Management.Automation, то он сможет для запуска экземпляра PowerShell, но для этого требуется, чтобы был включен PowerShell.SDK, который является средой выполнения PowerShell.

Если он включен, он работает локально в windows, но в Azure со средой Linux он не может понимать это. Для функции выдается ошибка 404:

Пример кода:

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());
            }
        }
    }
}
...