Quick vSphere Cluster BIOS check

The following check will compare the BIOS versions of the ESX hosts in a cluster and verify they are all at a consistent level.

The check makes use of a $Clusters variable, which can be created using the following line of code:

$clusters = Get-Cluster

This check will look for inconsistent BIOS versions between hosts in a vSphere cluster.


$misMatchBios = @()
$Clusters | select Name, ID | %{
	$thisClusterName = $_.Name
	$thisClusterBIOS = Get-View -ViewType HostSystem -SearchRoot $_.id -Property Name, "Hardware.BiosInfo" | Select Name,@{N="Cluster Name";E={$thisClusterName}},@{N="BIOS version";E={$_.Hardware.BiosInfo.BiosVersion}}, @{N="BIOS date";E={$_.Hardware.BiosInfo.releaseDate}}
	$thisClusterBiosGroup = $thisClusterBIOS | Group-Object -Property "BIOS Version"

	if ( ($thisClusterBiosGroup | Measure-Object).Count -gt 1 ) { $misMatchBios += ( $thisClusterBIOS | Sort Name )	}
}
$misMatchBios
Posted in Scripting, Virtualization | Leave a comment

Network related vSphere checks

The following two sections of code can be ran independently or used in conjunction with Alan Renouf’s vCheck script. They return network specific issues that could happen in a vSphere environment.

The first check makes use of a $clusters variable, which can be created using the following line of code:

$Clusters = Get-Cluster

The following section will report on any port groups that do not exist on all hosts in a cluster. This is a fairly common issue with standard vSwitches, but is typically resolved by using Distributed vSwitches (for the Enterprise Plus users).


$networkListHT = @{}
Get-View -ViewType Network -Property Name | %{ $networkListHT.Add($_.MoRef.value,$_.Name) }

$portGroupCheck = @()
$Clusters | Select Name, ID | %{
	$thisClusterName = $_.Name
	$thisClusterHosts = Get-View -ViewType HostSystem -SearchRoot $_.id -Property Name, Network

	$thisClusterNetworks = @()
	$thisClusterHosts | %{
		$thisHost = $_.Name
		$_.Network | %{ $thisClusterNetworks += New-Object psobject -Property @{ "Port Group"=$networkListHT[$_.Value]; Host=$thisHost; Cluster=$thisClusterName} }
	}

	$portGroupCheck += ($thisClusterNetworks | Group-Object -Property "Port Group" | ?{$_.Count -lt $thisClusterHosts.count} | Select -ExpandProperty Group | Sort Host )
}

$portGroupCheck

The following one liner will show any port group that does not have virtual machines. This could be a new network that simply doesn’t have VMs yet, or an old network that is no longer required.


Get-View -ViewType Network -Property Name, VM, Host |?{@($_.VM).Count -eq 0} | Select Name, @{Name="Host Count"; Expression={@($_.Host).Count}} | Sort Name
Posted in Scripting, Virtualization | Leave a comment

General vSphere Cluster counts/averages

A year or so ago, I had added some generic sections to Alan Renouf’s vCheck 5 script, which I was using to report on several environments that I managed. A few months ago, Alan released a new version of vCheck 6. I decided to re-write a couple of these checks into the new format. The new version of these checks are much more efficient than my previous versions, so I thought I would share them here.

Both checks make use of a $clusters variable, which can be created using the following line of code:

$clusters = Get-Cluster

This check will report on the average number of vCPUs per virtual machine and the average number of vCPUs per physical core.


$CpuClusterRatio = @()
$Clusters | select Name, ID | %{
	$thisClusterHost = Get-View -ViewType HostSystem -SearchRoot $_.id -property "Hardware.CpuInfo.NumCpuCores" | Select @{Name="NumCPU";Expression={$_.Hardware.CpuInfo.NumCpuCores}} |  Measure-Object -Property NumCPU -sum
	$thisClusterVM = Get-View -ViewType VirtualMachine -SearchRoot $_.id -property "Summary.Config" | Select @{Name="NumCPU";Expression={$_.Summary.Config.NumCPU}} |  Measure-Object -Property NumCPU -sum
	
	if ($thisClusterHost.Sum -gt 0) { $thisvCpuPerCore = ([math]::round(( $thisClusterVM.Sum / $thisClusterHost.Sum ), 2)) } else { $thisvCpuPerCore = 0 }
	if ($thisClusterVM.Count -gt 0) { $thisvCpuPerVM = ([math]::round(( $thisClusterVM.Sum / $thisClusterVM.Count ), 2)) } else { $thisvCpuPerVM = 0 }
	
	$CpuClusterRatio += New-Object psobject -Property @{
		Name = $_.Name
		NumHosts = $thisClusterHost.Count
		Cores = $thisClusterHost.Sum
		Guests = $thisClusterVM.Count
		"vCPU Count" = $thisClusterVM.Sum
		"vCPU per VM" = $thisvCpuPerVM
		"vCPU per Core" = $thisvCpuPerCore
	}
}

$CpuClusterRatio | select Name, NumHosts, Cores, Guests, "vCPU Count", "vCPU per VM", "vCPU per Core" | sort Name

This check will report on the average amount of RAM per virtual machine and the percentage of physical RAM allocated to all virtual machines.


