How to migrate from Standard Azure Virtual Machines to DS Series Storage Optimized VM’s

Background

We are implementing Azure solutions for a few clients. Most of our clients are use cloud services and virtual machines to implement their solutions on Azure platform. For many years Azure platform  only offered just one performance tier for storage. You can see the sizes of virtual machines and cloud services and the disk performance they offer here:

https://msdn.microsoft.com/en-us/library/azure/dn197896.aspx

For standard Azure virtual machines each disk is limited to 500 IOPS per disk. If you needed better performance you had to use disk striping with multiple disk to get better performance. Number of disks one could add to Azure Virtual Machine is constrained by the size of VM. One core allows us to add 2 VHD’s. Each VHD is a page blob with a maximum size of 1 TB. When we were deploying packaged software or custom applications with high IOPS requirements it was challenging to meet the needs of our customers. All this changed with the following announcement by Mark Russinovich where he announced General Availability of Azure Premium Storage.

http://azure.microsoft.com/blog/2015/04/16/azure-premium-storage-now-generally-available-2/

Azure premium storage offers durable SSD storage. Along with premium storage Microsoft also released storage optimized virtual machines called DS Series VM’s. These are capable of achieving up to 64000 IOPS and 524 MB/sec. This will enable many scenarios like NoSQL or even large SQL database that need higher IOPS than the standard Azure virtual machines offer. You can read about the specifications for DS Series VM’s in the link posted above. If you were using a standard Azure VM you can easily scale up or down to another standard virtual machine using Portal, PowerShell and Azure CLI. Unfortunately it is currently not possible to upgrade/migrate a standard Azure virtual machine to a DS Series virtual machine with premium storage. In this blog post I will show you how you can migrate an existing virtual machine to a DS’s series virtual machine with Premium(durable SSD) storage. It will provide a PowerShell script you can leverage to migrate a standard virtual machine to a DS Series virtual machine.

Details

Creating Premium Storage Account

Premium storage account is different than standard storage accounts. If you want to leverage premium storage you need to create a new storage account in the azure preview portal. Account type you need to select is “Premium Locally Redundant”

It is not possible to use the existing Azure management portal to provision premium storage account.

New Storage Account

Here is how you can use PowerShell cmdlet to create premium storage account. As you can see it is similar to how you create standard storage accounts. I was unable to find what value I had to specify for Type and I had to read the actual source code to determine that it was ‘Premium_LRS’

001
002
003
004
005
006
007
008
$StorageAccountTypePremium = ‘Premium_LRS’

$DestStorageAccount = New-AzureStorageAccount -StorageAccountName $DestStorageAccountName -Location $Location -Type $StorageAccountTypePremium -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null

if (!($?)) 
{ 
    throw “Cannot create the Storage Account [$DestStorageAccountName] on $Location. Error Detail: $errorVariable” 
}

 

Premium storage and DS Series virtual machines are not available in all regions. The complete script I will provide validates your location preference and fails if you specify a location where premium storage and DS Series VM’s are not available.

Creating DS Series Virtual machine is identical to creating standard virtual machines.

Here are a few things I learned about DS Series Virtual machines and Premium storage.

  • Premium storage does not allow us to add  disks smaller than 10 GB. If your VM has a disk smaller than 10 GB the script will fail
  • Default Host Caching option for Premium storage data disks is “Ready Only” as compared with “None” for standard data disks.
  • Default Host Caching option for Premium storage OS disk is “Read Write” which is same as standard OS disks
  • Currently this script only migrates virtual machines to the same subscription. It can be easily extended to support migration to different subscriptions. 
  • It can migrate VM’s to a different region as long as premium storage is available in that region
  • It shuts down the existing source VM before making of copy of the VHD’s for the virtual machine.
  • It validates that virtual network for the destination VM exists but does not validate if subnet also exists
  • It gives new names to the disks in the destination virtual machine
  • Currently I am only copying disks, end points, VM extensions. I am not copying ACL’s and other type of extensions like malware extension
  • I only tested the script with PowerShell SDK Version 0.9.2
  • I tested migrating standard VM in West US to DS Series VM in West US only. I logged into the newly created VM and verified that all disks were present. This is the extent of my testing. My VM with 3 Disk’s copied in 10 minutes.
  • If your destination storage account already exists it has to be of type “Premium_LRS”. If you have an existing account of different type the script will fail. If the storage account does not exist it will be created.

