[Azure]使用Powershell克隆ARM虚拟机(非托管磁盘)

来源:互联网 发布:base64.js下载 编辑:程序博客网 时间:2024/04/28 12:21

ARM模式下对多磁盘虚拟机捕获映像再批量创建需要对磁盘进行一般化操作,然后使用模板进行创建,整个过程比较复杂,因此为了简化操作,整理了一个用于克隆虚拟机的脚本。

特别针对多网卡虚拟机以及网卡多IP的情况进行了逻辑处理。但是对于诊断等设置没有进行克隆。

注意这个脚本针对非托管磁盘的虚拟机。


脚本如下:

param(    [Parameter(Mandatory = $true)]     [string]$SubscriptionName,      [Parameter(Mandatory = $true)]    [string]$ResourceGroupName,    [Parameter(Mandatory = $true)]    [string]$VMName,    [Parameter(Mandatory = $true)]    [string]$NewVmName,    [Parameter(Mandatory = $true)]    [string]$VmCount)Function GetResourceNameFromResourceId($resourceId){    return $resourceId.Substring($resourceId.LastIndexOf('/') + 1);}Function GetResourcePropertyFromResourceId($resourceId, $propertyName){    $propertyName = $propertyName + "/";    $rgName = $resourceId.Substring($resourceId.IndexOf($propertyName) + $propertyName.Length);    return $rgName.Substring(0, $rgName.IndexOf("/"));}Function GetStorageAccountNameFromVhdUri($vhdUri){    $startLength = "https://".Length;    return $vhdUri.Substring($startLength, $vhdUri.IndexOf(".blob.core.chinacloudapi.cn") - $startLength);}Function CollectVMInformation($rgName, $vmName){    $vmInfo = @{};    $vmInfo.Add("ResourceGroup", $rgName);    $vmInfo.Add("Name", $vmName);        $vm = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName -ErrorAction Ignore -WarningAction Ignore;    if ($vm -eq $null)    {        return $null;    }    $vmInfo.Add("Size", $vm.HardwareProfile.VmSize);    $vmInfo.Add("Location", $vm.Location);    if ($vm.AvailabilitySetReference -ne $null)    {        $vmInfo.Add("AvailabilitySet", $vm.AvailabilitySetReference.Id);    }    $vmInfo.Add("OSType", $vm.StorageProfile.OsDisk.OsType.ToString());    #network properties    $nicId = ($vm.NetworkProfile.NetworkInterfaces | where {$_.Primary -eq $true}).Id;    if ($nicId -eq $null -and $vm.NetworkProfile.NetworkInterfaces.Count -eq 1)    {        $nicId = $vm.NetworkProfile.NetworkInterfaces[0].Id;    }    $vmInfo.Add("PrimaryNetworkInterfaceId", $nicId);    $secondaryNics = @($vm.NetworkProfile.NetworkInterfaces | where {$_.Primary -eq $false});    $vmInfo.Add("SecondaryNetworkInterfaces", $secondaryNics);    #disk    $vmInfo.Add("OSDisk", $vm.StorageProfile.OsDisk);    $vmInfo.Add("DataDisks", @($vm.StorageProfile.DataDisks));    Write-Host ("{0, -16}: {1}" -f "Name", $vmInfo["Name"]) -ForegroundColor Cyan;    Write-Host ("{0, -16}: {1}" -f "Resource Group", $vmInfo["ResourceGroup"]) -ForegroundColor Cyan;    Write-Host ("{0, -16}: {1}" -f "Size", $vmInfo["Size"]) -ForegroundColor Cyan;    Write-Host ("{0, -16}: {1}" -f "Location", $vmInfo["Location"]) -ForegroundColor Cyan;    Write-Host ("{0, -16}: {1}" -f "OS Type", $vmInfo["OSType"]) -ForegroundColor Cyan;    if ($vmInfo.ContainsKey("AvailabilitySet"))    {        Write-Host ("{0, -16}: {1}" -f "Availability Set", $vmInfo["AvailabilitySet"]) -ForegroundColor Cyan;    }    Write-Host ("{0, -16}: {1}" -f "Primary NIC", $vmInfo["PrimaryNetworkInterfaceId"]) -ForegroundColor Cyan;    foreach ($secondaryNic in $vmInfo["SecondaryNetworkInterfaces"])    {        Write-Host ("{0, -16}: {1}" -f "Secondary NIC", $secondaryNic.Id) -ForegroundColor Cyan;    }    Write-Host ("{0, -16}: {1}" -f "OS Disk", $vmInfo["OSDisk"].Vhd.Uri) -ForegroundColor Cyan;    foreach ($dataDisk in $vmInfo["DataDisks"])    {        Write-Host ("{0, -16}: {1}" -f "Data Disk", $dataDisk.Vhd.Uri) -ForegroundColor Cyan;    }    return $vmInfo;}Function CopyBlob($sourceVhdUri, $newBlobName){    $storageAccountName = GetStorageAccountNameFromVhdUri $sourceVhdUri;    $containerName = GetResourcePropertyFromResourceId $sourceVhdUri ".blob.core.chinacloudapi.cn";    $srcBlobName = GetResourceNameFromResourceId $sourceVhdUri;    $storage = $allStorageAccounts | where {$_.StorageAccountName -eq $storageAccountName};    [void](Start-AzureStorageBlobCopy -SrcBlob $srcBlobName -SrcContainer $containerName -SrcContext $storage.Context -DestBlob $newBlobName -DestContainer $containerName -DestContext $storage.Context);    # check copy status    $state = Get-AzureStorageBlobCopyState -Context $storage.Context -Blob $newBlobName -Container $containerName;    while ($state.Status -ne "Success")    {        sleep 1;        $state = Get-AzureStorageBlobCopyState -Context $storage.Context -Blob $newBlobName -Container $containerName;    }    return ("https://{0}.blob.core.chinacloudapi.cn/{1}/{2}" -f $storageAccountName, $containerName, $newBlobName);}Function CopyNic($nicId, $newVmName, $nicIndex){    $nicName = GetResourceNameFromResourceId $nicId;    $rgName = GetResourcePropertyFromResourceId $nicId "resourceGroups";    $nic = Get-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName;    $primaryIPCfg = $nic.IpConfigurations | where {$_.Primary -eq $true};    $subnetId = $primaryIPCfg.Subnet.Id;    $subnetName = GetResourceNameFromResourceId $subnetId;    $vnetName = GetResourcePropertyFromResourceId $subnetId "virtualNetworks";    $newNic = $null;    $newNicName = ("{0}NIC{1}" -f $newVmName, $nicIndex);    if ($primaryIPCfg.PublicIpAddress -eq $null)    {        $newNic = New-AzureRmNetworkInterface -Name $newNicName -ResourceGroupName $nic.ResourceGroupName -Location $nic.Location -SubnetId $subnetId -WarningAction Ignore;    }    else    {        $newPrimaryPipName = ("{0}PIP{1}_0" -f $newVmName, $nicIndex);        $primaryPipId = (CopyPip $primaryIPCfg.PublicIpAddress.Id $newPrimaryPipName);        $newNic = New-AzureRmNetworkInterface -Name $newNicName -ResourceGroupName $nic.ResourceGroupName -Location $nic.Location -SubnetId $subnetId -PublicIpAddressId $primaryPipId -WarningAction Ignore;    }    if ($nic.NetworkSecurityGroup -ne $null)    {        $newNic.NetworkSecurityGroup = $nic.NetworkSecurityGroup;        [void]($newNic | Set-AzureRmNetworkInterface);    }    $secondaryIPCfgs = $nic.IpConfigurations | where {$_.Primary -eq $false};    for ($i = 0; $i -lt $secondaryIPCfgs.Count; $i++)    {        $ipCfgName = ("{0}PIP{1}_{2}" -f $newVmName, $nicIndex, ($i+1));        $ipCfg = $null;        if ($secondaryIPCfgs[$i-1].PublicIpAddress -eq $null)        {            $ipCfg = New-AzureRmNetworkInterfaceIpConfig -Name $secondaryIPCfgs[$i-1].Name -SubnetId $subnetId -WarningAction Ignore;        }        else         {            $newPipId = (CopyPip $secondaryIPCfgs[$i-1].PublicIpAddress.Id $ipCfgName);            $ipCfg = New-AzureRmNetworkInterfaceIpConfig -Name $secondaryIPCfgs[$i-1].Name -SubnetId $subnetId -PublicIpAddressId $newPipId -WarningAction Ignore;        }        [void]($newNic.IpConfigurations.Add($ipCfg));    }    [void]($newNic | Set-AzureRmNetworkInterface);    return $newNic.Id;}Function CopyPip($pipId, $newPipName){    $rgName = GetResourcePropertyFromResourceId $pipId "resourceGroups";    $ipName = GetResourceNameFromResourceId $pipId;    $oldPip = Get-AzureRmPublicIpAddress -Name $ipName -ResourceGroupName $rgName;    $pip = New-AzureRmPublicIpAddress -Name $newPipName -ResourceGroupName $rgName -Location $oldPip.Location -AllocationMethod $oldPip.PublicIpAllocationMethod -WarningAction Ignore;    return $pip.Id;}Function CreateNewVm($vmInfo, $vmName){    #basic information    $rgName = $vmInfo["ResourceGroup"];    $vmSize = $vmInfo["Size"];    $location = $vmInfo["Location"];    $osType = $vmInfo["OSType"];    #network    $primaryNicId = $vmInfo["PrimaryNetworkInterfaceId"];    $secondaryNics = $vmInfo["SecondaryNetworkInterfaces"];        #disk    $osDisk = $vmInfo["OSDisk"];    $dataDisks = $vmInfo["DataDisks"];    $vmconfig = $null;    if ($vmInfo.ContainsKey("AvailabilitySet"))    {        $avaSetId = $vmInfo["AvailabilitySet"];        $vmconfig = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize -AvailabilitySetId $avaSetId;    }    else    {        $vmconfig = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize;    }    $vmconfig = $vmconfig | Set-AzureRmVMBootDiagnostics -Disable;    Write-Host "Cloning disks..." -ForegroundColor Yellow;    $newOsDiskUri = (CopyBlob $osDisk.Vhd.Uri ("{0}_OSDisk.vhd" -f $vmName));    if ($osType -eq "Windows")    {        $vmconfig = $vmconfig | Set-AzureRmVMOSDisk –Name $osDisk.Name -VhdUri $newOsDiskUri -Caching $osDisk.Caching -CreateOption attach -Windows;    } else {        $vmconfig = $vmconfig | Set-AzureRmVMOSDisk –Name $osDisk.Name -VhdUri $newOsDiskUri -Caching $osDisk.Caching -CreateOption attach -Linux;    }    $vmconfig.StorageProfile.ImageReference = $null;    foreach ($dataDisk in $dataDisks)    {        $newDataDiskUri = (CopyBlob $dataDisk.Vhd.Uri ("{0}_DataDisk_{1}.vhd" -f $vmName,$dataDisk.Lun));        $vmconfig = $vmconfig | Add-AzureRmVMDataDisk -Name $dataDisk.Name -VhdUri $newDataDiskUri -Lun $dataDisk.Lun -Caching $dataDisk.Caching -CreateOption attach;    }    Write-Host "Cloning network interfaces..." -ForegroundColor Yellow;    $newPrimaryNicId = (CopyNic $primaryNicId $vmName 0);    $vmconfig = $vmconfig | Add-AzureRmVMNetworkInterface -Id $newPrimaryNicId -Primary;    $secondaryNicCount = $secondaryNics.Count;    for ($i = 0; $i -lt $secondaryNicCount; $i++)    {        $secondaryNicId = $secondaryNics[$i].Id;        $newSecondaryNicId = (CopyNic $secondaryNicId $vmName ($i+1));        $vmconfig = $vmconfig | Add-AzureRmVMNetworkInterface -Id $newSecondaryNicId;    }    Write-Host "Creating new virtual machine..." -ForegroundColor Yellow;    [void](New-AzureRmVM -ResourceGroupName $rgName -Location $location -VM $vmconfig);}[void](Select-AzureRmSubscription -SubscriptionName $SubscriptionName);$allStorageAccounts = Get-AzureRmStorageAccount;Write-Host "Virtual Machine information:" -ForegroundColor Green;$vmInfo = (CollectVMInformation $ResourceGroupName $vmName);if ($vmInfo -eq $null){    Write-Host "Failed to collect vm information." -ForegroundColor Red;    return;}for ($i = 0; $i -lt $VmCount; $i++){    $newName = $NewVmName + ($i+1);    Write-Host ("Cloning virtual machine {0}..." -f $newName) -ForegroundColor Yellow;    CreateNewVm $vmInfo $newName;    Write-Host ("Finished cloning virtual machine {0}." -f $newName) -ForegroundColor Green;}Write-Host "Finished" -ForegroundColor Green;

运行结果:


阅读全文
1 0
原创粉丝点击