Check VMware Configuration with Powershell

I have promised you I would post this script, so here it is!

This Powershell script generates an overview of any items that are not available to every ESX server in a VMware cluster. These items might prevent your vm’s being vmotioned by DRS or restarted by HA. Pretty serious business, I’d say!

The items involved are:
1. datastores
2. LUNs (important when using Raw Device Mappings)
3. port groups

The output is a nicely formatted HTML page showing not only which items are misconfigured, but also where the are available and where they are absent.

Here’s an example:
Compare Screenshot

And here’s the script:
Compare-Clusters (Rename to .ps1)

Enjoy!
Hugo

I’m not pretending that squeezing myself Baratas Ray Ban into jeans two sizes too small is fun. According to 50,000 games played (simulated) by the Predictalator, the Bengals win over the Cowboys 64.2 percent of the time and by ray bans sale an average score of http://www.cheapjerseysselling.com 28 22. The three main http://www.cheapjerseysselling.com ways cheap football jerseys to watch free TV shows online include: 1. Rivalries can be taken so seriously that it can even break up relationships. If you are curious about other stations, such as local access programing, scroll through to program listing to highlight a specific station, then press the “Info” button on your remote. So, he’s got all the freedom in the world. Mardy Fish managed to make it to the quarterfinals of the Farmers Classic after defeating Gilles Muller in straight sets on Thursday night at the Los Angeles Tennis Center, and is now hoping to take down Igor Kunitsyn in order to advance to the semis. The birds find it difficult to fly over the cold waters of Lake Ontario and prefer to fly around it. That always amused your kids, big tough Dad, hates needles. In 2012, Lazarus was sentenced to 27 years to life in prison for first degree murder and an additional two years for personal use of a firearm. When I was in nursing assistant training, my supervisor was constantly yelling at me to stand up straight, and I wanted to scream, “LOOK, LADY, I WILL STAND AS STRAIGHT AS YOU WANT IF YOU HAND ME SOME OF THAT PERCOCET OVER THERE,” but you don’t wanna launch into your whole medical history, and also yelling about lifting pain meds in a hospital is probably a bad idea. According to the F Internationale de Football Association, international soccer’s governing body, there is evidence that people in China might have played a game similar to soccer more than 2,000 years ago. Her lover, the Roman general Mark Antony, fared little better.. The camera takes fairly amazing pictures in good light, and even takes decent cheap jerseys pictures in poor lighting. Former Crow Scott Stevens was forced to retire last season with the after effects of concussion and ex Fremantle player Daniel Gilmore has also sought compensation. Tal como el Levi Stadium, el Soldier Field tambin recibi el 1 de diciembre de 2011 la certificacin LEED, por las caractersticas sustentables de la edificacin.Eventos:Algunos de los eventos ms importantes que ha recibido este estadio son: Una carrera de NASCAR la nica en la historia del Soldier Field en 1956. I often find GREAT decorations at the dollar storeso I suggest Wholesale China Jerseys starting there before buying on line.. We’re also pleased to see overall Personal Cloud adoption continuing to play out, as it did through the course of the year better than we had anticipated across our customer base.

