PowerShell Azure IaaS为灾难恢复导出虚拟机、虚拟网络和存储

PowerShell Azure IaaS为灾难恢复导出虚拟机、虚拟网络和存储,azure,azure-storage,azure-virtual-machine,azure-powershell,azure-virtual-network,Azure,Azure Storage,Azure Virtual Machine,Azure Powershell,Azure Virtual Network,是否有人知道从Azure IaaS虚拟机实现中检索以下信息的方法和/或示例代码 按名称列出的关联虚拟网络-而不是子网;我已经可以得到它了,因为它对于订阅中的所有虚拟网络都不是唯一的,所以无法使用 VM连接的磁盘的存储帐户 作为问题的补充,我们正在尝试生成用于灾难恢复目的的XML,这将允许我们在主数据中心发生故障时在辅助数据中心上重建IaaS实现。我们已经设法检索了大部分(如果不是全部的话)我们需要的信息,但是找不到一种方法来从VM获取VNet(反之亦然)或VM磁盘的存储帐户/容器。在(2)上,您

是否有人知道从Azure IaaS虚拟机实现中检索以下信息的方法和/或示例代码

  • 按名称列出的关联虚拟网络-而不是子网;我已经可以得到它了,因为它对于订阅中的所有虚拟网络都不是唯一的,所以无法使用
  • VM连接的磁盘的存储帐户
  • 作为问题的补充,我们正在尝试生成用于灾难恢复目的的XML,这将允许我们在主数据中心发生故障时在辅助数据中心上重建IaaS实现。我们已经设法检索了大部分(如果不是全部的话)我们需要的信息,但是找不到一种方法来从VM获取VNet(反之亦然)或VM磁盘的存储帐户/容器。

    在(2)上,您是否能够提取每个磁盘的MediaLocation值

    <PersistentVMRole xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <RoleName>name-of-the-virtual-machine</RoleName>
      <RoleType>PersistentVMRole</RoleType>
      <VMImage>name-of-vm-image</VMImage>
      <MediaLocation>path-to-vhds</MediaLocation>
    
    
    虚拟机的名称
    PersistentVMRole
    虚拟机映像的名称
    vhds的路径
    
    这将使用一个快速启动:

    https://management.core.windows.net/<subscription-id>/services/hostedservices/<cloudservice-name>/deployments/<deployment-name>/roles/<role-name>
    
    https://management.core.windows.net//services/hostedservices//deployments//roles/
    

    -马特

    我将回答你问题的第二部分。使用powershell非常简单。假设vm名称为“testvm”,服务名称为“testservice”。Powershell以获取存储帐户名-

     $disk = Get-AzureVM -ServiceName "testservice" –Name "testvm" | Get-AzureOSDisk
     $mediaLink = $disk.MediaLink
     $storageAccountName = $mediaLink.Host.Split('.')[0]
     $storageAccountName 
    

    希望这能回答你的问题。

    我知道这个问题很老了,但没有完整的答案。我使用这个PowerShell脚本在单个订阅中将VM的XML数据收集到一个文件中。本质上,它获取所有信息,然后进行过滤

    $VMs = Get-AzureRmVM
    $NICs = Get-AzureRmNetworkInterface
    $VNETs = Get-AzureRmVirtualNetwork
    
    $AzureVMInventory = foreach ($VM in $VMs) {
    
        $NIC = $NICs | Where { $_.Id -eq $VM.NetworkProfile.NetworkInterfaces.Id }
        $Subnet = $VNETs.Subnets | Where { $_.Id -eq $NIC.IPConfigurations.Subnet.Id }
        $VNET = $VNETs | Where {$_.Subnets.Id -eq $NIC.IPConfigurations.Subnet.Id}
    
        $Property = [ordered]@{
            Name = $VM.OSProfile.ComputerName
            VMSize = $VM.HardwareProfile.VmSize
            ResourceGroup = $VM.ResourceGroupName
            OSDisk = $VM.StorageProfile.OsDisk.Vhd.Uri
            DataDisk = $VM.StorageProfile.DataDisks.Vhd.Uri -join "#"
            IPAddresses = $NIC.IpConfigurations.PrivateIPAddress
            IPAllocationMethod = $NIC.IpConfigurations.PrivateIPAllocationMethod
            nicName = $NIC.Name
            vNet = $VNET.Name
            Subnet = $Subnet.Name
            Location = $NIC.Location
        }
    
        New-Object -TypeName PSObject -Property $Property
    }
    
    $XML = $AzureVMInventory | ConvertTo-Xml -Depth 99
    
    # Inject XSLT processing into the XML
    $ProcessInstruction = $XML.CreateProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="style.xsl"')
    $XML.InsertBefore($ProcessInstruction, $XML.DocumentElement)
    
    $XML.Save("$PSScriptRoot\ProductionVMs.xml")
    
    因为读取XML是一场噩梦,所以我插入了一条流程指令并调用了XSL样式表,这样当浏览器打开XML文件时,它就可以格式化为HTML格式,并且可以作为表读取。这适合上面生成的XML,但出于我的目的,其中有一些特定的代码

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output encoding="ISO-8859-1"/>
    
        <xsl:template name="tokenizeString">
            <!--passed template parameter -->
            <xsl:param name="list"/>
            <xsl:param name="delimiter"/>
            <xsl:choose>
                <xsl:when test="contains($list, $delimiter)">                
                        <!-- get everything in front of the first delimiter -->
                        <xsl:value-of select="substring-before($list,$delimiter)"/>
                    <br />
                    <xsl:call-template name="tokenizeString">
                        <!-- store anything left in another variable -->
                        <xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
                        <xsl:with-param name="delimiter" select="$delimiter"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="$list = ''">
                            <xsl:text/>
                        </xsl:when>
                        <xsl:otherwise>
                                <xsl:value-of select="$list"/>
                            <br />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template> 
    
     <xsl:template match="/">
    
    <html>
    <head>
    <title>Azure Virtual Machines</title>
    <link rel="stylesheet" href="style.css" type="text/css" />
    </head>
    <body>
        <table>
        <tr>
          <th>Name</th>
          <th>IP Addresses</th>
          <th>IP Allocation Method</th>
          <th>Virtual Network</th>
          <th>Subnet</th>
          <th>VMSize</th>
          <th>Resource Group</th>
          <th>Network Interface</th>
          <th>Location</th>
          <th>OS Disk</th>
          <th>Data Disks</th>
        </tr>
        <xsl:for-each select="//Objects/Object">
        <xsl:sort select="Property[@Name='Name']" order="ascending" data-type="text"/>
            <xsl:variable name="datadisks" select="Property[@Name='DataDisk']"/>
            <tr>
                <td><xsl:value-of select="Property[@Name='Name']" /></td>
                <td><xsl:value-of select="Property[@Name='IPAddresses']" /></td>
                <td><xsl:value-of select="Property[@Name='IPAllocationMethod']" /></td>
                <td><xsl:value-of select="Property[@Name='vNet']" /></td>
                <td><xsl:value-of select="Property[@Name='Subnet']" /></td>
                <td><xsl:value-of select="Property[@Name='VMSize']" /></td>
                <td><xsl:value-of select="Property[@Name='ResourceGroup']" /></td>
                <td><xsl:value-of select="Property[@Name='nicName']" /></td>
    
                    <!-- <td><xsl:value-of select="Property[@Name='Location']" /></td> -->
                    <xsl:choose>
                        <xsl:when test="Property[@Name='Location'] = 'northeurope'">
                            <td class="loc_ne">North Europe</td>
                        </xsl:when>
                        <xsl:when test="Property[@Name='Location'] = 'westeurope'">
                            <td class="loc_we">West Europe</td>
                        </xsl:when>
                        <xsl:otherwise>
                            <td class="loc_err">NOT EUROPE</td>
                        </xsl:otherwise>
                    </xsl:choose>
    
                <td><xsl:value-of select="Property[@Name='OSDisk']" /></td>
                <td>
                    <!-- <xsl:value-of select="Property[@Name='DataDisk']" /> -->
                    <xsl:choose>
                        <xsl:when test="boolean(Property[@Name='DataDisk'])">
                            <xsl:call-template name="tokenizeString">
                                <xsl:with-param name="list" select="Property[@Name='DataDisk']"/>
                                <xsl:with-param name="delimiter" select="'#'"/>
                            </xsl:call-template>
                        </xsl:when>
                        <xsl:otherwise/>
                    </xsl:choose>
                </td>
            </tr>
        </xsl:for-each> 
        </table>
    
    </body>
    </html>
    
    </xsl:template>
    
    </xsl:stylesheet>
    
    由于该对象是PowerShell对象,因此不必将其导出为XML,可以将其导出为JSON、CSV等。通过在PowerShell脚本底部添加一点额外代码,您可以直接导入XSL,然后在需要共享单个文件时导出为纯HTML

    # Convert to HTML (if required)
    $XSLT = New-Object System.Xml.Xsl.XslCompiledTransform;
    $XSLT.Load("style.xsl");
    $XSLT.Transform("VMs.xml", "VMs.html");
    

    谢谢Matt-我想知道这是否是唯一的方法,但我希望返回的对象属性中会出现值,而不必手动从字符串的一部分提取它。我认为这将是目前唯一的选择。
    # Convert to HTML (if required)
    $XSLT = New-Object System.Xml.Xsl.XslCompiledTransform;
    $XSLT.Load("style.xsl");
    $XSLT.Transform("VMs.xml", "VMs.html");