Recommended hotfixes for Windows 2012 R2 failover clusters

April 27, 2016

there is no more the need to keep your own lists of clustering patches as this is now summarized in KB2920151. this includes the recommended Failover Cluster and as well the Hyper-V patches

Windows Server 2012 Failover Cluster patches are covered in KB2784261 and the recommended patches for Windows Server 2012 Hyper-V can be found here

worth to take a look at it to keep your clusters healthy, stay tuned

Powershell-3rd Party modules

April 27, 2016

there are several 3rd party Powershell modules available which enables you to manage your devices like F5 BIG or Cisco UCS with Powershell. just from my experience, the functions are limited but at least if offers you ability to automate basic reoccurring stuff like a.e. backup configuration and also a good starter to develop your own crazy stuff. here are 2 which I use currently and which I can recommend to take a look at


Cisco UCS Powertool

Around Cisco UCS you can also check out this site from joemar which provides lots of examples for management UCS centers

there are many more out there so please share any 3rd party modules you would recommended and I will add them to this list

Thanks and stay tuned Winking smile


KB3000850–November Rollup 2014

December 4, 2014

3000850 is a recommended rollup for failover clusters. beside few others a lot of fixes around Hyper-V and Clustering are included.

A cumulative update that includes the security updates and nonsecurity updates including Failover Clustering updates that were released between April 2014 and November 2014. Available from Windows Update and for individual download from Download Center. To apply this update, you must first install the update 2919355 on Windows Server 2012 R2.

Checkout the details here

Powershell-Generate Automated CSVFreespace and Memory Report

December 4, 2014

This script relies the Hyper-V clusters are been managed by VMM but if you do not use VMM you can also modify based on your environment. It should just give you an idea how to collect data and use sentmail function to get a daily report of your resource status.

Note: script version 1.3 is targeted to be run as a task so no console outputs are considered, just a logfile is written into same folder where is script is located

as no user interaction is possible because we want to use this as a task following variables has to be updated in the script

$smtpServer = "YOURSMTP"
$smtpFrom = ""
$SMTPPort = "25"
$Username = ""
$Password = ‘YOURPASSWORD’
$smtpTo =

#Creator: Ramazan Can
#V1.2 	- dumping into log and generating mail with function "SentReportviaMail"
#		- mail sender, recipient, account for authentification can be modified in function "SentReportviaMail"
# 				$smtpFrom - $Username - $smtpTo 
#V1.3	- task scheduler version

#Write-Host " "
import-module virtualmachinemanager
import-module failoverclusters
$VMMClusters=(Get-SCVMHostCluster -vmmserver $VMMServer).Name
$timestamp=(get-date -Format d).Replace("/","_")
Get-item ".\CSVandMemory_Report_$timestamp.txt" -ea 0 | Remove-Item -ea 0

"This Report was run at $date " | out-file -filepath $logfile -append
" " | out-file -filepath $logfile -append

