Why create all your virtual machines with Windows 2012/ Windows 8?

0606-Server-2012

As the announcement on Teched there has been several improvements on Hyper-V 2012 R2.

With the Windows Hyper-V Server R2  you can create generation 2 virtual machines but these can only be Windows 2012/ Windows 8 or later. And in this post I will try to give you the insight in why it is important that you set up all your virtual machines from now with 2012 and later.

As several blogs have already created lists of the features in R2 I will just refer to them, Thomas Maurer has a great article and also Aidan Finn (The Irish human Hyper-v blogrobot 😉 )

Here are the information about the two features that I want to focus on in this post:

  • Online resizing of VHDX – You can expand and shrink VHDX files during the virtual machine is running.
  • Generation 2 virtual machines – Gen2 VMs are legacy free and based on UEFI. So this means no more emulated devices, boot from virtual SCSI controllers or synthetic network adapters (PXE boot >100MBit) and enables UEFI secure boot as a standard. Supported guest operating systems: 64-bit versions of Windows 8, Windows Server 2012, Windows 8.1 and Windows Server 2012 R2.

So, WoW we can now while the virtual machine runs resize the VHDX, not just extend but also shrink! But there is a limitation!! The vhdx must be connected to a SCSI controller in the virtual machine to be able to utilize this feature! And as you know the system drive (often C:\) in Hyper-V Gen 1 VM´s has to be connected to IDE controller. And yes it is best practice to install the applications and databases and stuff on a separate virtual hard drive that you connect to a SCSI controller but quite often the system drive get´s full with windows patches, logs  and also some applications, etc  and then you want to be able to extend it and being able to do that online is quite sweet!

I have seen several posts that omit this information and it is quite important to be aware of this and that is why I state above that already now before R2, start creating your virtual machines with Win 2012 so that you when R2 is released and you have it in production can migrate your virtual machines to the Generation 2 VM. Yes I know there are several third party software companies that not have support on 2012 yet with their products. But if they do, then there is no reason to install that on a Windows 2008 R2!

When I get my hands on the R2 bits I will test and see how it works to migrate and will do an post about that so check back 🙂

Windows PowerShell and Desired State Configuration HOL

On Teched 2013 there has been a massive announcement about the future of Windows 2012 R2 and System Center 2012 R2 and there was an session with Jeffrey Snover and Kenneth Hansen about Desired State Configuration DSC and how that works,

Now the Hands-On Lab has been released for DSC and accessible for everyone, this also means that you can access the other parts of PowerShell v4.

Screen Shot 2013-06-12 at 13.05.35

Here is a link to the HOL-310 http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/MDC-H310#fbid=9Ij04Tjn-bt

I have done the lab and it is quite impressive how simple and powerfull it is and being able to keep a desired state of installed/configurered servers with a service on them.

As I was in the lab environment I could not resist to check if there was any new powershell cmdlets for the Hyper-V module in R2

Screen Shot 2013-06-12 at 13.15.44

And with this command you can see that there is 14 new cmdlets in the R2 version of the hyper-v module compared to the 2012 version.

Screen Shot 2013-06-12 at 13.13.01

Here is a list of all the HOL that is available online and probably there will be more added later on.

SysCtr PDT deployment session on PSUG Sweden

Yesterday I was at the Swedish PowerShell User Group Community Day and I had a session about the System Center and deployment with PowerShell and talked about the PowerShell Deployment Toolkit.

Here is a screendump where I have installed VMM, AC,ORCH,SM,DPM,OM and also as you can see the automatic creation of shortcuts both on the desktop and the taskbar on the server that I have configured for console. As the PDT is designed to not kill itself I had to restart the deployment after rebooting the HV03 (the reason for this was the installation of .Net 3.51 which required the reboot) which was also the server running the deployment and the last part took 9 minutes. In a youtube video you can see how the deployment takes about an hour with the whole system center suite of roles and integrations between them, quite amazing!

finishedpdt