Sample Script

You can access the entire source code from my public GitHub repository

https://github.com/rajinders/migrate-to-azuredsvm

I have also pasted the entire source code here for your convenience.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
<#
Copyright 2015 Rajinder Singh
 
Licensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 
    http://www.apache.org/licenses/LICENSE-2.0
 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
#>

<#
.SYNOPSIS
Migrates an existing VM into a DS Series VM which uses Premium storage.
 
.DESCRIPTION
This script migrates an exitsing VM into a DS Series VM which uses Premium Storage. At this time DS Series VM’s are not available in all regions.
It currently expects the VM to be migrated in the same subscription. It supports migrating VM to the same region or a different region.
It can be easily extended to support migrating to a different subscription as well
 
.PARAMETER SourceVMName
The name of the VM that needs to be migrated
 
.PARAMTER SourceServiceName
The name of service for the old VM
 
.PARAMETER DestVMName
The name of New DS Series VM that will be created.
 
.PARAMTER DestServiceName
The name of the Service for the new VM
 
.PARAMTER Location
Region where new VM will be created
 
.PARAMTER Size
Size of the new VM
 
.PARAMTER DestStorageAccountName
Name of the storage account where the VM will be created. It has to be premium storage account
 
.PARAMETER ResourceGroupName
Resource group where the cache will be create
 
.EXAMPLE
 
# Migrate a standalone virtual machine to a DS Series virtual machine with Premium storage. Both the VM’s are in the same subscription
.\MigrateVMToPremiumStorage.ps1 -SourceVMName “rajsourcevm2” -SourceServiceName “rajsourcevm2” -DestVMName “rajdsvm12” -DestServiceName “rajdsvm12svc” -Location “West US” -VMSize Standard_DS2 -DestStorageAccountName ‘rajwestpremstg18’ -DestStorageAccountContainer ‘vhds’
 
 
# Migrate a standalone virtual machine to a DS Series virtual machine with Premium storage. Both the VM’s are in the same subscription
.\MigrateVMToPremiumStorage.ps1 -SourceVMName “rajsourcevm2” -SourceServiceName “rajsourcevm2” -DestVMName “rajdsvm16” -DestServiceName “rajdsvm16svc” -Location “West US” -VMSize Standard_DS2 -DestStorageAccountName ‘rajwestpremstg19’ -DestStorageAccountContainer ‘vhds’ -VNetName rajvnettest3 -SubnetName FrontEndSubnet
 
#>

[CmdletBinding(DefaultParameterSetName=“Default”)]
Param
(
    [Parameter (Mandatory = $true)]
    [string] $SourceVMName,

    [Parameter (Mandatory = $true)]
    [string] $SourceServiceName,

    [Parameter (Mandatory = $true)]
    [string] $DestVMName,

    [Parameter (Mandatory = $true)]
    [string] $DestServiceName,

    [Parameter (Mandatory = $true)]
    [ValidateSet(‘West US’,‘East US 2’,‘West Europe’,‘East China’,‘Southeast Asia’,‘West Japan’, ignorecase=$true)]
    [string] $Location,

    [Parameter (Mandatory = $true)]
    [ValidateSet(‘Standard_DS1’,‘Standard_DS2’,‘Standard_DS3’,‘Standard_DS4’,‘Standard_DS11’,‘Standard_DS12’,‘Standard_DS13’,‘Standard_DS14’, ignorecase=$true)]
    [string] $VMSize,

    [Parameter (Mandatory = $true)]
    [string] $DestStorageAccountName,

    [Parameter (Mandatory = $true)]
    [string] $DestStorageAccountContainer,

    [Parameter (Mandatory = $false)]
    [string] $VNetName,

    [Parameter (Mandatory = $false)]
    [string] $SubnetName
)

#publish version of the the powershell cmdlets we are using
(Get-Module Azure).Version

#$VerbosePreference = “Continue”
$StorageAccountTypePremium = ‘Premium_LRS’