function GetCSVFreeSpace {
#incorporated and modified from
$objs = @()

$csvs = Get-ClusterSharedVolume -Cluster $Cluster
foreach ( $csv in $csvs )
   $csvinfos = $csv | select -Property Name -ExpandProperty SharedVolumeInfo
   foreach ( $csvinfo in $csvinfos )
      $obj = New-Object PSObject -Property @{
         Name        = $csv.Name
         Path        = $csvinfo.FriendlyVolumeName
         Size        = $csvinfo.Partition.Size
         FreeSpace   = $csvinfo.Partition.FreeSpace
         UsedSpace   = $csvinfo.Partition.UsedSpace
         PercentFree = $csvinfo.Partition.PercentFree
      $objs += $obj

$objs | ft -auto Name,Path,@{ Label = "Size(GB)" ; Expression = { "{0:N2}" -f ($_.Size/1024/1024/1024) } },@{ Label = "FreeSpace(GB)" ; Expression = { "{0:N2}" -f ($_.FreeSpace/1024/1024/1024) } },@{ Label = "UsedSpace(GB)" ; Expression = { "{0:N2}" -f ($_.UsedSpace/1024/1024/1024) } },@{ Label = "PercentFree" ; Expression = { "{0:N2}" -f ($_.PercentFree) }}

function SentReportviaMail {
$logfile=(Get-item ".\CSVandMemory_Report*" -ea 0).Name
$Logs=Get-Content $logfile
$smtpServer = "YOURSMTP"
$smtpFrom = ""
$SMTPPort = "25"
$Username = ""
$Password = 'YOURPASSWORD'
$smtpTo = ""
$messageSubject = "$VMMServer - Automated CSV FreeSpace and Total Memory Report"

[string]$messagebody = ""

foreach ($log in $logs )
	$messagebody = $messagebody + $log + "`r`n"
#Write-Host " "
#Write-Host "Starting to sent mail to $smtpTo via $smtpServer ...." -ForegroundColor green
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
#Write-Host "mail sent completed " -ForegroundColor green
#Write-Host " "

foreach ($Cluster in $VMMClusters)
	#Write-Host "Starting to collect memory and CSV free space data in $Cluster ....." -foregroundcolor green
	[int]$TotalFreeMemory = 0;
	[int]$TotalMemory = 0;
	$ClusterNodes = Get-Cluster $Cluster | Get-ClusterNode
	foreach ($ClusterNode in $ClusterNodes)
		[int]$FreeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).FreePhysicalMemory / 1MB), 0)
		[int]$TotalFreeMemory = [int]$TotalFreeMemory + [int]$FreeMemory
		[int]$NodeMemory = [math]::round(((Get-WmiObject -ComputerName $ClusterNode -Class Win32_OperatingSystem).TotalVisibleMemorySize / 1MB), 0)
		[int]$TotalMemory = [int]$TotalMemory + [int]$NodeMemory


	$TotalAvailableMemory = $TotalFreeMemory - $NodeMemory
	"Cluster: $Cluster" | out-file -filepath $logfile -append
	"Total Memory: $TotalMemory" | out-file -filepath $logfile -append
	"Total Free Memory: $TotalFreeMemory" | out-file -filepath $logfile -append
	"Total Available Memory: $TotalAvailableMemory" | out-file -filepath $logfile -append
	" " | out-file -filepath $logfile -append
	"CSV Freespace : " | out-file -filepath $logfile -append
	GetCSVFreeSpace | out-file -filepath $logfile -append
	" " | out-file -filepath $logfile -append

example output mail:


Disclaimer: Please read, understand and test script before you run put in production! This should just give you an idea around the power of powershell and automation


best practices for running AV on SQL servers

September 25, 2014

Running Antivirus software is critical part of server security but it is also important to understand the impact and effect it has on SQL Server. here is some really good guidance on how to configure AV and exclusions.

1. SQL Server Data Files (files with extensions like .MDF, .NDF)
2. SQL Server Log Files (files with extensions like .LDF)
3. SQL Server Backup files (files with extensions like .BAK and .TRN)
4. Full-Text Catalog Files
5. SQL Server Audit Files
6. SQL Server Query Files (Extensions like .SQL)
7. Trace/Profiler Files (Extensions like .TRC)
8. Entire Directory that is holding Analysis Services files that is used for processing Cubes and used for queries that are reading files in to the data folder and the temp folder.
9. Folder where Analysis Services Backups Files Reside
10. Exclude SQLServer.Exe file (This is the main database engine file)
11. ReportingServicesService.Exe
12. MSMDSrv.exe
13. Cluster Directory (Usually it is C:\Windows\Cluster) *If your servers are clustered
14. Cluster Quorum Drive
15. FILETABLE and Filestream folders

Reference full article here

Powershell–How to monitor HP Smartarray disk status?

July 4, 2014

really a quick one and straight forward but sometimes very useful. here is a quick example how you can monitor your smartarray controller disk status and in case of “Failed” drive detected sent a mail out to you with the summary.

Of course, SCOM has also automated capabilities to monitor HP hardware components in a much more efficient way but that’s a another story

Prerequisites are:

– depends on your SA version – you need the “HP ProLiant Array Configuration Utility (CLI) for Windows” and can be found here, the user guide here

– if required, modify program path to hp array utility command line tool "C:\Program Files\HP\hpssacli\bin\hpssacli.exe"

– modify smtp settings $smtpServer, $smtpFrom, $SMTPPort, $Username, $Password and $smtpTo

– modify $localhost

– check if your controller is 0 “controller slot=0”

###Code Snippet###

Get-item ".\log.txt" -ea 0 | Remove-Item -ea 0

