#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