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 = "yoursmtp.server.com"
$smtpFrom = "sender@yourdomain.com"
$SMTPPort = "25"
$Username = "user@yourdomain.com"
$Password = "passwordhere"
$smtpTo = "recipient@yourdomain.com"
$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

Its all about IOPS

September 16, 2013

Sharing some personal experience from previous benchmarks. Here are some general guidelines for determining the number of hard disk drives required for a given I/O load.

Generally, a single disk drive can do this many "physical" IOPS per disk:
15k rpm: 180-210 IOPS
10k rpm: 130-150 IOPS
7200 rpm: 80-100 IOPS
5400 rpm: 50-80 IOPS

In a mirrored configuration:
Disk IOPS = Read IOPS + (2 * Write IOPS)
In a parity (RAID5) configuration:
Disk IOPS = Read IOPS + (4 * Write IOPS)
Summary of the number of operations per RAID type:
RAID 1 and 1/0 require that two disks to be written for each host initiated write.
Total IO = host reads + 2 x host writes
RAID5 (4+1) requires 4 operations per host write = a RAID5 write requires 2 reads and 2 writes
Total IO = host reads + 4 x host writes

Personal Note on RAID5: as you can see here, RAID5 does need more writes compared to other RAID level. my personal opinion on RAID5 is, when you know your IO pattern from your application you can also go with RAID5 to get efficiency and same time a "good performance" when the majority of IO operations are reads and not writes. a typical scenario for RAID5 would be a.e. "Streaming Services" where mainly 100% large sequential reads does happen.

if you are interested more on characterization of IO pattern, the SQL Team has released an really good Whitepaper on this -> http://download.microsoft.com/download/B/E/1/BE1AABB3-6ED8-4…

Storage Top 10 Best Practices

SQL Server Best Practices Article

NT Server and Disk Subsystem Performance


VHD Performance

Windows 8 keyboard shortcuts

April 30, 2013

I’m typically a keyboard user and try to find short ways to my required actions.

The comprehensive list can be found here at the Windows Team Blog –> http://blogs.windows.com/windows/b/windowsexperience/p/win8_keyboard_shortcuts.aspx

End of Life – Support ends for Windows XP and Office 2003

April 12, 2013

On April 8, 2014, Microsoft will end support for the decade-old Windows XP and Office 2003. This means you will no longer receive updates, including security updates, for Windows XP from Microsoft.

Security Risk:

Without critical Windows XP security updates, your PC may become vulnerable to harmful viruses, spyware, and other malicious software which can steal or damage your business data and information. Anti-virus software will also not be able to fully protect you once Windows XP itself is unsupported.

Software and 3rd Party Issues:

Many software and hardware vendors will no longer support their products that are running on Windows XP as they are unable to get the Windows XP and Office 2003 updates. For example, the new Office leverages the modern Windows and will not run on Windows XP.

More details can be found here –> http://www.microsoft.com/en-us/windows/business/retiring-xp.aspx and http://www.microsoft.com/en-us/windows/endofsupport.aspx

SCVMM 2008 R2–Error 2912 – An internal error has occurred trying to contact an agent

March 20, 2013

I love the “unknown” error things but as all of us know you can NOT handle all error conditions within application coding. Therefore I would like to provide here an possible resolution which you need to confirm if it applies to your environment.

I faced this error and did some research and found out that this could also be related to BITS (Background Intelligent Transfer Service). BITS is being used excessively by VMM for file transfers.

Error (2912)
An internal error has occurred trying to contact an agent on the vmmmserver.yourdomain.com server.
(Unknown error (0×80041001))

Recommended Action
Ensure the agent is installed and running. Ensure the WS-Management service is installed and running, then restart the agent.

Possible fix:

import-module BitsTransfer
Get-BitsTransfer -AllUsers

Check for the output if you see any BITS jobs which are not owned by "NT AUTHORITY\SYSTEM" and have status "Suspended".

To delete the failed/corrupt BITS job you need to run:
import-module BitsTransfer
$AllJobs = Get-BitsTransfer -AllUsers
Remove-BitsTransfer -BitsJob $AllJobs

You will receive an "Access Denied" but this is ok as SYSTEM owned jobs cannot be deleted:

Remove-BitsTransfer : Access is denied. (Exception from HRESULT: 0×80070005 (E_ACCESSDENIED))


List of known issues for Background Intelligent Transfer Service (BITS)

How to deploy an “classic” terminal server with Windows 2012

March 18, 2013

Since Windows 2008 the “oldschool” and well known 2003 terminal services are extended on rich web services which provides now great new capabilities in designing and deploying built in terminal server services based on HTTP/HTTPS. in combination with RD Gateway the applications can also be securely published to WWW and session host server be isolated in non public facing network segments. all terminal services are now called Remote Desktop services shortly RD. 

To enable RD (Remote Desktop) services there are generally 2 ways, “Quickstart” and “Standard Deployment”. Also there 2 types of RD services available, Session Virtualization or VDI (Virtual Desktop Infrastructure). In this blog article I focus and deploy RDS for session virtualization which means hosting and publishing of terminal server applications.


Quickstart is straight forward and deploys you quickly the required services and configure an standard pool of applications mainly can be used for setting up a lab/demo environment:


Standard Deployment Step-by-Step Guide:




Depending on your deployment select in following steps the Connection Broker, Web Access and Session Host server. In a single server deployment you can specify your single server for all roles:


Finished !! Your 2012 TS is ready for deploying and publishing applications Winking smile

Now you need to create a “session collection” to specify users/groups who can access which host servers:







I do not allow “user profile disks”  but in case this is required, select “Enable” and set the required NTFS permissions on folder.


When session collection group is created you can start with configuration of the apps you want to publish.




Now you can access your new RD published applications via web, the link is https://servername/rdweb


The connection is based on SSL (HTTPS) but the certificate used is a automatically created self signed certificate which can be exchanged with a trusted certificate.

After logged in with your specified credentials from the “session collection” you will see the published RemoteApp applications:


here is a list of helpful articles to get more insights in RDS features:

How to enable SSO (single-sign-on) in RD Web Access with Windows 2012?

Publishing RemoteApps in Windows Server 2012

Virtual Desktop Infrastructure services with Windows Server 2012

Remote Desktop Services @ MSDN

Remote Desktop Services Overview – Windows 2012

What’s New in Remote Desktop Services 2012

Remote Desktop Services Team Blog

Test Lab Guide: Remote Desktop Services Session Virtualization Standard Deployment


Get every new post delivered to your Inbox.

Join 49 other followers