【Azure 環境】在Azure虛擬機器(經典) 的資源中,使用SDK匯出VM列表的辦法

路邊兩盞燈發表於2021-05-18

Azure,  在2008年10月的Microsoft專業開發人員大會(PDC)上宣佈,當時使用內部專案代號“Project Red Dog”,並於2010年2月正式釋出為Windows Azure,然後在 2014年3月25日更名為Microsoft Azure

Azure, announced at Microsoft's Professional Developers Conference (PDC) in October 2008, went by the internal project codename "Project Red Dog", and formally released in February 2010, as Windows Azure before being renamed to Microsoft Azure on March 25, 2014

 

到2021年,經歷了11年的發展,其中的架構也經歷了大的變動,最明顯的就是從最早的經典模式到目前的ARM(Azure Resource Manager)模式,這兩中模式簡單區別的模式圖如:

【Azure 環境】在Azure虛擬機器(經典) 的資源中,使用SDK匯出VM列表的辦法

更多ARM模型與經典模型的區別,可以參考官網介紹:https://docs.microsoft.com/zh-cn/azure/azure-resource-manager/management/deployment-models

 

問題描述

因為兩種模型的不同,如果是較早使用經典部署建立的虛擬機器,則必須繼續通過經典操作對其進行操作。所以如何才能獲取到VM列表呢?

對於虛擬機器、儲存帳戶和虛擬網路,如果資源是通過經典部署建立的,則必須繼續通過經典操作對其進行操作。 如果虛擬機器、儲存帳戶或虛擬網路是通過 Resource Manager 部署建立的,則必須繼續使用 Resource Manager 操作。

 

 

解決方法

如果是想獲取ARM部署下的虛擬機器資源,可以通過SDK獲取,操作示例程式碼可見(【Azure Developer】使用Java SDK程式碼建立Azure VM (包含設定NSG,及新增資料磁碟SSD)),用  azure.virtualMachines().list() 這句程式碼,即可列出當前訂閱下的所有VM列表。

但是,獲取經典模式下的虛擬機器則完全不同。經過研究,程式碼方式可以通過REST API的方式來解決,只是操作步驟也最複雜:

 

REST API 介面:https://management.core.chinacloudapi.cn/{訂閱號ID}/services/hostedservices/{雲服務名稱}/deployments/{部署名}

 

1)  在呼叫介面前,需要保證您的當前訂閱有經典管理員的許可權,請參考:https://docs.azure.cn/zh-cn/role-based-access-control/classic-administrators

  1. 以服務管理員或共同管理員的身份登入到 Azure 門戶

  2. 開啟訂閱並選擇一個訂閱。

    只能在訂閱範圍分配共同管理員。

  3. 單擊“訪問控制(IAM)”。

  4. 單擊“經典管理員”選項卡。

    開啟經典管理員的螢幕截圖

  5. 單擊“新增” > “新增共同管理員”開啟“新增共同管理員”窗格。

    如果“新增共同管理員”選項已禁用,則表示你沒有相應的許可權。

  6. 選擇要新增的使用者,然後單擊“新增”。

 

 

2)  獲取一個證照檔案

【Azure 環境】在Azure虛擬機器(經典) 的資源中,使用SDK匯出VM列表的辦法

 

 

3)  在程式碼中通過REST API的方式獲取經典虛擬機器資訊

在Azure門戶中先檢視到經典雲服務和部署的名稱,然後通過 Get Deployment 方法獲取到部署資訊,返回的角色資訊節點中包含經典虛擬機器的資訊。在下面的程式碼中替換掉以下四個引數

  • credentialsPath = @"your.publishsettings" ## 第二步中所下載的檔案
  • subscriptionId = "subscriptionId"                 ##第一步中的訂閱號
  • cloudServiceName = "cloudServiceName" ##在雲服務中檢視
  • deploymentName = "deploymentName"     ##在雲服務中檢視
