Lets remove some VM´s with PowerShell on Hyper-V 3 in Windows 2012

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

The PowerCLI command is

Get-VM | %{Stop-VM $_ -Confirm:$false; Remove-VM $_ -DeletePermanently -Confirm:$false

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

Get-VM testvm* | %{ Stop-VM -VM $_ -Force; Remove-VM -vm $_ -Force ; Remove-Item -Path $_.Path -Recurse -Force}

And see in my VM´s folder how tidy and neat it is 😛

And as I started to describe in the top .. If you just use Get-VM | …  you will clean your Hyper-V host quick 🙂

PowerCLI installed on Windows2012 and working in PS Webaccess

Today my adventures continues, I had to test and install the PowerCLI on a Windows 2012 RC to see if it works and also if it could be used in the new Windows 2012 feature PowerShell Webaccess.

In an earlier post I showed how to configure the PowerShell Webaccess, then I was not successful to run the PowerCLI, the difference here is that I now installed the PowerCLI on the Win 2012 server.

To be able to install i had to enable the .net 2.0 (why the PowerCLI is built on that version is another discussion we will not go into here), as you can see on the dialog I had to enable that

Ok, and that should be done with PowerShell or? My server did not have an active Internet connection so I got a failure when trying to enable the .Net Framework, I had to use the Dism tool with the install media to get the .Net installed as it otherwise downloads the files necessary from MS.

dism /online /enable-feature /featurename:NetFx3 /all /source:D:\sources\sxs

When this is enabled then there was no problem installing the PowerCLI and when installed I can use for example the V3 functions Get-VM | where powerstate -eq “PoweredOn” <- notice I am not using any curly brackets and $_

Now to the Webaccess, I connect to the site https://pstest.vniklas.com/pswa and log on with an authorized account. After that I run Add-PSSnapin VMware.VimAutomation.Core to enable the PowerCLI functionality . Then i need to get the credential before connecting to the vCenter because the pswa could not show the promt for credential.

But that is easily fixed by using $cred = Get-Credential and then Connect-VIServer vc.vniklas.com -Credential $cred 🙂 and as you can see I can now connect and use the PowerCLI in a web browser.

May the PowerCLI be with you!

Using Powershell v3 Workflow with HyperV deployment

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.

# Inparallel.ps1
#
# Niklas Akerlund
# 2012-06-03

workflow create-VMs
{
    $VMRefDisk = "C:\VMs\master.vhdx"
    $VMNetwork = "Intern"
    $VMBaseLocation = "C:\VMs"
    $VMMemory = 384MB
    foreach -parallel ($item in 1..5) {
          
        $VMName = "TestVM$item"    
        $VMLocation = New-Item -Path "$VMBaseLocation\$VMName" -ItemType Directory -Force
        $VMDiskLocation = New-Item -Path "$VMLocation\Virtual Hard Disks" -ItemType Directory -Force
        $VMDisk01 = New-VHD –Path $VMDiskLocation\$VMName-OSDisk.vhdx -Differencing –ParentPath $VMRefDisk 
  
        New-VM –Name $VMname –MemoryStartupBytes $VMMemory –VHDPath $VMDisk01.path -SwitchName $VMNetwork -Path $VMBaseLocation
   
        Set-VM -VMName $VMName -DynamicMemory

        Start-VM -VMName $VMName
    }
    Get-VM TestVM*
}

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 😛

Upgrading my Win8 beta server to Windows 2012

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 🙂

VMware vSwitch ports massage with PowerCLI

This week I have been teaching my first vSphere 5 ICM, I have been trying to show the students the wonderful world of PowerCLI and all good you can do with it.

When we got to the virtual networking I tested if I could add a switch with any number of ports

get-vmhost esxi01* | New-VirtualSwitch -Name TestNumPorts -NumPorts 12 -Nic vmnic0

When I try to add 12 ports with the -NumPorts parameter, powerCLI tells me that my switch has been created with 16 ports, but look here in my vSphere Client screen dump

hmm smells like a bug? or ?

Well now I wanted to test if I could add more than 4 VM´s and connect them and then start them, first I have to create a Portgroup that i can connect and then a nice for loop to create 10 VM´s

get-vmhost esxi01* | Get-VirtualSwitch -Name TestNumPorts | New-VirtualPortGroup -Name Test

for ($i=1;$i -le 10;$i++){New-VM -VMHost (Get-VMHost esxi01*) -Name ("VM01" + $i) -Datastore (Get-Datastore delad02) -NetworkName Test}

The last  oneliner creates a standard VM with 256 MB ram and a 4 GB vmdk disk, and then I want to start them to actually connect them to the network I created to see if anyone of them does not get connected.

So to get them connected I start them

And check the last command where we can see that my number of available ports has not decremented?

Here you can see in the vSphere client that all my new VM´s are connected to the Test portgroup

In this screenshot you can see why my vSwitch got 16 ports (as 8 are allocated by the vmkernel) and the options are 8/24/56/120/248/504/1016 and so on, but still it does not explan why the powercli does not show that i have used 10 of the ports, or?

To see maybe what causing this I changed the number of ports to one of the “allowed” and when I changed the number to 16 ports, directly my free ports changed to 4, but I have 10 machines + 8 reserved?

The following powerCLI command shows the VM´s and if they are connected if you do not believe the gui 😉

Get-VM VM01* | Get-NetworkAdapter | select parent, connectionstate

 

The conclusion is that I have no answer if this is as it should be or if it is a bug, maybe someone out there could clarify 🙂

Now time to prepare for tomorrow and the modules in the course 🙂

Shrink HyperV virtual hard disk Win8 / Win2012 with PowerShell

I read this post by Ben (Virtual PC Guy) Armstrong about shrinking a virtual hard disk and thought this should be done with powershell.

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

# vNiklas Masterblaster shrink
#
# Niklas Akerlund / 2012-05-13

$VM = "Shrink8"

$cim = New-CimSession $VM

$partitionC = Get-Partition -CimSession $cim -DriveLetter C

$newSize = ($partitionC | Get-PartitionSupportedSize).SizeMin*1.20

Resize-Partition -PartitionNumber $partitionC.PartitionNumber -DiskNumber $partitionC.DiskNumber -Size $newSize -CimSession $cim

Get-Volume C -CimSession $cim

$VM = Get-VM $VM

Stop-VM $VM

$hdd = $VM | Get-VMHardDiskDrive

Resize-VHD -Path $hdd.Path -ToMinimumSize

Start-VM $VM

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 🙂

 

Bare metal deploy with SCVMM 2012 fail with error 800b0109 in WinPE

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”

Import-Module "C:\Program Files\Microsoft System Center 2012\Virtual Machine Manager\bin\psModules\virtualmachinemanager\virtualmachinemanager.psd1"
Get-SCVMMServer localhost
$mountdir = "E:\mount"

$winpeimage = "E:\temp\custom_winpe.wim"

$winpeimagetemp = $winpeimage + ".tmp"

mkdir "E:\mount"

copy $winpeimage $winpeimagetemp

dism /mount-wim /wimfile:$winpeimagetemp /index:1 /mountdir:$mountdir

$path = "E:\temp\drivers\be2nd62.inf" # $driver.sharepath
dism /image:$mountdir /add-driver /driver:$path

Dism /Unmount-Wim /MountDir:$mountdir /Commit

publish-scwindowspe -path $winpeimagetemp

Here is a link to the technet forum where I found another guy having the same issue, whom I helped.

After updating the WinPE we tried to do a new bare metal deploy and this time we had no issues with the certificate.

 

PowerCLI report on datastores, overprovision and number of powered on VM´s

Today I had an reason for running PowerCLI again, the case was to get an quick report on the datastores at a customer, I have made a post about the one-liner that get the number of running VM´s on a datastore. As i described in that post, if your SAN does not support VAAI then you do not want to many VM´s on each datastore because of the SCSI-locking that can occur. This is just an extension of that because we also wanted to check how overprovisioned the datastores was (when using thin provisioning there is a risk that you will fill your datastores as the VM´s fill their vmdk disk´s)

The PowerCLI code looks like this

Get-Datastore | Select Name,@{N="TotalSpaceGB";E={[Math]::Round(($_.ExtensionData.Summary.Capacity)/1GB,0)}},@{N="UsedSpaceGB";E={[Math]::Round(($_.ExtensionData.Summary.Capacity - $_.ExtensionData.Summary.FreeSpace)/1GB,0)}}, @{N="ProvisionedSpaceGB";E={[Math]::Round(($_.ExtensionData.Summary.Capacity - $_.ExtensionData.Summary.FreeSpace + $_.ExtensionData.Summary.Uncommitted)/1GB,0)}},@{N="NumVM";E={@($_ | Get-VM | where {$_.PowerState -eq "PoweredOn"}).Count}} | Sort Name | Export-Csv -Path C:\temp\vmds-datastore.csv -NoTypeInformation -UseCulture

And this is when i have run it on my test system, the difference here is that i removed the Export-CSV to get the output in the console

And here is a simple excel report

 

VMware vCloud Director vApp and DRS cluster affinity with PowerCLI

To fully utilize the performance in a vApp in vCloud Director I got the task to create an affinity rule based on the VMs in the vApp. This can be the case for example when you have VMs in an vApp that exchange high loads of data. In our case we have virtual ESXi Servers that have a vsa for shared storage and need good performance when deploying VM´s and storage vMotion etc.

When deploying several vApps from the same template it is not just to run Get-CIVM and then use the VM name returned to run Get-VM for the correlation between the VM in VCD and in vCenter, as you can see in the screendumps these two have the same name but followed with an identifier from vCD in the vSphere Client. This is also described in the vSphere blog.

The fine part is that the MoRef is unique (in the relation one vcd <-> one vcenter) so I can check on that which VMs in the vCenter belongs to the same vCloud Director vApp.

I got the code for the MoRef in this community post.

And here is my script

<#
.Synopsis
   Add an affinity rule for a vCloud Director vAPP
.DESCRIPTION
   This function takes a vApp as parameter and creates an affinity rule for them to keep them together
.EXAMPLE
   Add-CIVAppAffinity -CIVApp Green01
.NOTES
Author: Niklas Akerlund / RTS
Date: 2012-05-03
#>
function Add-CIVAppAffinity
{
    Param
    (
        # Parameter for the vAPP
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        $CIVApp,

        # If the rule should apply on a different cluster
        $Cluster = "vCD-Cluster"
    )

	$pod = Get-CIVapp $CIVApp
	if ($pod){
		$PodVMs = Get-CIVM -VApp $pod
		$VMs = @()
		$Cluster = Get-Cluster $Cluster
		Foreach ($PodVM in $PodVMs) { 
			$VMname = $PodVM.Name + "*"
			$VM =  Get-VM $VMname | where {$_.ExtensionData.MoRef.Value -eq $PodVM.ExtensionData.VCloudExtension[0].Any[0].VmVimObjectRef.MoRef}
			$VMs +=$VM
		}

		if (!(Get-DrsRule -Cluster $Cluster -Name $pod.Name -ErrorAction SilentlyContinue)){ 
			New-DrsRule -Name $pod.Name -Cluster $Cluster -KeepTogether $true -VM $VMs
		}else{
			Remove-DrsRule -Rule (Get-DrsRule -Cluster $Cluster -Name $pod.Name) -Confirm:$false
			New-DrsRule -Name $pod.Name -Cluster $Cluster -KeepTogether $true -VM $VMs
		}
	}
}

And when checking the cluster i can see that my DRS affinity rule has been created and the VMs have been migrated to the same host

It is not so extensive but it helps us with the case to create DRS affinity on the VMs in a particular vApp 🙂 , The Rule is deleted when the vApp is removed, I have an extra check in the script and remove it if it still exist of some reason.

 

Upgrade SCVMM 2012 RC to RTM

Today I wanted to upgrade my test environment from SC VMM 2012 RC to RTM, as it clearly says in the documentation, this is not supported (unless you are a TAP customer). But do not shout out in anger just until you read the forum, cause you can actually get the db upgrade util even if you weren’t in the TAP program.

Now I was one of the lucky to be in the TAP program so I could download the upgrade binary. First I had to uninstall the VMM Server and the Console, not to forget was to retain the database data (otherwise an upgrade would kind of be meaningless)

When the uninstall was complete, start an elevated prompt and run the tool, if you run UpgradeVMM2012RC.exe /?  you can see what different parameters you can use.

Now I could continue with the installation, but next little problem was to reconnect the old library (my library was not on the default path) so if would choose the existing I would not get my Library correct and I could not change that either in the installation wizard, I selected create a new and got the following error:

This was solved by going to the actual folder and deselect share, without restarting the installation i could continue

Then I was finished installing and the only thing left was to update the VMM agents on the hosts, some people had problems with the need to remove the agent manually but my update was successful

So now I am running the RTM version of SC VMM 2012 🙂