header image

Archive for Hyper-V

My test environment usually has a dozen or so machines at any one time. Some of these are short lived and used for a particular piece of testing – others are kept for  years. I decided that I wanted to keep up to date on the patching of these virtual machines so installed WSUS on a Windows 2012 box.

One issue is that if a VM isn’t started for 10 days WSUS starts complaining that it hasn’t been contacted and if you run the WSUS clean up wizard the non-reporting servers may be removed. Checking the WSUS console for which machines haven’t sync’d recently is a chore.

In Windows 2012 both WSUS and Hyper-V come with a PowerShell module. This means I can do this:

$date = (Get-Date).AddDays(-10)            
Get-WsusComputer -ToLastSyncTime $date |            
sort  LastSyncTime |            
select -First 4 |            
foreach {             
 $computer = ($_.FullDomainName -split "\.")[0]            
 Start-VM -Name $computer -ComputerName Server02 -Passthru            
}

I’m using the WSUS server as my admin box but if you were accessing a remote WSUS machine change the code to

Get-WsusServer -Name w12sus -PortNumber 8530 | Get-WsusComputer –ToLastSyncTime $date |

I sorted the computers WSUS knows about by date – picked the last 4 to sync so I didn’t overwhelm the Hyper-V host and started them up. Only trick is to get the computer name out of the FullDomainName property.

under: Hyper-V, Windows Server 2012, WSUS

I’ve had two projects in mind for a while.  First I need to build a new WSUS server in my virtual environment & secondly I want to automate as much of the VM creation and configuration as possible. Oh – and I’m not using SC Virtual Machine Manager. 

I’ll be using the Hyper-V cmdlets that come with Windows 2012.

I covered some of this in PowerShell and WMI but that was for Windows 2008 R2 and I was using James O’Neills hyper-v functions. 

Does it get any easier with the cmdlets

This is what I came up with

function new-virtualmachine {            
[CmdletBinding()]            
param (            
 [parameter(Mandatory=$true)]            
 [string]$name,            
             
 [parameter(Mandatory=$true)]            
 [string]$path,            
 [Int64]$mem = 4GB,            
 [string]$vswitch = "Local Area Connection - Virtual Network",            
            
 [ValidateSet("Windows2012", "Windows2008R2", "Windows7")]            
 [string]$iso,            
            
 [switch]$startvm            
)            
            
Write-Verbose -Message "Testing VM Path"            
$vpath = Join-Path -Path $path -ChildPath $name            
if (-not (Test-Path -Path $vpath)){            
 New-Item -Path $path -Name $name -ItemType Directory            
}            
            
switch ($iso){            
 "Windows2012" {$isopath = "C:\Source\Windows 2012 RTM\en_windows_server_2012_x64_dvd_915478.iso"}            
 "Windows2008R2" {$isopath = "C:\Source\Window 2008R2\en_windows_server_2008_r2_standard_enterprise_datacenter_and_web_with_sp1_x64_dvd_617601.iso" }            
 "Windows7" {$isopath = "C:\Source\Windows7 RTM\en_windows_7_ultimate_x86_dvd_x15-65921.iso"}            
}            
            
New-VM -Name $name -MemoryStartupBytes $mem -Path $vpath -BootDevice CD -NewVHDPath "$vpath\$name.vhdx" -NewVHDSizeBytes 120GB -SwitchName $vswitch            
Add-VMDvdDrive -VMName $name -Path $isopath            
            
if ($startvm){Start-VM -Name $name}            
}

The new VM name and path are mandatory, I’ve set a default memory size of 4GB  and added a default Virtual switch. I’m adding the iso file containing the OS I want to install – that’s constrained by the set validation and I have a final parameter that allows me to start the VM.

if the path in which I want to create the VM doesn’t exist I create it.

A switch statement is used to set the full path to the iso file.

The New-VM cmdlet is used to create the VM based on the information provided.  I do hard code the fact that I’m setting the VM to boot from the CD and that the virtual disk will be 120GB

Add-VMDvdDrive is used to add the DVD drive to the VM (the controller location is automatically worked out) and the iso file mounted.

If the startvm switch is used then the VM starts and OS install commences. I’m deliberately NOT automating the OS setup at this time – that may be another project.

under: Hyper-V, PowerShell V3, Virtualization, Windows Server 2012

In Windows 8/2012 you can mount a VHD into the file system. Is there a way to discover the drive letter of the mounted VHD

function get-mountedvhdDrive {            
$disks = Get-CimInstance -ClassName Win32_DiskDrive | where Caption -eq "Microsoft Virtual Disk"            
foreach ($disk in $disks){            
 $vols = Get-CimAssociatedInstance -CimInstance $disk -ResultClassName Win32_DiskPartition             
 foreach ($vol in $vols){            
   Get-CimAssociatedInstance -CimInstance $vol -ResultClassName Win32_LogicalDisk |            
   where VolumeName -ne 'System Reserved'            
 }            
}            
}