$RamClusterRatio = @()
$Clusters | select Name, ID | %{
	$thisClusterHost = Get-View -ViewType HostSystem -SearchRoot $_.id -property "Hardware.MemorySize" | Select @{Name="RamSize";Expression={$_.Hardware.MemorySize/1GB}} |  Measure-Object -Property RamSize -sum
	$thisClusterVM = Get-View -ViewType VirtualMachine -SearchRoot $_.id -property "Summary.Config" | Select @{Name="RamSize";Expression={$_.Summary.Config.MemorySizeMB / 1024}} |  Measure-Object -Property RamSize -sum
	
	if ($thisClusterVM.count -gt 0) { $avgRamPerVM = ([math]::round(( $thisClusterVM.Sum / $thisClusterVM.Count ), 2)) } else { $avgRamPerVM = 0 }
	if ($thisClusterHost.sum -gt 0) { $allocatedRam = ([math]::round(( $thisClusterVM.Sum / $thisClusterHost.Sum ) * 100, 2)) } else { $allocatedRam = 0 }
	
	$RamClusterRatio += New-Object psobject -Property @{
		Name = $_.Name
		NumHosts = $thisClusterHost.Count
		"Cluster RAM (GB)" = [Math]::Round($thisClusterHost.Sum,0)
		Guests = $thisClusterVM.Count
		"Guest RAM (GB)" = [Math]::Round($thisClusterVM.Sum,2)
		"Avg RAM per VM" = $avgRamPerVM
		"Allocated RAM %" = $allocatedRam
	}
}

$RamClusterRatio | select Name, NumHosts, "Cluster RAM (GB)", Guests, "Guest RAM (GB)", "Avg RAM per VM", "Allocated RAM %" | sort Name

I hope someone can find a use for either of these scripts.

Posted in Scripting, Virtualization | Leave a comment

VMware Support Assistant SSL

VMware recently released a new product call vCenter Support Assistant. This virtual appliance places an icon in the vCenter ‘Solutions and Applications’ area where you can contact support, open SRs and upload support bundles. You can view the entire product overview and access the download link from here: http://www.vmware.com/products/datacenter-virtualization/vcenter-support-assistant/overview.html.

This appliance provides a web server that serves up the ‘solution’ as well as the icon that appears in vCenter. Due to this, opening the vCenter client will load the initial icon and give you an SSL warning. The FAQ shows how this generic certificate can be installed on your workstation to prevent this popup, however I prefer to replace the SSL certificate with one signed by a trusted CA. Here are the steps to complete this procedure.

cd /support-assistant/keystore/

cp support_assistant support_assistant_BU

/usr/java/jre-vmware/bin/keytool -genkey -keyalg RSA -keysize 2048 -alias support_assistant -keystore support_assistant -storepass "SPH123oneAssist123@" -validity 3650 -dname "CN=support-assistant.bwuch.local,OU=My Department,O=My Company,L=City,ST=State,C=XX,emailAddress=vmware-admin@bwuch.local"

/usr/java/jre-vmware/bin/keytool -certreq -alias support_assistant -keystore support_assistant -file jetty.csr -storepass "SPH123oneAssist123@"

This will create a jetty.csr file. You’ll want to display the contents of that file (cat jetty.csr). Copy the contents of jetty.csr to the certificate request. Then download the base64 encoded chain file, open it in notepad. Back on the appliance use a text editor like vi to create a new jetty.crt file. Paste the contents of the P7B file to jetty.crt.

Run the following command to import the CA signed certificate into the keystore:

/usr/java/jre-vmware/bin/keytool -keystore support_assistant -import -alias support_assistant -file jetty.crt -trustcacerts -storepass "SPH123oneAssist123@"

Answer ‘yes’ if prompted to trust the certificate. You can either restart the service or reboot the server to read in the new certificate.

After the above process, open a web browser and access the management interface (the above example would be https://support-assistant.bwuch.local/). You should not receive any SSL warnings. Go ahead and register the vCenter Support Assistant into your vCenter. You may notice that when you open the vCenter client you’ll get an SSL warning. This is because the plugin has registered by IP address in your vCenter. You can fix this up with a few short lines of PowerCLI:


$exMgr = Get-View ExtensionManager
$sa = $exMgr.ExtensionList | ?{$_.key -eq 'com.vmware.supportassistant'}
$sa.Server[0].Url = "https://support-assistant.bwuch.local/plugin-config.xml"
$exMgr.UpdateExtension($sa)

Close out of the vCenter client and verify, but you shouldn’t get any more SSL warnings due to the Support Assistant.

Posted in Virtualization | 2 Comments

SQL Database Documentation

Over the years I’ve done quite a bit of scripting. Many of those scripts SELECT, INSERT or UPDATE a SQL database. The other day I was looking at my tables and realized I didn’t know what (or if) some of them were used for and I didn’t have very good documentation either. I decided to start making some documentation and thought the best place to keep the information would be as a new table in the database itself — that way I wouldn’t need to look too hard for it. I created a new table which contains a list of other tables, a description of what the data is for, a contact email address and a column for a list of systems/scripts that either use or update the data.  Useful information, but rather basic and doesn’t really warrant a blog post…

Here is the creative part.  I needed a system to track and notify when a table was added to the database but not added to my documentation. First we start with a rather simple select statement that I found with a bit of googling. This select statement returns a list of tables, when they were created and the number of columns in the table:

SELECT name, create_date, max_column_id_used
FROM sys.Tables

Once we have this information, we use my favorite WHERE clause to make it better — NOT IN! The following select statement is just like the one above, only in the where clause we filter out only the tables that are not in the new documentation table:

SELECT name, create_date, max_column_id_used
FROM sys.Tables
WHERE name NOT IN (SELECT distinct(tableName) from tblDatabaseDocumentation)
ORDER BY name

I then created a scheduled task to run daily that executes the above SQL statement. If there is one or more results I get an email notification. This reminds me to update my documentation or find out who created the table and remind them to document their work.

Posted in Scripting | Leave a comment