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.)
Posts Tagged ‘function’
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 { param( [string]$VMHostName, [string]$Vml ) 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
Enjoy!
Hugo
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!
Enjoy!
Hugo
Puzzle
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
Solution:
convert-texttohexandback
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
{
param($DEC)
ForEach ($value in $DEC)
{
“{0:x}” -f [Int]$value
}
}
# Description: Coverts a hexadecimal into a decimal
function Convert-HEXtoDEC
{
param($HEX)
ForEach ($value in $HEX)
{
[Convert]::ToInt32($value,16)
}
}
# Description: Coverts an octal into a decimal
function Convert-OCTtoDEC
{
param($OCT)
ForEach ($value in $OCT)
{
[Convert]::ToInt32($value,8)
}
}
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
{
param([string]$host1,[string]$host2)
$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
{
param([string]$host1,[string]$host2)
$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
{
param([string]$datastore)
Get-VMHost -Datastore (Get-Datastore $datastore) | Sort Name | %{$_.Name}
}
PS D:Scripts> Get-DatastoreHosts DATASTORE_TEST1
esxServer2
esxServer3
Thank Microsoft for Powershell and the Compare-Object cmdlet!
Hugo
Countdown to 2009
function CountDown
{
While ((Get-Date).Year -lt 2009)
{
Clear-Host
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 “http://www.peetersonline.nl”
Start-Sleep -Seconds 1
}
Clear-Host
Write-Host “HAPPY NEW YEAR!”
Write-Host “from Hugo at http://www.peetersonline.nl”
}
CountDown
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:
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!
Hugo
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
{
Process
{
ForEach ($Session in $_)
{
If ($Session.Key -ne $SM.CurrentSession.Key)
{
$Key = $session.Key
$SM.TerminateSession($Key)
Write-Host “Session $Key terminated.”
$Key = $null
}
Else
{
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.
Example:
Get-Session | Where { ((Get-Date) – $_.LastActiveTime).TotalHours -ge 8 } | Stop-Session
Enjoy!