function CheckSmartArray {
Write-Host " "
Write-Host "Checking SmartArray on system"$localhost"" -foregroundcolor green
C:\Windows\System32\cmd.exe /c "C:\Program Files\HP\hpssacli\bin\hpssacli.exe" controller slot=0 physicaldrive all show

CheckSmartArray | out-file -filepath $logfile -append

function SentDiskDrivefailedviaMail {
$Logs=Get-Content $logfile
$smtpServer = ""
$smtpFrom = ""
$SMTPPort = "25"
$Username = ""
$Password = "passwordhere"
$smtpTo = ""
$messageSubject = "Disk Drive failed at $localhost"

[string]$messagebody = ""

foreach ($log in $logs )
    $messagebody = $messagebody + $log + "`r`n"
Write-Host "failed disk detected – starting to sent mail to $smtpTo via $smtpServer …." -ForegroundColor red
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
Write-Host "mail sent completed " -ForegroundColor green
Write-Host " "

#Check logfile if a "Failed" status can be found, if true send a mail with "SentDiskDrivefailedviaMail" function
[array]$logcontent=gc $logfile
foreach ($line in $logcontent) {
    if ($line -match "Failed") {
    Write-Host " "
    write-host "failed disk found at $localhost " -foregroundcolor red
    write-host "detailed logs can be found $logfile " -foregroundcolor red
    Write-Host " "

###Code Snippet###

Sample Output from smart array CLI utility “controller slot=0 physicaldrive all show”


Disclaimer: Please read and test script before you run in your production!

Powershell-How to easily verify patch level between computers

July 4, 2014

Compare patches between computers? Here is a quick and easy way how you can verify this with Powershell

$node1 = Get-HotFix -ComputerName SERVER1
$node2 = Get-HotFix -ComputerName SERVER2
Compare-Object -ReferenceObject $node1 -DifferenceObject $node2 -Property HotFixID

Example Output:

HotFixID                                                    SideIndicator
——–                                                    ————-
KB2862152                                                   =>
KB2876331                                                   =>
KB2884846                                                   <=
KB2892074                                                   <=
KB2894029                                                   =>

The Compare-Object cmdlet compares two sets of objects. One set of objects is the "reference set," and the other set is the "difference set."

The result of the comparison indicates whether a property value appeared only in the object from the reference set (indicated by the <= symbol), only in the object from the difference set (indicated by the => symbol) or, if the IncludeEqual parameter is specified, in both objects (indicated by the == symbol).

Compare-Object is really powerful, check it out

Powershell – How to get total VM memory overview (dynamic, static and startup memory) per node in a cluster?

June 16, 2014

Host Memory Pressure – I think this is one of the keys (in addition to storage, network, CPU) in performance when running virtualization with dynamic memory and should be monitored. An balance between high density of running VMs on a host and memory calculation/demand is something to consider when managing self service clouds and/or running memory intensive workloads.

Write-host " "
Write-Host " "
$Cluster = Read-Host "Cluster Name "
Write-Host " "
Write-Host "Starting to check VM Memory pressure on $Cluster nodes " -ForegroundColor green
Write-Host " "
Write-Host "Collecting data like nodes, VMs Memory….please be patient" -ForegroundColor green
Write-Host " "
Write-Host " "
$Hostnames=(Get-Cluster $Cluster | Get-ClusterNode).Name

foreach ($Host1 in $Hostnames) {
[int]$hostmem=@{} | Out-Null
[int]$totalstartupmem=@{} | Out-Null
[int]$totalmaxmem=@{} | Out-Null
[int]$staticmemory=@{} | Out-Null
[int]$overcommited=@{} | Out-Null
[int]$totalramrequired=@{} | Out-Null

$AllVMs=(get-vm -ComputerName $Host1).Name
$Hostmem=(Get-VMhost -ComputerName $Host1).MemoryCapacity / 1024 / 1024 / 1024

foreach ($VM in $AllVMs) {
$CurrentVM=(get-VM $VM -ComputerName "$Host1" | fl *)
if ((Get-VMMemory -vmname $VM -ComputerName "$Host1").DynamicMemoryEnabled -eq "True") {
$memorystartup=(get-vm $VM -ComputerName "$Host1" | select-object MemoryStartup).MemoryStartup /1024 / 1024 / 1024
$MemoryMaximum=(get-vm $VM -ComputerName "$Host1" | select-object MemoryMaximum).memorymaximum /1024 / 1024 / 1024
$totalstartupmem += $memorystartup
$totalmaxmem += $MemoryMaximum
else {
$static=(get-vm $VM -ComputerName "$Host1" | select-object MemoryStartup).MemoryStartup /1024 / 1024 / 1024
$staticmemory += $static
$totalramrequired=$totalstartupmem + $staticmemory

write-host "Summary Report for Host $Host1" -foregroundcolor green
write-host "Total Startupmem for Dynamic VMs $totalstartupmem GB " -foregroundcolor green
write-host "Total Staticmem for Static VMs $staticmemory GB " -foregroundcolor green
write-host "Total minimum RAM (Startup+Static) required $totalramrequired GB " -foregroundcolor yellow
write-host "Total Maxmem for Dynamic VMs $totalmaxmem GB " -foregroundcolor yellow
write-host "Total available memory $Hostmem GB " -foregroundcolor green
if ($totalmaxmem -gt $Hostmem) {Write-Host "$Host1 is overcomitted " -foregroundcolor red}
write-host " "
write-host " "


This is just one way to get a total summary per node in your Hyper-V cluster and their configured memory demand. It provides a quick view on memory utilization of your Hyper-V nodes. Be creative and modify based on your needs.

Disclaimer: Please read and test script before you run in your production!

Dynamic Memory Pressure Monitoring:

…a “bad” configuration can result in “bad” performance:-)

Stay tuned…

Failover Cluster – Recommended hotfixes and updates for Windows Server 2012 RTM and R2 based clusters

May 20, 2014

Checkout KB2920151 for getting a comprehensive list of the recommended hotfixes and updates for clusters based on Windows Server 2012 R2

+ Checkout Rollup Update June which includes several Hyper-V and Cluster relevant patches too.

Same exists for Windows 2012 RTM based clusters too

Also take a look at the Cluster-Aware Updating feature which is introduced in 2012 R2 –> Cluster-Aware Updating Overview 

….Stay tuned😉

How to configure Preferred Owners and AutoFailback with Powershell in Failover Cluster?

April 7, 2014

Consider scenario, you “balanced” your VMs across your nodes and you come back in the morning and they are migrated “for whatever reason” to different nodes. But as a typical administrator😉 you know your workload best and you want to keep them preferred on a targeted node. In case of an unexpected reboot the VMs will get migrated to next available node in your Failover Cluster and goal is as soon as the node is back the VM should automatically fail back = PreferredOwners. 

Here is a quick example where you configure all clustered VM roles in a targeted cluster for preferred owners based on the current owner node. this should only give you an idea how things can be automated very easily with Powershell:

$Cluster = Read-Host "Cluster Name "
$Praefix = Read-Host "Please provide präfix for your clustered VM role names (a.e.SCVMM) "
Write-Host " "
Write-Host "Getting all clustered VM roles and configure Preferred Owners in cluster $Cluster" -ForegroundColor yellow
Write-Host " "
Write-Host " "
$AllClusterGroup = Get-ClusterGroup -Cluster $Cluster -Name $Praefix*

Write-Host "….running loop for all Clustered VMs"
Write-Host " "
Write-Host " "
foreach ($ClusterGroup in $AllClusterGroup)
    $ClusterGroupDetails = Get-ClusterGroup -Name "$ClusterGroup"
    Write-Host "Getting current Owner for $ClusterGroup…." -ForegroundColor yellow
    $CurrentOwner = $ClusterGroupDetails.OwnerNode.Name

    Set-ClusterOwnerNode -Group $ClusterGroup $CurrentOwner
    Write-Host "Current owner for VM $ClusterGroup is $CurrentOwner, configure Preferred Owner…done" -ForegroundColor yellow
    #Enable Autofailback
    (Get-ClusterGroup -Name "$ClusterGroup").AutoFailbackType=1
    Write-Host "Enabling Autofailback VM $ClusterGroup…done" -ForegroundColor yellow
    Write-Host " "

Disclaimer: Please read and test script before you run in your production, this reconfigures the preferred owner property at all your clustered VM roles in your cluster !!

There are more options how you can control clustered roles, like “AntiAffinityClass” – when a group is moved during failover, anti-affinity affects the algorithm used to determine the destination node. a.e. never run together at same node…

Here are just a few more good resources around failover options in a Failover Cluster:

Preferred Owners in a Cluster

Failover behavior on clusters of three or more nodes

Understanding Hyper-V Virtual Machine (VM) Failover Policies

Modify the Failover Settings for a Clustered Service or Application

Configure Failover and Failback Settings for a Clustered Service or Application


Using Guest Clustering for High Availability


Get every new post delivered to your Inbox.

Join 54 other followers