/****************************** Module Header ******************************\
* Module Name: Program.cs
* Project:     GetClassicVMInfo
* Copyright (c) Microsoft Corporation.
* 
* Managing Azure in Role instance may be difficult, because it requires a client 
* certificate. This sample will show how to use the base64 string certificate 
* instead of getting the certificate from Certificates store
* 
* This source is subject to the Microsoft Public License.
* See http://www.microsoft.com/en-us/openness/licenses.aspx#MPL
* All other rights reserved.
* 
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
* EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/


using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Xml.Linq;
using System.Net;
using System.IO;

namespace GetClassicVMInfo
{
    class Program
    {
        public static string credentialsPath = @"your.publishsettings";
        public static string subscriptionId = "subscriptionId";
        public static string cloudServiceName = "cloudServiceName";
        public static string deploymentName = "deploymentName";

        static void Main(string[] args)
        {
            XElement x=XElement.Load(credentialsPath);

            var Base64cer = (from c in x.Descendants("Subscription")
                                where c.Attribute("Id").Value == subscriptionId
                                select c.Attribute("ManagementCertificate").Value).FirstOrDefault();

            X509Certificate2 cer = null;
            if (Base64cer != null)
            {
                cer = new X509Certificate2(Convert.FromBase64String(Base64cer));
            }
            if (cer != null)
            {
                GetHostedServicesByRESTAPI(subscriptionId, cer);
            }
            Console.ReadLine();        
        }

        static void GetHostedServicesByRESTAPI(string subscriptionId, X509Certificate2 certificate)
        {
            string uri = string.Format("https://management.core.chinacloudapi.cn/{0}/services/hostedservices/{1}/deployments/{2}", subscriptionId, cloudServiceName, deploymentName);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(uri));
            request.Method = "GET";
            request.ClientCertificates.Add(certificate);
            request.ContentType = "application/xml";
            request.Headers.Add("x-ms-version", "2016-06-01");

            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                // Parse the web response.
                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);

                string xml = reader.ReadToEnd();                
                XDocument doc = XDocument.Parse(xml);
                XNamespace ns = doc.Root.Name.Namespace;
                XElement roleInstanceList = doc.Root.Element(ns + "RoleInstanceList");
                if (roleInstanceList != null)
                {
                    foreach (XElement roleInstance in roleInstanceList.Elements())
                    {
                        Console.WriteLine("InstanceName:"+roleInstance.Element(ns + "InstanceName").Value);
                        Console.WriteLine("InstanceStatus:" + roleInstance.Element(ns + "InstanceStatus").Value);
                    }
                }
                // Close the no longer needed resources.
                response.Close();
                responseStream.Close();
                reader.Close();
                Console.ReadKey();
            }
            catch (WebException ex)
            {
                Console.Write(ex.Response.Headers.ToString());
                Console.Read();
            }
           
        }
    }
}

 

PS: 也可以通過List Cloud Services方法獲取到所有云服務,然後遍歷其中的部署資訊獲取經典虛擬機器的資訊

Get Deployment : https://docs.microsoft.com/en-us/previous-versions/azure/reference/ee460804(v=azure.100)

List Cloud Services : https://docs.microsoft.com/en-us/rest/api/compute/cloudservices/rest-list-cloud-services 

以上文件中的URL均為Global Azure,如果在中國區使用,則需要轉換成:management.core.chinacloudapi.cn, 這點非常重要。

 

附錄一:在Azure 門戶中使用Azure Resource Graph快速檢視經典虛擬機器列表(無程式碼),然後另存為本地檔案。

點選“https://portal.azure.cn/#blade/HubsExtension/ArgQueryBlade”進入 Azure Resource Graph Explorer 頁面,輸入以下查詢語句:

Resources
| project name, location, type
| where type =~ 'Microsoft.ClassicCompute/virtualMachines'
| order by name desc

查詢結果:

【Azure 環境】在Azure虛擬機器(經典) 的資源中,使用SDK匯出VM列表的辦法

 

 

 

 

參考資料

Azure 經典訂閱管理員: https://docs.azure.cn/zh-cn/role-based-access-control/classic-administrators

Azure 資源管理器和經典部署:瞭解部署模型和資源狀態 : https://docs.microsoft.com/zh-cn/azure/azure-resource-manager/management/deployment-models

Get Deployment : https://docs.microsoft.com/en-us/previous-versions/azure/reference/ee460804(v=azure.100)

List Cloud Services : https://docs.microsoft.com/en-us/rest/api/compute/cloudservices/rest-list-cloud-services 

中國區Azure 終結點 Endpoint:https://docs.azure.cn/zh-cn/articles/guidance/developerdifferences#check-endpoints-in-azure

 

相關文章