#############################################################################################################
#validation section
#Perform as much upfront validation as possible
#############################################################################################################

#validate upfront that this service we are trying to create already exists
if((Get-AzureService -ServiceName $DestServiceName -ErrorAction SilentlyContinue) -ne $null)
{
    Write-Error “Service [$DestServiceName] already exists”
    return
}

#Determine we are migrating the VM to a Virtual network. If it is then verify that VNET exists
if( !$VNetName -and !$SubnetName )
{
    $DeployToVNet = $false
}
else
{
    $DeployToVNet = $true
    $vnetSite = Get-AzureVNetSite -VNetName $VNetName -ErrorAction SilentlyContinue

    if (!$vnetSite)
    {
        Write-Error “Virtual Network [$VNetName] does not exist”
        return
    }
}

Write-Host “DepoyToVNet is set to [$DeployToVnet]”

#TODO: add validation to make sure the destination VM size can accomodate the number of disk in the source VM

$DestStorageAccount = Get-AzureStorageAccount -StorageAccountName $DestStorageAccountName -ErrorAction SilentlyContinue

#check to see if the storage account exists and create a premium storage account if it does not exist
if(!$DestStorageAccount)
{
    # Create a new storage account
    Write-Output “”;
    Write-Output (“Configuring Destination Storage Account {0} in location {1}” -f $DestStorageAccountName, $Location);

    $DestStorageAccount = New-AzureStorageAccount -StorageAccountName $DestStorageAccountName -Location $Location -Type $StorageAccountTypePremium -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null

    if (!($?)) 
    { 
        throw “Cannot create the Storage Account [$DestStorageAccountName] on $Location. Error Detail: $errorVariable” 
    } 
   
    Write-Verbose “Created Destination Storage Account [$DestStorageAccountName] with AccountType of [$($DestStorageAccount.AccountType)]”    
}
else
{
    Write-Host “Destination Storage account [$DestStorageAccountName] already exists. Storage account type is [$($DestStorageAccount.AccountType)]”

    #make sure if the account already exists it is of type premium storage
    if( $DestStorageAccount.AccountType -ne $StorageAccountTypePremium )
    {
        Write-Error “Storage account [$DestStorageAccountName] account type of [$($DestStorageAccount.AccountType)] is invalid”
        return
    }
}

Write-Host “Source VM Name is [$SourceVMName] and Service Name is [$SourceServiceName]”

#Get VM Details
$SourceVM = Get-AzureVM -Name $SourceVMName -ServiceName $SourceServiceName -ErrorAction SilentlyContinue

if($SourceVM -eq $null)
{
    Write-Error “Unable to find Virtual Machine [$SourceServiceName] in Service Name [$SourceServiceName]”
    return
}

Write-Host “vm name is [$($SourceVM.Name)] and vm status is [$($SourceVM.Status)]”

#need to shutdown the existing VM before copying its disks.
if($SourceVM.Status -eq “ReadyRole”)
{
    Write-Host “Shutting down virtual machine [$SourceVMName]”
    #Shutdown the VM
    Stop-AzureVM -ServiceName $SourceServiceName -Name $SourceVMName -Force
}

$osdisk = $SourceVM | Get-AzureOSDisk

Write-Host “OS Disk name is $($osdisk.DiskName) and disk location is $($osdisk.MediaLink)”

$disk_configs = @{}

# Used to track disk copy status
$diskCopyStates = @()

##################################################################################################################
# Kicks off the async copy of VHDs
##################################################################################################################

