2

I want to get the PowerState (on/off/restarting, etc.) of a known Azure VM instance in a C#/dotnet application using Azure.ResourceManager (not PowerShell, not CLI, not REST, not using any deprecated Fluent approach).

I can do it successfully with REST so I know the underlying VM InstanceView data exists, but for this application REST will not pass muster.

I am using the following code; vm.Data.Name comes back as expected, but am getting null responses from InstanceView.Statuses.

I haven't been able to find any helpful MSFT documentation, except for old, deprecated approaches.

Does anyone know how to get PowerState via Azure.ResourceManager, or why I am getting NULL back?

Thanks!!

[code sample updated below on 1/16/23, changed auth approach, InstanceView still returning NULL]

using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Resources;

namespace Test
{
    public class Program
    {
        public static async Task ListAllVms()
        {
            ArmClient armClient = new ArmClient(new DefaultAzureCredential());
            SubscriptionResource subscription = await armClient.GetDefaultSubscriptionAsync();
            string rgName = "redacted";
            ResourceGroupResource resourceGroup = await subscription.GetResourceGroups().GetAsync(rgName);
            VirtualMachineCollection vmCollection = resourceGroup.GetVirtualMachines();
            AsyncPageable<VirtualMachineResource> response = vmCollection.GetAllAsync();
            
            await foreach (VirtualMachineResource vm in response)
            {
                Console.WriteLine(vm.Data.Name);
                foreach (InstanceViewStatus istat in vm.Data.InstanceView.Statuses)
                {
                    Console.WriteLine("\n  code: " + istat.Code);
                    Console.WriteLine("  level: " + istat.Level);
                    Console.WriteLine("  displayStatus: " + istat.DisplayStatus);
                }
            }
        }

        public static async Task Main(string[] args)
        {
            await ListAllVms();
        }
    }
}
cjr
  • 25
  • 6
  • Your using directives don't match with your code as `ComputeManagementClient` exists in `Microsoft.Azure.Management.Compute` which you haven't imported. Can you please state which Nuget packages you're using along with their exact version for the code sample above? – Ermiya Eskandary Jan 14 '23 at 10:50
  • Thanks for the response. I messed something up in the process of editing the code sample to remove code not relevant to the problem. I'll figure it out and edit, or maybe even repost. Thank you and sorry. – cjr Jan 15 '23 at 00:01
  • Don’t be! It’s more for me to be able to help more - edit whenever and I’ve followed the question so i’ll know to revisit – Ermiya Eskandary Jan 16 '23 at 00:47
  • Code sample updated on 1/16/23, changed auth approach, InstanceView still returning NULL – cjr Jan 17 '23 at 01:01

2 Answers2

1

After reproducing from my end, I could able to achieve this using vm.Get().Value.InstanceView().Value.Statuses[1].DisplayStatus. Below is the complete code that worked for me where I list all the vm present in my resource group and get the statuses of it.

using System;
using System.Threading.Tasks;
using Azure;
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Resources;

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            ArmClient armClient = new ArmClient(new InteractiveBrowserCredential(new InteractiveBrowserCredentialOptions() { TenantId = "<YOUR_TENAT_ID>" }));
            SubscriptionResource subscriptionResource = await armClient.GetDefaultSubscriptionAsync();

            string rgName = "<YOUR_RESOURCE_GROUP>";
            ResourceGroupResource resourceGroupResource = await subscriptionResource.GetResourceGroups().GetAsync(rgName);

            VirtualMachineCollection vmCollection = resourceGroupResource.GetVirtualMachines();
    
            // Lists all virtual machines
            AsyncPageable<VirtualMachineResource> vmList = vmCollection.GetAllAsync();
            Console.WriteLine("Listing");
            await foreach (VirtualMachineResource vm in vmList)
            {
                Console.WriteLine(vm.Data.Name);
                Console.WriteLine(vm.Get().Value.InstanceView().Value.Statuses[1].DisplayStatus);
            }
        }
    }
}

output:

enter image description here

SwethaKandikonda
  • 7,513
  • 2
  • 4
  • 18
  • 1
    That certainly works! Thank you very much! Please don't misunderstand this as lack of appreciation for a working solution (that unblocks me thank you very much) but it feels like there should be a cleaner, more "direct" one shot way to do this and the data should be returned in vmList without additional calls to the server ( vm.Get() triggers a call, right? ). Is this just how it works? You need to call vm.Get() for each vm to load each InstanceView? – cjr Jan 17 '23 at 04:58
  • @cjr `vm.Get()` returns the status with Azure.ResourceManager.Compute.VirtualMachineResource object. Hence to retrieve the status, I had to use `vm.Get().Value.InstanceView().Value.Statuses[1].DisplayStatus`. and yes you need to call vm.Get() to retrive its InstanceView – SwethaKandikonda Jan 18 '23 at 03:03
  • I'm migrating code from Fluent to ResourceManager and this is so bizarre. What is Statuses[0]?? I guess I will have to debug to find out. I'm writing an extension method to return something like the "PowerState" from the Fluent API and this seems really awkward. – Skrymsli Mar 28 '23 at 16:15
1

Accepted answer above was almost there but for me I had to change the code to:

vm.Get(InstanceViewType.InstanceView).Value.Data.InstanceView.Statuses[1].DisplayStatus

Hope that helps someone.

naloney
  • 11
  • 1