One thing that is wrong in the package of PDT is the size of the Microsoft.Windows.Server.Library.mp so when the installer.ps1 is validating the size of the files the validation fails. This mp is not wrong it is just updated. Edit the workflow.xml file and set the right size and you should be fine.

Screen Shot 2013-05-24 at 13.17.00

In the workflow.xml file find the line and update the size to the correct value

Screen Shot 2013-05-24 at 13.45.24

I have created a small scripted file that creates all the AD accounts in the PDT as this is not included. This also create an OU that it puts all objects in so it will be more manageable and easy to find.

# Add all Accounts nesssesary for SC Deploy with PDT
#
# Niklas Akerlund

# Create OU´s for groups, users and Server objects
$OU = New-ADOrganizationalUnit -Name SCPDT -PassThru
$SAccounts = "installer","vmm","or","spf","ac","om_saa","om_das","om_dra","om_dwa","sm_s","sm_w","sm_r","sm_a","sm_p"

foreach ($Account in $SAccounts){
    #Account creation  
    New-ADUser -Name $Account -SamAccountName $Account -AccountPassword (convertto-securestring -string "LUMA15gate" -asplaintext -force) -PasswordNeverExpires $true -Enabled $true -path $OU
    get-adgroup "domain admins" | Add-ADGroupMember -Members (Get-ADUser $Account)

}
# rest of admin groups and stuff
New-ADGroup -Name SPFAdmins -path $OU -GroupScope Global -GroupCategory Security
New-ADGroup -Name SM_PDT -path $OU -GroupScope Global -GroupCategory Security
New-ADGroup -Name DW_PDT -path $OU -GroupScope Global -GroupCategory Security
New-ADGroup -Name SMAdmins -path $OU -GroupScope Global -GroupCategory Security
New-ADGroup -Name SQLAdmins -path $OU -GroupScope Global -GroupCategory Security
Get-ADGroup "SQLAdmins" | Add-ADGroupMember -Members (Get-ADgroup "domain Admins")

Adding 2016 subnets to AD Sites and Services

In a recent post I showed how to configure the DHCP server with multiple scopes of subnets with PowerShell and how blazing fast that could be done in the Windows 2012 compared to Windows 2008 R2.

One thing we might forget is to populate the Active Directory Sites and Services subnets with this information to get the clients to access the domain controllers that is nearest. As you can read in this technet post the reason for populating this:

“Domain controllers register service (SRV) resource records in Domain Name System (DNS) that identify their site names. Domain controllers also register host (A) resource records in DNS that identify their IP addresses. When a client requests a domain controller, it provides its site name to DNS. DNS uses the site name to locate a domain controller in that site (or in the next closest site to the client). DNS then provides the IP address of the domain controller to the client for the purpose of connecting to the domain controller. For this reason, it is important to ensure that the IP address that you assign to a domain controller maps to a subnet that is associated with the site of the respective server object. Otherwise, when a client requests a domain controller, the IP address that is returned might be the IP address of a domain controller in a distant site. When a client connects to a distant site, the result can be slow performance and unnecessary traffic on expensive WAN links.”

So as we do not want to update 2016 subnets manually we do this with PowerShell instead, and as you can see with the Windows 2012 it goes quite fast (I have tested on Win 2008 R2 and it works there also).

sitesps

and here is the small PowerShell bits that do the magic

# Populate Subnets in AD Sites and Services
#
# Niklas Akerlund 2013-05-14 

for($b=1;$b -le 63 ; $b++){
    for($i=0;$i -le 255){ 
        $Name = "10.10.$b.$i" + "/29"
        $Description = "10.10.$b.$i" + "/255.255.255.248"
        New-ADObject -Name $Name -Type subnet -Description $Description -OtherAttributes @{location="RemoteVPN";siteObject="CN=HQ,CN=Sites,CN=Configuration,DC=lumademo,DC=local"} -Path "CN=Subnets,CN=Sites,CN=Configuration,DC=lumademo,DC=local"     
        $i = $i +8
    }
}

And then when you look in the Active Directory Sites and Services you will find all the subnets and that they correlate to the right site.

