I live in Sweden and thus have Sweden as regional format setting and that did Powershell version 3 not like, at least not for the Get-WinEvent cmdlet 😛
Using powershell to change the format or culture is done with the following
Get-Culture
Set-Culture en-US
And when I open a new PowerShell Console I can see the messages for my Hyper-V events 🙂 not so good with the bug though..
Lets hope there is a bug fix soon, a bit embarrassing when some parts of the powershell console is not working in other regional settings besides en-US, are we in other parts of the world not that important or just an mistake by an developer, lets hope for the later..
A big thanks to Andreas Hultgren that was first to let me know about the bug 🙂
I have been trying to get some Events out of my test environment for some Hyper-V stuff.
What I have noticed when digging down into the Get-EventLog and Get-WinEvent I get different information
The Get-EventLog gives me information and message about the Windows Logs and there it works nicely as you can see
But when I try to get information from as in this case Hyper-V logs with Get-WinEvent I get no information in the fields LevelDisplayName and Messages?!
And in the Event Viewer you can see that the information is there:
Have IÂ misunderstood something how to get the Events in PowerShell or is there a bug in the system? In the old “Windows 2008 R2” I got the information correctly as you can see on this screendump, so the Get-WinEvent issue is related to Win 2012 version!
Â
It kind of sucks if I cannot search the messages for some data and collect that information, and what I can see it seems to be the same case for all application and services logs and I will not accept to have to go the Event Viewer GUI 🙂
After visiting a customer this friday we talked about their environment and the need to check that their cluster shared volumes in a Windows 2008 R2 SP1 Hyper-V cluster was healthy.
They have started to take host level backup but have not yet got the hardware VSS driver in place and when we checked the backup agent had got into a faulty state and locked the CSV volume in redirected access mode. When we restarted the backup agent  the status got back to online.
Aidian Finn has done a white paper about backup and CSV volumes which describes the redirection and what that can make for impact on the performance. But in short, the cluster node that is the owner will during the redirected access have sole write access to the CSV volume and that means that the other nodes in the cluster must send all storage trafic to that node.
Alan Renouf´s vCheck script is a really easy and good way to keep in a daily control  of your environment, it works for both a VMware vSphere environment and also for Hyper-V with SCVMM thanks to Jan Egil Ring. The best way is to configure it with scheduled tasks and to send a mail every morning.
What I have done is editing the Cluster Shared Volume check plugin to report the status also, as this can be quite important. It is just a minor addition to the plugin, I have also chosen to change so if you set it to 100 the CSV part will always be included in the report and not depending on a percentage space remaining.
I had a task in an assignment in a recent month about handling massive amounts of logs and did an article that was published on the PowerShell Magazine 🙂
The logs are quite unique but you can see some of the new powershell v3 features that I am using for analysis and calculations.
A customer found the bug that exists in the System Center Virtual Machine Managers function for setting a host in maintenance mode. The bug is that when you set a host in maintenance mode it will live migrate all VM´s to the next node in the cluster. This is kind of impractical when you for example want to patch the Hosts and you end up with the last host that is filled with in worst case all  VM´s on it and it takes longer time to live migrate them. The VMM bug should be fixed in the SC SP1 that is coming soon This of course depending on if you have enabled the Dynamic Optimization, that function helps you with the distribution but that will take some time before it runs.
He made a script for evacuating the host and distributing the VMs to the other nodes in the cluster. I have added a bit of logic that also set the host group to not allow dynamic optimization during the scripted evacuation.
The load balancing in my script is quite easy because right now the only thing I look at is the host memory and migrate the VM to the Host that has most memory left at the moment.
<#
.Synopsis
A function to evacuate a host in vmm and set it in maintence mode
.DESCRIPTION
This function migrates all your VM´s to other nodes in the cluster based on available Host memory
.EXAMPLE
Evacuate-SCVMHost -VMHost hyp02 -HostGroup DC01
.Notes
Niklas Akerlund/Lumagate 2012-11-25
#>
function Evacuate-SCVMHost
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# What VMHost you want to set to maintmode
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$VMHost,
# In what hostgroup the host resides
$HostGroup
)
# Get The cluster and disable the dynamic optimization during evac
$HostGroup = Get-SCVMHostGroup $HostGroup
$HostGroup | Get-SCDynamicOptimizationConfiguration | Set-SCDynamicOptimizationConfiguration -ManualMode
$VMHost = Get-VMHost $VMHost
# Evacuate the host
$VMs = $VMHost | Get-VM
foreach ($VM in $VMs){
# Find the most apropriate Host in cluster for each VM
$VMHostTarget = Get-SCVMHostCluster -VMHostGroup $HostGroup | Get-SCVMHost | where {$_.ComputerName -ne $VMHost.ComputerName} | Sort-Object AvailableMemory -Descending | Select-Object -First 1
Move-SCVirtualMachine -VM $VM -VMHost $VMHostTarget
}
# Set the host in maintmode
Disable-VMHost -VMHost $VMHost -MoveWithinCluster
# Enable dynamic optimization
$HostGroup | Get-SCDynamicOptimizationConfiguration | Set-SCDynamicOptimizationConfiguration -AutomaticMode
In this little screendump you can see for all my Hyper-V hosts what VM´s without a network connection, you can also easily change the -eq $null to a switch name and then get what VM´s are connected to that particular virtual switch on all your hosts
Inspired by Indiana Jones, I have made a little Powershell function to search cluster nodes for VM´s that has not been cluster enabled. If you create a VM in the Hyper-V manager or the Hyper-V powershell cmdlets, the VM is not highly available by default, even if you added it to a SMB share.
What do I do then, I only use one parameter and that is the cluster name, from this I get the HA – enabled VM´s and then check them for all VM´s registered on the hosts. After this I do a comparison and get a list of the VM´s objects that are not Cluster enabled, this can be pipelined to Add-VMToCluster cmdlet (an alias for Add-ClusterVirtualMachineRole) and you are home safe :-). Of course there might be situations where you want a VM to reside only on one cluster node and not be highly available, Guest Clustering is one case where this might be a reason to not add them to a cluster. And if the VM has the configuration and storage locally you wont be able to add it to the cluster anyway
I can easily with PowerShell get the VM´s that are already HA enabled, but with this command I do not get the other VM´s on the cluster nodes.
So if I want to get only the VM´s not cluster enabled, here is the function
<#
.Synopsis
This function search the hosts for VMs tha are not HA enabled
.DESCRIPTION
This function lets you find what VM´s that is running on your hosts and not activated on the virtual machine role on the cluster
.EXAMPLE
Get-VMNotInCluster -Cluster HVCL30
.Link
vniklas.djungeln.se
.Notes
Author: Niklas Akerlund /20121004
#>
function Get-VMNotInCluster
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# Name of the Cluster
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$Cluster
)
Process
{
$ClusterNodes = Get-ClusterNode -Cluster $Cluster
$VMsInCluster = Get-VM -ClusterObject (Get-ClusterResource -Cluster $Cluster | where ResourceType -eq "Virtual Machine")
$VMsTotal = Get-VM -ComputerName (Get-ClusterNode -Cluster $Cluster).Name
$VMsNotInCluster =@()
foreach ($VM in $VMsTotal){
if($VMsInCluster -notcontains $VM){
$VMsNotInCluster += $VM
}
}
$VMsNotInCluster
}
}
And here is a screendump of it running
And here is when I enable so that all VM´s are Highly Available
Now I do not have so many VM´s in my test environment but in a production environment maybe you can see the potential of knowing that all VM´s on all Clustered nodes are made HA enabled.
To convert an vhd disk file to vhdx superduper format with PowerShell you just use the cmdlet Convert-VHD (this work only on hyper-v enabled machines). I read Virtual PC Guys post about how to do it in the GUI and wanted to make a small post about how to do it in powershell
I have tested a bit with the WinServ first in the early version 8 and then RC and now RTM, and what I thought was a bug that MS would fix before RTM seems to be still there.
What am I talking about then, well when you do a live or cold storage migration of a VM from for example your local storage to a SMB share either with the gui or preferebly with PowerShell, the built-in function leaves folders behind. And you can see where this is leading when moving a lot of VM´s, several VM´s folders retain with nothing inside and causing confusion!
As you can see on the screendump, the VM 2012 has been moved to another place but the folder still resides with no data in it, the subfolders are there but no disk files. And of course if I use the parameter -RetainVhdCopiesOnSource the folders should stay and also the configuration, vhd files 🙂
So I have done a modified Move-VMStorage function that actually removes the source folder also after moving the VM.
Here is the powershell function and a screendump how it actually deletes the folder also, And as you can see, I check if the VM resides on a share or locally on a hyper-v host and then I use Invoke-Command to delete the folder on the host´s local volume. The script can run on any machine that has RSAT-Hyper-V Powershell tools installed and with an account that has rights to delete folders on the shares/hosts.
<#
.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
.EXAMPLE
Move-VMStorage2 -VM test -ComputerName HV02 -Path \\SMB-srv01\VMs\test
.NOTES
Author: Niklas Akerlund 20120926
#>
function Move-VMStorage2
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# A name of a VM or a VM object
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$VM,
# The name of the Hyper-V host
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
$ComputerName,
# The path where the VM is going to be relocated to.
[string]
$Path
)
# Lets move and tidy the source folder
$VM = Get-VM $VM -ComputerName $ComputerName
Move-VMStorage -VM $VM -DestinationStoragePath $Path
$VMOldPath = $VM.Path
if ($VMOldPath.StartsWith("\\")) {
Remove-Item -Path $VMOldPath -Recurse -Force
}else{
Invoke-Command -ComputerName $VM.ComputerName -ScriptBlock {Remove-Item -Path $Using:VMOldPath -Recurse -Force}
}
}
Make sure that you always add the VM´s name to the path otherwise you will put the VM´s folders and files in the SMB folder directly and that will cause a mess and when you run my function it will try to clean that folder and all subfolders wich means all VM´s not running in that folder. Maybe I will add the control that It checks that the path to delete includes the VM name in a future update 😛
Today I have tested to set up VM monitoring and see how it works.
Kristian Nese has made a blog post about it, I wanted to do a bit more in Powershell, He also points out that it might in some scenarios not be so good to activate this on a VM that have multiple roles and I must agree in that. Another thing to say again is, this can only be done on Windows 2012 VM´s and they haft to either be in the same domain as the failover-cluster or in a trusted domain and also the cluster nodes must be able to connect to the VM over the network.
First for the cluster to be able to see the services that can be monitored I have to allow that in the VM´s firewall, I will also enable Remote Service Management to communicate so I can remotely check services with powershell.
And then I can do some magic in the powershell console to set up the VM monitoring, I use the -OverrideServiceRecoveryActions parameter so the VM monitoring will trigger first no matter what the service is configured to do in the recovery settings.
To test this I want to kill the service and for that I can use the Stop-Process, this can not be used in a cmdlet remote so I have to use remoting again so with the Invoke-Command I get the process and kill it 🙂
In this example I have used a third party open source software to show that the monitoring not only just works with Microsoft services. It is as I said in the beginning useful in the right circumstance.