When migrating from Hyper-V to Azure Stack HCI, it's important to gather the right kind of information to support migration strategy moving forward. I created a short script to help with this process. When migrating, we need to know lots of information so we can ensure the correct settings are migrated, VMs are distributed to the correct target hosts & also plan how long it will take to migrate VMs. It will only gather all the data for Windows-based VMs and a subset for linux-based VMs.
I could have broken the script down into just 2 functions, but I left it at what it is now - it's easier to understand and very easy to add columns to the export by adding functions, then array members.
The script uses the VirtualMachineManager PowerShell module to gather information, so System Centre VMM is a requirements. The script will;
Create a list of the running VMs
Gather the VM data we need (listed below)
Prompt for a CSV file to save.
It gathers the following information;
VM Name
The name of the VM
CPU Count
The number of CPUs assigned to the VM
Assigned Memory
The amount of Memory (in GB) that's assigned to the VM
Here's the script - hope it's useful..
IP Address(es)
What IP addresses are assigned to the VM
VMID
The ID of the VM (used if running the compare-vm or import-vm cmdlets and specifying the export xml file)
Generation
Whether it's a Generation 1 or 2 VM
Host
The host that the VM is currently located on
Host Volume
The volume(s) that the disks are located
Number of Disks
The number of disks attached to the VM
Total Storage Size
The total size of all the VHDX files
Number of Checkpoints
Have any checkpoints been created?
Does it have a replica?
Whether therethere are any replicas of this VM on other hosts
Mac Address Type
Is the MAC address dynamic or static (may need remediation)
VLAN ID
The assigned VLAN ID
Here's the script - you can download it here: Gather-VMData.ps1
<#
.Synopsis
Gathers information using SCVVM from Hyper-V hosts to support migration, created by Tony Brown.
.Description
Gathers Virtual Machine information using System Center Virtual Machine Manager Cmdlets
.Example
# ./Gather-VMData.ps1
.Link
# Online version: http://1337.uk/
#>
#Import the Module
import-module VirtualMachineManager
#Setup the Functions
function Get-IPAddress ($VM)
{
$msv = Get-SCVirtualMachine -name $VM | Get-SCVirtualNetworkAdapter | select-object IPv4Addresses
$result = $msv.IPv4Addresses -join ";"
return $result
}
function Get-Memory ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object Memory
return $result
}
function Get-CPUs ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object CPUCount
return $result
}
function Get-VLAN ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object VlanID
return $result
}
function Get-CheckPoints ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVMCheckpoint).count
return $result
}
function Get-StorageSize ($VM)
{
$VMid = Get-SCVirtualMachine -id $VM.guid
$VHDs = $VMid.VirtualHardDisks
foreach ($VHD in $VHDs) {$result += $VHD.Size/1GB}
$result = [math]::round($result,2)
return $result
}
function Get-ReplicaStatus ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Select-Object ReplicationMode
if ($result.ReplicationMode -eq "Primary"){
return "Yes"
}
else
{
return "No"
}
}
function Get-MacAddressType ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object PhysicalAddressType
return $result
}
function Get-Disks ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk).count
return $result
}
function Get-HostVolume ($VM)
{
$msv = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk | select-object HostVolume
$result = $msv.HostVolume -join ";"
return $result
}
#Discover the inital VM Set and create the report, we're assuming that VM's which are turned off do not need to be migrated
$virtualMachines = Get-SCVirtualMachine | ? StatusString –eq "Running"
$VMMReport = @()
#Cycle through the VMs, gathering the data
foreach ($virtualMachine in $virtualMachines)
{
#Run the functions to get the data
$IPAddress = Get-IPAddress $virtualMachine.name
$Memory = Get-Memory $virtualMachine.id
$CPUCount = Get-CPUs $virtualMachine.id
$CheckPoints = Get-CheckPoints $virtualMachine.id
$VLAN = Get-VLAN $virtualMachine.id
$NumberOfDisks = Get-Disks $virtualMachine.id
$StorageSize = Get-StorageSize $virtualMachine.id
$MacAddressType = Get-MacAddressType $virtualMachine.id
$HostVolume = Get-HostVolume $virtualMachine.id
$ReplicaStatus = Get-ReplicaStatus $virtualMachine.id
#Create the Data Array
$VMObj = New-Object PSObject
$VMObj | Add-Member -type NoteProperty -name VMName -value $virtualMachine.name
$VMObj | Add-Member -type NoteProperty -name CPUCount -value $CPUCount.CPUCount
$VMObj | Add-Member -type NoteProperty -name Memory -value $Memory.Memory
$VMObj | Add-Member -type NoteProperty -name IPAddress -value $IPAddress
$VMObj | Add-Member -type NoteProperty -name VMID -value $virtualMachine.VMId
$VMObj | Add-Member -type NoteProperty -name Generation -value $virtualMachine.Generation
$VMObj | Add-Member -type NoteProperty -name Host -value $virtualMachine.VMHost
$VMObj | Add-Member -type NoteProperty -name VLAN -value $VLAN.VLanID
$VMObj | Add-Member -type NoteProperty -name HostVolume -value $HostVolume
$VMObj | Add-Member -type NoteProperty -name NumberOfDisks -value $NumberOfDisks
$VMObj | Add-Member -type NoteProperty -name "StorageSize(GB)" -value $StorageSize
$VMObj | Add-Member -type NoteProperty -name NoOfCheckpoints -value $CheckPoints
$VMObj | Add-Member -type NoteProperty -name HasReplica -value $ReplicaStatus
$VMObj | Add-Member -type NoteProperty -name MacAddressType -value $MacAddressType.PhysicalAddressType
$VMMReport += $VMObj
}
#Create the 'save-as dialog box'
Add-Type -AssemblyName System.Windows.Forms
$dlg=New-Object System.Windows.Forms.SaveFileDialog -property @{Filter = 'CSV Files (*.csv)|*.csv'}
if($dlg.ShowDialog() -eq 'Ok'){
Write-host "Saving CSV File to: $($dlg.filename)"
}
#export the CSV file to the path specified.
$VMMReport | export-csv -NoTypeInformation -Path $dlg.FileName
<#
.Synopsis
Gathers information using SCVVM from Hyper-V hosts to support migration, created by Tony Brown.
.Description
Gathers Virtual Machine information using System Center Virtual Machine Manager Cmdlets
.Example
# ./Gather-VMData.ps1
.Link
# Online version: http://1337.uk/
#>
#Import the Module
import-module VirtualMachineManager
#Setup the Functions
function Get-IPAddress ($VM)
{
$msv = Get-SCVirtualMachine -name $VM | Get-SCVirtualNetworkAdapter | select-object IPv4Addresses
$result = $msv.IPv4Addresses -join ";"
return $result
}
function Get-Memory ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object Memory
return $result
}
function Get-CPUs ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object CPUCount
return $result
}
function Get-VLAN ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object VlanID
return $result
}
function Get-CheckPoints ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVMCheckpoint).count
return $result
}
function Get-StorageSize ($VM)
{
$VMid = Get-SCVirtualMachine -id $VM.guid
$VHDs = $VMid.VirtualHardDisks
foreach ($VHD in $VHDs) {$result += $VHD.Size/1GB}
$result = [math]::round($result,2)
return $result
}
function Get-ReplicaStatus ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Select-Object ReplicationMode
if ($result.ReplicationMode -eq "Primary"){
return "Yes"
}
else
{
return "No"
}
}
function Get-MacAddressType ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object PhysicalAddressType
return $result
}
function Get-Disks ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk).count
return $result
}
function Get-HostVolume ($VM)
{
$msv = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk | select-object HostVolume
$result = $msv.HostVolume -join ";"
return $result
}
#Discover the inital VM Set and create the report, we're assuming that VM's which are turned off do not need to be migrated
$virtualMachines = Get-SCVirtualMachine | ? StatusString –eq "Running"
$VMMReport = @()
#Cycle through the VMs, gathering the data
foreach ($virtualMachine in $virtualMachines)
{
#Run the functions to get the data
$IPAddress = Get-IPAddress $virtualMachine.name
$Memory = Get-Memory $virtualMachine.id
$CPUCount = Get-CPUs $virtualMachine.id
$CheckPoints = Get-CheckPoints $virtualMachine.id
$VLAN = Get-VLAN $virtualMachine.id
$NumberOfDisks = Get-Disks $virtualMachine.id
$StorageSize = Get-StorageSize $virtualMachine.id
$MacAddressType = Get-MacAddressType $virtualMachine.id
$HostVolume = Get-HostVolume $virtualMachine.id
$ReplicaStatus = Get-ReplicaStatus $virtualMachine.id
#Create the Data Array
$VMObj = New-Object PSObject
$VMObj | Add-Member -type NoteProperty -name VMName -value $virtualMachine.name
$VMObj | Add-Member -type NoteProperty -name CPUCount -value $CPUCount.CPUCount
$VMObj | Add-Member -type NoteProperty -name Memory -value $Memory.Memory
$VMObj | Add-Member -type NoteProperty -name IPAddress -value $IPAddress
$VMObj | Add-Member -type NoteProperty -name VMID -value $virtualMachine.VMId
$VMObj | Add-Member -type NoteProperty -name Generation -value $virtualMachine.Generation
$VMObj | Add-Member -type NoteProperty -name Host -value $virtualMachine.VMHost
$VMObj | Add-Member -type NoteProperty -name VLAN -value $VLAN.VLanID
$VMObj | Add-Member -type NoteProperty -name HostVolume -value $HostVolume
$VMObj | Add-Member -type NoteProperty -name NumberOfDisks -value $NumberOfDisks
$VMObj | Add-Member -type NoteProperty -name "StorageSize(GB)" -value $StorageSize
$VMObj | Add-Member -type NoteProperty -name NoOfCheckpoints -value $CheckPoints
$VMObj | Add-Member -type NoteProperty -name HasReplica -value $ReplicaStatus
$VMObj | Add-Member -type NoteProperty -name MacAddressType -value $MacAddressType.PhysicalAddressType
$VMMReport += $VMObj
}
#Create the 'save-as dialog box'
Add-Type -AssemblyName System.Windows.Forms
$dlg=New-Object System.Windows.Forms.SaveFileDialog -property @{Filter = 'CSV Files (*.csv)|*.csv'}
if($dlg.ShowDialog() -eq 'Ok'){
Write-host "Saving CSV File to: $($dlg.filename)"
}
#export the CSV file to the path specified.
$VMMReport | export-csv -NoTypeInformation -Path $dlg.FileName
<#
.Synopsis
Gathers information using SCVVM from Hyper-V hosts to support migration, created by Tony Brown.
.Description
Gathers Virtual Machine information using System Center Virtual Machine Manager Cmdlets
.Example
# ./Gather-VMData.ps1
.Link
# Online version: http://1337.uk/
#>
#Import the Module
import-module VirtualMachineManager
#Setup the Functions
function Get-IPAddress ($VM)
{
$msv = Get-SCVirtualMachine -name $VM | Get-SCVirtualNetworkAdapter | select-object IPv4Addresses
$result = $msv.IPv4Addresses -join ";"
return $result
}
function Get-Memory ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object Memory
return $result
}
function Get-CPUs ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | select-object CPUCount
return $result
}
function Get-VLAN ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object VlanID
return $result
}
function Get-CheckPoints ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVMCheckpoint).count
return $result
}
function Get-StorageSize ($VM)
{
$VMid = Get-SCVirtualMachine -id $VM.guid
$VHDs = $VMid.VirtualHardDisks
foreach ($VHD in $VHDs) {$result += $VHD.Size/1GB}
$result = [math]::round($result,2)
return $result
}
function Get-ReplicaStatus ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Select-Object ReplicationMode
if ($result.ReplicationMode -eq "Primary"){
return "Yes"
}
else
{
return "No"
}
}
function Get-MacAddressType ($VM)
{
$result = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualNetworkAdapter | select-object PhysicalAddressType
return $result
}
function Get-Disks ($VM)
{
$result = (Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk).count
return $result
}
function Get-HostVolume ($VM)
{
$msv = Get-SCVirtualMachine -id $VM.guid | Get-SCVirtualHardDisk | select-object HostVolume
$result = $msv.HostVolume -join ";"
return $result
}
#Discover the inital VM Set and create the report, we're assuming that VM's which are turned off do not need to be migrated
$virtualMachines = Get-SCVirtualMachine | ? StatusString –eq "Running"
$VMMReport = @()
#Cycle through the VMs, gathering the data
foreach ($virtualMachine in $virtualMachines)
{
#Run the functions to get the data
$IPAddress = Get-IPAddress $virtualMachine.name
$Memory = Get-Memory $virtualMachine.id
$CPUCount = Get-CPUs $virtualMachine.id
$CheckPoints = Get-CheckPoints $virtualMachine.id
$VLAN = Get-VLAN $virtualMachine.id
$NumberOfDisks = Get-Disks $virtualMachine.id
$StorageSize = Get-StorageSize $virtualMachine.id
$MacAddressType = Get-MacAddressType $virtualMachine.id
$HostVolume = Get-HostVolume $virtualMachine.id
$ReplicaStatus = Get-ReplicaStatus $virtualMachine.id
#Create the Data Array
$VMObj = New-Object PSObject
$VMObj | Add-Member -type NoteProperty -name VMName -value $virtualMachine.name
$VMObj | Add-Member -type NoteProperty -name CPUCount -value $CPUCount.CPUCount
$VMObj | Add-Member -type NoteProperty -name Memory -value $Memory.Memory
$VMObj | Add-Member -type NoteProperty -name IPAddress -value $IPAddress
$VMObj | Add-Member -type NoteProperty -name VMID -value $virtualMachine.VMId
$VMObj | Add-Member -type NoteProperty -name Generation -value $virtualMachine.Generation
$VMObj | Add-Member -type NoteProperty -name Host -value $virtualMachine.VMHost
$VMObj | Add-Member -type NoteProperty -name VLAN -value $VLAN.VLanID
$VMObj | Add-Member -type NoteProperty -name HostVolume -value $HostVolume
$VMObj | Add-Member -type NoteProperty -name NumberOfDisks -value $NumberOfDisks
$VMObj | Add-Member -type NoteProperty -name "StorageSize(GB)" -value $StorageSize
$VMObj | Add-Member -type NoteProperty -name NoOfCheckpoints -value $CheckPoints
$VMObj | Add-Member -type NoteProperty -name HasReplica -value $ReplicaStatus
$VMObj | Add-Member -type NoteProperty -name MacAddressType -value $MacAddressType.PhysicalAddressType
$VMMReport += $VMObj
}
#Create the 'save-as dialog box'
Add-Type -AssemblyName System.Windows.Forms
$dlg=New-Object System.Windows.Forms.SaveFileDialog -property @{Filter = 'CSV Files (*.csv)|*.csv'}
if($dlg.ShowDialog() -eq 'Ok'){
Write-host "Saving CSV File to: $($dlg.filename)"
}
#export the CSV file to the path specified.
$VMMReport | export-csv -NoTypeInformation -Path $dlg.FileName