Created
November 11, 2014 21:34
-
-
Save smasterson/25862683c8f822917177 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires –Version 3 | |
#Requires -PSSnapin VMware.VimAutomation.Core | |
<# | |
.SYNOPSIS | |
Exports VMware host (ESX/ESXi) information to Excel | |
.DESCRIPTION | |
Queries one or more ESX/ESXi servers directly and exports all info to an Excel workbook | |
A new workbook/file will be created for each host | |
.PARAMETER Server | |
The name of one or more ESX/ESXi servers to query | |
.PARAMETER Path | |
Path to folder where Excel workbook is saved | |
.EXAMPLE | |
.\Get-VMHostInfo.ps1 -server myesxhost -path "E:\Reports" | |
Gathers info from myesxhost and exports info to an Excel workbook saved in E:\Reports | |
.EXAMPLE | |
.\Get-VMHostInfo.ps1 -server "myesxhost","myotheresxhost" -path "E:\Reports" | |
Gathers info from myesxhost and myotheresxhost, exports info to separate Excel workbooks located in E:\Reports | |
.EXAMPLE | |
$servers = Get-Content "E:\myhosts.txt";.\Get-VMHostInfo.ps1 -server $servers -path "E:\Reports" | |
Gathers a list of ESX/ESXi host names from E:\myhosts.txt and gathers\exports info to separate Excel workbooks located in E:\Reports | |
.NOTES | |
Author : Shawn Masterson | |
Export-Xlsx function from Gilbert van Griensven https://www.itpilgrims.com/2013/01/export-xlsx-extended/ | |
Excel is required to be installed on script host | |
Tested with ESX 4 and ESXi 4.1 thru 5.5 | |
#> | |
[CmdletBinding()] | |
Param ( | |
[parameter(Mandatory=$true)] | |
[String[]] | |
$server, | |
[parameter(Mandatory=$true)] | |
[String] | |
$path | |
) | |
### Supporting function ### | |
Function Export-Xlsx { | |
<# | |
.SYNOPSIS | |
Exports objects to an Excel workbook | |
.DESCRIPTION | |
Exports objects to an Excel workbook and applies cosmetics. Optionally add a title, autofilter, autofit and a chart. | |
Allows for export to .xls and .xlsx format. If .xlsx is specified but not available (Excel 2003) the data will be exported to .xls. | |
.PARAMETER InputObject | |
The data to be exported to Excel | |
.PARAMETER Path | |
The path of the Excel file. Defaults to %HomeDrive%\Export.xlsx. | |
.PARAMETER WorksheetName | |
The name of the worksheet. Defaults to filename in $Path without extension. | |
.PARAMETER ExpandArrayValues | |
Joins an array value to a newline separated list. | |
.PARAMETER ChartType | |
Name of an Excel chart to be added. | |
.PARAMETER TableStyle | |
Apply a style to the created table. Does not work in Excel 2003. | |
For an overview of styles see http://msdn.microsoft.com/fr-fr/library/documentformat.openxml.spreadsheet.tablestyle.aspx | |
The Pivot styles are not used in this function. | |
.PARAMETER Title | |
Adds a title to the worksheet. | |
.PARAMETER SheetPosition | |
Adds the worksheet either to the 'begin' or 'end' of the Excel file. | |
.PARAMETER TransposeColumnProperty | |
Selects a property of the input object which will be moved to the top row of the transposed table. | |
.PARAMETER ChartOnNewSheet | |
Adds a chart to a new worksheet instead of to the worksheet containing data. | |
The Chart will be placed after the sheet containing data. | |
.PARAMETER AppendWorksheet | |
Appends a worksheet to an existing Excel file. | |
.PARAMETER Borders | |
Adds borders to all cells. Defaults to True. | |
.PARAMETER HeaderColor | |
Applies background color to the header row. Defaults to True. | |
.PARAMETER AutoFit | |
Apply autofit to columns. Defaults to True. | |
.PARAMETER AutoFilter | |
Apply autofilter. Defaults to True. | |
.PARAMETER PassThru | |
Returns file object of the generated file. | |
.PARAMETER Force | |
Overwrites existing Excel sheet. When this switch is not used but the Excel file already exists, a new file with datestamp will be generated. | |
.PARAMETER Transpose | |
Transposes the data in Excel. This will automatically disable AutoFilter and HeaderColor. | |
.PARAMETER FreezePanes | |
Freezes the title row. | |
.EXAMPLE | |
Get-Process | Export-Xlsx -Path D:\Data\ProcessList.xlsx | |
Exports a list of running processes to Excel | |
.EXAMPLE | |
Get-ADuser -Filter {enabled -ne $True} | Select-Object Name,Surname,GivenName,DistinguishedName | Export-Xlsx -Path 'D:\Data\Disabled Users.xlsx' -Title 'Disabled users of Contoso.com' | |
Export all disabled AD users to Excel with optional title | |
.EXAMPLE | |
Get-Process | Sort-Object CPU -Descending | Export-Xlsx -Path D:\Data\Processes_by_CPU.xlsx | |
Export a sorted processlist to Excel | |
.EXAMPLE | |
Export-Xlsx (Get-Process) -AutoFilter:$False -PassThru | Invoke-Item | |
Export a processlist to %HomeDrive%\Export.xlsx with AutoFilter disabled, and open the Excel file | |
.NOTES | |
Author : Gilbert van Griensven | |
Based on http://www.lucd.info/2010/05/29/beyond-export-csv-export-xls/ | |
#> | |
[CmdletBinding(DefaultParametersetName="Default")] | |
Param ( | |
[Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)] | |
[ValidateNotNullOrEmpty()] | |
$InputObject, | |
[ValidateScript({ | |
$ReqExt = [System.IO.Path]::GetExtension($_) | |
($ReqExt -eq ".xls") -or | |
($ReqExt -eq ".xlsx") | |
})] | |
$Path=(Join-Path $env:HomeDrive "Export.xlsx"), | |
$WorksheetName = [System.IO.Path]::GetFileNameWithoutExtension($Path), | |
[Switch] $AppendWorksheet, | |
[ValidateSet("begin","end")] $SheetPosition="begin", | |
$Title, | |
[Switch] $AutoFit=$True, | |
[Switch] $AutoFilter=$True, | |
[Switch] $FreezePanes, | |
[Switch] $Transpose, | |
[String] $TransposeColumnProperty, | |
[Switch] $ExpandArrayValues, | |
[PSObject] $ChartType, | |
[Switch] $ChartOnNewSheet, | |
[Parameter(ParameterSetName="CustomStyle")] | |
[Switch] $Borders=$True, | |
[Parameter(ParameterSetName="CustomStyle")] | |
[Switch] $HeaderColor=$True, | |
[Parameter(ParameterSetName="TableStyle")] | |
[String] $TableStyle, | |
[Switch] $Force, | |
[Switch] $PassThru | |
) | |
DynamicParam { | |
# Adds custom argument completers for 'ChartType' and 'TableStyle' parameters for this function only | |
If ([Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Excel") -ne $Null) { | |
$Completion_xlChartType = { | |
Param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) | |
[Enum]::GetValues([Microsoft.Office.Interop.Excel.XlChartType]) | % { | |
New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', "$($_)" | |
} | |
} | |
$Completion_xlTableStyle = { | |
Param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) | |
1..28 | % { | |
@("TableStyleMedium$($_)") | |
If ($_ -le 21) { @("TableStyleLight$($_)") } | |
If ($_ -le 11) { @("TableStyleDark$($_)") } | |
} | | |
Sort-Object | % { | |
New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', "$($_)" | |
} | |
} | |
If (!($global:options)) { $global:options = @{CustomArgumentCompleters = @{};NativeArgumentCompleters = @{}} } | |
$global:options['CustomArgumentCompleters']['Export-Xlsx:ChartType'] = $Completion_xlChartType | |
$global:options['CustomArgumentCompleters']['Export-Xlsx:TableStyle'] = $Completion_xlTableStyle | |
$function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { If ($Null -ne $options) {$options += $global:options} Else {$options = $global:options}' | |
} | |
} | |
Begin { | |
Function Convert-NumberToA1 { | |
Param([parameter(Mandatory=$true)] [int]$number) | |
$a1Value = $null | |
While ($number -gt 0) { | |
$multiplier = [int][system.math]::Floor(($number / 26)) | |
$charNumber = $number - ($multiplier * 26) | |
If ($charNumber -eq 0) { $multiplier-- ; $charNumber = 26 } | |
$a1Value = [char]($charNumber + 96) + $a1Value | |
$number = $multiplier | |
} | |
Write-Verbose "Converted '$($number)' to '$($a1Value)'" | |
Return $a1Value | |
} | |
Function Using-Culture ([System.Globalization.CultureInfo]$Culture, [ScriptBlock]$Script) { | |
$OldCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture | |
Trap { [System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture } | |
[System.Threading.Thread]::CurrentThread.CurrentCulture = $Culture | |
$ExecutionContext.InvokeCommand.InvokeScript($Script) | |
[System.Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture | |
} | |
$Path = [System.IO.Path]::GetFullPath($Path) | |
$Script:WorkingData = @() | |
} | |
Process { | |
$Script:WorkingData += $InputObject | |
} | |
End { | |
If ($Script:WorkingData.Count -eq 0) { | |
$ExceptionMessage = New-Object System.FormatException "Input object is empty. Nothing to export to Excel." | |
Throw $ExceptionMessage | |
} | |
$Props = $Script:WorkingData[0].PSObject.properties | % { $_.Name } | |
Write-Verbose "$($Props.Count) object properties detected" | |
If ($Transpose) { | |
Write-Verbose "Setting up for transposed data collection" | |
If (($TransposeColumnProperty) -and ($Props -contains $TransposeColumnProperty)) { | |
$Props = $Props | ? {$_ -ne $TransposeColumnProperty} | |
$Rows = 1 | |
} Else { | |
$TransposeColumnProperty = $Null | |
$HeaderColor = $False | |
} | |
$Rows += $Props.Count | |
$Cols = $Script:WorkingData.Count+1 | |
$AutoFilter = $False | |
} Else { | |
Write-Verbose "Setting up for data collection" | |
$Rows = $Script:WorkingData.Count+1 | |
$Cols = $Props.Count | |
} | |
Write-Verbose "Input object has $($Rows) rows and $($Cols) columns" | |
$A1Cols = Convert-NumberToA1 $Cols | |
$Array = New-Object 'object[,]' $Rows,$Cols | |
$Col = 0 | |
$Row = 0 | |
Write-Verbose "Storing object properties as data headers into array" | |
If (($Transpose) -and ($TransposeColumnProperty)) { | |
$Array[$Row,$Col] = $TransposeColumnProperty | |
$Row++ | |
} | |
$Props | % { | |
$Array[$Row,$Col] = $_.ToString() | |
If ($Transpose) { | |
$Row++ | |
} Else { | |
$Col++ | |
} | |
} | |
Write-Verbose "Storing object data into array" | |
$Row = 1 | |
$Script:WorkingData | % { | |
$Item = $_ | |
$Col = 0 | |
$Props | % { | |
If (($Transpose) -and ($TransposeColumnProperty) -and ($Col -eq 0)) { | |
$Array[$Col,$Row] = $Item.($TransposeColumnProperty).ToString() | |
$Col++ | |
} | |
If ($Item.($_) -eq $Null) { | |
If ($Transpose) { | |
$Array[$Col,$Row] = "" | |
} Else { | |
$Array[$Row,$Col] = "" | |
} | |
} Else { | |
If (($Item.($_) -is [System.Array]) -and ($ExpandArrayValues)) { | |
$ItemData = [String]::Join("`r`n",$Item.($_)) | |
} Else { | |
$ItemData = $Item.($_).ToString() | |
} | |
If ($Transpose) { | |
$Array[$Col,$Row] = $ItemData | |
} Else { | |
$Array[$Row,$Col] = $ItemData | |
} | |
} | |
$Col++ | |
} | |
$Row++ | |
} | |
Using-Culture en-US { | |
Write-Verbose "Attempting to start Excel as COM object" | |
Try { $ExcelApplication = New-Object -ComObject Excel.Application } | |
Catch { | |
$ExceptionMessage = New-Object System.FormatException "Could not create COM object. Please ensure Microsoft Excel is installed." | |
Throw $ExceptionMessage | |
} | |
$ExcelApplication.DisplayAlerts = $False | |
$ExcelApplicationFixedFormat = [Microsoft.Office.Interop.Excel.XLFileFormat]::xlWorkbookNormal | |
If ([System.IO.Path]::GetExtension($Path) -eq '.xlsx') { | |
Write-Verbose "Selected file format: .xlsx" | |
If ($ExcelApplication.Version -lt 12) { | |
Write-Verbose "Current Excel version `($($ExcelApplication.Version)`)does not support .xlsx format. Switching to .xls format" | |
$Path = [System.IO.Path]::ChangeExtension($Path,".xls") | |
} Else { | |
$ExcelApplicationFixedFormat = [Microsoft.Office.Interop.Excel.XLFileFormat]::xlWorkbookDefault | |
} | |
} Else { | |
Write-Verbose "Selected file format: .xls" | |
} | |
If (Test-Path -Path $Path -PathType "Leaf") { | |
Write-Verbose "$($Path) exists" | |
If ($AppendWorkSheet) { | |
Write-Verbose "AppendWorkSheet parameter received. Attempting to open $($Path)" | |
$Workbook = $ExcelApplication.Workbooks.Open($Path) | |
If ($Workbook.ReadOnly) { | |
$Workbook.Close() | |
$ExcelApplication.Quit() | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)) {} | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelApplication)) {} | |
[GC]::Collect() | |
$ExceptionMessage = New-Object System.FormatException "The file $($Path) is marked read-only. Please check NTFS permissions and ensure the file is not open in other applications" | |
Throw $ExceptionMessage | |
} | |
If ($SheetPosition -eq "end") { | |
Write-Verbose "Setting sheet position to 'end'" | |
$Workbook.Worksheets.Add([System.Reflection.Missing]::Value,$Workbook.Sheets.Item($Workbook.Sheets.Count)) | Out-Null | |
} Else { | |
Write-Verbose "Setting sheet position to 'begin'" | |
$Workbook.Worksheets.Add($Workbook.Worksheets.Item(1)) | Out-Null | |
} | |
} Else { | |
If (!($Force)) { | |
$Path = $Path.Insert($Path.LastIndexOf(".")," - $(Get-Date -Format "ddMMyyyy-HHmm")") | |
Write-Verbose "No Force parameter specified. Target file is changed to: $($Path)" | |
} Else { | |
Write-Verbose "Force parameter specified. Overwriting existing file" | |
} | |
Write-Verbose "Adding new workbook" | |
$Workbook = $ExcelApplication.Workbooks.Add() | |
While ($Workbook.Worksheets.Count -gt 1) { $Workbook.Worksheets.Item(1).Delete() } | |
} | |
} Else { | |
Write-Verbose "$($Path) does not exist. Adding new workbook" | |
$Workbook = $ExcelApplication.Workbooks.Add() | |
While ($Workbook.Worksheets.Count -gt 1) { $Workbook.Worksheets.Item(1).Delete() } | |
} | |
$Worksheet = $Workbook.ActiveSheet | |
Try { $Worksheet.Name = $WorksheetName } | |
Catch { | |
Write-Verbose "!!! Unable to set worksheet name to $($WorksheetName)" | |
} | |
If ($Title) { | |
Write-Verbose "Adding title" | |
$Worksheet.Cells.Item(1,1) = $Title | |
$TitleRange = $Worksheet.Range("a1","$($A1Cols)2") | |
$TitleRange.Font.Size = 18 | |
$TitleRange.Font.Bold=$True | |
$TitleRange.Font.Name = "Cambria" | |
$TitleRange.Font.ThemeFont = 1 | |
$TitleRange.Font.ThemeColor = 4 | |
$TitleRange.Font.ColorIndex = 55 | |
$TitleRange.Font.Color = 8210719 | |
$TitleRange.Merge() | |
$TitleRange.VerticalAlignment = -4160 | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($TitleRange)) {} | |
$UsedRange = $Worksheet.Range("a3","$($A1Cols)$($Rows + 2)") | |
If ($HeaderColor) { | |
Write-Verbose "Setting header row background color" | |
$Worksheet.Range("a3","$($A1Cols)3").Interior.ColorIndex = 48 | |
$Worksheet.Range("a3","$($A1Cols)3").Font.Bold = $True | |
} | |
If (($FreezePanes) -and ((($Transpose) -and ($TransposeColumnProperty)) -or (!($Transpose)))) { | |
Write-Verbose "Freezing panes" | |
$Worksheet.Range("a4:a4").Select() | Out-Null | |
$ExcelApplication.ActiveWindow.FreezePanes = $True | |
} | |
} Else { | |
$UsedRange = $Worksheet.Range("a1","$($A1Cols)$($Rows)") | |
If ($HeaderColor) { | |
Write-Verbose "Setting header row background color" | |
$Worksheet.Range("a1","$($A1Cols)1").Interior.ColorIndex = 48 | |
$Worksheet.Range("a1","$($A1Cols)1").Font.Bold = $True | |
} | |
If (($FreezePanes) -and ((($Transpose) -and ($TransposeColumnProperty)) -or (!($Transpose)))) { | |
Write-Verbose "Freezing panes" | |
$Worksheet.Range("a2:a2").Select() | Out-Null | |
$ExcelApplication.ActiveWindow.FreezePanes = $True | |
} | |
} | |
Write-Verbose "Transferring array data to selected range in Excel" | |
$UsedRange.Value2 = $Array | |
$UsedRange.HorizontalAlignment = -4131 | |
$UsedRange.VerticalAlignment = -4160 | |
If ($Borders) { | |
Write-Verbose "Adding borders" | |
$UsedRange.Borders.LineStyle = 1 | |
$UsedRange.Borders.Weight = 2 | |
} | |
If ($AutoFilter) { | |
Write-Verbose "Applying autofilter" | |
$UsedRange.AutoFilter() | Out-Null | |
} | |
If ($AutoFit) { | |
Write-Verbose "Applying autofit" | |
$Worksheet.UsedRange.EntireColumn.AutoFit() | Out-Null | |
$Worksheet.UsedRange.EntireRow.AutoFit() | Out-Null | |
} | |
If (($TableStyle) -and ($ExcelApplication.Version -ge 12)) { | |
Write-Verbose "Applying table style '$($TableStyle)'" | |
$ListObject = $Worksheet.ListObjects.Add([Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, $UsedRange, $Null, [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes, $Null) | |
$ListObject.TableStyle = $TableStyle | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($ListObject)) {} | |
} | |
If ($ChartType) { | |
Try { | |
Write-Verbose "Attempting to add chart of type '$($ChartType)'" | |
[Microsoft.Office.Interop.Excel.XlChartType]$ChartType = $ChartType | |
If ($ChartOnNewSheet) { | |
Write-Verbose "Adding chart to new worksheet" | |
$Workbook.Charts.Add().ChartType = $ChartType | |
$Workbook.ActiveChart.setSourceData($UsedRange) | |
Try { $Workbook.ActiveChart.Name = "$($WorksheetName) - Chart" } | |
Catch { } | |
$Workbook.ActiveChart.Move([System.Reflection.Missing]::Value,$Workbook.Sheets.Item($Worksheet.Name)) | |
} Else { | |
Write-Verbose "Adding chart to current sheet" | |
$Worksheet.Shapes.AddChart($ChartType).Chart.setSourceData($UsedRange) | Out-Null | |
} | |
} | |
Catch { | |
Write-Verbose "!!! '$($ChartType)' is not a valid Excel chart type. Use tab expansion to choose between valid chart types." | |
} | |
} | |
Write-Verbose "Saving Excel workbook to $($Path)" | |
$Workbook.Worksheets.Item(1).Select() | |
Try { $Workbook.SaveAs($Path,$ExcelApplicationFixedFormat) } | |
Catch { $ExceptionMessage = New-Object System.FormatException "Unable to save to $($Path). Please ensure you have write access." } | |
Write-Verbose "Closing Excel and cleaning up references" | |
$Workbook.Close() | |
$ExcelApplication.Quit() | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($UsedRange)) {} | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($Worksheet)) {} | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($Workbook)) {} | |
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($ExcelApplication)) {} | |
[GC]::Collect() | |
If ($ExceptionMessage) { Throw $ExceptionMessage } | |
} | |
If ($PassThru) { Return Get-Item $Path } | |
} | |
} | |
### Main script begin ### | |
# Test path | |
If (!(Test-Path $path)) { | |
Write-Host "Path not found - $path" -ForegroundColor Red | |
Exit | |
} | |
# Obtain Credentials | |
$creds = Get-Credential -Message "Enter ESX/ESXi host credentials used to connect" -UserName root | |
# Cycle through servers gathering and exporting info | |
Foreach ($ESX in $Server) { | |
# Create full path to Excel workbook | |
$FullPath = $Path.Trimend('\') + "\HostInfo_" + $ESX + "_" + (Get-Date -Format MM-dd-yyyy) + ".xlsx" | |
# Connect to ESX/ESXi host | |
$connection = Connect-VIServer $ESX -Credential $creds | |
# Ensure connection | |
If ($connection) { | |
Write-Host "Connected to $ESX" | |
# Get ESX(i) Host Info | |
$VMHost = Get-VMHost $ESX | |
$VMHostProp = [ordered]@{} | |
$VMHostProp.Name = $VMHost.NetworkInfo.HostName | |
$VMHostProp."Domain Name" = $VMHost.NetworkInfo.DomainName | |
$VMHostProp.Hypervisor = $VMHost.Extensiondata.Config.Product.FullName | |
$VMHostProp.License = $VMHost.LicenseKey | |
$VMHostProp.Vendor = $VMHost.Manufacturer | |
$VMHostProp.Model = $VMHost.Model | |
$VMHostProp."BIOS Version" = $VMHost.Extensiondata.Hardware.BiosInfo.BiosVersion | |
$VMHostProp."CPU Model" = $VMHost.ProcessorType | |
$VMHostProp."CPU Count" = $VMHost.ExtensionData.Summary.Hardware.NumCpuPkgs | |
$VMHostProp."Total Cores" = $VMHost.ExtensionData.Summary.Hardware.numCpuCores | |
$VMHostProp."Total Threads" = $VMHost.ExtensionData.Summary.Hardware.numCpuThreads | |
$VMHostProp."Hyperthreading Enabled" = $VMHost.HyperThreadingActive | |
$VMHostProp."CPU Current Usage (Mhz)" = $VMHost.CpuUsageMhz | |
$VMHostProp."Memory (GB)" = [Math]::Round($VMHost.MemoryTotalGB,0) | |
$VMHostProp."Memory Current Usage (GB)" = [Math]::Round($VMHost.MemoryUsageGB,0) | |
$VMHostProp."FC HBAs" = ($VMHost | Get-VMHostHba | where {$_.Type -eq "FibreChannel"}).Count | |
$VMHostProp."iSCSI HBAs" = ($VMHost | Get-VMHostHba | where {$_.Type -eq "IScsi"}).Count | |
$VMHostProp."Physical NICs" = $VMHost.ExtensionData.Config.Network.Pnic.Count | |
If ($VMHost.NetworkInfo.VMKernelGateway) { | |
$VMHostProp."VMKernel Gateway" = $VMHost.NetworkInfo.VMKernelGateway | |
} Else { | |
$VMHostProp."Console Gateway" = $VMHost.NetworkInfo.ConsoleGateway | |
} | |
Try { | |
$domainStatus = "" | |
$domainStatus = $VMHost | Get-VMHostAuthentication -ErrorAction Stop | |
$VMHostProp."Authentication Domain" = If ($domainStatus.Domain){$domainStatus.Domain} Else {"Not Configured"} | |
$VMHostProp."Authentication Domain Status" = If ($domainStatus.DomainMembershipStatus){$domainStatus.DomainMembershipStatus} Else {"Unknown"} | |
$VMHostProp."Trusted Domains" = If ($domainStatus.Trusteddomains) {$domainStatus | Select -ExpandProperty TrustedDomains | Out-String} Else {"None"} | |
} Catch {} | |
$VMHostProp."DNS Server(s)" = $VMHost.ExtensionData.Config.Network.DnsConfig.Address | Out-String | |
$VMHostProp."Search Domain(s)" = $VMHost.NetworkInfo.SearchDomain | Out-String | |
$VMHostProp.TimeZone = $VMHost.TimeZone | |
$VMHostProp."NTP Server(s)" = $VMHost | Get-VMHostNtpServer | Out-String | |
Try { | |
$VMHostProp."Syslog Server(s)" = $VMHost | Get-VMHostSysLogServer -ErrorAction Stop | %{$_.Host + ":" + $_.Port} | Out-String | |
} Catch { | |
$VMHostProp."Syslog Server(s)" = "Unavailable" | |
} | |
Try { | |
$VMHostProp."Firewall Default Allow Incoming" = $VMHost | Get-VMHostFirewallDefaultPolicy -ErrorAction Stop | Select -ExpandProperty IncomingEnabled | |
$VMHostProp."Firewall Default Allow Outgoing" = $VMHost | Get-VMHostFirewallDefaultPolicy -ErrorAction Stop | Select -ExpandProperty OutgoingEnabled | |
} Catch {} | |
$VMHostProp."VM Count" = ($VMHost | Get-VM).Count | |
$VMHostProp."Report Created" = Get-Date | |
$VMHostInfo = New-Object –TypeName PSObject –Prop $VMHostProp | |
$VMHostInfo | Export-Xlsx -Path $FullPath -WorksheetName "ESX(i) Info" -Title "VMHost Information" -Transpose -Borders:$false -Force | |
# Get HBA Info | |
$HBAInfo = @() | |
$HBAs = $VMHost | Get-VMHostHba | |
Foreach ($HBA in $HBAs) { | |
$HBAProp = [ordered]@{} | |
$HBAProp.Device = $HBA.Device | |
$HBAProp."HBA Model" = $HBA.Model | |
$HBAProp."HBA Type" = $HBA.Type | |
$HBAProp.Driver = $HBA.Driver | |
$HBAProp.PCI = $HBA.PCI | |
$NWWN = $null | |
$NWWNFormatted = $null | |
[String] $NWWN = "{0:x}" -f $HBA.NodeWorldWideName | |
If ($NWWN) { | |
For ($i=0;$i -lt 8;$i++) | |
{ | |
$NWWNFormatted += "{0}:" -f $($NWWN.SubString($i * 2, 2)) | |
} | |
$NWWNFormatted = $NWWNFormatted.SubString(0, $NWWNFormatted.Length - 1) | |
} | |
$PWWN = $null | |
$PWWNFormatted = $null | |
[String] $PWWN = "{0:x}" -f $HBA.PortWorldWideName | |
If ($PWWN) { | |
For ($i=0;$i -lt 8;$i++) | |
{ | |
$PWWNFormatted += "{0}:" -f $($PWWN.SubString($i * 2, 2)) | |
} | |
$PWWNFormatted = $PWWNFormatted.SubString(0, $PWWNFormatted.Length - 1) | |
} | |
$HBAProp.NWWN = $NWWNFormatted | |
$HBAProp.PWWN = $PWWNFormatted | |
$HBAProp."Software Based" = $HBA.IsSoftwareBased | |
$HBAProp."iSCSI Name" = $HBA.IScsiName | |
$HBAProp."iSCSI Alias" = $HBA.IScsiAlias | |
$HBAProp.Status = $HBA.Status | |
$HBATemp = New-Object –TypeName PSObject –Prop $HBAProp | |
$HBAInfo += $HBATemp | |
} | |
If ($HBAInfo) { | |
$HBAInfo | Export-Xlsx -Path $FullPath -WorksheetName "HBA Info" -Title "HBA Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Host Disks | |
$diskInfo = @() | |
$disks = $VMHost | Get-VMHostDisk | |
ForEach ($disk in $disks) { | |
$diskProp = [ordered]@{} | |
$diskProp."Device Name" = $disk.DeviceName | |
$diskProp."SCSI LUN" = $disk.ScsiLun | |
$diskProp.Cylinders = $disk.Cylinders | |
$diskProp.Heads = $disk.Heads | |
$diskProp.Sectors = $disk.Sectors | |
$diskProp.TotalSectors = $disk.TotalSectors | |
$diskTemp = New-Object –TypeName PSObject –Prop $diskProp | |
$diskInfo += $diskTemp | |
} | |
If ($diskInfo) { | |
$diskInfo | Sort "Device Name" | Export-Xlsx -Path $FullPath -WorksheetName "Disks" -Title "Host Disks" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get SCSI LUNs | |
$lunInfo = @() | |
$scsiLuns = $VMHost | Get-ScsiLun | |
ForEach ($scsiLun in $scsiLuns) { | |
$scsiLunProp = [ordered]@{} | |
$scsiLunProp."Runtime Name" = $scsiLun.RuntimeName | |
$scsiLunProp."Canonical Name" = $scsiLun.CanonicalName | |
$scsiLunProp."Device Path" = $scsiLun.ConsoleDeviceName | |
$scsiLunProp.Type = $scsiLun.LunType | |
$scsiLunProp.Vendor = $scsiLun.Vendor | |
$scsiLunProp.Model = $scsiLun.Model | |
$scsiLunProp."Serial Number" = $scsiLun.SerialNumber | |
$scsiLunProp."Capacity (GB)" = [Math]::Round($scsiLun.CapacityGB,2) | |
$scsiLunProp."Multipath Policy" = $scsiLun.MultipathPolicy | |
$scsiLunProp.Local = $scsiLun.IsLocal | |
$scsiLunProp.SSD = $scsiLun.ExtensionData.Ssd | |
$scsiLunProp.UUID = $scsiLun.ExtensionData.Uuid | |
$scsiLunTemp = New-Object –TypeName PSObject –Prop $scsiLunProp | |
$lunInfo += $scsiLunTemp | |
} | |
If ($lunInfo) { | |
$lunInfo | Sort Type | Export-Xlsx -Path $FullPath -WorksheetName "SCSI LUNs" -Title "SCSI LUNs" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Multipathing Info | |
$pathInfo = @() | |
$luns = $VMhost.ExtensionData.config.storagedevice.multipathinfo.lun | |
ForEach ($lun in $luns) { | |
$lunName = $lun.Id | |
$lunPolicy = $lun.policy.policy | |
$lunPaths = $lun.path | |
Foreach ($lunPath in $lunPaths) { | |
$pathProp = [ordered]@{} | |
$pathProp."LUN ID" = $lunName | |
$pathProp."LUN Policy" = $lunPolicy | |
$pathProp.State = $lunPath.pathstate | |
$pathProp."Path Name" = $lunPath.Name | |
$pathProp."Adapter Name" = ($lunPath.Name).Split("-")[0] | |
$pathProp."Target Name" = ($lunPath.Name).Split("-")[1] | |
$pathProp."LUN Name" = ($lunPath.Name).Split("-")[2] | |
$pathTemp = New-Object –TypeName PSObject –Prop $pathProp | |
$pathInfo += $pathTemp | |
} | |
} | |
If ($pathInfo) { | |
$pathInfo | Sort "LUN ID" | Export-Xlsx -Path $FullPath -WorksheetName "Multipath Info" -Title "Multipath Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get iSCSI HBA Targets | |
$iscsiTargetInfo = @() | |
$iscsiTargets = Get-IScsiHbaTarget -Server $ESX | |
ForEach ($iscsiTarget in $iscsiTargets) { | |
$iscsiTargetProp = [ordered]@{} | |
$iscsiTargetProp.Name = $iscsiTarget.Name | |
$iscsiTargetProp."iSCSI Name" = $iscsiTarget.IScsiName | |
$iscsiTargetProp.Address = $iscsiTarget.Address | |
$iscsiTargetProp.Port = $iscsiTarget.Port | |
$iscsiTargetProp.Authentication = $iscsiTarget.AuthenticationProperties | |
$iscsiTargetProp.Type = $iscsiTarget.Type | |
$iscsiTargetProp."iSCSI HBA Name" = $iscsiTarget.IScsiHbaName | |
$iscsiTargetTemp = New-Object –TypeName PSObject –Prop $iscsiTargetProp | |
$iscsiTargetInfo += $iscsiTargetTemp | |
} | |
If ($iscsiTargetInfo) { | |
$iscsiTargetInfo | Sort Name | Export-Xlsx -Path $FullPath -WorksheetName "iSCSI Targets" -Title "iSCSI HBA Targets" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Host Diagnostic Partitions | |
$diagInfo = @() | |
$diags = $VMHost | Get-VMHostDiagnosticPartition | |
ForEach ($diag in $diags) { | |
$diagProp = [ordered]@{} | |
$diagProp."Canonical Name" = $diag.CanonicalName | |
$diagProp."Diagnostic Type" = $diag.DiagnosticType | |
$diagProp."Storage Type" = $diag.StorageType | |
$diagProp.Slots = $diag.SlotCount | |
$diagProp.Active = $diag.Active | |
$diagTemp = New-Object –TypeName PSObject –Prop $diagProp | |
$diagInfo += $diagTemp | |
} | |
If ($diagInfo) { | |
$diagInfo | Sort Active -Descending | Export-Xlsx -Path $FullPath -WorksheetName "Diagnostic Partitions" -Title "Diagnostic Partitions" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Datastore Info | |
$DSInfo = @() | |
$DSs = $VMHost | Get-Datastore | |
Foreach ($DS in $DSs) { | |
$DSProp = [ordered]@{} | |
$DSProp.Name = $DS.Name | |
$DSProp.Type = $DS.Type | |
$DSProp."Size (GB)" = [Math]::Round($DS.CapacityGB,2) | |
$DSProp."Used (GB)" = [Math]::Round($DS.CapacityGB - $DS.FreeSpaceGB,2) | |
$DSProp."Free (GB)" = [Math]::Round($DS.FreeSpaceGB,2) | |
$usedPerc = ($DS.CapacityGB - $DS.FreeSpaceGB)/$DS.CapacityGB | |
$DSProp."Used %" = "{0:P1}" -f $usedPerc | |
$DSProp."Mount Point" = $DS.ExtensionData.Info.Url | |
$DSProp.Extents = If ($DS.Type -eq "VMFS"){$DS.ExtensionData.Info.Vmfs.Extent.DiskName} | |
ElseIf ($DS.Type -eq "NFS"){$DS.ExtensionData.Info.Nas.RemoteHost + ":" + $DS.ExtensionData.Info.Nas.RemotePath} | |
$DSProp.StorageIOControlEnabled = $DS.StorageIOControlEnabled | |
$DSProp.FileSystemVersion = $DS.FileSystemVersion | |
$DSProp.BlockSize = $DS.ExtensionData.Info.Vmfs.BlockSizeMB | |
$DSProp.SSD = $DS.ExtensionData.Info.Vmfs.Ssd | |
$DSProp.Local = $DS.ExtensionData.Info.Vmfs.Local | |
$DSProp."VM Count" = ($DS | Get-VM).Count | |
$DSProp.State = $DS.State | |
$DSTemp = New-Object –TypeName PSObject –Prop $DSProp | |
$DSInfo += $DSTemp | |
} | |
If ($DSInfo) { | |
$DSInfo | Sort Name | Export-Xlsx -Path $FullPath -WorksheetName "Datastores" -Title "Datastores" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Datastore Chart | |
$DSInfo = @() | |
Foreach ($DS in $DSs) { | |
$DSProp = [ordered]@{} | |
$DSProp.Name = $DS.Name | |
$DSProp."Used (GB)" = [Math]::Round($DS.CapacityGB - $DS.FreeSpaceGB,2) | |
$DSProp."Free (GB)" = [Math]::Round($DS.FreeSpaceGB,2) | |
$DSTemp = New-Object –TypeName PSObject –Prop $DSProp | |
$DSInfo += $DSTemp | |
} | |
If ($DSInfo) { | |
$DSInfo | Sort Name | Export-Xlsx -Path $FullPath -WorksheetName "Datastores - Chart" -Title "Datastores - Chart" -ChartType xlColumnStacked -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Physical NIC Info | |
$pNICInfo = @() | |
$NICs = $VMHost | Get-VMHostNetworkAdapter -Physical | |
Foreach ($NIC in $NICs) { | |
$NICProp = [ordered]@{} | |
$NICProp.pNIC = $NIC.DeviceName | |
$NICProp.Model = ($VMHost.ExtensionData.Hardware.PciDevice | where {$_.Id -eq $NIC.ExtensionData.Pci}).DeviceName | |
$NICProp.Driver = $NIC.ExtensionData.Driver | |
$NICProp."Speed (MB)" = $NIC.ExtensionData.LinkSpeed.SpeedMB | |
$NICProp."Full Duplex" = $NIC.ExtensionData.LinkSpeed.Duplex | |
$NICProp.MAC = $NIC.Mac | |
$NICProp."PCI Location" = $NIC.ExtensionData.Pci | |
$NICProp.vSwitch = ($VMHost | Get-VirtualSwitch | where {$_.Nic -contains $NIC.DeviceName}).Name | |
$NICTemp = New-Object –TypeName PSObject –Prop $NICProp | |
$pNICInfo += $NICTemp | |
} | |
If ($pNICInfo) { | |
$pNICInfo | Export-Xlsx -Path $FullPath -WorksheetName "pNIC Info" -Title "Physical NIC Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get VMKernel Virtual Network Adapter Info | |
$vNICInfo = @() | |
$vNICs = $VMHost | Get-VMHostNetworkAdapter -VMKernel | |
Foreach ($vNIC in $vNICs) { | |
$vNICProp = [ordered]@{} | |
$vNICProp.VMKernel = $vNIC.DeviceName | |
$vNICProp.MAC = $vNIC.Mac | |
$vNICProp.MTU = $vNIC.Mtu | |
$vNICProp.IPv6Enabled = $vNIC.IPv6Enabled | |
$vNICProp.DHCPEnabled = $vNIC.DhcpEnabled | |
$vNICProp.IP = $vNIC.IP | |
$vNICProp.SubnetMask = $vNIC.SubnetMask | |
$vNICProp.PortGroupName = $vNIC.PortGroupName | |
$vNICProp.MgmtEnabled = $vNIC.ManagementTrafficEnabled | |
$vNICProp.vMotionEnabled = $vNIC.vMotionEnabled | |
$vNICProp.FTEnabled = $vNIC.FaultToleranceLoggingEnabled | |
$vNICProp.VSANEnabled = $vNIC.VsanTrafficEnabled | |
$vNICTemp = New-Object –TypeName PSObject –Prop $vNICProp | |
$vNICInfo += $vNICTemp | |
} | |
If ($vNICInfo) { | |
$vNICInfo | Export-Xlsx -Path $FullPath -WorksheetName "VMKernel Info" -Title "VMKernel Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Service Console Info | |
$cNICInfo = @() | |
$cNICs = $VMHost | Get-VMHostNetworkAdapter -Console | |
Foreach ($cNIC in $cNICs) { | |
$cNICProp = [ordered]@{} | |
$cNICProp.cNIC = $cNIC.DeviceName | |
$cNICProp.MAC = $cNIC.Mac | |
$cNICProp.DHCPEnabled = $cNIC.DhcpEnabled | |
$cNICProp.IP = $cNIC.IP | |
$cNICProp.SubnetMask = $cNIC.SubnetMask | |
$cNICProp.PortGroupName = $cNIC.PortGroupName | |
$cNICTemp = New-Object –TypeName PSObject –Prop $cNICProp | |
$cNICInfo += $cNICTemp | |
} | |
If ($cNICInfo) { | |
$cNICInfo | Export-Xlsx -Path $FullPath -WorksheetName "Service Console Info" -Title "Service Console Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Standard Switch Info | |
$sSwInfo = @() | |
$sSwitchs = $VMHost | Get-VirtualSwitch -Standard | |
Foreach ($sSwitch in $sSwitchs) { | |
$sSwProp = [ordered]@{} | |
$sSwProp.Name = $sSwitch.Name | |
$sSwProp.MTU = $sSwitch.Mtu | |
$sSwProp."pNIC(s)" = $sSwitch.Nic | Out-String | |
$sSwProp."Load Balancing" = $sSwitch.ExtensionData.Spec.Policy.NicTeaming.Policy | |
$sSwProp."Network Failure Detection" = If ($sSwitch.ExtensionData.Spec.Policy.NicTeaming.FailureCriteria.CheckBeacon) { | |
"Beacon probing"} Else {"Link status only"} | |
$sSwProp."Notify Switches" = $sSwitch.ExtensionData.Spec.Policy.NicTeaming.NotifySwitches | |
$sSwProp."Failback" = $sSwitch.ExtensionData.Spec.Policy.NicTeaming.ReversePolicy | |
$sSwProp."Active pNIC(s)" = $sSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.ActiveNic | Out-String | |
$sSwProp."Standby pNIC(s)" = $sSwitch.ExtensionData.Spec.Policy.NicTeaming.NicOrder.StandbyNic | Out-String | |
$sSwProp."Promiscuous Mode" = $sSwitch.ExtensionData.Spec.Policy.Security.AllowPromiscuous | |
$sSwProp."Mac Address Changes" = $sSwitch.ExtensionData.Spec.Policy.Security.MacChanges | |
$sSwProp."Forged Transmits" = $sSwitch.ExtensionData.Spec.Policy.Security.ForgedTransmits | |
$sSwProp."Traffic Shaping Enabled" = $sSwitch.ExtensionData.Spec.Policy.ShapingPolicy.Enabled | |
$sSwProp."Average Bandwidth" = $sSwitch.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth | |
$sSwProp."Peak Bandwidth" = $sSwitch.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth | |
$sSwProp."Burst Size" = $sSwitch.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize | |
$sSwProp."Portgroup(s)" = $sSwitch | Get-VirtualPortGroup | Select -ExpandProperty Name | Out-String | |
$sSwTemp = New-Object –TypeName PSObject –Prop $sSwProp | |
$sSwInfo += $sSwTemp | |
} | |
If ($sSwInfo) { | |
$sSwInfo | Export-Xlsx -Path $FullPath -WorksheetName "Standard Switch Info" -Title "Standard Switch Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Distributed Switch Information | |
$dvSwInfo = @() | |
$dvSwitchs = $VMHost | Get-VDSwitch | |
Foreach ($dvSwitch in $dvSwitchs) { | |
$dvSwProp = [ordered]@{} | |
$dvSwProp.Name = $dvSwitch.Name | |
$dvSwProp.MTU = $dvSwitch.Mtu | |
$dvSwProp."Overall Status" = $dvSwitch.ExtensionData.OverallStatus | |
$dvSwProp."Config Status" = $dvSwitch.ExtensionData.ConfigStatus | |
$dvSwProp.Note = "vCenter needed for further info" | |
$dvSwTemp = New-Object –TypeName PSObject –Prop $dvSwProp | |
$dvSwInfo += $dvSwTemp | |
} | |
If ($dvSwInfo) { | |
$dvSwInfo | Export-Xlsx -Path $FullPath -WorksheetName "Distributed Switch Info" -Title "Distributed Switch Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Standard Portgroup Information | |
$sPortInfo = @() | |
$sPortGroups = $VMHost | Get-VirtualPortGroup -Standard | |
Foreach ($sPortGroup in $sPortGroups) { | |
$sPortProp = [ordered]@{} | |
$sPortProp."Virtual Switch" = $sPortGroup.VirtualSwitchName | |
$sPortProp.Portgroup = $sPortGroup.Name | |
$sPortProp.VLAN = $sPortGroup.Vlanid | |
$sPortProp."Load Balancing" = $sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.Policy | |
$sPortProp."Network Failure Detection" = If ($sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.FailureCriteria.CheckBeacon) { | |
"Beacon probing"} Else {"Link status only"} | |
$sPortProp."Notify Switches" = $sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.NotifySwitches | |
$sPortProp."Failback" = $sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.ReversePolicy | |
$sPortProp."Active pNIC(s)" = $sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.NicOrder.ActiveNic | Out-String | |
$sPortProp."Standby pNIC(s)" = $sPortGroup.ExtensionData.ComputedPolicy.NicTeaming.NicOrder.StandbyNic | Out-String | |
$sPortProp."Promiscuous Mode" = $sPortGroup.ExtensionData.ComputedPolicy.Security.AllowPromiscuous | |
$sPortProp."Mac Address Changes" = $sPortGroup.ExtensionData.ComputedPolicy.Security.MacChanges | |
$sPortProp."Forged Transmits" = $sPortGroup.ExtensionData.ComputedPolicy.Security.ForgedTransmits | |
$sPortProp."Traffic Shaping Enabled" = $sPortGroup.ExtensionData.ComputedPolicy.ShapingPolicy.Enabled | |
$sPortProp."Average Bandwidth" = $sPortGroup.ExtensionData.ComputedPolicy.ShapingPolicy.AverageBandwidth | |
$sPortProp."Peak Bandwidth" = $sPortGroup.ExtensionData.ComputedPolicy.ShapingPolicy.PeakBandwidth | |
$sPortProp."Burst Size" = $sPortGroup.ExtensionData.ComputedPolicy.ShapingPolicy.BurstSize | |
$sPortProp."VM Count" = ($sPortGroup | Get-VM).Count | |
$sPortTemp = New-Object –TypeName PSObject –Prop $sPortProp | |
$sPortInfo += $sPortTemp | |
} | |
If ($sPortInfo) { | |
$sPortInfo | Sort "Virtual Switch", Portgroup | Export-Xlsx -Path $FullPath -WorksheetName "Standard Portgroup Info" -Title "Standard Portgroup Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Distributed Portgroup Information | |
$dvPortInfo = @() | |
$dvPortGroups = Get-VDPortgroup -Server $ESX | |
Foreach ($dvPortGroup in $dvPortGroups) { | |
$dvPortProp = [ordered]@{} | |
$dvPortProp."Virtual Switch" = $dvPortGroup.VDSwitch | |
$dvPortProp.Portgroup = $dvPortGroup.Name | |
$dvPortProp."Port Binding" = $dvPortGroup.PortBinding | |
$dvPortProp."Overall Status" = $dvPortGroup.ExtensionData.OverallStatus | |
$dvPortProp."Config Status" = $dvPortGroup.ExtensionData.ConfigStatus | |
$dvPortProp.Note = "vCenter needed for further info" | |
$dvPortTemp = New-Object –TypeName PSObject –Prop $dvPortProp | |
$dvPortInfo += $dvPortTemp | |
} | |
If ($dvPortInfo) { | |
$dvPortInfo | Sort "Virtual Switch", Portgroup | Export-Xlsx -Path $FullPath -WorksheetName "Distributed Portgroup Info" -Title "Distributed Portgroup Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Firewall Exceptions | |
$fwInfo = @() | |
Try { | |
$fwExceptions = $VMHost | Get-VMHostFirewallException -ErrorAction Stop | |
Foreach ($fwException in $fwExceptions) { | |
$fwProp = [ordered]@{} | |
$fwProp.Enabled = $fwException.Enabled | |
$fwProp.Name = $fwException.Name | |
$fwProp."Incoming Ports" = $fwException.IncomingPorts | |
$fwProp."Outgoing Ports" = $fwException.OutgoingPorts | |
$fwProp."Protocol(s)" = $fwException.Protocols | |
$fwProp."Allow all IPs" = $fwException.ExtensionData.AllowedHosts.AllIp | |
$fwProp.Service = $fwException.ExtensionData.Service | |
$fwProp."Service Running" = $fwException.ServiceRunning | |
$fwTemp = New-Object –TypeName PSObject –Prop $fwProp | |
$fwInfo += $fwTemp | |
} | |
} Catch {} | |
If ($fwInfo) { | |
$fwInfo | Sort Enabled, Name | Export-Xlsx -Path $FullPath -WorksheetName "Firewall Exceptions" -Title "Firewall Exceptions" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Services Information | |
$svcInfo = @() | |
$services = $VMHost | Get-VMHostService | |
Foreach ($service in $services) { | |
$svcProp = [ordered]@{} | |
$svcProp.Service = $service.Label | |
$svcProp.Key = $service.Key | |
$svcProp.Running = $service.Running | |
switch ($service.Policy) | |
{ | |
"on" {$svcProp."Startup Policy" = "Start and stop with host"} | |
"off" {$svcProp."Startup Policy" = "Start and stop manually"} | |
"automatic" {$svcProp."Startup Policy" = "Start and stop with port usage"} | |
default {$svcProp."Startup Policy" = "Unknown"} | |
} | |
$svcProp.Required = $service.Required | |
$svcProp.Uninstallable = $service.Uninstallable | |
$svcProp."Source Package" = $service.ExtensionData.SourcePackage.SourcePackageName | |
$svcProp."Source Package Desc" = $service.ExtensionData.SourcePackage.Description | |
$svcTemp = New-Object –TypeName PSObject –Prop $svcProp | |
$svcInfo += $svcTemp | |
} | |
If ($svcInfo) { | |
$svcInfo | Sort Service | Export-Xlsx -Path $FullPath -WorksheetName "Services Info" -Title "Services Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get SNMP Info | |
$snmpInfo = @() | |
$snmpDetails = Get-VMHostSnmp -Server $ESX | |
$snmpProp = [ordered]@{} | |
$snmpProp.Enabled = $snmpDetails.Enabled | |
$snmpProp.Port = $snmpDetails.Port | |
$snmpProp."Read Only Communities" = $snmpDetails.ReadOnlyCommunities | Out-String | |
$snmpProp."Trap Targets" = $snmpDetails.TrapTargets | Out-String | |
$snmpTemp = New-Object –TypeName PSObject –Prop $snmpProp | |
$snmpInfo += $snmpTemp | |
If ($snmpInfo) { | |
$snmpInfo | Export-Xlsx -Path $FullPath -WorksheetName "SNMP Info" -Title "SNMP Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Installed ESX(i) Patches | |
$patchInfo = @() | |
Try { | |
$patches = (Get-EsxCli).software.vib.list() | |
ForEach ($patch in $patches) { | |
$patchProp = [ordered]@{} | |
$patchProp.Name = $patch.Name | |
$patchProp.ID = $patch.ID | |
$patchProp.Vendor = $patch.Vendor | |
$patchProp.Version = $patch.Version | |
$patchProp."Acceptance Level" = $patch.AcceptanceLevel | |
$patchProp."Created Date" = $patch.CreationDate | |
$patchProp."Install Date" = $patch.InstallDate | |
$patchProp.Status = $patch.Status | |
$patchTemp = New-Object –TypeName PSObject –Prop $patchProp | |
$patchInfo += $patchTemp | |
} | |
} Catch { | |
$patches = $VMHost | Get-VMHostPatch | |
ForEach ($patch in $patches) { | |
$patchProp = [ordered]@{} | |
$patchProp.Name = $patch.Description | |
$patchProp.ID = $patch.ID | |
$patchProp."Install Date" = $patch.InstallDate | |
$patchTemp = New-Object –TypeName PSObject –Prop $patchProp | |
$patchInfo += $patchTemp | |
} | |
} | |
If ($patchInfo) { | |
$patchInfo | Sort "Install Date" -Descending | Export-Xlsx -Path $FullPath -WorksheetName "Patch Info" -Title "Patch Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Local Users | |
$accountInfo = @() | |
$accounts = Get-VMHostAccount -Server $ESX | |
ForEach ($account in $accounts) { | |
$accountProp = [ordered]@{} | |
$accountProp.Name = $account.Name | |
$accountProp.Description = $account.Description | |
$accountProp.ShellAccess = $account.ShellAccessEnabled | |
$accountProp.Groups = $account.Groups | Out-String | |
$accountTemp = New-Object –TypeName PSObject –Prop $accountProp | |
$accountInfo += $accountTemp | |
} | |
If ($accountInfo) { | |
$accountInfo | Sort IsSystem, Name | Export-Xlsx -Path $FullPath -WorksheetName "Local Users" -Title "Local Users" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Local Groups | |
$grpInfo = @() | |
Try { | |
$grps = Get-VMHostAccount -Server $ESX -Group -ErrorAction Stop | |
ForEach ($grp in $grps) { | |
$grpProp = [ordered]@{} | |
$grpProp.Name = $grp.Name | |
$grpProp.Description = $grp.Description | |
$grpProp.Users = $grp.Users | Out-String | |
$grpTemp = New-Object –TypeName PSObject –Prop $grpProp | |
$grpInfo += $grpTemp | |
} | |
} Catch {} | |
If ($grpInfo) { | |
$grpInfo | Sort Name | Export-Xlsx -Path $FullPath -WorksheetName "Local Groups" -Title "Local Groups" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get VI Roles | |
$roleInfo = @() | |
$roles = Get-VIRole -Server $ESX | |
ForEach ($role in $roles) { | |
$roleProp = [ordered]@{} | |
$roleProp.Name = $role.Name | |
$roleProp.Description = $role.Description | |
$roleProp.IsSystem = $role.IsSystem | |
$roleProp.Privileges = $role.PrivilegeList | Out-String | |
$roleTemp = New-Object –TypeName PSObject –Prop $roleProp | |
$roleInfo += $roleTemp | |
} | |
If ($roleInfo) { | |
$roleInfo | Sort IsSystem, Name | Export-Xlsx -Path $FullPath -WorksheetName "VI Roles" -Title "VI Roles" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get Permissions | |
$permInfo = @() | |
$perms = Get-VIPermission -Server $ESX | |
ForEach ($perm in $perms) { | |
$permProp = [ordered]@{} | |
$permProp.Entity = $perm.Entity | |
$permProp.Role = $perm.Role | |
$permProp.Principal = $perm.Principal | |
$permProp.IsGroup = $perm.IsGroup | |
$permProp.Propagate = $perm.Propagate | |
$permTemp = New-Object –TypeName PSObject –Prop $permProp | |
$permInfo += $permTemp | |
} | |
If ($permInfo) { | |
$permInfo | Sort Entity, Principal | Export-Xlsx -Path $FullPath -WorksheetName "Permissions" -Title "Permissions" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get VM Info | |
$vmInfo = @() | |
$vms = $VMHost | Get-VM | |
ForEach ($vm in $vms) { | |
$vmProp = [ordered]@{} | |
$vmProp.Name = $vm.Name | |
$vmProp.State = $vm.PowerState | |
$vmProp.FullName = If (!$VM.Guest.hostname) {"Tools Not Running\Unknown"} Else {$VM.Guest.hostname} | |
$vmProp.GuestOS = If (!$VM.Guest.OSFullName) {"Tools Not Running\Unknown"} Else {$VM.Guest.OSFullName} | |
$vmProp.IP = If (!$VM.Guest.IPAddress[0]) {"Tools Not Running\Unknown"} Else {$VM.Guest.IPAddress[0]} | |
$vmProp.NumCPU = $vm.NumCPU | |
[int]$vmProp."Memory (GB)" = $vm.MemoryGB | |
$vmProp."Disk (GB)" = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2) | |
$vmProp."DiskFree (GB)" = If (![Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2)) ` | |
{"Tools Not Running\Unknown"} Else {[Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2)} | |
$vmProp."DiskUsed (GB)" = If ($vmProp."DiskFree (GB)" -eq "Tools Not Running\Unknown") ` | |
{"Tools Not Running\Unknown"} Else {$vmProp."Disk (GB)" - $vmProp."DiskFree (GB)"} | |
$vmProp.Notes = $VM.Notes | |
$vmTemp = New-Object –TypeName PSObject –Prop $vmProp | |
$vmInfo += $vmTemp | |
} | |
If ($vmInfo) { | |
$vmInfo | Sort Created -Descending | Export-Xlsx -Path $FullPath -WorksheetName "VM Info" -Title "VM Info" -AppendWorksheet -SheetPosition "end" | |
} | |
# Get VM Snapshots | |
$snapInfo = @() | |
$snaps = $VMHost | Get-VM | Get-Snapshot | |
ForEach ($snap in $snaps) { | |
$snapProp = [ordered]@{} | |
$snapProp.VM = $snap.VM | |
$snapProp.Name = $snap.Name | |
$snapProp.Description = $snap.Description | |
$snapProp.Created = $snap.Created | |
$snapProp."Size (GB)" = [Math]::Round($snap.SizeGB,2) | |
$snapProp.IsCurrent = $snap.IsCurrent | |
$snapTemp = New-Object –TypeName PSObject –Prop $snapProp | |
$snapInfo += $snapTemp | |
} | |
If ($snapInfo) { | |
$snapInfo | Sort Created -Descending | Export-Xlsx -Path $FullPath -WorksheetName "Snapshot Info" -Title "Snapshot Info" -AppendWorksheet -SheetPosition "end" | |
} | |
Disconnect-VIServer $ESX -Confirm:$false | |
Write-Host "$ESX Report Complete - $FullPath" | |
} Else { | |
Write-Host "Unable to connect to $ESX" -ForegroundColor Red | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment