Tool: UBERAlign by Nick Weaver

We all know that one of the biggest performance killers in our virtual environments is the wonderful alignment of partitions so that they may work in harmony and produce many I/Os with our SANs.  There are a few good tools out there for us to use but we are often caught in the middle of having to purchase the product or only have access to a vendor specific application for doing this.

The wait is over!  Let the alignment begin!

Presenting UBERAlign, a tool for VMware Virtual Machine alignment and Space Reclamation

Some of the features:

  • Allows for fast alignment checking of virtual machines with detailed logging.
  • Can perform alignment to any offset you want. Even the crazy ones that you shouldn’t choose.
  • Works with both Windows 2000/XP/2003/2008 (NTFS) and Linux Distros (EXT2/EXT3/EXT4).
  • Is able to work on NTFS boot drives perfectly. It does this by rewriting NTFS Metadata (the right way).
  • Auto detects Windows 2008 and Windows 7 native installs (alignment not needed). Will not touch a System Reserved Partition (important for Windows 2008).
  • Preserves all Windows drive mapping (AFAIK only one to do so). This means no having to remap drive letters and complete support for non “C:\”  system drives with some Windows builds (some Citrix stuff).
  • Completely Storage Array agnostic. That’s right: if it connects to vSphere and host storage UBERAlign will work with it.