# Copies to remote storage account
# Returns blob copy state to poll against
function StartCopyVHD($sourceDiskUri, $diskName, $OS, $destStorageAccountName, $destContainer)
{
    Write-Host “Destination Storage Account is [$destStorageAccountName], Destination Container is [$destContainer]”

    #extract the name of the source storage account from the URI of the VHD
    $sourceStorageAccountName = $sourceDiskUri.Host.Replace(“.blob.core.windows.net”, “”)
   

    $vhdName = $sourceDiskUri.Segments[$sourceDiskUri.Segments.Length  1].Replace(“%20”,” “) 
    $sourceContainer = $sourceDiskUri.Segments[$sourceDiskUri.Segments.Length  2].Replace(“/”, “”)

    $sourceStorageAccountKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageAccountName).Primary
    $sourceContext = New-AzureStorageContext -StorageAccountName $sourceStorageAccountName -StorageAccountKey $sourceStorageAccountKey

    $destStorageAccountKey = (Get-AzureStorageKey -StorageAccountName $destStorageAccountName).Primary
    $destContext = New-AzureStorageContext -StorageAccountName $destStorageAccountName -StorageAccountKey $destStorageAccountKey
    if((Get-AzureStorageContainer -Name $destContainer -Context $destContext -ErrorAction SilentlyContinue) -eq $null)
    {
        New-AzureStorageContainer -Name $destContainer -Context $destContext | Out-Null

        while((Get-AzureStorageContainer -Name $destContainer -Context $destContext -ErrorAction SilentlyContinue) -eq $null)
        {
            Write-Host “Pausing to ensure container $destContainer is created..” -ForegroundColor Green
            Start-Sleep 15
        }
    }

    # Save for later disk registration
    $destinationUri = “https://$destStorageAccountName.blob.core.windows.net/$destContainer/$vhdName”
   
    if($OS -eq $null)
    {
        $disk_configs.Add($diskName, “$destinationUri”)
    }
    else
    {
       $disk_configs.Add($diskName, “$destinationUri;$OS”)
    }

    #start async copy of the VHD. It will overwrite any existing VHD
    $copyState = Start-AzureStorageBlobCopy -SrcBlob $vhdName -SrcContainer $sourceContainer -SrcContext $sourceContext -DestContainer $destContainer -DestBlob $vhdName -DestContext $destContext -Force

    return $copyState
}

##################################################################################################################
# Tracks status of each blob copy and waits until all the blobs have been copied
##################################################################################################################

function TrackBlobCopyStatus()
{
    param($diskCopyStates)
    do
    {
        $copyComplete = $true
        Write-Host “Checking Disk Copy Status for VM Copy” -ForegroundColor Green
        foreach($diskCopy in $diskCopyStates)
        {
            $state = $diskCopy | Get-AzureStorageBlobCopyState | Format-Table -AutoSize -Property Status,BytesCopied,TotalBytes,Source
            if($state -ne “Success”)
            {
                $copyComplete = $true
                Write-Host “Current Status” -ForegroundColor Green
                $hideHeader = $false
                $inprogress = 0
                $complete = 0
                foreach($diskCopyTmp in $diskCopyStates)
                { 
                    $stateTmp = $diskCopyTmp | Get-AzureStorageBlobCopyState
                    $source = $stateTmp.Source
                    if($stateTmp.Status -eq “Success”)
                    {
                        Write-Host (($stateTmp | Format-Table -HideTableHeaders:$hideHeader -AutoSize -Property Status,BytesCopied,TotalBytes,Source | Out-String)) -ForegroundColor Green
                        $complete++
                    }
                    elseif(($stateTmp.Status -like “*failed*”) -or ($stateTmp.Status -like “*aborted*”))
                    {
                        Write-Error ($stateTmp | Format-Table -HideTableHeaders:$hideHeader -AutoSize -Property Status,BytesCopied,TotalBytes,Source | Out-String)
                        return $false
                    }
                    else
                    {
                        Write-Host (($stateTmp | Format-Table -HideTableHeaders:$hideHeader -AutoSize -Property Status,BytesCopied,TotalBytes,Source | Out-String)) -ForegroundColor DarkYellow
                        $copyComplete = $false
                        $inprogress++
                    }
                    $hideHeader = $true
                }
                if($copyComplete -eq $false)
                {
                    Write-Host “$complete Blob Copies are completed with $inprogress that are still in progress.” -ForegroundColor Magenta
                    Write-Host “Pausing 60 seconds before next status check.” -ForegroundColor Green 
                    Start-Sleep 60
                }
                else
                {
                    Write-Host “Disk Copy Complete” -ForegroundColor Green
                    break 
                }
            }
        }
    } while($copyComplete -ne $true) 
    Write-Host “Successfully Copied up all Disks” -ForegroundColor Green
}

