I have been asked to individuate all the ESX that need being remediated as well as retrieve the capacity of their local storage to see if some of them might need larger disks to be bought.
There are a few hundreds ESX in that server farm, so I am going to show you how I used Powershell and PowerCLI cmdlets to retrieve exactly what I wanted.
The aim of my script is to return a custom Powershell object (aka PSObject) that contains all the needed properties for later analysis.
These properties are: the ESX name, model, version, build and all of its local datastores with their capacity. This last one in particular I retrieve it using the MultipleHostAccess property.
Here's the script I wrote:
- function Get-Esxinfo {
- <#
- .SYNOPSIS
- This script returns information on one or more ESX.
- .DESCRIPTION
- This script returns information on one or more ESX.
- You can run the script against one or more ESX.
- This script can display the information in a spreadsheet.
- .PARAMETER Server
- Specify the vSphere servers on which you want to run this function.
- .PARAMETER Name
- Specify the names of the hosts you want to retrieve.
- By default this script will retrieve all the ESX hosts connected to the current vCenter.
- .PARAMETER Filepath
- Specifies the path to the CSV output file. The default is 'esxinfo.csv'. This file will be saved in the local temp folder.
- .PARAMETER OpenFile
- Opens the output file with the program associated with CSV files.
- .PARAMETER PassThru
- Returns the object.
- .EXAMPLE
- Get-Esxinfo -server virtualcenter
- Gets information for all the ESX connected to VIserver named 'virtualcenter'.
- .EXAMPLE
- Get-Esxinfo -server virtualcenter -name esx00*
- Gets information for all the ESX whose name starts with esx00* connected to VIserver named 'virtualcenter'.
- .EXAMPLE
- $EsxServers = Get-Content ESXServers.txt
- $EsxServers | Get-Esxinfo -server virtualcenter -openfile -passthru
- Gets the information from all the ESX listed in ESXServers.txt
- Opens the output file with the program associated with CSV files.
- Returns the object.
- .EXAMPLE
- Get-Esxinfo -server virtualcenter -verbose | format-table
- Gets information for all the ESX connected to VIserver named 'virtualcenter' and show the output in a table.
- Show verbose information.
- .INPUTS
- System.String
- .OUTPUTS
- PSObject
- .NOTES
- Author: happysysadm.com
- Created: 27Avril2013
- #>
- #requires -version 2.0
- [CmdletBinding()]
- param(
- [Parameter(Mandatory=$true)]
- [string[]]$server,
- [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipeLineByPropertyName=$True)]
- [string[]]$name="*",
- [Parameter()]
- [ValidateScript({
- if((Test-Path -LiteralPath $_ -IsValid) -and ($_ -like '*.CSV'))
- {
- $true
- }
- else
- {
- throw ('The specified path "{0}" is invalid. Valid arguments include a path to a CSV file. Exiting.' -f $_)
- }
- })]
- [string]$filepath = (Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath "esxinfo.csv"),
- [Parameter()]
- [switch]$OpenFile,
- [Parameter()]
- [switch]$PassThru
- )
- write-verbose "Adding VMware Powershell Snapin"
- IF (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) {
- Add-PSSnapin VMware.VimAutomation.Core
- }
- write-verbose "Connecting to vCenter"
- try
- {
- Connect-VIServer $server
- }
- catch
- {
- Write-Warning "An error occured.`n$_`nExiting..."
- break
- }
- write-verbose "Preparing the wrapper for the returned psobjects"
- $esxarray = @()
- write-verbose "Retrieving the ESX information and storing it in an array (can take a bit...)"
- try
- {
- $esxsource = @(Get-VMHost -Name $name)
- }
- catch
- {
- Write-Warning "An error occured.`n$_`nExiting..."
- break
- }
- write-verbose "Counting the number of ESX to show a progress bar"
- $totalesx = ($esxsource).count
- write-verbose "Initialiasing a counter"
- $a = 0
- foreach($esx in $esxsource)
- {
- write-verbose "Creating a psobject and adding members to it"
- $esxobject = New-Object -typename psobject
- $esxobject | add-member -membertype noteproperty -name 'ESX Name' -Value $esx.name
- $esxobject | add-member -membertype noteproperty -name 'ESX Model' -value $esx.model
- $esxobject | add-member -membertype noteproperty -name 'ESX Version' -value $esx.version
- $esxobject | add-member -membertype noteproperty -name 'ESX Build' -value $esx.build
- write-verbose "Retrieving local datastores only, LUNs are excluded because they are not local hardware"
- $datastores = Get-Datastore -VMHost $esx | Get-View | ?{$_.Summary.MultipleHostAccess -match 'false'}
- $i = 1
- foreach($datastore in $datastores)
- {
- $esxobject | add-member -membertype noteproperty -name "ESX $i datastore name" -value $datastore.summary.name
- $esxobject | add-member -membertype noteproperty -Name "ESX $i datastore capacity GB" -value ($datastore.summary.capacity /1GB)
- $i++
- }
- write-verbose "Adding PSObject to array"
- $esxarray += $esxobject
- write-verbose "Removing psobject to be reused"
- $esxobject = $null
- $a++
- write-verbose "Writing a progress bar"
- Write-Progress -Id 1 -Activity ("Querying ESX") -PercentComplete ($a / $totalesx * 100) -Status ("Queried {0} ESX of {1}" -f $a, $totalesx)
- }
- write-verbose "Going to write array content to $filepath"
- try
- {
- $esxarray | Export-Csv -UseCulture -NoTypeInformation $filepath
- }
- catch [System.IO.IOException]
- {
- Write-Warning "Unable to write to $filepath. File could be in use.`n$_`nExiting..."
- break
- }
- catch
- {
- Write-Warning "An error occured.`n$_`nExiting..."
- }
- write-verbose "Opening file if asked so"
- if ($OpenFile)
- {
- Invoke-Item -Path $FilePath
- }
- write-verbose "Returning psobject if asked so"
- if ($PassThru)
- {
- $esxarray
- }
- }
- Get-Esxinfo -server virtualcenter -name myesx* -verbose -PassThru -OpenFile | ft
The only mandatory parameter is the name of your vCenter, which is used for initial connection. Other optional parameters are the name of the ESX to retrieve (* is used in case you specify none), the name of the logfile (which will be saved in your temp folder), and the possibility to invoke the program associated with CSV files (-openfile).
As you can see I create two hashtables:
- one for containing the output of the get-vmhost command, so that later queries can quickly be done against this object instead of waiting for powershell to query the vCenter database again and again;
- one for containing every ESX object with its properties.
Interesting articles that explain the use of PSObject and that I suggest you to read are:
- New-Object PSObject –Property [HashTable]
- Create a Truly Advanced PowerShell Function
- Windows PowerShell: The Many Ways to a Custom Object
I would also like to point out the use I made of a progress bar. This is a nice Powershell feature which is often overlooked by scripters. I like the idea of having this pop-up bar, so I deeply suggest getting used to it because its syntax is not so diffcult.
Note that the appearance of the progress bar varies when it is used at the Powershell prompt or within the PowerGUI:
![]() |
Powershell write-progress as it appears at the prompt |
![]() |
Powershell write-progress as it appears in PowerGUI |
No comments:
Post a Comment