Yesterday I upgraded a Hyper-V node in a cluster from RC to RTM, Now I want to live migrate VM´s from the RC node to the RTM and then upgrade that.
As you can see on this screendump I have one node with build number 8400 (RC) and one with 9200 (RTM)
As you can see on this next image I have two VM´s running on my old node and I want to migrate them. The VM´s reside on a SMB 3.0 share and the cluster have a quorum share
And how do I move the VM´s to the other node, yes with powershell also, what you can see is that the Move-ClusterVirtualMachineRole can take the VMid from the VM objects as pipelined input, and that is really nice.
So now I have live migrated over the VM´s from the old RC to the RTM server and I can continue to upgrade that node.
I get an error if I try to live migrate them back to the old node, the only way I can do that is when the VM´s are powered off.
Of course I would rather have all my hosts in my System Center VMM 2012 SP1 but if I do not, or I just as an ITPro admin want to check if there are some new Hyper-V servers out there in my Active Directory and if they have VM´s on them I can use PowerShell.
I have looked at Ravikanth´s blog and done some modifications, also I am using the Win2012 and Powershell v3.
I can with the following powershell cmd get all hyper-v virtual machines in my Active Directory (of some reason the VMware machines do not get registered in the AD as virtual machines). With powershell version 3 it autoloads the Active Directory Module, this requires though that I have the feature RSAT-AD-PowerShell installed, easily done with Get-WindowsFeature RSAT-AD-PowerShell | Add-WindowsFeature.
I cannot do so much more with this information, what I want is to check a list of Hyper-V servers and also try to get the VM´s on them, sadly only win2012 servers can interact with the hyper-v powershell module and give that info, but hey whom has win 2008 r2 hyper-v servers 😉
This first query gives me all Hyper-V servers in the domain, 2008->2012
I wanted to create a function that could help an IT Pro Admin with the task to create a clone of a running VM, Yes you can use the Export-VM cmdlet but then your VM must be turned off and in some cases, for example when you want to test a new release or patch on a production system but first test it in a safe environment and you are not allowed to stop the original VM.
The function exists in System Center Virtual Machine Manager but there it also must be turned off
So how do I do? I have made a PowerShell function that take a snapshot, copies the vhd files and creates a new VM, connect the vhd´s and network cards, configures the VM with number of processors, dynamic memory etc.
As the Snapshot merges the vhdx files when the VM is running in this new Hyper-V version I thought it was an sufficient way to solve that the VM actually was not writing to the .vhdx files when I copy them but into the .avhdx diff file.
This is a version 0.1 and yes it need some development but right now I do not have the time to make it supernice,
Here you can see it in action
And when It is finished It looks like this in the gui
And here is the PowerShell function
<#
.Synopsis
Function to clone a running VM
.DESCRIPTION
This function can be used to clone a running vm and connect the copied vhd´s and network
.EXAMPLE
Clone-VM -VMName vmdisktest -VMCloneName vmdisktest-clone -Path c:\VMs
.EXAMPLE
Clone-VM -VMName vmdisktest -VMCloneName vmdisktest-clone -Path c:\VMs -Switch Private
.Notes
Author: Niklas Akerlund
Date: 2012-06-19
#>
function Clone-VM
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# Name of the VM to be cloned
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$VMName,
[string] $VMCloneName,
# Where to store the VM-clone
[string] $Path,
# Set to another network switch
[string] $Switch = " "
)
# Get VM
$VM = Get-VM $VMName
$VHDs = Get-VMHardDiskDrive -VM $VM
#$VHDPath = (Get-VMHardDiskDrive -VM $VM).Path
$VHDClonePath = "$Path\$VMCloneName\Virtual Hard Disks\"
# Create a new array of VHD info
$VHDOrg = @()
foreach ($VHD in $VHDs){
$data = New-Object PSObject -property @{
VHDName = (Get-Item $VHD.Path).Name
VHDPath = $VHD.Path
ControllerType = $VHD.ControllerType
ControllerNumber = $VHD.ControllerNumber
ControllerLocation = $VHD.ControllerLocation
}
$VHDOrg +=$data
}
$VMNics = Get-VMNetworkAdapter -VM $VM
# Take snapshot
$VM | Checkpoint-VM
New-Item -ItemType directory -Path $VHDClonePath
New-VM -Name $VMCloneName -Path $Path -NoVHD -MemoryStartupBytes $VM.MemoryStartup -BootDevice IDE
$VMClone = Get-VM -Name $VMCloneName
Get-VMNetworkAdapter -VMName $VMCloneName | Remove-VMNetworkAdapter
# Configure VM-Clon
if ($VM.DynamicMemoryEnabled){
Set-VM -VMName $VMCloneName -ProcessorCount $VM.ProcessorCount -DynamicMemory -MemoryMinimumBytes $VM.MemoryMinimum -MemoryMaximumBytes $VM.MemoryMaximum
}else{
Set-VM -VMName $VMCloneName -ProcessorCount $VM.ProcessorCount -StaticMemory
}
# Add all network cards
foreach ($VMNic in $VMNics){
if ($Switch -eq " "){
Add-VMNetworkAdapter -VMName $VMCloneName -SwitchName $VMNic.SwitchName -IsLegacy $VMNic.IsLegacy
}else{
Add-VMNetworkAdapter -VMName $VMCloneName -SwitchName $Switch -IsLegacy $VMNic.IsLegacy
}
}
# Copy all VHDs
foreach ($VHDcopy in $VHDOrg){
$Dest = $VHDClonePath + $VHDcopy.VHDName
Copy-Item -Path $VHDcopy.VHDPath -Destination $Dest
Add-VMHardDiskDrive -VMName $VMCloneName -ControllerType $VHDCopy.ControllerType -ControllerLocation $VHDCopy.ControllerLocation -ControllerNumber $VHDCopy.ControllerNumber -Path $Dest
}
# Remove snapshot
$VM | Remove-VMSnapshot
}
Good luck in testing, but do take in consideration that this is an copy of the running VM so do not start it at the same time on the same network or you will get IP collision etc, as you can see above I have added an -Switch parameter that you can use to set the network cards of the VM to be connected on another switch to avoid any problems.. 🙂
A colleague wanted a script for a reconfiguration of a VM´s settings. Once the VM is powered off that is not a big issue. The smart thing is when using Powershell version 3 I can configure a scheduled job that I want to execute off hours.
Imagine that you have the task to add a vCPU to a VM but you can only do it during the service window that happens to be around midnight, I don´t know about you but I rather sleep then if I can automate it. Yes I could in earlier versions use scheduled task but now I am using Win 2012 and Hyper-V 3 and the latest powershell.
So what do I need to do then, Jan Egil Ring has made a blog post about scheduled jobs and I want to show an example regarding Virtual Machine management..
In Powershell version 3 there are 16 cmdlets regarding scheduled jobs
First I need a Trigger
$once = New-JobTrigger -Once -At 11:59PM
Then I need a job with the trigger, I could use a parameter -FilePath to use a script file instead of -ScriptBlock
And here you can see a screendump of the changing, Now I changed the trigger time to not have to wait to midnight for the blog post but I think you can imagine…
To check that the Job went ok, you run the cmdlet Get-Job ( and if you do not get any job you might need to run import-module PSScheduledJob to get the right Get-Job in that session)
In the PowerCLI world there is a kind of evil oneliner to remove all VM´s from a datacenter, I was searching for something alike in the Hyper-V v3 world
And of course that is pure evil because the parameter -deletepermanently will remove not only the VM but also it´s files from the datastore, The % is to take care of each VM and in case the VM is running I will shut it down (otherwise if I only run like Get-VM | Stop-VM -Confirm:$false | Remove-VM -deletePermanently -Confirm:$false I will only remove the ones running, cause I will get an error on the others because I cannot change state to what it is already)
In Hyper-V and the powershell v3 It is not quite as easy but of course it can be done and don´t you dare use the gui 😉
This approach requires that you have put your VM in a separate folder for each of them (or of course it will be clean in your default Hyper-V VM folder..)
The Remove-VM cmdlet does not allow you to actually remove the VM´s virtual hard disk and the folders (which in some times can become a bit messy after a while)
Here is my VM´s
And here is my folder
So if I remove one VM now with the Remove-VM TestVM1, this also requires that the VM is off.
And lets see in the folders what do we have
So to clean both VM´s and folder data I run all at once and this looks like this
Now that the Windows 2012 RC has arrived with the Powershell v3 I wanted to explore the functionality a bit more, I have seen some posts about how to use the Workflows but none when deploying VM´s in Hyper-V.
I have loaned some code from Mikael Nyström (Deployment Bunny) but had to rewrite a little to make it work with the workflow -parallel.
Also when I downloaded Mikael´s scripts they where automatically blocked ( I had set my demo system to -Unrestricted) but as you see in the screenshot they are still blocked. but luckily I can use the Unblock-File cmdlet in the Powershell v3, when using the v2 there was a utility tool streams.exe from SysInternals that could help.
and here is it in the properties dialog
But if I have like 5-10 or 100 files I would like to use Powershell (Anyone out there unblocking like 100 scriptfiles by clicking in a dialog?)
To create the “Master” vhdx I used the Convert-WindowsImage.ps1 script, I am creating the master to be deployed with win 2012 RC datacenter core version (Updated:I got a tip in the comments to look at the Convert-WindowsImage instead of the Wim2VHD.ps1)
Now to my workflow, I am testing to create 5 VM´s at the same time with differential disks connected to the master. the workflows also set all VM´s to dynamic memory and starts them.
It is quite simple but still powerfull, If I for example had like more hosts i can deploy many VM´s at the same time and the thing that would stop me is the hardware and the storage 😛
as yesterday the RC of the Windows 2012 came I thought i would give it a try.
First of all, i wanted to test if I could upgrade my win8 beta server to the Windows 2012 RC but as you can see on the picture from the installation this is not possible. So what to do, as I had two nodes i live migrated my VM´s to the other win8 beta and did a fresh install.
When it was finished I wanted to add the server to the domain and of course this should be done with powershell. When installing you all know that the OS get a not so friendly name so with the parameter -NewName I rename it at the same time as I add it to the domain.
Next step was of course to add the Hyper-V role,
And what to do next, well i want to live migrate my VM´s from my other node but that was unfortunately not possible 🙁 cause of some kind of mismatch with the protocol as you can see on my next screendump
Ok so my next plan was to export the VM´s and then import them, this also with powershell, but as the win8 beta set the dynamic memory maximum to 2 TB i got a configuration issue so I had to handle that before i had an successfull import
After this I could import it ( notice though I could not use the parameter -copy when using -CompabilityReport, so I had to manually copy the VM to the Hyp31 server )
Good luck in your migration to the Windows 2012 RC 🙂
So first I have to shrink the partition inside the VM, for this I use the New-CIMSession (instead of powershell remoting and such) and then I shut down the VM and shrink the VHDx file, As someone correctly noted, this shrink of the virtual disk file is only possible when using the new VHDx format.
The VM is part of the same domain as the hyper-V server from which I am running the script, this made it easier to make a cim connection. The VM is also a Win 8 beta cause I need the latest win framework with powershell 3.
As you can see, the disk in my VM is 60 GB and I want to shrink it to the minimum size * 20% (so i get at least some space left 😉
Now I will run my little script and here is what that looks like
And here you can see the result, a quite simple solution..
Good luck in your shrinking 🙂
Update: I totally missed that Ben had done a post about doing it with powershell, just after his other post when i was making this post… At least my solution show how to connect to a VM with CIM 🙂
Today I was at a customer and upgraded their VMM 2012 from RC to RTM. We got an issue when trying to run a bare metal deploy after the upgrade, at first we did not understand what was causing the error, but my suspicion was on the winpe that was published by VMM in the WDS PXE.
Here is the error in the VMM Console also
And then i used PowerShell to update the VMM WinPE that resides in the WDS, this because their environment had new HP blades and i needed to add a nic driver. If you do not need to add anything to the winpe you can right click on the VMM console and the PXE and you find a selection “Update WinPE Image” this will use an image from the WAIK installed on the VMM Server. Here is the link for the powershell cmdlet that updates the WinPE
The Powershell I ran was as below, I had to run the dism tools with elevated rights, this can be done by right click on the Powershell console and “Run As Administrator”