Piyush
Piyush

Reputation: 399

Retrieving Job Id status for Azure Runbook is throwing 401 error in C# code

My intension is to call An Azure Runbook in c# code (Azure Function) via webhook. Check the status of the function and then retrieve the output of the Runbook. I am able to easily trigger runbook but when I am trying to get the Job status I am getting Error 401. My function is running in cluster and I am using Managed Id to Connect. The Managed Id have appropriate role assigned to the Automation Account. Below is the code ,please suggest if anyone have encountered this issue or have done something similar.

using (var client = new HttpClient())
{
    //var inputJson1 = JsonConvert.SerializeObject(input);

    HttpContent inputContent = new StringContent(inputJson, Encoding.UTF8, "application/json");
    //connect to the REST endpoint         
    var url = "<Webhook URL>";
    var response = await client.PostAsync(url, inputContent);

    var content = await response.Content.ReadAsStringAsync();

    
    RunBookData rData = JsonConvert.DeserializeObject<RunBookData>(content);

    var jobId = new Guid(rData.JobIds[0]);  // Assumes the response is a quoted GUID

    while (true)
    {
        // Get the job status
        response = await client.GetAsync($"https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Automation/automationAccounts/{automationAccountName}/jobs/{jobId}?api-version=2015-10-31");

        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("----------------------> Failed to get job status "+ response.IsSuccessStatusCode);
            throw new Exception("Failed to get job status");
        }

        content = await response.Content.ReadAsStringAsync();
        var status = JObject.Parse(content)["properties"]["status"].Value<string>();

        if (status == "Completed" || status == "Failed" || status == "Stopped")
        {
            status = "Completed";
            Console.WriteLine("Status----------------------> " + status);
            break;
        }

        await Task.Delay(TimeSpan.FromSeconds(30));
    }


    //var response = HttpPostRequest(client, url, inputContent, log).ConfigureAwait(false);
    // check to see if we have a successful response
}

Upvotes: 0

Views: 83

Answers (1)

RithwikBojja
RithwikBojja

Reputation: 11208

I have followed below steps to get job status:

Firstly create a app registration and give user_impersonation role.

enter image description here

Then Give the Automation Contributor role in subscription level to the app registration.

enter image description here

Then used below code to get the status of runbook job, I followed SO-Thread and Microsoft-Document:

using System.Net.Http.Headers;
using Microsoft.Identity.Client;
class Program
{
    private const string ri_scp = "https://management.azure.com/.default";
    private const string ri_sub_id = "13f2016";
    private const string ri_rg_name = "rithwik";
    private const string ri_auto_acc_nme = "rithwik1";
    private const string ri_job_name = "37e2ad3";
    private const string ri_clnt_id = "7edc04";
    private const string ri_Tnt_Id = "932f6d";
    private const string ri_clnt_sect = "Qz78aBi";

    static async Task Main(string[] args)
    {
        IConfidentialClientApplication rith = ConfidentialClientApplicationBuilder.Create(ri_clnt_id)
            .WithClientSecret(ri_clnt_sect)
            .WithAuthority(new Uri($"https://login.microsoftonline.com/{ri_Tnt_Id}")).Build();
        string[] riscps = new string[] { ri_scp };
        AuthenticationResult result = await rith.AcquireTokenForClient(riscps).ExecuteAsync();
        string tst_url = $"https://management.azure.com/subscriptions/{ri_sub_id}/resourceGroups/{ri_rg_name}/providers/Microsoft.Automation/automationAccounts/{ri_auto_acc_nme}/jobs/{ri_job_name}?api-version=2023-11-01";
        using (HttpClient ri_cl = new HttpClient())
        {
            ri_cl.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
            HttpResponseMessage ri_res = await ri_cl.GetAsync(tst_url);
            ri_res.EnsureSuccessStatusCode();
            string ri_out = await ri_res.Content.ReadAsStringAsync();
            Console.WriteLine("Hello Rithwik, Job Status is " + ri_out);
        }
    }
}

Output:

enter image description here

Upvotes: 0

Related Questions