###################### # Storage vMotions VM files from one datastore to another, ie. from NetApp to NexSAN ###################### ## Must have VMWare PowerCLI 6+ installed Add-PSSnapin "VMware.VimAutomation.Core" ###################### # Function block # ###################### function cenWriteLog ($Message, $NewFile) { $DateTimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $DateTimeStamp = "** $DateTimeStamp **" if ($NewFile) { $DateTimeStamp | out-file "log.txt" } else { $DateTimeStamp | out-file "log.txt" -Append } $Message | out-file "log.txt" -Append $DateTimeStamp $Message } #Endfunction cenWriteLog ###################### # Function block end # ###################### ###################### # Main script # ###################### #Disaster Recovery control variables $VC_Server = "Target vCentre server" $VM_LOCATION = 'Example folder name ' #VC folder to look in $DS_SOURCE_FILTER ="Snap*" #source DataStore location, use wild cards to scan more than one datastore $DS_TARGET_FILTER_PRIMARY = '*nexsan*sas*' #Primary target DataStore, accepts wildcards $DS_TARGET_FILTER_SECONDARY = '*nexsan*sata*' #Secondary target DataStor, accepts wildcards #Process control variables $TASK_MAX = 1 #Maximum number of VC tasks that can execute, due to the preformance of the storage subsystem, max recommended value is 3 $TASK_WAIT = 1 #Delay between retrys in minutes $VM_MOVE_ASYNC = $true #$true for async, $false for sync. To force one svmotion at a time, set this to $false $DS_BUFFER = 200 #Datastore space (GB) to remain free after SVMotion CLS cenWriteLog -Message "Scripted SVMotion started" -NewFile $true #Connect to VCenter $ResultText = Connect-viserver -Server $VC_Server cenWriteLog -Message $ResultText $FoundVMs = Get-VM -Datastore $DS_SOURCE_FILTER |WHERE {($_.Folder -like $VM_LOCATION )} |SELECT Name, UsedSpaceGB cenWriteLog -Message $FoundVMs foreach($VM in $FoundVMs) { #record VM details $VMName = $VM.Name $RequiredSpace = $VM.UsedSpaceGB + $DS_BUFFER [boolean] $VM_Relocate = $false #Flag to monitor the status of the operation #Get primary datastores $DataStore = Get-Datastore -Name $DS_TARGET_FILTER_PRIMARY |WHERE {$_.FreeSpaceGB -ge $RequiredSpace} |SELECT Name | SELECT -First 1 #if a suitable datastore has been found if($DataStore) { $TargetDSName = $DataStore.Name $VM_Relocate = $true } #if else { #Get secondary datastores $DataStore = Get-Datastore -Name $DS_TARGET_FILTER_SECONDARY |WHERE {$_.FreeSpaceGB -ge $RequiredSpace} |SELECT Name | SELECT -First 1 if($DataStore) { $TargetDSName = $DataStore.Name $VM_Relocate = $true } #if } if ($VM_Relocate) { $SleepCOunt = 0 do { #Increase the sleep time to prevent querying the VC server too often $SleepCount++ #Get current task stats $Task_Queued = Get-Task -Status:Queued $Task_Running = Get-Task -Status:Running $TaskCount = 0 #Count the number of tasks currently running, sleep for a few seconds/minutes if applicable in order to reduce load on the server if ($Task_Queued) {$TaskCount = $Task_Queued.Count} if ($Task_Running){$TaskCount += $Task_Running.Count} if ($TaskCount -ge $TASK_MAX) { $SleepTime = ($TASK_WAIT * $SleepCount) cenWriteLog -Message "Sleeping for $SleepTime minutes, task count $TaskCount" Start-Sleep -Seconds ($SleepTime * 60) } } while ($TaskCount -ge $TASK_MAX) cenWriteLog -Message "Moving $VMName" Move-VM -VM $VMName -Datastore $TargetDSName -RunAsync:$VM_MOVE_ASYNC } else { cenWriteLog -Message "Unable to move $VMName" } } #for..each Disconnect-VIServer -Server "Target vCentre Server" -Confirm:$false ###################### # Main script end # ######################