User Confirmation in Powershell

Built-in cmdlets usually offer the -Confirm parameter whenever you need user confirmation. When writing your own scripts, you might want to ask the eventual user of the script for confirmation yourself. This handy little function (store it in your profile!) allows you to ask for confirmation whenever, where-ever. (Try not to bug your users too much.)

Continue reading User Confirmation in Powershell

Translate Vml to LUN Path with Powershell

While checking the vmkernel logs on our VMware ESX Servers today, I ran into some errors referencing luns using a vml string. It looks something like this: vml.827149017315617. I would like to know what lun this error is referencing, but I prefer the LUN Path notation, e.g.: vmhba1:2:137. So I wrote this Powershell VI Toolkit function that can translate the vml into the lun path:

# Function: Translate a VML (e.g.: vml.9364839746917650) to a Lun Path (e.g.: vmhba1:2:137)
function Translate-VmlToLunPath
	Return (Get-VMHost $VMhostName | Get-ScsiLun | Where {$_.ConsoleDeviceName -match $Vml}).CanonicalName

Feed it a host name and a vml string and it will return the lun path. Here’s an example script that uses this function when looking for LUNs with SCSI Reservation Errors:

# Example use in a script: Get LUNs with SCSI Reservation Conflicts
$VIServerName = "myVIServer"
$NumLines = 1000
$VC = Connect-VIServer $VIServerName
ForEach ($VMHost in Get-VMHost)
	ForEach ($Log in ($VMHost | Get-Log -Key vmkernel -NumLines $NumLines))
		$MatchedEntries = $Log.Entries | Where {$_ -match "reservation" -and $_ -match "vml.\d*"}
		ForEach ($VmlId in $matches.values)
			$myObj = "" | Select VMHost, ErrorLun
			$myObj.VMHost = $VMHost.Name
			$myObj.ErrorLun = Translate-VmlToLunPath -VMHostName $VMHost.Name -Vml $VmlId
			Return $myObj
Disconnect-VIServer -Confirm:$False



Regular Expression Magic in Powershell

I have been looking at regular expressions in Windows Powershell recently. Although it seems very complex, the power of regular expressions (regex) is worth the effort! Think about server naming conventions for example. It’s easy for a human to recognise a server name that begins with a location code and contains a status (Development, Test, Acceptance or Production) amongst other things. RegEx allows you to learn Powershell to recognise the same things.

The attached script contains a function that finds matches for a regular expresion and converts the named matches to object properties. Sounds complex? Take a look at this example for server names:


If you can create the regular expression, this function does the matching and objectizing. It requires no modification at all for working with regular expressions that match other kinds of things, because you name the matching groups inside the regex definition. Cool stuff!

Obj-RegEx (Rename to .ps1)




Just having a bit of fun with Powershell:

48 6F 6C 64 20 66 61 73 74 20 74 6F 20 64 72 65 61 6D 73 A 46 6F 72 20 69 66 20 64 72 65 61 6D 73 20 64 69 65 A 4C 69 66 65 20 69 73 20 61 20 62 72 6F 6B 65 6E 2D 77 69 6E 67 65 64 20 62 69 72 64 A54 68 61 74 20 63 61 6E 6E 6F 74 20 66 6C 79 2E A 48 6F 6C 64 20 66 61 73 74 20 74 6F 20 64 72 65 61 6D 73 A 46 6F 72 20 77 68 65 6E 20 64 72 65 61 6D 73 20 67 6F A 4C 69 66 65 20 69 73 20 61 20 62 61 72 72 65 6E 20 66 69 65 6C 64 A 46 72 6F 7A 65 6E 20 77 69 74 68 20 73 6E 6F 77 2E 20 A A 2D 2D 4C 61 6E 67 73 74 6F 6E 20 48 75 67 68 65 73


From HEX to DEC and back

Why do computer nerds mix up Halloween and Christmas? Because 31 OCT = 25 DEC :)

I always mix up the commands used to convert integers to and from decimal, hexadecimal and octal in Powershell. That’s why I wrote these functions and put them in my profile:

# Description: Coverts a decimal into a hexadecimal

function Convert-DECtoHEX
ForEach ($value in $DEC)
“{0:x}” -f [Int]$value

# Description: Coverts a hexadecimal into a decimal

function Convert-HEXtoDEC
ForEach ($value in $HEX)

# Description: Coverts an octal into a decimal

function Convert-OCTtoDEC
ForEach ($value in $OCT)

Here are some example uses:

Compare ESX configurations with Powershell

One of the challenges in managing a large VMware Infrastructure is keeping all ESX Servers within a cluster equal. This is essential for having vmotion capabilities and therefore essential for a solid HA configuration. I have showed you earlier how to add the LUN Count for each ESX Server to your VI Client. This allows you to spot differences quickly. But finding exactly which datastores are missing on which ESX Server can be a bigger challenge.

Here are some small functions that can help you determine where the major differences are.

