Real World Solutions

Here are some virtual machine management problems you might encounter and their possible solutions.

Replacing Virtual Switches

Challenge

You have been told that some network engineering will be taking place, and you must move every virtual machine that is on a virtual switch called External1 to a different virtual switch called External2. This sounds simple until you find that there are more than 400 virtual machines connected to External1 on the host that you manage. How will you complete this task as quickly as possible?

Solution

A common problem is the need to make a simple change—but to lots of virtual machines. Using the GUI is out of the question because it is too slow. This is where PowerShell can prove its value. This one line of code will make the required change to the over 400 virtual machines:

Get-VMNetworkAdapter * | Where-Object {$_.SwitchName -Eq "External1"} | `
Connect-VMNetworkAdapter -SwitchName “External2”

The code does the following:

  • Gets all virtual network adapters
  • Filters them for only those that connect to a virtual switch called External1
  • Connects those remaining virtual network adapters to External2

Performing Simultaneous Live Migration

Challenge

Your monitoring system has detected a hardware fault on a nonclustered Hyper-V host. There are 200 virtual machines running on the host. All of the virtual machines are stored on a file share, and your hosts are all configured for Kerberos-constrained delegation. Live Migration is configured, and you can do up to 20 simultaneous Live Migrations. You need to drain the host of virtual machines as quickly as possible. How will you do this?

Solution

If the host was clustered, you could take advantage of a Failover Clustering feature called Live Migration Queuing. This would allow you to pause the host. This puts the host into maintenance mode and forces the host to transfer the virtual machines to other hosts in the cluster. However, this host is not clustered, and you do not want to manually start Live Migration of each virtual machine because it will take too long.

The following code uses a PowerShell V3 concept called workflows to perform up to five (limited by Windows Workflow Foundation) simultaneous tasks:

Workflow Invoke-ParallelLiveMigrate
{
Param
    (
    # Param1 List
    [string[]]
    $VMList,

    # Param2 The host you are live migrating from
    $SourceHost,

    # Param3 The host you are live migrating to
    $DestinationHost
    )
ForEach -Parallel ($VM in $VMList) 
    {
    Move-VM -ComputerName $SourceHost -Name $VM -DestinationHost $DestinationHost
    }
}
#The script starts here. First we define the two hosts:
$FromHost = "Host2"
$ToHost = "Host1"
$VMList = Get-VM -ComputerName $FromHost
if ($VMList -ne $Null)
    {
    Invoke-ParallelLiveMigrate -VMList $VMList.Name $FromHost $ToHost
    }
else
    {
    Write-Output "There is nothing to move"
    }

The code does the following:

1. Gets a listing of every virtual machine on Host2 (the source host).
2. Sends the list of virtual machines, the name of the source host, and the name of the destination host to a workflow called Invoke-ParallelLiveMigrate
.
3. The workflow live-migrates all of the virtual machines to Host1 by using a loop. The loop allows up to five simultaneous Live Migrations. The loop will continue until all of the virtual machines have been moved off of Host2.

Overcoming the Limits of Windows Workflow Foundation
A PowerShell workflow is enabled by Windows Workflow Foundation (WF). WF limits a workflow to five parallel threads of execution, and this cannot be expanded. This limits the preceding PowerShell example to five simultaneous Live Migrations.
Jeff Wouters, a PowerShell wizard in the Netherlands, wrote a blog post (http://jeffwouters.nl/index.php/2012/11/powershell-workflow-foreach-parallel-limited-to-5-parallel-threads/) on how to overcome this limit by using a feature of PowerShell called ScriptBlock.

Rapid Virtual Machine Creation

Challenge

You manage the Hyper-V infrastructure for a software development company. They use Hyper-V virtual machines to test new builds of their software every day. They need new virtual machines for each set of tests. The process that has been used up to now requires too much manual intervention and is too slow. You have been asked to create a better solution that will feature automation, will be flexible, and will allow software developers/testers to vary the specification of each virtual machine.

Solution

The solution is to combine many of the solutions that are featured in this chapter in a PowerShell script. The script reads in a comma-separated values (CSV) file that can be created in Microsoft Excel. The header row lists a set of defined headers for columns. Each column configures a specific setting in a virtual machine. Each additional row specifies a virtual machine. Each line of the CSV file is read in and used to create a virtual machine according to that specification.

To speed up the creation of virtual machines, the script enables virtual machines to be created by using differencing disks. These differencing virtual hard disks point to selected parent virtual hard disks. This enables the testing infrastructure to deploy lots of virtual machines from a range of template virtual hard disks in a very speedy fashion. Virtual machines can be quickly destroyed and re-created.

Other settings such as Dynamic Memory, processor counts, and high availability are also available. The design of the CSV file is described in the script. This script and the CSV file design can be customized to suit the needs of any organization.

# Instructions
##############
#
# This script will read a comma-separated values (CSV) file to create VMs.
# The CSV file is specified in $CSVPath. A log file is created by this script.
# This log file is specified in $LogPath.
#
# The script expects to see a CSV file with a header row that specifies the
# column names (variables).
# Each row after that will define a new VM to create.  The variables are as
# follows:
#
# VMName: The name of the new VM to create
# VMPath: Where to create the VM's files
# DiskType: Differencing, Fixed, or Dynamic (the default). No value = Dynamic.
# DiffParent: Used when DiskType = Dynamic. Specifies the parent for the
# differencing disk
# DiskSize: Used if DiskType = Fixed or Dynamic (or blank). Size in GB for the
# new VHDX
# ProcessorCount: How many vCPUs the VM will have
# StartupRAM: Amount in MB that the VM will boot up with (Dynamic Memory or not)
# DynamicMemory: Yes or No (default). Do you enable DM or not?
# MinRAM: Amount in MB for Minimum RAM if DM is enabled.
# MaxRAM: Amount in MB for Maximum RAM if DM is enabled.
# MemPriority: 0-100 value if for Memory Weight DM is enabled
# MemBuffer: 5-2000 value for Memory Buffer is DM is enabled
# StaticMAC: Any non-Null value will be used as a MAC address. No error
# detection.
# AddToCluster: The new VM will be added to the specified cluster if not blank.
# Start: If set to Yes, then the VM will be started up.
# Clear the screen
cls
$CSVPath = "\demo-sofs1CSV1VMs.txt"
$LogPath = "C:ScriptsVMsLog.txt"
# Remove the log file
Remove-Item -Path $LogPath -ErrorAction SilentlyContinue
Import-Csv $CSVPath | ForEach-Object {
# Construct some paths
$Path = $_.VMPath
$VMName = $_.VMName
$VHDPath = "$Path$VMName"
Add-Content $LogPath "Beginning: Creating $VMName."
# Only create the virtual machine if it does not already exist
if ((Get-VM $VMName -ErrorAction SilentlyContinue))
    {
    Add-Content $LogPath "FAIL: $VMName already existed."
    }
    else
    {
    # Create a new folder for the VM if it does not already exist
    if (!(Test-Path $VHDPath))
        { 
        New-Item -Path $VHDPath -ItemType "Directory"
        }
    # Create a new folder for the VHD if it does not already exist
    if (!(Test-Path "$VHDPathVirtual Hard Disks"))
        {    
        $VhdDir = New-Item -Path "$VHDPathVirtual Hard Disks" -ItemType `
        “Directory”
        }
    # Create the VHD if it does not already exist
    $NewVHD = "$VhdDir$VMName-Disk0.vhd"
    if (!(Test-Path $NewVHD))
        {
        # Have to set these variables because $_.Variables are not available
        # inside the switch.
        $ParentDisk = $_.DiffParent
        $DiskSize = [int64]$_.DiskSize * 1073741824
        switch ($_.DiskType)
            {
            'Differencing' {New-VHD -Differencing -Path $NewVHD -ParentPath `
            $ParentDisk}
            'Fixed' {New-VHD -Fixed -Path $NewVHD -SizeBytes $DiskSize}
            Default {New-VHD -Dynamic -Path $NewVHD -SizeBytes $DiskSize}
            }
        if (Test-Path $NewVHD)
            {
            Add-Content $LogPath "  Progress: $NewVHD was created."
            }
            else
            {
            Add-Content $LogPath "  Error: $NewVHD was not created."
            }
        }
        else
        {
        Add-Content $LogPath "  Progress: $NewVHD already existed"
        }
    # Create the VM
    New-VM -Name $_.VMName -Path $Path -SwitchName ConvergedNetSwitch -VHDPath `
    $NewVHD -MemoryStartupBytes ([int64]$_.StartupRam * 1MB)
    # Is the VM there and should we continue?
    if ((Get-VM $VMName -ErrorAction SilentlyContinue))
        {
        Add-Content $LogPath "  Progress: The VM was created."
        # Configure the processors
        Set-VMProcessor $_.VMName -Count $_.ProcessorCount -ErrorAction `
        SilentlyContinue
        If ((Get-VMProcessor $_.VMName).count -eq $_.ProcessorCount) 
            { 
            Add-Content $LogPath "  Progress: Configured processor count."
            }
            else
            { 
            Add-Content $LogPath "  ERROR: Processor count was not configured."
            }
        # Configure Dynamic Memory if required
        If ($_.DynamicMemory -Eq "Yes")
            {
            Set-VMMemory -VMName $_.VMName -DynamicMemoryEnabled $True `
            -MaximumBytes ([int64]$_.MaxRAM * 1MB) -MinimumBytes ([int64]$_. `
            MinRAM * 1MB) -Priority $_.MemPriority -Buffer $_.MemBuffer
If ((Get-VMMemory $_.VMName).DynamicMemoryEnabled -eq $True)
                {
                Add-Content $LogPath "  Progress: Dynamic Memory was set."
                }
                else
                { 
                Add-Content $LogPath "  ERROR: Dynamic Memory was not set."
                }
            }
        # Is a static MAC Address required?
        If ($_.StaticMAC -ne $NULL)
            {
            Set-VMNetworkAdapter $_.VMName -StaticMacAddress $_.StaticMAC `
            -ErrorAction SilentlyContinue
            If ((Get-VMNetworkAdapter $_.VMName).MacAddress -eq $_.StaticMAC)
                {
                Add-Content $LogPath "  Progress: Static MAC address set."
                }
                else
                { 
                Add-Content $LogPath "  ERROR: Static MAC address was not set."
                }
            }
        Add the VM to the cluster?
            $ClusterName = $_.AddToCluster
            If ($ClusterName -ne $NULL)
            {
            If (Add-ClusterVirtualMachineRole -Cluster $_.AddToCluster -VMName `
            $_.VMName -ErrorAction SilentlyContinue)
                {
                Add-Content $LogPath "  Progress: Added VM to $ClusterName `
                cluster.”
                }
                else
                { 
                Add-Content $LogPath "  ERROR: Did not add VM to $ClusterName `
                cluster.”
                }
            }
        # Start the VM?
            If ($_.Start -eq "Yes")
            {
            Start-VM $_.VMName -ErrorAction SilentlyContinue
            If ((Get-VM $_.VMName).State -eq "Running")
                {
                Add-Content $LogPath "  Progress: Started the VM."
                }
                else
                { 
                Add-Content $LogPath "  ERROR: Did not start the VM."
                }
            }
        # End of "Is the VM there and should we continue?"
        Add-Content $LogPath "Success: $VMName was created."
        }
        else
        {
        Add-Content $LogPath "FAIL: $VMName was created."
        }
    }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.76.181