25 thoughts on “Check VMware Configuration with Powershell”

  1. Pingback: Compare your hosts… « H9Newser’s Blog
  2. I had problems running your script:

    PS C:isopowershell> ./compare-clusters.ps1
    There were one or more problems with the server certificate:

    * A certification chain processed correctly, but terminated in a root certificate which isn’t trust
    d by the trust provider.

    * A required certificate is not within its validity period.

    * The certificate’s CN name does not match the passed value.

    Get-View : The argument cannot be null or empty.
    At C:isopowershellcompare-clusters.ps1:23 char:36
    + $VMHostViews = $VMHosts | Get-View <<<< | Sort Name
    Get-Datastore : The argument cannot be null or empty.
    At C:isopowershellcompare-clusters.ps1:26 char:37
    + $Datastores = Get-Datastore -VMHost <<<< $VMHosts
    Get-Datastore : The argument cannot be null or empty.
    At C:isopowershellcompare-clusters.ps1:27 char:82
    + $DSdiffs = $VMHosts | ForEach {Compare-Object $Datastores (Get-Datastore -VMHost <<<< $_) -S
    yncWindow 1000} | ForEach {$_.InputObject} | Sort Name | Select Name -Unique
    Compare-Object : Cannot bind argument to parameter ‘ReferenceObject’ because it is null.
    At C:isopowershellcompare-clusters.ps1:48 char:30
    + $LUNdiffs += Compare-Object <<<< $LUNs $HostLUNs -SyncWindow 1000 | ForEach {$_.InputObj
    ect}
    Get-VirtualPortGroup : The argument cannot be null or empty.
    At C:isopowershellcompare-clusters.ps1:73 char:44
    + $PortGroups = Get-VirtualPortGroup -VMHost <<<< $VMHosts | ForEach {$_.Name} | Select -Uniqu
    e
    Get-VirtualPortGroup : The argument cannot be null or empty.
    At C:isopowershellcompare-clusters.ps1:77 char:42
    + $HostPGs = Get-VirtualPortGroup -VMHost <<<< $VMHost | ForEach {$_.Name} | Select -Uniqu
    e
    Compare-Object : Cannot bind argument to parameter ‘ReferenceObject’ because it is null.
    At C:isopowershellcompare-clusters.ps1:78 char:29
    + $PGdiffs += Compare-Object <<<< $PortGroups $HostPGs -SyncWindow 1000 | ForEach {$_.Inpu
    tObject}

    1. The first error says that Get-View did not get any arguments. So there are two possible causes:
      1) Get-View does not support input from pipeline. This is only the case for the beta release of the VI Toolkit. Make suer you use the v1.0.
      2) The $VMHosts variable is empty, which would mean filling it somehow went wrong. Try dot-sourcing the script (start powershell interactively and run “. c:\iso\compare-clusters.ps1” (without the quotes). Then take a look ate the variable $VMHosts if it contains anything.

      Good luck,
      Hugo

      »crosslinked«

  3. Hey thanks for the great script. I also get a bunch errors similar to the one posted above. For the most part the script seems to run and produce a report its been very helpful in identifying invalid configurations.

    As for possible debugging information that may help with the errors.

    VC is 2.5 Update 3 on Win2k3 Server
    Host are mostly 3.01
    Toolkit Version is 1.0 build 113525

    Am not sure if your open to feed back to continue to improve the script or if you released it to the community and for them to have at it.

    If so here is my feedback.

    Since its a cluster audit it would be nice not to see the local disk. Since I’ve seen most environments local label vary from host to host usually something along the lines with the hostname this usually helps to ensure that nobody puts a VM on the Local host.

    Also I glance thru the script and I’m not sure are you checking for VLAN tags. Are you ? I’ve seen many issues because somebody fat fingered a VLAN tag. So a VM will move but not respond to any pings. Or even the VMotion port group wont move the VM because of the VLAN tag.

    Thanks again

    1. Hi Daniel, thank you for taking the time to post your comment. I read every comment on my site and try to improve my scripts or help out in other ways. Keep watching my site and you might see an improved version of the script some time soon. Thanks again for your comments!
      Hugo

  4. How do I get rid of this annoying output when I run the powershell scripts?

    There were one or more problems with the server certificate:

    * A certification chain processed correctly, but terminated in a root certificat
    e which isn’t trusted by the trust provider.

    1. You can import the certificate to get rid of the first message, but the second one will remain as your server will most likely not be called ‘vmware’. Might work to create a dns alias for it, but that’s not very nice. Maybe you can find out a way to generate a new certificate with the proper server name in it. If anybody finds a way before I do, let me know.
      Hugo

  5. Thanks for lots of great scripts. Looking for VCB ones but liked what I found anyway. My script works some time but other times the snapshot times out. Wanted your clear connection script to see if that was my issue, wasn’t. Your list disks script will help also.

  6. Hi Hugo,

    I was trying to do exactly as Daniel requested and managed to fudge something together. Would appreciate it if you would take the time to have a look and see how it could be improved as i think the method I came up with to compare VLANS works but is a little convoluted.

    let me know if you have the time or inclination to take a look and i’ll post the script.

  7. Just ran this script and it works fine but:
    – you might want to filter the local luns (vmhba0:0:0) cause they usually have a different name on every single host in a cluster
    – the script throws an error when a cluster doesn’t contain hosts

  8. I was wondering if Paul had a workable solution or addition for auditing the port group VLANs. I love the script above but really need to audit the por group VLANs as well.

  9. Hi Guys,

    Got the same issue, its reporting my local drives as datastores and reporting a mismatch on the clusters.

    Any chance of looking into this? Great work otherwise… love it!

  10. Hi Hugo,

    Great script, I was a little confused on one of my outputs because there were several vmhba devices denoted across the ESXhosts. It is simple to figure out the ones that have 1 vmhba denoted and the rest saying true or false but having more than one has confused me. Can you help to decipher this?

    LunUuid ESX001.xxx ESX002.xxx ESX003.xxx ESX005.xxx ESX011.xxx ESX020.xxx
    0200010000600508b400106b3400009000020c0000485356323130 vmhba0:4:1 vmhba0:2:1 vmhba0:4:1 vmhba0:1:1 False vmhba0:2:1
    0200020000600508b400106b3400009000020c0000485356323130 False False False False vmhba0:4:2 False
    0200020000600508b400106b340000900002110000485356323130 vmhba0:4:2 vmhba0:2:2 vmhba0:4:2 vmhba0:1:2 False vmhba0:2:2
    0200030000600508b400106b340000900002110000485356323130 False False False False vmhba0:4:3 False

    Thanks!

    Also, it would take longer but could you include a host rescan before the script starts executing so that all of the data can be current?

  11. Thanks for the script. I took a couple of snips from the vCheck script to add send-email capability. Also made some formatting and colorization additions.

    # When displaying to the screen an output file is created. Set the format of the filename below:
    $dateFormat = “yyyy-MM-dd__HH-mm”

    # path and file name of output report
    $date = Get-Date -format $dateFormat
    $outputFile = ‘C:\vCheck_Reports\ESX-comparison_’ + $date + ‘.html’

    # Virtual Center servername
    $VCServer = “vcenter”

    # Set the SMTP Server address
    $SMTPSRV = “mail.domain.local”

    # Set the Email address to recieve from
    $EmailFrom = “user@domain.com”

    # Set the Email address to send the email to – seperate multiple with comma
    $EmailTo = “user@domain.com”

    # When displaying to the screen an output file is created. Set the format of the filename below:
    $dateFormat = “yyyyMMdd_HHmm” # use “d-M-yyyy” for legacy v5.0 format

    # Use the following item to define if an email report should be sent once completed
    $SendEmail = $true

    # Use the following item to define if the output should be displayed in the local browser once completed
    $DisplaytoScreen = $false

    function Send-SMTPmail($to, $from, $subject, $smtpserver, $body) {
    $mailer = new-object Net.Mail.SMTPclient($smtpserver)
    $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
    $msg.IsBodyHTML = $true
    $mailer.send($msg)
    }

    Function Create-HTMLTable
    {
    param([array]$Array)
    $arrHTML = $Array | ConvertTo-Html
    $arrHTML[-1] = $arrHTML[-1].ToString().Replace(”,””)
    Return $arrHTML[5..1000]
    }

    $output = @()
    $output += ”
    $output += ‘.sectionTitle{color:blue;font-weight:bold;}.section{margin-top:10px;margin-bottom:30px;}.errorDiv{color:red;font-weight:bold;}table{border-style:solid;border-width:1px;font-size:8pt;background-color:#ccc;width:100%;}th{text-align:left;}td{background-color:#fff;width:20%;border-style:solid;border-width:1px;}body{font-family:verdana;font-size:8pt;}h1{font-size:12pt;}h2{font-size:10pt;}’

    $output += ‘ESXi Host Inconsistency Report’
    # $output += ‘The following items are not available to all ESX servers in the cluster:’

    $VC = Connect-VIServer $VCServer

    ForEach ($Cluster in (Get-Cluster | Sort Name))
    {
    $VMHosts = $Cluster | Get-VMHost | Sort Name
    $VMHostViews = $VMHosts | Get-View | Sort Name

    $myDSCol = @()
    $Datastores = Get-Datastore -VMHost $VMHosts
    $DSdiffs = $VMHosts | ForEach {Compare-Object $Datastores (Get-Datastore -VMHost $_) -SyncWindow 1000} | ForEach {$_.InputObject} | Sort Name | Select Name -Unique
    ForEach ($DSdiff in $DSdiffs)
    {
    If ($DSdiff.Name -ne $null)
    {
    $myDSObj = “” | Select Datastore
    $myDSObj.Datastore = $DSdiff.Name
    ForEach ($VMHost in $VMHosts)
    {
    $myDSObj | Add-Member -MemberType NoteProperty -Name $VMHost.Name -Value (!!(Get-Datastore -Name $myDSObj.Datastore -VMHost $VMHost -ErrorAction SilentlyContinue))
    }
    $myDSCol += $myDSObj
    }
    }

    $myLUNCol = @()
    $LUNs = $VMHostViews | ForEach {$_.Config.StorageDevice.ScsiLun | ForEach {$_.Uuid}} | Select -Unique
    $LUNdiffs = @()
    ForEach ($VMHostView in $VMHostViews)
    {
    $HostLUNs = $VMHostView.Config.StorageDevice.ScsiLun | ForEach {$_.Uuid} | Select -Unique
    $LUNdiffs += Compare-Object $LUNs $HostLUNs -SyncWindow 1000 | ForEach {$_.InputObject}
    Clear-Variable HostLUNs -ErrorAction SilentlyContinue
    }
    ForEach ($LUNdiff in ($LUNdiffs | Select -Unique | Sort))
    {
    If ($LUNdiff -ne $null)
    {
    $myLUNObj = “” | Select LunUuid
    $myLUNObj.LunUuid = $LUNdiff
    ForEach ($VMHostView in $VMHostViews)
    {
    If (($VMHostView.Config.StorageDevice.ScsiLun | Where {$_.Uuid -eq $myLUNObj.LunUuid}) -ne $null)
    {
    $myLUNObj | Add-Member -MemberType NoteProperty -Name $VMHostView.Name -Value (($VMHostView.Config.StorageDevice.ScsiLun | Where {$_.Uuid -eq $myLUNObj.LunUuid}).CanonicalName)
    }
    Else
    {
    $myLUNObj | Add-Member -MemberType NoteProperty -Name $VMHostView.Name -Value $False
    }
    }
    $myLUNCol += $myLUNObj
    }
    }

    $myPGCol = @()
    $PortGroups = Get-VirtualPortGroup -VMHost $VMHosts | ForEach {$_.Name} | Select -Unique
    $PGdiffs = @()
    ForEach ($VMHost in $VMHosts)
    {
    $HostPGs = Get-VirtualPortGroup -VMHost $VMHost | ForEach {$_.Name} | Select -Unique
    $PGdiffs += Compare-Object $PortGroups $HostPGs -SyncWindow 1000 | ForEach {$_.InputObject}
    Clear-Variable HostPGs -ErrorAction SilentlyContinue
    }
    ForEach ($PGdiff in ($PGdiffs | Select -Unique | Sort))
    {
    If ($PGdiff -ne $null)
    {
    $myPGObj = “” | Select PortGroup
    $myPGObj.PortGroup = $PGdiff
    ForEach ($VMHost in $VMHosts)
    {
    $myPGObj | Add-Member -MemberType NoteProperty -Name $VMHost.Name -Value (!!(Get-VirtualPortGroup -Name $myPGObj.PortGroup -VMHost $VMHost -ErrorAction SilentlyContinue))
    }
    $myPGCol += $myPGObj
    }
    }

    $output+= ”
    $output += $Cluster.Name
    $output+= ”
    $output += ‘Datastore check: ‘
    If ($myDSCol.Count -eq 0)
    {
    $output += “All datastores OK.”
    $output += ”
    }
    Else
    {
    $output += ‘ERROR: Datastore config has incontistencies! Please investigate.’
    $output += Create-HTMLTable $myDSCol
    $output += ”
    }

    $output += ‘LUN check: ‘
    If ($myLUNCol.Count -eq 0)
    {
    $output += ‘All LUNs OK.’
    $output += ”
    }
    Else
    {
    $output += ‘ERROR: LUN config has incontistencies! Please investigate.’
    $output += Create-HTMLTable $myLUNCol
    $output += ”
    }

    $output += ‘Portgroup check: ‘
    If ($myPGCol.Count -eq 0)
    {
    $output += “All portgroups OK.”
    $output += ”
    }
    Else
    {
    $output += ‘ERROR: Portgroup config has incontistencies! Please investigate.’
    $output += Create-HTMLTable $myPGCol
    $output += ”
    }

    Clear-Variable VMHosts -ErrorAction SilentlyContinue
    Clear-Variable Datastores -ErrorAction SilentlyContinue
    Clear-Variable DSdiffs -ErrorAction SilentlyContinue
    Clear-Variable PortGroups -ErrorAction SilentlyContinue
    Clear-Variable PGdiffs -ErrorAction SilentlyContinue
    Clear-Variable LUNs -ErrorAction SilentlyContinue
    Clear-Variable LUNdiffs -ErrorAction SilentlyContinue
    }

    $output += ”
    $output | Out-File $outputFile -Force
    if ($DisplayToScreen) {
    Write-Host “..Displaying HTML results”
    Invoke-Item $Filename
    }

    Disconnect-VIServer -Confirm:$False

    if ($SendEmail) {
    Write-Host “..Emailing HTML results”
    send-SMTPmail $EmailTo $EmailFrom “$VCServer ESXi host comparison check” $SMTPSRV $output
    }

Leave a Reply