sitesservice

Adding 2016 DHCP Scopes with PowerShell in Windows 2012

I have had a lot to do and that is why I have not done so much updating on the blog, soon my third article will be published on Petri IT Knowledge 🙂 I have also attended the MMS in Las Vegas where I got loads of good information and meet lots of people!

In this post I want to show you the improvements in Windows 2012 and with the PowerShell native cmdlets in this version.

The task was to automatically create 2016 DHCP Scopes for clients on a DCHP server and every scope was a /29 net with 3 lease addresses and one router for each.

I tested this on a Windows 2008 R2 with the community powershell module  and with the following script it took, and I am not kidding, almost 5 hours!! the module utilise the net sh commands with dhcp and probably there could be a lot of improvements for performance, and seriously, just creating one or two scopes can be done in the gui but doing over 2000 will demand a scripted way!

Screen Shot 2013-04-24 at 19.28.45
# Massive DHCP Scope 2016
#
# Niklas Akerlund 2013-04-24

write-host (get-date)
for($b=1;$b -le 63 ; $b++){
    for($i=0;$i -le 255){ 
        New-DHCPScope -Server localhost -Name 10.10.$b.$i -Address 10.10.$b.$i -SubnetMask 255.255.255.248 | Out-Null
        $startip = $i+2
        $endip = $i+4
        $router = $i+1
        Add-DHCPIPRange -Server localhost -Scope 10.10.$b.$i -StartAddress 10.10.$b.$startip -EndAddress 10.10.$b.$endip | Out-Null
        Get-DHCPScope -Server localhost -Scope 10.10.$b.$i | Set-DHCPOption -OptionID  003 -DataType IPADDRESS -Value 10.10.$b.$router | Out-Null
        $i = $i +8
    }
}
write-host (get-date)

With the PowerShell DHCP module for WIndows 2012 I have created the following script for creating the same amount of scopes and configuration and running it took only about 1 minute!!

Screen Shot 2013-04-24 at 20.02.35
# Massive DHCP Scope 2016
#
# Niklas Akerlund 2013-04-24

write-host (get-date)
for($b=1;$b -le 63 ; $b++){
    for($i=0;$i -le 255){ 
        $startip = $i+2
        $endip = $i+4
        $router = $i+1
        Add-DhcpServerv4Scope -Name 10.10.$b.$i -StartRange 10.10.$b.$startip -EndRange 10.10.$b.$endip -SubnetMask 255.255.255.248
        Set-DhcpServerv4OptionValue -ScopeId 10.10.$b.$i -Router  10.10.$b.$router
        $i = $i +8
    }
}
write-host (get-date)

As you can see, handling lots of changes and configurations can easily be done in the new Windows 2012 and it´s native cmdlets!

Not able to set HA on a running VM with SC VMM 2012 SP1

I have described before in blog posts about how to add a running VM to a Hyper-V failover cluster with the PowerShell cmdlets without moving it or turning it off, asuming it already was on a highly available storage such as a CVFS volume or smb 3.0 file share

In my exploration of the virtual machine manager PowerShell module I wanted to test and see if this was also possible in there but I do not succeed, or more correctly maybe should be noted that the SCVMM team has not implemented that for this release 🙁 what has been implemented is the possibility to make a VM highly available when moving between datastores on a cluster node or from a single hyper-v host to a cluster node. As there is some copying of data it will also take longer time than the below command.

In Hyper-V with failover cluster PowerShell module I can add a VM to the cluster with the following cmdlets without stopping the VM.

sethighavailpshv
Hyper-V\Get-VM vmtest -ComputerName HV02 | Add-VMToCluster -Cluster HVCL30

As you see, the reason why I have added the Hyper-V to the cmdlet is that because in the VMM PowerShell cmdlet there is an alias that is called Get-VM and refers to the Get-SCVirtualMachine and that conflicts with the Hyper-V PowerShell module´s Get-VM and I have imported both modules in the same console. I have also imported the failover cluster module in the same console.

