[Azure]使用Azure Powershell重新部署ASM虚拟机

60 篇文章 0 订阅
59 篇文章 0 订阅

重新部署虚拟机的主要思路是将原虚拟机以“保留磁盘”的方式删除,然后使用保留下来的磁盘重建虚拟机。

不过实际情况中,问题往往要比以上情况复杂许多,要考虑的因素例如:虚拟机的终结点,ACL,NSG,虚拟网络,子网,所在云服务的公网IP地址(如果未保留且这台虚拟机是该云服务下的唯一一台,则重建后云服务IP会发生变化),虚拟机内网IP地址,数据磁盘,实例级公网IP,可用性集等等。

这个脚本针对以上方面进行了恢复,对于实例级公网IP,由于不能固定,所以重建后该IP地址会发生变化。此外,对于云服务存在多VIP的情况,脚本中仅对默认IP进行了保留,如果添加了其他IP地址且云服务中仅有这一台虚拟机,这种情况下,未保留的其他云服务VIP会发生改变。


脚本如下:

param(
    #Subscription Name
    [Parameter(Mandatory = $true)] 
    [string]$SubscriptionName, 

    # Cloud Service Name
    [Parameter(Mandatory = $true)]
    [string]$ServiceName,
 
    # Virtual Machine Name
    [Parameter(Mandatory = $true)]
    [string]$VmName
)