That list is only a small portion of the feature list.  The best part of all of this is that this tools is completely free.  Thanks to Nick over at Nickapedia (http://nickapedia.com) for taking the time to develop such a great tool and bring it into the community for that awesome price of FREE!

Head over to Nickapedia to read more and download the tool.  The link is: http://nickapedia.com/2011/11/03/straighten-up-with-a-new-uber-tool-presenting-uberalign/

Script: Track-Datastores.ps1

#Global Functions
#This function generates a nice HTML output that uses CSS for style formatting.
function Generate-Report {
    Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0077D4;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal-left {text-align:left;}.Normal {text-align:center;}</style></head><body><table><tr class=""Title""><td colspan=""3"">VMware Datastore Change Report</td></tr><tr class="Title"><td>Datastore</td><td>Difference(MB)</td><td>% Free</td></tr>"
 
                Foreach ($line in $myColDiff){
                    Write-Output "<td class=""Normal-left"">$($line.name)</td><td class=""Normal"">$($line.Diff)</td><td class=""Normal"">$($line.PercentFree)</td></tr> "
                }
        Write-Output "</table></body></html>"
    }
   
# Variables #
#############

$VIServer = "VISERVER"
$username = "changeme"
$password = "supersecret"
$digits = 2
$Folder = 'C:\Reports'
$currentFile = 'Datastores_Current.xml'
$previousFile = 'Datastores_Previous.xml'

# Script #
##########

# First, if a Current file exists, rename this Current file to Previous

If (Test-Path "$Folder\$currentFile")
{
    Remove-Item -Path "$Folder\$previousFile" -Force
    Rename-Item -Path "$Folder\$currentFile" -NewName $previousFile
}

# Next, let's measure and save current datastore sizes

# Connect to Virtual Center
$VC = Connect-VIServer $VIServer -user $username -password $password

# Get all datastores and put them in alphabetical order
$datastores = Get-Datastore | Sort-Object Name

# Create an array to hold the output
$myColCurrent = @()

# Loop through datastores
ForEach ($store in $datastores)
{
    # Create a custom object and define its properties
    $myObj = "" | Select-Object Name, CapacityGB, UsedGB, PercFree
    # Set the values of each property
    $myObj.Name = $store.name
    $myObj.CapacityGB = [math]::Round($store.capacityMB/1024,$digits)
    $myObj.UsedGB = [math]::Round(($store.CapacityMB - $store.FreeSpaceMB)/1024,$digits)
    $myObj.PercFree = [math]::Round(100*$store.FreeSpaceMB/$store.CapacityMB,$digits)
    # Add the object to the output array
    $myColCurrent += $myObj
}

# Export the output to an xml file; the new Current file
$myColCurrent | Export-Clixml -Path "$Folder\$currentFile"

# Disconnect from Virtual Center
Disconnect-VIServer -Confirm:$False

# Finally, let's compare the Current information to that in the Previous file

# Check if a Previous file exists
If (Test-Path "$Folder\$previousFile")
{
    # Import the Previous file
    $myColPrevious = Import-Clixml "$Folder\$previousFile"
    # Create an array to hold the differences
    $myColDiff = @()
    # Loop through the current datastores
    ForEach ($myObjCurrent in $myColCurrent)
    {
        # The actual compare command
        $diff = Compare-Object ($myColPrevious | Where { $_.Name -eq $myObjCurrent.Name }) $myObjCurrent -Property PercFree
        # In case of any differences, try to get specifics
        If ($diff)
        {
            # Again, a custom object and properties for outputting results
            $myObjDiff = "" | Select-Object Name, PercentFree, Diff
            # Again, setting the values of each property
            $myObjDiff.Name = $myObjCurrent.Name
            $myObjDiff.PercentFree = $myObjCurrent.PercFree
            # The most important property is the calculated difference between the current and previous values of PercFree. You can substitute it for UsedGB if you like.
            $myObjDiff.Diff = ($diff | Where { $_.SideIndicator -eq '=>' }).PercFree - ($diff | Where { $_.SideIndicator -eq '<=' }).PercFree
            # And agin, adding it to the output array
            $myColDiff += $myObjDiff
        }
        # Clearing the variable used inside the loop to prevent incorrect output in case of problems setting the variable!
        Clear-Variable diff -ErrorAction "SilentlyContinue"
    }
    # If nothing changed, we don't want an empty file.
    If ($myColDiff.Length -eq 0)
    {
        $myColDiff = "No changes since last check."
    }
    # And we conclude by outputting the results to a text file, which can be emailed or printed.
    Generate-Report > "$Folder\Track-Datastore.html"
}

IF ($myColDiff -ne "No changes since last check."){
    $SmtpClient = New-Object system.net.mail.smtpClient
    $SmtpClient.host = "my.smtp.host"   #Change to a SMTP server in your environment
    $MailMessage = New-Object system.net.mail.mailmessage
    $MailMessage.from = "System.Automation@example.com"   #Change to email address you want emails to be coming from
    $MailMessage.To.add("yomomma@example.com")  #Change to email address you would like to receive emails.
    $MailMessage.IsBodyHtml = 1
    $MailMessage.Subject = "VMware Datastore Change Report"
    $MailMessage.Body = Generate-Report
    $SmtpClient.Send($MailMessage)}

Script: Report-Snapshots.ps1

@"
===============================================================================
Title:             Report-Snaphots.ps1
Description:     List snapshots on all VMWARE ESX/ESXi servers as well as VM's
managed by Virtual Center.
Requirements:     Windows Powershell and the VI Toolkit
Usage:            .\Report-Snaphots.ps1
===============================================================================
"
@

#Global Functions
#This function generates a nice HTML output that uses CSS for style formatting.
function Generate-Report {
Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0077D4;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal {}</style></head><body><table><tr class=""Title""><td colspan=""6"">VMware Snaphot Report</td></tr><tr><td>VM Name  </td><td>Snapshot Name  </td><td>Date Created  </td><td>Size(MB)  </td><td>Description  </td><td>Host  </td></tr>"

Foreach ($snapshot in $report){
Write-Output "<td>$($snapshot.vm)</td><td>$($snapshot.name)</td><td>$($snapshot.created)</td><td>$($snapshot.sizemb)</td><td>$($snapshot.description)</td><td>$($snapshot.host)</td></tr> "
}
Write-Output "</table></body></html>"
}

#Login details for standalone ESXi servers
$username = 'changeme'
$password = 'supersecret' #Change to the root password you set for you ESXi server

#Folder to store report
$Folder = "C:\Reports"

#List of servers including Virtual Center Server.  The account this script will run as will need at least Read-Only access to Cirtual Center
$ServerList = "vc1.example.net"#, "vc2.example.net", "vc3.example.net"    #Chance to DNS Names/IP addresses of your ESXi servers or Virtual Center Server

#Initialise Array
$Report = @()

#Get snapshots from all servers
foreach ($server in $serverlist){

# Check is server is a Virtual Center Server and connect with current user
if ($server -eq "VCServer"){Connect-VIServer $server}

# Use specific login details for the rest of servers in $serverlist
else {Connect-VIServer $server -user $username -password $password}

get-vm | get-snapshot | %{
$Snap = {} | Select VM,Name,Created,SizeMB,Description,Host
$Snap.VM = $_.vm.name
$Snap.Name = $_.name
$Snap.Created = $_.created
$Snap.SizeMB = $_.sizemb
$Snap.Description = $_.description
$Snap.Host = $_.vm.host.name
$Report += $Snap
}
}

# Disconnect from Virtual Center
Disconnect-VIServer -Confirm:$False

# Generate the report and email it as a HTML body of an email
Generate-Report > "$Folder\Report-Snapshots.html"
IF ($Report -ne ""){
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "my.smtp.host"   #Change to a SMTP server in your environment
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "System.Automation@example.com"   #Change to email address you want emails to be coming from
$MailMessage.To.add("yomomma@example.com")    #Change to email address you would like to receive emails.
$MailMessage.IsBodyHtml = 1
$MailMessage.Subject = "VMware Snapshots Report"
$MailMessage.Body = Generate-Report
$SmtpClient.Send($MailMessage)}

Download here:  http://vsential.com/wp-content/uploads/2011/05/Report-Snapshots.ps1_.txt

Script: Report-Datastores.ps1

@"
===============================================================================
Title:             Report-Datastores.ps1
Description:     Report Datastore usage for all Datastores managed by vCenter
Requirements:     Windows Powershell and the VI Toolkit
Usage:            .\Report-Datastores.ps1
===============================================================================
"
@

#Global Functions
#This function generates a nice HTML output that uses CSS for style formatting.
function Generate-Report {
Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0077D4;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal-left {text-align:left;}.Normal {text-align:right;}</style></head><body><table><tr class=""Title""><td colspan=""4"">VMware Datastore Report</td></tr><tr><td>Datastore  </td><td>Capacity(GB)  </td><td>Used(GB)  </td><td>% Free  </td></tr>"

Foreach ($store in $report){
Write-Output "<td class=""Normal-left"">$($store.name)</td><td class=""Normal"">$($store.CapacityGB)</td><td class=""Normal"">$($store.UsedGB)</td><td class=""Normal"">$($store.PercFree)</td></tr> "
}
Write-Output "</table></body></html>"
}

#Login details
$username = 'changeme'
$password = 'supersecret'

#Current, Previous, Difference File information
$digits = 2
$Folder = 'C:\Reports'

#List of servers including Virtual Center Server.  The account this script will run as will need at least Read-Only access to Cirtual Center
$VIServer = "vc1.example.net"    #Chance to DNS Names/IP addresses of your ESXi servers or Virtual Center Server

#Initialise Array
$Report = @()

# Connect to Virtual Center
$VC = Connect-VIServer $VIServer -user $username -password $password

# Get all datastores and put them in alphabetical order
#$datastores = Get-Datastore | Sort-Object Name

#Get all datastores and put them in alphabetical order
foreach ($server in $serverlist){

# Check is server is a Virtual Center Server and connect with current user
if ($server -eq "VCServer"){Connect-VIServer $VIServer}

# Use specific login details for the rest of servers in $serverlist
else {Connect-VIServer $VIServer -user $username -password $password}

Get-Datastore | Sort-Object Name | %{
$Store = {} | Select Name, CapacityGB, UsedGB, PercFree
$Store.Name = $_.name
$Store.CapacityGB = [math]::Round($_.capacityMB/1024,$digits)
$Store.UsedGB = [math]::Round(($_.CapacityMB - $_.FreeSpaceMB)/1024,$digits)
$Store.PercFree = [math]::Round(100*$_.FreeSpaceMB/$_.CapacityMB,$digits)
$Report += $Store
}
# Disconnect from Virtual Center
Disconnect-VIServer -Confirm:$False
}

# Disconnect from Virtual Center
Disconnect-VIServer -Confirm:$False

# Generate the report and email it as a HTML body of an email
Generate-Report > "$Folder\Report-Datastore.html"
IF ($Report -ne ""){
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "my.smtp.host"   #Change to a SMTP server in your environment
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "System.Automation@example.com"   #Change to email address you want emails to be coming from
$MailMessage.To.add("yomomma@example.com")    #Change to email address you would like to receive emails.
$MailMessage.IsBodyHtml = 1
$MailMessage.Subject = "VMware Datastore Report"
$MailMessage.Body = Generate-Report
$SmtpClient.Send($MailMessage)}

Download here:  http://vsential.com/wp-content/uploads/2011/05/Report-Datastores.ps1_.txt

Holy VMFS3 Batman!

“Robin, go carve me out a new LUN for our new Batworks Monitoring System!”, says Batman.  Robin replies, “It is ready for you Batman, let’s get monitoring the Batwork.”

**POW** **BOOM**  **SPLAT**

My P2V has failed…”Failed to create virtual disk: There is not enough space on the file system for the selected operation.” What will Gotham do now!?!?

I am sure that many of you have run into the issue where your Storage Guy gives you a new LUN and you create a VMFS datastore and find out you somehow don’t have enough space.  Although, you know for fact that you were given 1TB or more on the LUN.  What happened?

Well, a lot of people tend to click right on through accepting any and all defaults that are presented to you.  One thing you missed was the wonderful block size selection.  You are presented with the Disk/LUN Formatting section and you see you actually had choices you could make:  small (1MB), medium (2MB), large (4MB), and super size (8MB).

If you were presented with 1TB then you would need to make sure that you select the appropriate block size to enable the use of that ever-so-expensive disk space.  For example-sake, if you need to provision a VMFS datastore of a size less than 256GB you need to select 1MB blocks, if you need to provision 512GB then use 2MB blocks, 1TB would require at least 4MB blocks, and 2TB requires 8MB blocks.

Now one asks, “Why and what causes this?”

The answer is simple…filesystem limitations of VMFS3.  Word has it that VMFS4 will not have these limitations.  It will supposedly follow ext4 limitations which enable 16TB.  Sound off in the comments regarding your thoughts and experiences with VMFS3 and the future of VMFS!