# Mark the start time of the script execution
$startTime = Get-Date 

Write-Host “Destination storage account name is [$DestStorageAccountName]”

# Copy disks using the async API from the source URL to the destination storage account
$diskCopyStates += StartCopyVHD -sourceDiskUri $osdisk.MediaLink -destStorageAccount $DestStorageAccountName -destContainer $DestStorageAccountContainer -diskName $osdisk.DiskName -OS $osdisk.OS

# copy all the data disks
$SourceVM | Get-AzureDataDisk | foreach {

    Write-Host “Disk Name [$($_.DiskName)], Size is [$($_.LogicalDiskSizeInGB)]”

    #Premium storage does not allow disks smaller than 10 GB
    if( $_.LogicalDiskSizeInGB -lt 10 )
    {
        Write-Warning “Data Disk [$($_.DiskName)] with size [$($_.LogicalDiskSizeInGB) is less than 10GB so it cannnot be added” 
    }
    else
    {
        Write-Host “Destination storage account name is [$DestStorageAccountName]”
        $diskCopyStates += StartCopyVHD -sourceDiskUri $_.MediaLink -destStorageAccount $DestStorageAccountName -destContainer $DestStorageAccountContainer -diskName $_.DiskName
    }
}

#check that status of blob copy. This may take a while if you are doing cross region copies.
#even in the same region a 127 GB takes nearly 10 minutes
TrackBlobCopyStatus -diskCopyStates $diskCopyStates

# Mark the finish time of the script execution
$finishTime = Get-Date 
 
# Output the time consumed in seconds
$TotalTime = ($finishTime  $startTime).TotalSeconds 
Write-Host “The disk copies completed in $TotalTime seconds.” -ForegroundColor Green

Write-Host “Registering Copied Disk” -ForegroundColor Green

$luncount = 0   # used to generate unique lun value for data disks
$index = 0  # used to generate unique disk names
$OSDisk = $null

$datadisk_details = @{}

foreach($diskName in $disk_configs.Keys)
{
    $index = $index + 1

    $diskConfig = $disk_configs[$diskName].Split(“;”)

    #since we are using the same subscription we need to update the diskName for it to be unique
    $newDiskName = “$DestVMName” + “-disk-“ + $index

    Write-Host “Adding disk [$newDiskName]”

    #check to see if this disk already exists
    $azureDisk = Get-AzureDisk -DiskName $newDiskName -ErrorAction SilentlyContinue

    if(!$azureDisk)
    {

        if($diskConfig.Length -gt 1)
        {
           Write-Host “Adding OS disk [$newDiskName] -OS [$diskConfig[1]] -MediaLocation [$diskConfig[0]]”

           #Expect OS Disk to be the first disk in the array
           $OSDisk = Add-AzureDisk -DiskName $newDiskName -OS $diskConfig[1] -MediaLocation $diskConfig[0]

           $vmconfig = New-AzureVMConfig -Name $DestVMName -InstanceSize $VMSize -DiskName $OSDisk.DiskName 

        }
        else
        {
            Write-Host “Adding Data disk [$newDiskName] -MediaLocation [$diskConfig[0]]”

            Add-AzureDisk -DiskName $newDiskName -MediaLocation $diskConfig[0]

            $datadisk_details[$luncount] = $newDiskName

            $luncount = $luncount + 1  
        }
    }
    else
    {
        Write-Error “Unable to add Azure Disk [$newDiskName] as it already exists”
        Write-Error “You can use Remove-AzureDisk -DiskName $newDiskName to remove the old disk”
        return
    }
}

#add all the data disks to the VM configuration
foreach($lun in $datadisk_details.Keys)
{
    $datadisk_name = $datadisk_details[$lun]

    Write-Host “Adding data disk [$datadisk_name] to the VM configuration”

    $vmconfig | Add-AzureDataDisk -Import -DiskName $datadisk_name  -LUN $lun
}

#read all the end points in the source VM and create them in the destination VM
#NOTE: I don’t copy ACL’s yet. I need to add this.
$SourceVM | get-azureendpoint | foreach {

    if($_.LBSetName -eq $null)
    {
        write-Host “Name is [$($_.Name)], Port is [$($_.Port)], LocalPort is [$($_.LocalPort)], Protocol is [$($_.Protocol)], EnableDirectServerReturn is [$($_.EnableDirectServerReturn)]]”
        $vmconfig | Add-AzureEndpoint -Name $_.Name -LocalPort $_.LocalPort -PublicPort $_.Port -Protocol $_.Protocol -DirectServerReturn $_.EnableDirectServerReturn
    }
    else
    {
        write-Host “Name is [$($_.Name)], Port is [$($_.Port)], LocalPort is [$($_.LocalPort)], Protocol is [$($_.Protocol)], EnableDirectServerReturn is [$($_.EnableDirectServerReturn)], LBSetName is [$($_.LBSetName)]”       
        $vmconfig | Add-AzureEndpoint -Name $_.Name -LocalPort $_.LocalPort -PublicPort $_.Port -Protocol $_.Protocol -DirectServerReturn $_.EnableDirectServerReturn -LBSetName $_.LBSetName -DefaultProbe
    }
}