Comparing datastores:

function Compare-VMHostDatastores
$a = Get-VMHost $host1 | Get-Datastore | %{$_.Name}
$b = Get-VMHost $host2 | Get-Datastore | %{$_.Name}
Compare-Object $a $b

Compare-VMHostDatastores esxServer1 esxServer2

InputObject                         SideIndicator
———–                                ————-
esxServer1_Local             <=
esxServer2_Local             =>
DATASTORE_TEST1         =>

And comparing Port Groups:

function Compare-VMHostPortgroups
$a = Get-VirtualPortGroup (Get-VMHost $host1) | %{$_.Name}
$b = Get-VirtualPortGroup (Get-VMHost $host2) | %{$_.Name}
Compare-Object $a $b

Compare-VMHostPortgroups esxServer1 esxServer2

InputObject                SideIndicator
———–                      ————-
PortGroup_TEST     <=
Internal                       <=

Maybe you prefer to go the other way around and check to which ESX servers a specific datastore is attached?

function Get-DatastoreHosts
Get-VMHost -Datastore (Get-Datastore $datastore) | Sort Name | %{$_.Name}

PS D:Scripts> Get-DatastoreHosts DATASTORE_TEST1


Thank Microsoft for Powershell and the Compare-Object cmdlet!


Countdown to 2009

function CountDown
 While ((Get-Date).Year -lt 2009)
  Write-Host “COUNTDOWN TO 2009:”
  (Get-Date “1/1/2009 0:00″) – (Get-Date) | Format-Table Days, Hours, Minutes, Seconds -AutoSize
  Write-Host “Countdown brought to you by:”
  Write-Host “
  Start-Sleep -Seconds 1
 Write-Host “HAPPY NEW YEAR!”
 Write-Host “from Hugo at

Happy Holidays to all of you!

Powershell function to find event log explanations

Today I am attending the Dutch VMware User Group (VMUG) Meeting. No doubt I’ll return with lost of inspiration for new Powershell VI Toolkit scripts.
In the meantime, I will show you a nifty little function that will come in handy if you are troubleshooting Windows Server Event Log errors and / or warings. The usage is super-simple:

Find-Event EventID [Source]
For example: Find-Event 18056
Or: Find-Event 1 MSSQLServer

What it does? Give it a go (it’s harmless)… 😉

Here’s the code:

Continue reading Powershell function to find event log explanations

Handy little function: Create-Script

One of the great features of Windows Powershell is the combination of the rich scripting language and the interactive shell. I often find myself playing around in the interactive shell until I know how to get the information I need. Then I start to put the code into a script for easy use. (And to share it with you, of course.) And although the shell allows for copy/paste, I wouldn’t be much of a scripting enthusiast if I didn’t want that to be easier 😉
Enter Create-Script. This little function belongs in any scripter’s profile. It copies your entire history into a file and opens it for you. Just remove the obsolete lines and add formatting and comment and your script is as good as done!

function Create-Script
$ScriptFile = ‘D:\scripts\newscript.ps1′
Remove-Item $ScriptFile -Confirm
ForEach ($i in (Get-History -Count 999))
Add-Content $ScriptFile $i.CommandLine
Invoke-Item $ScriptFile

The function re-uses the same file each time, asking for confirmation to overwrite it. Don’t forget to use Save As… to store your finished work.

I can’t wait to see the masterpieces you will create. Don’t forget to share them!

PS: You might want to consider to increase the amount of commands kept in your history. Just set the $MaximumHistoryCount variable to the desired value.

Finding and Stopping VI Sessions with Powershell

If you have been trying out the VMware VI Toolkit for Windows Powershell, you have probably noticed. You have to disconnect (disconnect-viserver) each session you set up to the VI Server (connect-viserver), or it will linger for eternity (or until the next reboot at least). That’s why I always include a disconnect-viserver command at the end of my VI Toolkit scripts. But what happens in real life: when debugging a script, it hardly ever reaches the end of the script. It will stop at an error or be cancelled by me to fix some bug I notice. I regularly check the Sessions tab in my VI Client and terminate all my idle sessions to keep VI clean and fast. So why not automate that too? Here’s how:

function Get-Session
$Global:SI = Get-View ServiceInstance
$Global:SM = Get-View $SI.Content.SessionManager
Return $SM.SessionList

function Stop-Session
ForEach ($Session in $_)
If ($Session.Key -ne $SM.CurrentSession.Key)
$Key = $session.Key
Write-Host “Session $Key terminated.”
$Key = $null
Write-Warning “Cannot terminate current session.”

The function Get-Session lists the currently active sessions. You can then filter them as you do any collection of objects in Powershell and pipe them to Stop-Session to have them terminated. Note that VI Client sessions appear to create two actual sessions and that the API (and therefore my function) will not allow you to terminate the current session.

Get-Session | Where { ((Get-Date) – $_.LastActiveTime).TotalHours -ge 8 } | Stop-Session