Today I have been exploring a bit in patching hyper-v hosts with windows updates and hotfixes and when we have a cluster we can use the CAU ( Cluster Aware Updating) that can help you in the process of getting those hotfixes on in a automated fashion but that does not work on single hosts..
And then we can use the WUSA and that wrapped in a foreach with a little while loop to handle that not a new wusa starts before the preceding one is done as it cannot be run several instances simultaneously (maybe there is a better way to do this of course but this works 😉 )
As I have a Technet subscription with my MCT I had to download right away install and see if it works….
When I had installed the server I activated the Hyper-V role and the management tools
In the RTM version of the Hyper-V PowerShell module there is 178 cmdlets and in the preview it was the same number so no new cmdlets have appeared in the latest release.
I had to test the Live Migration feature and see if it worked to move a VM from a win 2012 Hyper-V to a R2 RTM, I had some issues when trying from the R2 ( I had done the delegation in the AD for kerberos) and when trying from the hyper-v manager it was not totally clear what was wrong:
and it was in the PowerShell console the error was stated and as you can see I had forgot to set up a virtual network with the same name as on the source host and that was why the migration failed..
once that was done the migration worked flawlessly 🙂
Tomorrow I will continue evaluate the RTM release and maybe there will be a new post about my findings then 🙂
In your local cloud and Hyper-V 2012 you can create VM´s with OS disks connected to the IDE that is larger than 127 GB, although the best practice is to create additional disks and connect them to the SCSI controller instead and install the services there!
So to test first that i could convert a vhdx to vhd and then upload it, and also be able to use it in Azure I used the Convert-WindowsImage.ps1 script to create my test-vm that was 128GB large.
When uploading with the cmdlet from the Azure PowerShell module it goes quite fast as it only uploads the bits that contains data, not empty blocks.
And when the upload is finished you create a disk from the uploaded VHD, and as you can see on the screendump it is still 128 GB
and when I start and connect to it, it show the disk size of 128 GB inside the IaaS VM also!
One lesson learned is that before uploading your own virtual machine VHD to Azure, and that is to enable remote desktop settings as otherwise you will not be able to connect to the Azure virtual machine once it is running.
Today I was on Sommarkollo at Microsoft Sweden and speaking on the event and this was the last of two sessions about the MAT (Migration Automation Toolkit).
This automation tool that I first got to know about at MMS 2013 in Las Vegas (sadly it looks like there will be no more MMS 🙁 but that is another story ) in the session held by “Migration Mark” and Matt McSpirit WS-B325 and there in the video about 41 minutes into I ask about how the MAT take care of IP addresses on the migrated VM´s and they answered me that is not part of the MAT yet! And well I would say that this would be quite painful to migrate 100-200 VM´s with this automation tool and still have to enter IP settings for each migrated vm manually!!
But I have an example on how that can be done, I have not integrated it into the MAT scripts yet but it automates the collection of not just the IP addresses but also dns,subnet and gateway.
The information is available via the PowerCLI from the vCenter and here I show you how you can collect all that info after you have got the migration list
Here you can see the csv file after it has run in my test environment, one thing that I will extend with after discussing with some folks is the vlan number the port group the vm is connected to so that can be configured on the other side also.
And then I also with the possibility that there is in Hyper-V 2012, configure the network on the guest from the host, this requires that the virtual machine has the latest integration components installed. Ravikanth has done a blog post about how his function, I have added the possibility to run it from a remote computer
And here is the script that I run to configure the VM´s after the MAT has done the conversions, and yes as Mark says about MAT, there is room for improvements here also of course, As you can see I start with injecting the latest integration components into the VM, the sleep cmdlet is used to get the vm fully booted and integration components installed and then an reboot inside the VM.
# Configure and set VM after Conversion
#
# Niklas AKerlund / 2013-07-01
# Function import
. .\Set-VMNetworkConfiguration.ps1
$VMNICs = Import-CSV -Path D:\mat\vmniclist.txt -Delimiter ";"
$ConvertedVMs = Get-Content -Path D:\mat\VMlist.txt
# Configure each vm before starting
foreach ($ConvertedVM in $ConvertedVMs){
$VM = Get-VM $ConvertedVM.Split(".")[0]
write-host $VM.Name
#patch each VM with latest Integration Tools
$virtualHardDiskToUpdate =($VM | Get-VMHardDiskDrive).path
$integrationServicesCabPath ="C:\Windows\vmguest\support\amd64\Windows6.x-HyperVIntegrationServices-x64.cab"
#Mount the VHD
$diskNo=(Mount-VHD -Path $virtualHardDiskToUpdate –Passthru).DiskNumber
#Get the driver letter associated with the mounted VHD, note this assumes it only has one partition if there are more use the one with OS bits
$driveLetter=(Get-Disk $diskNo | Get-Partition | where Size -GT 100MB).DriveLetter
#Check to see if the disk is online if it is not online it
if ((Get-Disk $diskNo).OperationalStatus -ne 'Online'){Set-Disk $MountedVHD.Number -IsOffline:$false -IsReadOnly:$false}
#Install the patch
Add-WindowsPackage -PackagePath $integrationServicesCabPath -Path ($driveLetter + ":\")
#Dismount the VHD
Dismount-VHD -Path $virtualHardDiskToUpdate
Start-VM -VM $VM
Start-Sleep -Seconds 300
# Wait for the Integration components being installed and the server reboot (reboot requires interaction or automatic script inside VM or you will have to do an unclean poweroff
Start-VM -VM $VM
# check that the migrated VM actually has ic that responds
do {
$notok = Get-VMIntegrationService -VM $VM | Select -First 1 | where PrimaryStatusDescription -eq "OK"
} while( $notok -eq $null)
# COnfigure NICs
foreach ($VMNic in $VMNICs){
write-host "Configuring"
if($VMNIC.VMName -eq $VM.Name){
if(!(Get-VMNetworkAdapter -VM $VM)){
$VMNetAdapter = Add-VMNetworkAdapter -VM $VM -SwitchName $VMNic.NetworkName -Passthru
$VMNetAdapter | Set-VMNetworkConfiguration -IPAddress $VMNic.IP -DefaultGateway $VMNic.GW -Subnet $VMNic.SubnetMask -DNSServer $VMNic.Dns -ComputerName HV03
}else {
Connect-VMNetworkAdapter -VMName $VM.Name -SwitchName $VMNic.NetworkName
$VMNetAdapter = Get-VMNetworkAdapter -VM $VM
write-host "connecting $VMNic.NetworkName "
$VMNetAdapter | Set-VMNetworkConfiguration -IPAddress $VMNic.IP -DefaultGateway $VMNic.GW -Subnet $VMNic.Subnet -DNSServer $VMNic.DNS -ComputerName HV03
}
}
}
}
And after running as you can see in the Hyper-V manager I have the right IP on the VM (and if you check inside the VM, you will see that the dns,subnet and gateway also has been set correctly.
Today I have been exploring a bit in the Windows 2012 R2 Preview and when looking in the technet article “What´s new in Hyper-V 2012 R2” I found the interesting part with the new Integration Service “Guest Services” that allows moving files from the host to the virtual machine without any network connectivity.
This requires two things, first that the “Guest Services” integration component is activated in the VM settings and also that the virtual machine has the latest integrational components installed and the “Hyper-V Guest Interface” service running.
When creating a new virtual machine this is not enabled but I have noticed that when you install Windows 2012 R2 inside the Virtual Machine it gets enabled somehow during the installation, both good and bad… Maybe you want to have some control on what VM´s get this enabled, this can however be a Preview “bug” and will change when the R2 is RTM.
Inside the VM the following Service is running and makes it possible to move files to the VM from the Host. Note that even that you can run the powershell cmdlet from a remote server that have the Hyper-V RSAT tools installed you will have to put the file/files you want to transfer to the VM on the host!
With the parameter -CreateFullPath the folders will be created that I have in the -DestinationPath inside the VM.
If you want to check what VM´s have this Integration guest service enabled you can check it with PowerShell and also disable it and only enable on a per VM basis when transferring files.
Get-VM -ComputerName hvr2 | Get-VMIntegrationService -Name "Guest Service Interface" | where Enabled -eq $true | Disable-VMIntegrationService -Passthru
And on the following screendump you can see that after disabling this I cannot transfer files to the VM.
In my little lab it was quite the time to do an rearm of the servers licenses as I had installed them with the evaluation version. This can be done with the slmgr.vbs /rearm command and a reboot.
And when I came to the second server where the domain controller resides I noticed that it consumed a lot of memory for just having the DC role.
When looking a bit closer I noticed sessions where me and a colleague that have been logged in but in disconnected mode and consumed both CPU and memory. In almost every server this is not optimal where Admins can stay logged in forever and this can be handled with a GPO setting to restrict the time for a disconnected session on servers residing in a specific OU.
Another problem was that when I created the DC VM I just activated the Dynamic memory without setting any limits and this could cause a host with no physical memory left and VM´s going crazy with allocated memory. Setting the Startup memory is important but also setting the Maximum RAM, I have as a best practice to set the startup and Maximum to the same values.
With PowerShell I easily could change the settings of the VM to have a more reasonable maximum value than 1TB. And as you can see with the -PassThrough parameter I can do it in one line.
As Microsoft has released an updated version with Windows 2012 R2 and System Center 2012 R2 Preview I wanted to give you the script with updated url´s so you can easily download and try out the different roles! Note though that the Configuration Manager evaluation VHD has not yet been released, I still have the link in the script so when it will be available you can download it! They have also changed the packages to .bin instead of .rar.
Make sure that you have enough space on your volume and then run the following script and you will within a time that of course depends on your internet connection have all files necessary to start evaluate. I will update the script with the right size of R2 once I have downloaded all but think that 70 GB will be enough at lest now when SCCM is not available 🙂
And as I already have emphasized is that you can only online resize VHDX´s that are connected to a SCSI controller, and it is only on Generation 2 VM that your Hyper-V VM´s can have the boot disk connected to the SCSI and also that limits the number of OS´s (Windows 2012/2012R2 and Win 8/8.1)
I have not yet successfully migrated a Gen 1 VM´s system disk to a Gen 2 but I am working on it 😛 (the Gen 2 uses UEFTI and GPT) and some kind of backup/restore will probably be required.. I will post updates in my pursue of this task.
In the following part of this post I want to show you how I resize both a VHDX with the system and boot partition on it and an additional VHDX with data on the VM running on the Generation 2.
As you can see with this PowerShell I can easily extend the VHDX and also with the following command I can get the minimum size that I can shrink it to, this depends on the volume inside and that can also be shrunk online of course, that has been possible since Windows 2008. I have also gone through this case in an earlier post, the main difference here with R2 is that it can be done online.
When checking the help for the Hyper-V PowerShell module in R2 it can be noted that the help information has not been updated as it says still that it is an offline operation 😛
So to resize during the VM is running is shown here in the following screendump, and as you can see, both the system drive and the L-drive are extended.
And here you can see how we can shrink the VHDX also, note that I have extended the system volume with 3 GB inside the VM also so the minimum have gone up all this when the VM was running!
I read Hyper-V.nu great blog article about Christian Edwards script that checks both hosts and clusters for hotfixes and updates and found some things I wanted to improve in the script, first of all I wanted an object list instead of just some Write-Host with cool colors.. Then I can use the fabulous techniques of PowerShell to just show the once that I do not have installed or make a decent report for my cluster or just standalone hosts.
The next improvement I thought of was the automatic download of all hotfixes.. Well registering at the web page and downloading each hotfix can work for some but not many, so I extended the XML files with the DownloadURL and also changed the script to support either a host or a cluster object. The download parameter will not check what´s installed or not, it will just download all hotfixes that I found URL´s for so bare with me if it is not complete and make a comment or send me a tweet and I will try to update the xml file
Here you can see how I can run it and also as I have the result as objects filter on installed or not
And here you can see when I check a cluster and also add the parameters for downloading and the path to where the downloaded files shall reside
And here is a screendump of some of the hotfix files that are downloaded, as you can see in the script I utilize the BITS engine to download the files 🙂
Updated with hotfixes to 2013-07-15! Here is the script and the xml files with the extended DownloadURL are in this download zip file-> hyperv12updatescheck.
# Remake of Christian Edwards script to make it more flexible
# http://blogs.technet.com/b/cedward/archive/2013/05/31/validating-hyper-v-2012-and-failover-clustering-hotfixes-with-powershell-part-2.aspx
#
# Niklas Akerlund 2013-06-28
param
(
[parameter(ValueFromPipeline=$true,
Position=0)]
[string]$Hostname,
[parameter(ValueFromPipeline=$true,
Position=1)]
$ClusterName,
[switch]$Download,
[string]$DownloadPath
)
#Getting current execution path
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$listofHotfixes = @()
#Loading list of updates from XML files
[xml]$SourceFileHyperV = Get-Content $dir\UpdatesListHyperV.xml
[xml]$SourceFileCluster = Get-Content $dir\UpdatesListCluster.xml
$HyperVHotfixes = $SourceFileHyperV.Updates.Update
$ClusterHotfixes = $SourceFileCluster.Updates.update
#Getting installed Hotfixes from all nodes of the Cluster/hosts
if ($ClusterName){
$Nodes = Get-Cluster $ClusterName | Get-ClusterNode | Select -ExpandProperty Name
}else
{
$Nodes = $Hostname
}
foreach($Node in $Nodes)
{
$Hotfixes = Get-HotFix -ComputerName $Node |select HotfixID,description
foreach($RecomendedHotfix in $HyperVHotfixes)
{
$witness = 0
foreach($hotfix in $Hotfixes)
{
If($RecomendedHotfix.id -eq $hotfix.HotfixID)
{
$obj = [PSCustomObject]@{
HyperVNode = $Node
HotfixType = "Hyper-V"
RecomendedHotfix = $RecomendedHotfix.Id
Status = "Installed"
Description = $RecomendedHotfix.Description
DownloadURL = $RecomendedHotfix.DownloadURL
}
$listOfHotfixes += $obj
$witness = 1
}
}
if($witness -eq 0)
{
$obj = [PSCustomObject]@{
HyperVNode = $Node
HotfixType = "Hyper-V"
RecomendedHotfix = $RecomendedHotfix.Id
Status = "Not Installed"
Description = $RecomendedHotfix.Description
DownloadURL = $RecomendedHotfix.DownloadURL
}
$listofHotfixes += $obj
}
}
foreach($RecomendedClusterHotfix in $ClusterHotfixes)
{
$witness = 0
foreach($hotfix in $Hotfixes)
{
If($RecomendedClusterHotfix.id -eq $hotfix.HotfixID)
{
$obj = [PSCustomObject]@{
HyperVNode = $Node
HotfixType = "Cluster"
RecomendedHotfix = $RecomendedClusterHotfix.Id
Status = "Installed"
Description = $RecomendedClusterHotfix.Description
DownloadURL = $RecomendedClusterHotfix.DownloadURL
}
$listOfHotfixes += $obj
$witness = 1
}
}
if($witness -eq 0)
{
$obj = [PSCustomObject]@{
HyperVNode = $Node
HotfixType = "Cluster"
RecomendedHotfix = $RecomendedClusterHotfix.Id
Status = "Not Installed"
Description = $RecomendedClusterHotfix.Description
DownloadURL = $RecomendedClusterHotfix.DownloadURL
}
$listOfHotfixes += $obj
}
}
}
if ($Download){
foreach($RecomendedHotfix in $HyperVHotfixes){
if ($RecomendedHotfix.DownloadURL -ne ""){
Start-BitsTransfer -Source $RecomendedHotfix.DownloadURL -Destination $DownloadPath
}
}
foreach($RecomendedClusterHotfix in $ClusterHotfixes){
if ($RecomendedClusterHotfix.DownloadURL -ne ""){
Start-BitsTransfer -Source $RecomendedClusterHotfix.DownloadURL -Destination $DownloadPath
}
}
}
$listofHotfixes