Kürzlich hatte ich die Anforderung, zwischen zwei verschiedenen Azureinstallationen VHD Dateien kopieren zu müssen. Dabei hatte ich im ersten Mandanten (Quelle) die VHDs erstellt und in virtuellen Maschinen genutzt. In einer zweiten Installation (Ziel) von Azure wurde diese dann produktiv verwendet. Das Kopieren der VHDs kann ich natürlich realisieren, indem ich die Quell-VHD auf meinen Rechner herunterlade und dann wieder auf das Zielsystem hoch lade. Besser wäre allerdings die Möglichkeit, die VHDs direkt in Azure zu kopieren. Genau dies soll das unten stehende Skript bewirken. Das Skript können Sie auch von http://www.nicothiemer.de/Download/CopyVHDsInAzure.zip herunterladen.
Bei der Ausführung des Skripts gilt die Voraussetzung, dass das Zielsystem in Azure noch nicht konfiguriert ist. Der Azuremandat steht unmittelbar nach dem anlegen zur Verfügung. Da ich mehrere Mandanten habe, muss ich in der PowerShell zwischen diesen wechseln. Wie dies geht, beschreibt dieser Blogbeitrag https://nicothiemer.wordpress.com/2015/08/24/arbeiten-mit-mehreren-mandaten-in-der-azure-powershell. Gestartet werden sollte das Skript aus dem Mandanten des Zielsystems! Dieser muss auch als Default subscription eingetragen sein.Damit das Skript erfolgreich laufen kann, muss ich daher in der PowerShell mit dem Zielmandanten verbunden sein.
Was genau das Skript wie macht, ist in den Kommentaren beschrieben. Natürlich müssen die Dummys für die Variablen mit den echten Werten ersetzt werden. Einfach gesagt kopiert es eine VHD Datei und erstellt anschließend eine VM, welche die VHD nutzt. Es soll auch bewusst als Inspiration dienen. Ich habe darum auf Abfragen, ob schon Objekte bestehen, verzichtet. Damit sollte der eigentliche Code besser lesbar sein.
Anpassungen
Sie müssen sämtliche Variablen mit Ihnen eigenen Werten versehen. Einige Werte benötigen dazu besondere Aufmerksamkeit.
In der Zeile 55 muss noch eine Anpassung vorgenommen werden. In dieser wird mit Set-AzureVNetConfig das neu erstellte Netzwerk konfiguriert. Die XML Datei dazu steht in der Zeile 14 in der Variable $netconfigpath. Neben diesem Pfad müssen Sie außerdem noch die Datei als solche anpassen. Sie finden diese Datei in der .zip Datei zum Download oder am Ende des Artikels.
Was ich noch brauche, ist die URL der VHD, welche kopiert werden soll. Diese kann ich u.a. erhalten, wenn ich mir in der UI von Azure die Eigenschaften der VHD anzeigen lasse. Gehen Sie dazu im Quellsystem im (alten) Azureportal auf ihre virtuellen Rechner und klicken Sie dort auf den Reiter Datenträger. Ganz am rechten Rand haben Sie die Spalte Speicherort. Wenn Sie über diese Einträge mit der Maus fahren, erscheint ein Symbol zum Kopieren. Klicken Sie auf dieses und Sie haben den Speicherort der VHD. Die Variable für den Wert ist $diskSource und steht in Zeile 20.
Natürlich muss die virtuelle Maschine, welche die VHD die Sie kopieren möchten verwendet, heruntergefahren sein. Ich möchte auch nicht verschweigen, dass ich mich bei der Erstellung dieses Skripts großzügig vom Installationsskript für den Kurs MOC 20-346C Managing Office 365 Identities and Services inspiriert haben lassen.
Skript CopyVHDsInAzure.ps1
#Azure variables: $affinitygroup = "Your affinitygroup" #locations: https://azure.microsoft.com/en-us/regions/#services $location = "West Europe" #Storage #only use lowercase letters and numbers! $storage = "your storagename" #network variables $dnsname = "Your dns" $netconfigpath ="C:\Azure\NetworkConfigFinal.xml" $vnet=" Your virtualnetwork" $subnet = "Your subnet" #copy VHDs $diskSource = "source of your your vhd, eg. https://xxx.blob.core.windows.net/vhds/xxx.vhd " $diskname = "Name of the new vhd in the destination, eg. xxx-new.vhd" $AzureDiskname = "Name of the new vhs without vhd., eg. xxx-new" $srcStorageContainer = "Source storagecontainer, eg. vhds" $destStorageContainer = "Destination storagecontainer, eg. vhds" #create VM $servername="name of the new virtuel machine" $cloudservice ="name of the cloudservice" Write-Host " " Write-Host "Step 1. Create Azure affinity group" -ForegroundColor Magenta Write-Host " " #create affinitygroup New-AzureAffinityGroup -Name $affinitygroup -Location $location # Wait while affinity group is created Write-Host " " Write-Host "Step 2. Create Azure storage service" -ForegroundColor Magenta Write-Host " " #create storage New-AzureStorageAccount -StorageAccountName $storage -AffinityGroup $affinitygroup #get the current subscription $subscriptionObj = get-AzureSubscription -Default $subscriptionId = $subscriptionObj.SubscriptionId set-azuresubscription -SubscriptionId $subscriptionId -CurrentStorageAccountName $storage select-azuresubscription -SubscriptionId $subscriptionId Write-Host " " Write-Host "Step 3. Create Virtual Network" -ForegroundColor Magenta Write-Host " " #create network $dns = New-AzureDns -IPAddress 10.0.0.4 -Name $dnsname Set-AzureVNetConfig -ConfigurationPath $netconfigpath Write-Host " " Write-Host "Step 4. Copy VHD Blob" -ForegroundColor Magenta Write-Host " " #copy VHDs - create Storage Container $destStorageAccountKeyObj = get-azurestoragekey $storage $destStorageAccountKey = $destStorageAccountKeyObj.Primary $dest = New-AzureStorageContext $storage $destStorageAccountKey New-AzureStorageContainer $destStorageContainer -Permission Container -context $dest #copy VHDs Start-AzureStorageBlobCopy -AbsoluteUri $diskSource -DestBlob $diskname -DestContext $dest -DestContainer $destStorageContainer $stateCopy = Get-AzureStorageBlob -Context $dest -Container $destStorageContainer | where {$_.Name -like $diskname} $stateCopy | Get-AzureStorageBlobCopyState do { Write-Verbose "Checking storage blob copy status every $delaySeconds seconds." Write-Verbose "This will repeat until all copy operations are complete." $continue = $false Get-AzureStorageBlobCopyState -Blob $diskname -Container $destStorageContainer | Format-Table -AutoSize -Property Status,@{label="Percent";expression={"{0:P2}" -f $($_.BytesCopied/$_.TotalBytes)}}, @{label="VHD";expression={$($_.Source).tostring().substring(44,13)}} $blobStatusPending = Get-AzureStorageBlobCopyState -Blob $diskname -Container $destStorageContainer # Continue checking status as long as at least one operations is still pending. if (!$continue) { $continue = $blobStatusPending.Status -eq "Pending" } if ($continue) { Start-Sleep $delaySeconds } } while ($continue) Write-Host " " Write-Host "Step 5. Define Virtual Disks" -ForegroundColor Magenta Write-Host " " $blobsToDisks = Get-AzureStorageBlob -Context $dest -Container $destStorageContainer | where {$_.Name -like $diskname} Add-AzureDisk -DiskName $AzureDiskName -MediaLocation $blobsToDisks.ICloudBlob.Uri -OS Windows Write-Host " " Write-Host "Step 6 Creating VM" -ForegroundColor Magenta Write-Host " " $vmName = $servername $newVM = New-AzureVMConfig -Name $vmName -DiskName $vmName -InstanceSize 'Small' ` | Add-AzureProvisioningConfig -Windows ` | Set-AzureSubnet -SubnetNames $subnet New-AzureVM -ServiceName $cloudservice -AffinityGroup $affinitygroup -VMs $newVM -VNetName $vnet -DnsSettings $dns -WaitForBoot Write-Host "Finish!"
Datei NetworkConfigFinal.xml
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration"> <VirtualNetworkConfiguration> <Dns> <DnsServers> <DnsServer name="Your DNS name" IPAddress="10.0.0.4" /> </DnsServers> </Dns> <VirtualNetworkSites> <VirtualNetworkSite name="Your virtualnetwork" AffinityGroup="Your affinitygroup"> <AddressSpace> <AddressPrefix>10.0.0.0/8</AddressPrefix> </AddressSpace> <Subnets> <Subnet name="Your subnet"> <AddressPrefix>10.0.0.0/11</AddressPrefix> </Subnet> </Subnets> <DnsServersRef> <DnsServerRef name="Your DNS name" /> </DnsServersRef> </VirtualNetworkSite> </VirtualNetworkSites> </VirtualNetworkConfiguration> </NetworkConfiguration>
Vielen Dank für Ihr Interesse an meinem Blogeintrag.
Gerne beantworte ich Ihnen persönlich weitergehende Fragen zu diesem Thema.
Kontaktieren Sie mich einfach über mein Kontaktformular.
Sie wollen mehr über mich erfahren? Dann gehen Sie auf meine Site
http://www.nicothiemer.de
Nico Thiemer