Search This Blog

Wednesday, March 16, 2011

An Explanation of Storage I/O Control vs. Storage Adapter Load Balancing

During a recent conversation I was stumped when asked what's the difference between VMware Storage I/O and Round Robin Multipathing.
  1. Storage I/O balances storage resources among VM's according to allocated shares per VM when contention exists for storage resources.Therefore, storage I/O's are prioritized based on VM share level and balances the available storage I/O's among VM's on an Storage I/O enabled disk volume. This feature is a solution to storage resource contention among VM's sharing the same datastore.

  2. Round Robin Multpathing alternates paths between the ESXi/ESX host and the datastore upon exceeding a specified threshold of I/O blocks. It continues to do this and ping-pong back and forth as well as provide fail over should one the used path become unavailable. This method is a solution to path availability and congestion.
Both can be described, or debated, as a method of load balancing but each are solutions to different problems. For Multipath, check your SAN vendor before enabling because the wrong MP policy can cause thrashing on the SAN.

Enabling Storage I/O or multipathing is easy. From the ESX/ESXi host or datacenter, RIGHT-CLICK the storage, choose properties, the select ENABLED uner the Storage I/O Control.


To enable Multipath, click the MANAGE PATHS button lower right and you get the following window:

Thursday, January 20, 2011

Get-Objects.ps1 Recursively Retrieves Object Properties

Here's my holy grail of Powershell and Powercli scripts to recursively get objects. In the past I've used Format-Custom and Select-Object * such as this:
$object| Format-Custom
or
$object | Select *

But that doesn't work for me. I wanted to get the object properties AND the properties of the properties recursively like this:

(Get-Process textpad) | .\Get-Objects.ps1 -Depth 1

I want to get you to the script, so the output to the example above is below.

Hence, Get-Objects.ps1 below:

param($Object = $null, [byte]$Depth = 3 , $Verbose=$False)