Use Get-CimInstance to get the Win32_DiskDrive class. Filter on caption equalling "Microsoft Virtual Disk"

for each “physical” disk returned get the associated Win32_Volume and use that to get the associated Win32_Logical disk where you will find the drive letter.

Nice example of using associations in the CIM cmdlets

under: Hyper-V, PowerShell and WMI, PowerShell V3, Windows Server 2012

Swapping virtual switches

Posted by: | November 14, 2011 | No Comment |

Virtualisation is a great technique for creating demo labs. I took my laptop with a bunch of VMs of Windows 8/Server 8 to the PowerShell Deep Dive.  Normally I run my “server” laptop and my development laptop on a switch or connected via a cross over cable. The VM nics are bound to the “server” laptops real ethernet NIC.

This don’t work when you ( a ) forget the cross over cable and ( b ) have the battery collapse on the dev box. I needed to swap the VMs to run off the internal private Hyper-V network.  Swapping the nics between virtual switches is easy but its a pain when you need to do a number of them.

Time for a couple of functions

function set-loopbackswitch {            
            
Get-VM |            
foreach {            
 $nic = Get-VMNIC -VM $_ |             
 where{$_.SwitchName -eq "Local Area Connection - Virtual Network"}             
 Set-VMNICSwitch -NIC $nic -Virtualswitch "LoopBack"            
}            
}            
            
function set-realswitch {            
Get-VM |            
foreach {            
 $nic = Get-VMNIC -VM $_ |             
 where{$_.SwitchName -eq "LoopBack"}             
 Set-VMNICSwitch -NIC $nic -Virtualswitch "Local Area Connection - Virtual Network"            
}            
}

These get the virtual machines and get the nics corresponding to the appropriate switch. It then swaps the the nic to the other switch. Created as 2 functions as its quicker to write.

The functions are based on James O’Neill’s Hyper-V library – if you haven’t got it it is on codeplex

under: Hyper-V, PowerShellV2

Networking pains

Posted by: | June 26, 2011 | No Comment |

Last week my wireless router decided that it had enough and wasn’t going to work any more. This was annoying because I was due to give a user group presentation that night.

I got a new router up and working but today discovered that connectivity from my Hyper-V environment wasn’t working. With the previous router I’d configured bridging between a Hyper-V virtual network and the wireless adapter in my host. That had to be recreated at which point I discovered that the new router didn’t want to support bridging.

I ended up using RRAS and NAT to get the connectivity. The instructions I found here

http://sqlblog.com/blogs/john_paul_cook/archive/2008/03/23/using-wireless-with-hyper-v.aspx

provide most of what you need.

Remember to set the default gateways and DNS servers properly for it all to work.

under: Hyper-V, Virtualization, Windows Server 2008 R2

Beginning of the week I took delivery of a Lenovo W510 – i7 quad core with Hyper-Threading (Windows sees 8 cores) and 16GB of RAM.  From reviews I’d seen it seemed to run Hyper-V OK so it fitted the bill for a mobile lab.

Partitioned the disk OK and got Windows 2008 R2 installed.  Had to download a few drivers from the Lenovo (IBM) site but everything I needed was there or on the box already.  I’d ordered it with Windows 7 64bit so most of the drivers were available.

Installed Hyper-V and joined it to the domain.

Started moving Virtual Machines on to it and it started crash with a Blue Screen of Death.  Not good & I’m not amused at this point. Eventually got to the point where it wouldn’t start – continual BSOD.  Very not good – my new toy is going back if this continues!

Did some research and it seems there can be a conflict between core parking and Hyper-V.  Core parking is a power saving technology that puts cores to sleep if they are not being used. Hyper-V expects them to be there = BANG.

I booted into the BIOS screen and disabled the power management features on the CPU (and PCI bus for good measure) that enable core parking.  Restarted and everything now seems OK.

I can comfortably run a bunch of VMs and have a reasonable performance. 

Then I discovered that I had to reactivate Windows on all the VMs.  They’d been originally been running on a machine with AMD processor. New processor is Intel.  Its enough of a change to trigger reactivation.

All done and everything seems to work fine.

Time to get Virtual Machine Manager installed and see what that actually does.

under: Hyper-V, Technology, Virtualization, Windows Server 2008 R2

Hyper-V PowerShell library

Posted by: | February 15, 2010 | No Comment |

James has announced an update to his PowerShell Hyper-V library.  http://blogs.technet.com/jamesone/archive/2010/02/15/powershell-and-hyperv.aspx

 

download it from

http://pshyperv.codeplex.com/releases/view/38769

 

Technorati Tags: PowerShell v2,Hyper-V
under: Hyper-V, PowerShellV2

« Newer Posts

Categories