If I try to use the Set-SCVirtualmachine vmtest -HighlyAvailable $true I get the following error.

sethighavailvmm

In the VMM Console this option is also greyed out and cannot be set.

isavailablegui

Here is the command to move the VM from one datastore to another and in the same time making it highly available,

movevmworks

I have made a blog post about the issue with Move-SCVirtualMachine not updating the cluster resource and this can be a way to handle this but in my opinion a far more complicated way as you have to move the VM to a new datastore and removing the high availability and then moving it again to another datastore and making it high available again, with a large virtual machine this can take some considerable time when it otherwise just is to run the cluster cmdlet.

New book : Windows 2012 Hyper-V Install and Configuration Guide

HypVConfgInstallgd

Today I bought this book that is written by

  • Aidan Finn
  • Patrick Lownds
  • Michel Luescher
  • Damian Flynn

And in part one I found that Aidan had referred to one of my scripts for moving virtual machine storage without leaving anything behind,

cleaningvNiklas

since the book got into production I have made an update to do some checking and not deleting to much that could happend in the first version!

I feel really honored to be included within a such complete and thorough book about Hyper-V in Windows 2012!

It takes som extra days before it is going to start being delivered in Europe but You can as I by it directly from the Amazon US Kindle store and get it delivered to your App on a chosen device.

Failover Cluster not updated after vm storage migration in VMM 2012 SP1

I was talking to a customer today about an issue they had with their SC VMM 2012 SP1 and when they where doing some storage migrations between their CSV SAN volumes in the Hyper-V cluster.

Screen Shot 2013-03-19 at 22.24.56
Move-SCVirtualMachine -VM (Get-SCVirtualMachine VMtest) -VMHost (Get-VMHost HV02) -Path "C:\ClusterStorage\Volume2" -UseLAN

Everything looks good inside VMM and also the VM works nicely but when looking at the failover cluster manager the resource is not updated which resulted in failure in backup with DPM and probably more issues.

Here is a screendump of the VM in failover cluster manager and also an screendump of the VM in VMM after the migration, as you can see these values does not match

Screen Shot 2013-03-19 at 20.24.47
Screen Shot 2013-03-19 at 20.57.09

There is a way to solve this but that will mean that we have to use the failover cluster and Hyper-V cmdlets. Also should be noted that if we use the failover cluster manager it works so it is a bug in VMM.

So I opened a new PowerShell console and typed the following:

Get-VM VMtest -ComputerName HV02 | Update-ClusterVirtualMachineConfiguration -Cluster HVCL30

And here you can now see that the cluster resource reflects the right data

Screen Shot 2013-03-19 at 22.40.42

There is actually one more solution and that is to remove the VM from the cluster and then add it again but it is easier to just update the cluster virtual machine configuration 🙂

On the management computer I always install the RSAT tools for Hyper-V and also Failover Cluster along with the VMM console to be able to do all management from one place even if I cannot do it all in VMM.

SCVMM 2012 SP1 VM Network Name missing issue

Today when I was going to test the P2V functionality of the VMM 2012 SP1 I found a strange issue.

walking through the wizard for the p2v migration, it gave me an error that I first did not understand, but as it did not allow me to continue the wizard I had to start searching. Based on the object name VMNetwork I concluded that it probably had something to do with the VM Networks.

vmmp2verror

Using PowerShell with the VMM module and the cmdlet Get-SCVMNetwork gave me the following error, and that did not look so good, it should be working right?!

errorvmmpsnet

And looking in the VMM console over the VM networks showed me the following, and yes it is not possible to create a VM Network that has no name but somehow it had happend in my system!

beforevmnetworkconsole

When I restarted the VMM Console the whole list was empty so surely the system did not like this..

So how did I fix it? As all data except the library files are stored in the VMM database I went in there. Here is an excellent place for a reminder for you guys out there that not yet have set up any backup for your VMM servers and particularly the DB, DO IT!

Now my system is a test/lab so if I would break it there is no production systems that will be dependent of any errors or failures.