Function RebuildVirtualMachine()
{
    # collect basic virtual machine information
    Write-Host "Collecting virtual machine basic information...";
    $vm = Get-AzureVM -ServiceName $ServiceName -Name $VmName;
    $service = Get-AzureService -ServiceName DanEastCS;
    $deployment = Get-AzureDeployment -ServiceName $ServiceName;
    $vmSize = $vm.InstanceSize;
    $vnetName = $vm.VirtualNetworkName;
    $subnetName = $vm.VM.ConfigurationSets[0].SubnetNames[0];
    $location = $service.Location;
    $osType = $vm.VM.OSVirtualHardDisk.OS;
    $availabilitySetName = $vm.AvailabilitySetName;    # if not exist, $availabilitySetName -eq $null
    Write-Host "VM Size:" $vmSize;
    Write-Host "VNET:" $vnetName;
    Write-Host "Subnet:" $subnetName;
    Write-Host "Location:" $location;
    Write-Host "OS Type:" $vm.VM.OSVirtualHardDisk.OS;
    Write-Host "Availability Set:" $availabilitySetName;
    
    # collect Disk information
    Write-Host "Collecting disk information...";
    $osDisk = $vm.VM.OSVirtualHardDisk;    # use $osDisk.MediaLink.AbsoluteUri to get vhd url
    Write-Host "OS Disk:" $osDisk.MediaLink.AbsoluteUri;
    $dataDisks = $dataDisks = $vm.VM.DataVirtualHardDisks;
    foreach ($dataDisk in $dataDisks)
    {
        Write-Host "Data Disk:" $dataDisk.MediaLink.AbsoluteUri;
    }

    # collect endpoint information and ACL
    Write-Host "Collecting endpoint configuration...";
    $endpoints = $vm | Get-AzureEndpoint;    # use $endpoints[index].Acl.Rules to get acl rules
    Write-Host $endpoints.Count "endpoint(s) collected";

    # collect network security group to virtual machine
    Write-Host "Collecting network security group information...";
    $networkSecurityGroupName = $vm.VM.ConfigurationSets[0].NetworkSecurityGroup;    # if not exist, $networkSecurityGroupName -eq $null
    if ($networkSecurityGroupName -ne $null)
    {
        Write-Host "Network security group:" $networkSecurityGroupName;
    }

    # reservedIP (Cloud Service VIP)
    $reservedIPName = $deployment.ReservedIPName;
    if ($reservedIPName -eq $null)
    {
        Write-Host "CloudService VIP is not reserved, begin reserving...";
        $reservedIPName = $ServiceName + "ReserveIP";
        [void](New-AzureReservedIP -ReservedIPName $reservedIPName -ServiceName $ServiceName -Location $location);
        Write-Host "CloudService VIP reserved, reservedIP name:" $reservedIPName;
    }

    # collect instance-level public ip address
    Write-Host "Checking instance-level public ip configuration...";
    $pipName = $null;
    if ($vm.VM.ConfigurationSets[0].PublicIPs.Count -gt 0)
    {
        $pipName = $vm.VM.ConfigurationSets[0].PublicIPs[0].Name;
        Write-Host "Instance-level public ip:" $pipName;
    } else {
        Write-Host "No instance-level public ip configured";
    }

    # collectstatic vnet ip
    Write-Host "Collecting vnet ip configuration...";
    $dip = $vm.IpAddress;    # if not exist, $dip -eq $null
    if ($dip -ne $null)
    {
        Write-Host "Vnet ip:" $dip;
    }
    
    Write-Host "Rebuilding virtual machine...";
    [void](Remove-AzureVM -ServiceName $ServiceName -Name $VmName);
    Write-Host "Old virtual machine removed";

    # wait some time for disks to be detached
    sleep(120);

    Write-Host "Configuring new virtual machine";
    # build virtual machine configurations
    $vmConfig = New-AzureVMConfig -Name $VmName -InstanceSize $vmSize -DiskName $osDisk.DiskName;
    $vmConfig = $vmConfig | Set-AzureSubnet -SubnetNames $subnetName;
    
    # attach data disks
    foreach ($dataDisk in $dataDisks)
    {
        $vmConfig = $vmConfig | Add-AzureDataDisk -Import -DiskName $dataDisk.DiskName -LUN $dataDisk.Lun -HostCaching $dataDisk.HostCaching;
    }

    # configure endpoints and ACLs
    foreach ($endpoint in $endpoints)
    {
        if ($endpoint.LBSetName -ne $null)
        {
            if ($endpoint.ProbePath -ne $null)
            {
                $vmConfig = $vmConfig | Add-AzureEndpoint -Name $endpoint.Name -Protocol $endpoint.Protocol `
                                                          -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port `
                                                          -LBSetName $endpoint.LBSetName -ProbePort $endpoint.ProbePort `
                                                          -ProbeProtocol $endpoint.ProbeProtocol -ProbePath $endpoint.ProbePath `
                                                          -ProbeIntervalInSeconds $endpoint.ProbeIntervalInSeconds `
                                                          -ProbeTimeoutInSeconds $endpoint.ProbeTimeoutInSeconds;
            } else {
                $vmConfig = $vmConfig | Add-AzureEndpoint -Name $endpoint.Name -Protocol $endpoint.Protocol `
                                                          -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port `
                                                          -LBSetName $endpoint.LBSetName -ProbePort $endpoint.ProbePort `
                                                          -ProbeProtocol $endpoint.ProbeProtocol `
                                                          -ProbeIntervalInSeconds $endpoint.ProbeIntervalInSeconds `
                                                          -ProbeTimeoutInSeconds $endpoint.ProbeTimeoutInSeconds;
            }
        } else {
            $vmConfig = $vmConfig | Add-AzureEndpoint -Name $endpoint.Name -Protocol $endpoint.Protocol `
                                                      -LocalPort $endpoint.LocalPort -PublicPort $endpoint.Port;
        }
        if ($endpoint.InternalLoadBalancerName -ne $null)
        {
            $vmConfig = $vmConfig | Set-AzureEndpoint -Name $endpoint.Name -InternalLoadBalancerName $endpoint.InternalLoadBalancerName;
        }
        $vmConfig = $vmConfig | Set-AzureEndpoint -Name $endpoint.Name -DirectServerReturn $endpoint.EnableDirectServerReturn -ACL $endpoint.Acl;
        if ($endpoint.IdleTimeoutInMinutes -ne $null)
        {
            $vmConfig = $vmConfig | Set-AzureEndpoint -Name $endpoint.Name -IdleTimeoutInMinutes $endpoint.IdleTimeoutInMinutes;
        }
        if ($endpoint.LoadBalancerDistribution -ne $null)
        {
            $vmConfig = $vmConfig | Set-AzureEndpoint -Name $endpoint.Name -LoadBalancerDistribution $endpoint.LoadBalancerDistribution;
        }
        if ($endpoint.VirtualIPName -ne $null)
        {
            $vmConfig = $vmConfig | Set-AzureEndpoint -Name $endpoint.Name -VirtualIPName $endpoint.VirtualIPName;
        }
    }

    # configure instance-level public ip
    if ($pipName -ne $null)
    {
        $vmConfig = $vmConfig | Set-AzurePublicIP -PublicIPName $pipName;
    }

    # configure vnet ip
    if ($dip -ne $null)
    {
        $vmConfig = $vmConfig | Set-AzureStaticVNetIP -IPAddress $dip;
    }

    # configure availability set
    if ($availabilitySetName -ne $null)
    {
        $vmConfig = $vmConfig | Set-AzureAvailabilitySet -AvailabilitySetName $availabilitySetName;
    }

    Write-Host "Finished configurations, creating virtual machine...";
    [void]($vmConfig | New-AzureVM -ServiceName $ServiceName -VNetName $vnetName -Location $location -WaitForBoot -WarningAction Ignore);
    Write-Host "Virtual machine created";

    # if reservedIP is released, re-associate it to cloudservice
    $deployment = Get-AzureDeployment -ServiceName $ServiceName;
    $ripName = $deployment.ReservedIPName;
    if ($ripName -eq $null)
    {
        Write-Host "Recovering cloudservice reserved ip...";
        [void](Set-AzureReservedIPAssociation -ReservedIPName $reservedIPName -ServiceName $ServiceName);
        Write-Host "CloudService reserved ip recovered";
    }

    # configure network security group
    if ($networkSecurityGroupName -ne $null)
    {
        $vm = Get-AzureVM -ServiceName $ServiceName -Name $VmName;
        $vm | Set-AzureNetworkSecurityGroupAssociation -Name $networkSecurityGroupName -Force;
    }

    Write-Host "Finished rebuilding virtual machine";
}

Function BreakLease($diskUrl, $context)
{
    $storageAccountName = GetPropertyFromUrl $diskUrl "https://" ".";
    $containerName = GetPropertyFromUrl $diskUrl ".blob.core.chinacloudapi.cn/" "/";
    $blobName = $diskUrl.Substring($diskUrl.LastIndexOf("/") + 1);

    $blob = Get-AzureStorageBlob -Context $context -Container $containerName -Blob $blobName -ErrorAction Ignore;
    if ($blob.ICloudBlob.Properties.LeaseStatus -eq "Locked")
    {
        $blob.ICloudBlob.BreakLease();
    }
}

Function ShowWarning() {
    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes","Description.";
    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No","Description.";
    $cancel = New-Object System.Management.Automation.Host.ChoiceDescription "&Cancel","Description.";
    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no, $cancel);

    $title = "!!! Before rebuilding this virtual machine !!!";
    $message = "WARNING: Data on temporary disk (Usually 'D:\' or '/dev/sdb') will be `
                lost, Instance-Level Public IP Address could not be reserved (Will be `
                changed), are you sure to continue?";
    $result = $host.ui.PromptForChoice($title, $message, $options, 1);    # 0 - YES / 1 - NO / 2 - Cancel
    
    return $result;
}

$choice = ShowWarning;
if ($choice -eq 0)
{
    $cred = Get-Credential;
    [void](Add-AzureAccount -Environment AzureChinaCloud -Credential $cred);
    
    [void](Select-AzureSubscription -SubscriptionName $SubscriptionName);
    RebuildVirtualMachine;
}

执行过程:

PS C:\Users\DanielHX> &.\[ASM]rebuild_virtualmachine.ps1 -SubscriptionName XXXXXXXX -ServiceName DanEastCS -VmName DanCentOS65

!!! Before rebuilding this virtual machine !!!
WARNING: Data on temporary disk (Usually 'D:\' or '/dev/sdb') will be lost, Instance-Level Public IP Address could
 not be reserved (Will be changed), are you sure to continue?
[Y] Yes  [N] No  [C] Cancel  [?] Help (default is "N"): y

cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
Collecting virtual machine basic information...
VM Size: Large
VNET: DanEastVNET
Subnet: Subnet-1
Location: China East
OS Type: Linux
Availability Set:
Collecting disk information...
OS Disk: https://danieleaststorage.blob.core.chinacloudapi.cn/vhds/DanEastCS-DanCentOS65-2016-05-17.vhd
Data Disk: https://danieleaststorage.blob.core.chinacloudapi.cn/vhds/DanServerTest-DanCentOS65-0616-DataDisk1.vhd
Data Disk: https://danieleaststorage.blob.core.chinacloudapi.cn/vhds/DanServerTest-DanCentOS65-0616-DataDisk2.vhd
Data Disk: https://danieleaststorage.blob.core.chinacloudapi.cn/vhds/DanServerTest-DanCentOS65-0616-DataDisk3.vhd
Data Disk: https://danieleaststorage.blob.core.chinacloudapi.cn/vhds/DanServerTest-DanCentOS65-0616-DataDisk4.vhd
Collecting endpoint configuration...
4 endpoint(s) collected
Collecting network security group information...
Checking instance-level public ip configuration...
No instance-level public ip configured
Collecting vnet ip configuration...
Vnet ip: 10.0.0.4
Rebuilding virtual machine...
Old virtual machine removed
Configuring new virtual machine
Finished configurations, creating virtual machine...
Virtual machine created
Finished rebuilding virtual machine


  • 28
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值