This blog post will list some simple things you can do with PowerShell to make Hyper-V easier to manage – the details and commands for this post are taken from TechEd Australia 2014 – you can watch the original session at http://channel9.msdn.com/Events/TechEd/Australia/2014/DCI313.
Want to find a command to use ?
e.g. Get-Command –Module Hyper-V –Name *vhd*
Swap the text in RED for the type of command you want to look for. If you are not sure if it’s a Hyper-V command then don’t limit it to a module bur search all loaded modules.
Get-command *Adapter*
If you want to list all of the available commands in a module you need to know the module name.
Get-Command –Module Hyper-V
If you are using Get-Help to understand how to use individual commands, use
Get-Help Update-Help
to understand how to update the help files to the latest versions of the help files
If you just want to see how to construct an individual command type
Show-Command
This will pop up a screen showng all the available commands. You can the search for a command and the GUI will allow you to browse the options for that command.
Creating new VMs is a cinch – enter a command similar to the below:
New-VM –Name “VM Name” –MemoryStartupBytes 512MB –Path “C:CulesterVolumesVolume1MyVMs”
If you want to create 10 new VMs then this can be done with a single command line by creating an array holding 10 values and then ForEach of those items in the array, create a new VM. An example of the code required is:
$CreateVM = @(): (1..10) | %{ $CreateVM += new-VM –Name “MyVM$_”}
This will create 10 new virtual machines named MyVM1, MyVM2 tjhrough to MyVM10.
Want to know which virtual machines are powered down ?
Get-VM | where-object {$_.state = ‘Off’}
The above is for PowerShell 3 – in PowerShell 4 it’s been made even easier !
Get-VM | Where-Object State –eq Off
As you can see, we no longer need to tell PowerShell that state is an attribute if our object, it understands the context. It also doesn’t need to be told that “off” is a value rather than a variable, it just works it out – amazing !
If you want to be able to review the results in something other than the PowerShell command line interface, just pipe the results to “Out-Gridview” to open them in a grid in a new interface
Get-VM | Out-GridView
This is very useful in very large environments as it allows searching of the results.
Want to create a new disk ?
New-VHD C:CustomerVolumesVolume1MyVHDMyDisk.VHD –SizeBytes 60GB
This will create a new 60GB disk. If you want a dynamic disk, add the –Dynamic switch.
Want to convert a VHD to the newer VHDx format (to expand the disk beyond 2TB) ?
Convert-VHD C:CustomerVolumesVolume1MyVHDMyDisk.VHD C:CustomerVolumesVolume1MyVHDMyDisk.VHDX -Passthru
The –Passthru switch ensures that the results of the command are disaplyed on the screen (it says to pass through the output to the pipeline, as no commands follow it simply writes to the screen) – without this the command simply executes. Don’t forget, you can use a command line to get all VM, get all of their disks and convert all disks to the new format.
If you want to connect the disk you created to a virtual machine then simply
Add-VMHardDiskDrive –VMName MyVM –Path C:CustomerVolumesVolume1MyVHDMyDisk.VHDX -Passthru
Want to move all of your VMs from cluster to another ? Well, you can do live motion or a shred noting move but to do this using PowerShell we can simply export and import.
Get-VM | Export-VM –Path C:MyExportedVMs –Passthru
Now that we can create disks and VMs, we can also create networking within Hyper-V also. To create a new virtual switch we can simply
New-VMSwaitch “MyvSwitch” –SwitchType Internal
This will create a new vSwitch to enable communications only within the node itself – To create a switch available for external use we can use the command
New-VMSwitch “QoS Switch” -NetAdapterName “Wired Ethernet Connection 3” -MinimumBandwidthMode Weight
i.e. External is assumed by default – the above switch will be enabled for QoS for traffic which is especially useful where NICs have been presented to the Management OS also.
If we want to add a network adapter to our virtual machine we use a command similar to the below
Add-VMNetworkAdapter –VMName “MyVM” –Name “NewNIC” –Passthru
If we want to present a NIC to the ManagementOS (for converged networking) then, instead of using the –VMName switch, we use the –ManagementOS switch)
Add-VMNetworkAdapter –ManagementOS –Name “NewNIC” –SwitchName “MyvSwitch” –Passthru
As you can see, we connect to the switch at the time. For our “standard” VM NICs, we can connect the network adapter we created to our vSwitch as follows
Connect-VMNetworkAdapter –VMName “MyVM” –SwitchName “MyvSwitch”
Once our VM is created we can migrate it between nodes
Move-VM –Name MyVM -DestinationHost Server2
If we don’t have a cluster and want to perform a “shared nothing” migration between stand alone nodes or even between clusters then we can do this
Move-VM MyVM Server2 –IncludeStorage –DestinationStoragePath C:ClusterVolumesVolume2MyVM
Of course, we can use tokens to move multiple machines one after the other.
Get-VM –Name * | % {Move-VMStorage $_.Name “C:ClusterStorageVolume2$($_.Name)” }
The above will move the storage only for all of our virtual machines to a new disk – great for rebalancing our storage.
We can set QoS for our virtual machines – this is only bandwidth based and does not priorities traffic by type.
Set-VMNetworkAdapter –VMName MyVM –Name MyNIC –MaximumBandwidth 100MB –MinimumBandwidthAbsolute 20MB –Passthru
We can also set Access Control Lists on our VM (essentially at the virtual switch level rather than in the OS) using PowerShell. We do this to ensure that our environment is safe. For example, this should be done to prevent access to the management layer from tenant VMs.
Add-VMNetworkAdapterACL –VMName myVM –RemoteIPAddress 10.1.1.1 –Direction Outbound –Action Deny
As you can see, the ACL is not fully featured and is based on IP address though it can be filtered by VM NIC also, it secures traffic between IP addresses and the direction (Inbound, Outbound of BOTH).
You can view any ACLs applied to a VM by using the command
Get-VMNetworkAdapterACL –VMName MyVM
We can set memory within a VM as follows
Set-VMMemory –VMName MyVM –DynamicMemoryEnabled $True – MaximumBytes 2GB –MinimumBytes 1GB –StartupBytes 2GB –Pasteur
Again, we can apply to multiple machines either by listing them
Set-VMMemory –VMName MyVM1, MyVM2, MyVM2
Or by tokenizing the name
Set-VMMemory –VMName MyVM*
We can also start multiple VMs in the same way
Get-VM MyVM* | Start-VM -Passthru
If we want to monitor our VMs, we can use VM Resource Metering to record what resources each VM is consuming – this can only be set via PowerShell
Get-VM | EnableVMResourceMetering
Will enable resource metering for all VMs
Get-VM –Name MyVM | Measure-VM
Will return the performance statistics for an individual VM that is being measured / metered.