To be on the safe side I stopped the VMMService before I edited the database and that of course with PowerShell:

stopvmmsrvc

And when that was done I opened the SQL Management Studio and expanded the VMM database, they have a good best practice in naming the tables so it did not take so long time for me to find the one that I wanted to edit, in this case dbo.tbl_NetMan_VMNetwork , right click and chose the edit top 200 rows (if you have more than 200 vm networks you will have to do a query instead 🙂 )

editdbtable

And as you can see on the rows in this table there is one that has in a mysterious way gone blank on the name field, I edited it with the name “Internal” as that was the name I had before and then hit Enter, closed the table and then I started the VMMService again.

editdbtablerow

And in the VM Networks view of the VMM Console everything was back to normal again:

backtovmnetworkconsole

Now I will look at some logs and try to find out why the VM Network´s name disappeared in the first place 🙂

Updated Move-VMStorage2 function for Hyper-V PowerShell

I have been updating my function that extends the Hyper-V PowerShell module cmdlet Move-VMStorage. A while ago I made a blog post about that I think that the folders on the source directory should be removed when doing a Live Storage Migration or you will get a mess with empty VM folders after a while and that can cause some confusion for the admins.

The updates in this script function are the following:

  • I will not delete folders if they do not reside within a folder with the VM´s name (In the earlier version I just deleted and that recursive with no questions asked which could have some consequences )
  • And if the folder was the default or named with another name you will get an output that tells you to clean manually
  • If you do not give the VM´s Name in the -Path parameter I will add that for you to get a nice and tidy folder structure

Here is a screendump on the updated function in action

move-vmstorage2

And here you can see what happens if I move from a folder that is not named after the VM´s name

manuallyclean

And here is a screendump of the folders that are left in the c:\vms that you need to manually delete and you might want to check that not another vm is residing inside these folders before removing them 😛

foldersbehind
    <#
    .Synopsis
       An updated Move-VMStorage function
    .DESCRIPTION
       To also remove the folder where the VM was residing this function also deletes the folder after moving the VM
       This function also helps you in creating a folder in the path if forgotten
    .EXAMPLE
       Move-VMStorage2 -VMName test -ComputerName HV02 -Path \\SMB-srv01\VMs\test
    .NOTES
    Author: Niklas Akerlund 20130226
    Version: 0.2
    #>
    function Move-VMStorage2
    {
        [CmdletBinding()]
        [OutputType([int])]
        Param
        (
            # A name of a VM
            [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=0)]
            $VMName,
            # The name of the Hyper-V host
            [Parameter(Mandatory=$false,
                       ValueFromPipelineByPropertyName=$true,
                       Position=1)]
            $ComputerName = "localhost",
            # The path where the VM is going to be relocated to.
             [Parameter(Mandatory=$true,
                       ValueFromPipelineByPropertyName=$true,
                       Position=2)]
            [string] $Path
        )
    
            # Lets move and tidy the source folder
            $VM = Get-VM $VMName -ComputerName $ComputerName
            # For some reason the path does not get refreshed when moving one VM several times in the same console that is why i do a select *
            $VMOldPath = Get-VM $VMName -ComputerName $ComputerName | select * -ExpandProperty Path 
                    
            if ($Path -notmatch $VM.VMName){
                $Path = $Path + "\" + $VM.VMName
                Move-VMStorage -VM $VM -DestinationStoragePath $Path
            }else{
                Move-VMStorage -VM $VM -DestinationStoragePath $Path
            }
            
            if (($VMOldPath.StartsWith("\\")) -and $VMOldPath -match $VM.VMName) {
               Remove-Item -Path $VMOldPath -Recurse -Force
            }elseif ($VMOldPath -match $VM.VMName){
                Invoke-Command -ComputerName $VM.ComputerName -ScriptBlock {Remove-Item -Path $Using:VMOldPath -Recurse -Force}
            }else{
                Write-Host "The VM :" $VM.VMName " was in the following path " $VMOldPath " Clean it manually!"
            }
            
    }