Process {
$Description ="This Script recursively returns an array of objects showing properties of an object."
$i = 1

Function GetList ($Object, $PreviousLabel ){
if($Object ){
#Get Property List excluding object methods
$PropertyList = $Object | Get-Member -Membertype Properties
$PreviousLabel = $PreviousLabel + "[.]"

#Return/Print Label and Object
$ErrorActionPreference = "silentlycontinue"
if($Verbose) { write-host "Depth: $i of $Depth - $PreviousLabel " -fore yellow}

"Depth $i of $Depth - " + $PreviousLabel+"[.]"+$Label
$Object | select *

#Proceed if iteration less than $Depth
if (($I+1) -LE $Depth ) {
#Increment Iteration $I
$i++
if ($PropertyList ) {
#Recursively GetList for Each Properties
foreach ($Property in $PropertyList ) {
#Get Property Name
$n = $Property.name
#Get object from PropertyList.Property
$obj = $object.$n
#GetList again (recurse)
GetList -Object $obj -PreviousLabel ($PreviousLabel + $n )
}
}
}
}else{
##Show Script Syntax if
if ($i -LE 1) {
Write-Host "
SYNOPSIS:
" ($Description | Out-String -Width 30) "

PARAMETERS
-Depth Default = $Depth. Sets the recursive depth level.
-Object Any process, variable, or object that has a property.
Any object without a property will not be displayed.
-Verbose Defaults to `$FALSE. -Verbose `$True writes progress to screen

SYNTAX
" (Get-help $$) "

SYNTAX EXAMPLES:
----------------------- EXAMPLE 1 -----------------------
`$AnyVariableOrObject | $$ -Depth 2

----------------------- EXAMPLE 2 -----------------------
$$ -Depth 2 `-Object `$AnyVariableOrObject


"
}
}
}

#Recursively get object from passed objects
if ($object){
GetList -Object $Object
} else {
GetList -Object $_
}
}




Copy the script above to a text file, save as Get-Objects.ps1 and have fun!



Output Example:

Depth 1 of 1 - [.]System.Diagnostics.Process
__NounName : Process
Name : TextPad
Handles : 152
VM : 88981504
WS : 9117696
PM : 7483392
NPM : 12608
Path : C:\tools\textpad\TextPad.exe
Company : Helios Software Solutions
CPU : 6.2868403
FileVersion : 5.2.0
ProductVersion : 5.2.0
Description : TextPad
Product : TextPad
Id : 6248
PriorityClass : BelowNormal
HandleCount : 152
WorkingSet : 9117696
PagedMemorySize : 7483392
PrivateMemorySize : 7483392
VirtualMemorySize : 88981504
TotalProcessorTime : 00:00:06.2868403
BasePriority : 6
ExitCode :
HasExited : False
ExitTime :
Handle : 1956
MachineName : .
MainWindowHandle : 0
MainWindowTitle :
MainModule : System.Diagnostics.ProcessModule (TextPad.exe)
MaxWorkingSet : 1413120
MinWorkingSet : 204800
Modules : {System.Diagnostics.ProcessModule (TextPad.exe), System.Diagnostics.Pr
ocessModule (ntdll.dll), System.Diagnostics.ProcessModule (wow64.dll),
System.Diagnostics.ProcessModule (wow64win.dll)...}
NonpagedSystemMemorySize : 12608
NonpagedSystemMemorySize64 : 12608
PagedMemorySize64 : 7483392
PagedSystemMemorySize : 143672
PagedSystemMemorySize64 : 143672
PeakPagedMemorySize : 7565312
PeakPagedMemorySize64 : 7565312
PeakWorkingSet : 13725696
PeakWorkingSet64 : 13725696
PeakVirtualMemorySize : 88985600
PeakVirtualMemorySize64 : 88985600
PriorityBoostEnabled : True
PrivateMemorySize64 : 7483392
PrivilegedProcessorTime : 00:00:01.3572087
ProcessName : TextPad
ProcessorAffinity : 255
Responding : True
SessionId : 0
StartInfo : System.Diagnostics.ProcessStartInfo
StartTime : 1/14/2011 5:15:03 PM
SynchronizingObject :
Threads : {5768, 6432, 1816}
UserProcessorTime : 00:00:04.9296316
VirtualMemorySize64 : 88981504
EnableRaisingEvents : False
StandardInput :
StandardOutput :
StandardError :
WorkingSet64 : 9117696
Site :
Container :

Tuesday, December 14, 2010

PowerShell One-liner to get IP address to hostname

Well, not really.

You could do this:
[System.Net.Dns]::GetHostAddresses("google.com")

Or create a script to help out little bit:

GetIP.ps1
param ($names  )

process {

if ($_ ) { $list = $_ }
if ($names ) { $list = $names  }



foreach ( $h in ( $list  ) )
{
    $row="" | select Name, IP;
    $i = [System.Net.Dns]::GetHostAddresses($h)  | ? { $_.AddressFamily -eq "Internetwork" } | % {$_.IpAddressToString }
    $row.Name = $h ;
    $row.IP = $i;
    if ($i) {
        $row ;
    }
    rv h, i
}

}


Wednesday, December 8, 2010

Powershell Script to Get Windows Product Keys

The following script was adapted (credits embedded) for the Powershell and POWERCLI VMware vSphere environment to retrieve Windows Product Key. Primarily, error handling was added for connection and permission failures.

"Caption" is used to store the error. It would probably neater to store the error in .Error, but oh well.





param ($Computernames = ".")

function Get-WindowsKey {
## function to retrieve the Windows Product Key from any PC
## adapted from Jakob Bindslet (jakob@bindslet.dk)
param ($targets = ".")
$obj = New-Object Object

$hklm = 2147483650
$regValue = "DigitalProductId"


Foreach ($target in $targets) {
$regPath2000_2003 = "Software\Microsoft\Windows NT\CurrentVersion"
$regPath = "Software\Microsoft\Windows NT\CurrentVersion\DefaultProductKey"
$caption = "$Target retrieving..."

#check target if online
If ((test-connection $Target -Count 1 -Quiet) -eq $False){
$caption = "[ERROR] $Target (NO PING)"
write-host $caption -Foregroundcolor Yellow

$obj = New-Object Object
$obj | Add-Member Noteproperty Computer -value $target
$obj | Add-Member Noteproperty Caption -value $caption
$obj

}else {
$productKey = $null
$win32os = $null
$win32os = Get-WmiObject Win32_OperatingSystem -computer $target -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
trap {
$win32os = $null
Continue
}

#check if target cann connect
If ($win32os -eq $null){
$caption = "[ERROR] $Target (ACCESS DENIED)"
write-host $caption -Foregroundcolor RED

$obj = New-Object Object
$obj | Add-Member Noteproperty Computer -value $target
$obj | Add-Member Noteproperty Caption -value $caption
$obj

}else{
write-host $caption -ForeGroundColor Green
$caption = ""
$wmi = [WMIClass]"\\$target\root\default:stdRegProv"
if ($win32os.Caption -NotMatch "2008" -AND $win32os.Caption -NotMatch "Windows 7") {
$regPath = $regPath2000_2003
#$win32os.Caption
}
$data = $wmi.GetBinaryValue($hklm,$regPath,$regValue)
$binArray = ($data.uValue)[52..66]
$charsArray = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9"
## decrypt base24 encoded binary data
For ($i = 24; $i -ge 0; $i--) {
$k = 0
For ($j = 14; $j -ge 0; $j--) {
$k = $k * 256 -bxor $binArray[$j]
$binArray[$j] = [math]::truncate($k / 24)
$k = $k % 24
}
$productKey = $charsArray[$k] + $productKey
If (($i % 5 -eq 0) -and ($i -ne 0)) { $productKey = "-" + $productKey }
} ## For $i
} #end if else

$obj = New-Object Object
$obj | Add-Member Noteproperty Computer -value $target
$obj | Add-Member Noteproperty Caption -value ($win32os.Caption + $caption )
$obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion
$obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture
$obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber
$obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser
$obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber
$obj | Add-Member Noteproperty ProductKey -value $productkey
$obj
} ##check target if online


}#End foreach
} #end Function Get-WindowsKey


Get-WindowsKey $Computernames








Tuesday, November 23, 2010

PowerCLI Gets Resource Limits of VM.

Here is a PowerCLI script for getting VM resources. Get-View is used because it is many times faster than using Get-VM. Post comments if you have questions or improvements.

param ($ShowAll)

write-host "#Gets Resource Limits of VM's. –Showall Parameter can be used to remove filter."

$vmset = Get-view -ViewType VirtualMachine

if ($ShowAll ){ Write-Host "#Show all VM's"

}else{ #filter

write-host "#Use ""-ShowAll True "" to show all VM's"

$vmset = $vmset | where { ($_.Config.MemoryAllocation.Limit -gt 0) -OR $_.Config.CpuAllocation.Limit -gt 0 }

}

$table = @()

$vmset | % { if ($i -gt 0 ) {$i = 0}else{$i=$i+1}

$_ | % {

$row = "" | select Name, MemoryLimit, CpuLimit, MemoryMB, MemoryReservation, CpuReservation

$row.Name = $_.Name

$row.MemoryMB = $_.Summary.Config.MemorySizeMB

$row.MemoryReservation = $_.Config.memoryallocation.reservation

$row.MemoryLimit = $_.Config.memoryallocation.limit

$row.CpuReservation = $_.Config.CpuAllocation.reservation

$row.CpuLimit = $_.Config.CpuAllocation.limit

$table += $row

$i = $i + 1

}

}

$table

Output looks like this:

Thursday, November 4, 2010

Powercli one liner for finding Fault Tolerance Detection

Here's the fancy script  using the last the last article's oneliner:

#create array for table
$table = @()

#get-view of VM's and filter on FaultToleranceState
$ft = Get-View -ViewType VirtualMachine -filter @{"Runtime.FaultToleranceState"="enabled|ing"  }

#post message
write-host "Found FT on "  ($ft.count/2) "VM(s)..."

#assign results array
$ft | % {    
    $row = "" | select Name, FaultToleranceState, RecordReplayState
    $row.Name = $_.Name
    $row.FaultToleranceState = $_.Runtime.FaultToleranceState
    $row.RecordReplayState = $_.Runtime.RecordReplayState
    $row.RecordReplayState = $_.Runtime.RecordReplayState
    $table +=  $row
}
write-host ($ft.count )  "FT instances found."
$table


Output:


[vSphere PowerCLI] C:\powercli> .\Get-FT.ps1

 Found FT on  2 VM(s)...

 

Name                 FaultToleranceState         RecordReplayState

----                 -------------------         -----------------

testvm2              running                     recording 

testvm2              running                     replaying

 

keywords: Vmware vSphere powershell 2 powercli FT

VMware Powercli oneliner for finding FaultTolerance (FT) Virtual Machines


Get-View -ViewType VirtualMachine -filter @{"Runtime.FaultToleranceState"="enabled|ing"  }

Using Get-View is a very fast method. Took a while to figure out the filter aspect. This link is where I got my info:
http://wannemacher.us/?p=259