#
if( $DeployToVnet )
{
    Write-Host “Virtual Network Name is [$VNetName] and Subnet Name is [$SubnetName]” 

    $vmconfig | Set-AzureSubnet -SubnetNames $SubnetName
    $vmconfig | New-AzureVM -ServiceName $DestServiceName -VNetName $VNetName -Location $Location
}
else
{
    #Creating the virtual machine
    $vmconfig | New-AzureVM -ServiceName $DestServiceName -Location $Location
}

#get any vm extensions
#there may be other types of extensions that be in the source vm. I don’t copy them yet
$SourceVM | get-azurevmextension | foreach {
    Write-Host “ExtensionName [$($_.ExtensionName)] Publisher [$($_.Publisher)] Version [$($_.Version)] ReferenceName [$($_.ReferenceName)] State [$($_.State)] RoleName [$($_.RoleName)]”
    get-azurevm -ServiceName $DestServiceName -Name $DestVMName -Verbose | set-azurevmextension -ExtensionName $_.ExtensionName -Publisher $_.Publisher -Version $_.Version -ReferenceName $_.ReferenceName -Verbose | Update-azurevm -Verbose
}

 

Conclusion

I had to look at many different code samples as well as MSDN documentation to create this script. I am grateful to all the open source samples folks are contributing and this is my way of giving back to the Azure community. If you have questions and/or features requests drop me a line and I will do what  I can to help.

This entry was posted in DevOps, Virtual Machines, Windows Azure and tagged , , , . Bookmark the permalink.
  • Pingback: Luper's Learnings - Azure Technical Community for Partners (July 2015) - Luper’s Learnings - Site Home - TechNet Blogs()

  • rajan bhayana

    got an error after the disk was copied. Does it creates a VM for you. or we need to make a DS4 VM and then provide that as destination?

    Must specify MediaLocation or set a current storage account using Set-AzureSubscription.

    • http://rajinders.com rajisingh

      It should have created a VM for you. However there are so many changes being made to the Azure V2 services that things can break at any time. The repository is public so you can contribute to it. I can also take a look in near future.

      • rajan bhayana

        Thanks
        I think we need to specify storage when we set subscription. I ll update you if it works. thanks for the script. looks great.

  • http://jaymeedwards.com/ Jayme Edwards

    Yeah this script did half the work great, when it goes to create the new VM config, it bombs because it needs to select the new storage account first. I got it working after running each of the commands after manually but this should be fixed. Thanks though this definitely helped me out with most of the migration!

    • admin

      Jayme,
      Would you mind either updating the github repo or share the changes you made so I can update the blog post.

      Thanks

      Raj

  • George

    Hi I have a simple question to you.
    “have D series VMs in North Central America servers to be migrated to DS series Central America server and assigning new resources ” . First all ,i would like to Know ,whether it is possible . (2) If it is possible ,How do we do it. Can you Pls. Guide me.

  • Mircea Coste

    Awesome sauce!! It needed a bit of trial and error, but this is essentially doing exactly what it is supposed to do.

    Thank you so much for this!

  • Andre Nel

    Has any 1 done this moving a VM from classic to ARM and changing from D-series to DS-series?