diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index afad9c9..b735373 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -20,12 +20,16 @@ A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. -**System (please provide the following information about the system from which you are trying to generate a report):** - - OS: [e.g. Windows 10] - - Windows PowerShell version [Provide output from the following command: `$PSVersionTable.PSVersion`] - - 3rd party PowerShell module name and version [e.g. VMware PowerCLI 11.2] - - AsBuiltReport Core module version [e.g. 1.0.0] - - AsBuiltReport Report module name and version [e.g. AsBuiltReport.VMware.vSphere 1.0.0] +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] **Additional context** -Add any other context about the problem here. \ No newline at end of file +Add any other context about the problem here. diff --git a/.github/workflows/PSScriptAnalyzer.yml b/.github/workflows/PSScriptAnalyzer.yml new file mode 100644 index 0000000..fe69d8f --- /dev/null +++ b/.github/workflows/PSScriptAnalyzer.yml @@ -0,0 +1,17 @@ +name: PSScriptAnalyzer +on: [push, pull_request] +jobs: + lint: + name: Run PSScriptAnalyzer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: lint + uses: devblackops/github-action-psscriptanalyzer@master + with: + sendComment: true + failOnErrors: true + failOnWarnings: false + failOnInfos: false + repoToken: ${{ secrets.GITHUB_TOKEN }} + settingsPath: .github/workflows/PSScriptAnalyzerSettings.psd1 \ No newline at end of file diff --git a/.github/workflows/PSScriptAnalyzerSettings.psd1 b/.github/workflows/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 0000000..c053761 --- /dev/null +++ b/.github/workflows/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,8 @@ +@{ + ExcludeRules = @( + 'PSUseToExportFieldsInManifest', + 'PSReviewUnusedParameter', + 'PSUseDeclaredVarsMoreThanAssignments', + 'PSAvoidGlobalVars' + ) +} \ No newline at end of file diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml new file mode 100644 index 0000000..ce3040e --- /dev/null +++ b/.github/workflows/Release.yml @@ -0,0 +1,15 @@ +name: Publish PowerShell Module + +on: + release: + types: [published] + +jobs: + publish-to-gallery: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Publish + shell: pwsh + run: | + Publish-Module -Path ./ -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose diff --git a/.vscode/settings.json b/.vscode/settings.json index 26ecfec..c133455 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,20 +1,25 @@ { "powershell.codeFormatting.preset": "Custom", + "powershell.codeFormatting.useCorrectCasing": true, + "powershell.codeFormatting.autoCorrectAliases": true, "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, "powershell.codeFormatting.whitespaceBeforeOpenParen": true, "powershell.codeFormatting.whitespaceAroundOperator": true, "powershell.codeFormatting.whitespaceAfterSeparator": true, + "powershell.codeFormatting.addWhitespaceAroundPipe": true, "powershell.codeFormatting.ignoreOneLineBlock": true, "powershell.codeFormatting.newLineAfterCloseBrace": false, "powershell.codeFormatting.newLineAfterOpenBrace": true, "powershell.codeFormatting.openBraceOnSameLine": true, + "powershell.codeFormatting.alignPropertyValuePairs": false, "powershell.codeFolding.enable": true, - "powershell.codeFormatting.alignPropertyValuePairs": false, - "powershell.bugReporting.project": "https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/", + "powershell.scriptAnalysis.enable": true, + "powershell.scriptAnalysis.settingsPath": ".github/workflows/PSScriptAnalyzerSettings.psd1", "editor.tabSize": 4, "editor.insertSpaces": true, "editor.detectIndentation": false, "editor.rulers": [ 115 - ] + ], + "files.trimTrailingWhitespace": true } \ No newline at end of file diff --git a/AsBuiltReport.VMware.ESXi.Style.ps1 b/AsBuiltReport.VMware.ESXi.Style.ps1 index 6351bcb..dc88f6c 100644 --- a/AsBuiltReport.VMware.ESXi.Style.ps1 +++ b/AsBuiltReport.VMware.ESXi.Style.ps1 @@ -4,30 +4,37 @@ DocumentOption -EnableSectionNumbering -PageSize A4 -DefaultFont 'Arial' -MarginLeftAndRight 71 -MarginTopAndBottom 71 -Orientation $Orientation # Configure Heading and Font Styles -Style -Name 'Title' -Size 24 -Color '485969' -Align Center -Style -Name 'Title 2' -Size 18 -Color '006A91' -Align Center -Style -Name 'Title 3' -Size 12 -Color '006A91' -Align Left -Style -Name 'Heading 1' -Size 16 -Color '006A91' -Style -Name 'Heading 2' -Size 14 -Color '006A91' -Style -Name 'Heading 3' -Size 12 -Color '006A91' -Style -Name 'Heading 4' -Size 11 -Color '006A91' -Style -Name 'Heading 5' -Size 10 -Color '006A91' +Style -Name 'Title' -Size 24 -Color '717074' -Align Center +Style -Name 'Title 2' -Size 18 -Color 'A1A0A4' -Align Center +Style -Name 'Title 3' -Size 12 -Color '006A91' -Align Center +Style -Name 'Heading 1' -Size 16 -Color '00364D' +Style -Name 'Heading 2' -Size 14 -Color '004B6B' +Style -Name 'Heading 3' -Size 12 -Color '00567A' +Style -Name 'Heading 4' -Size 11 -Color '00648F' +Style -Name 'Heading 5' -Size 10 -Color '0072A3' Style -Name 'Normal' -Size 10 -Color '565656' -Default -Style -Name 'TOC' -Size 16 -Color '006A91' -Style -Name 'TableDefaultHeading' -Size 10 -Color 'FAFAFA' -BackgroundColor '485969' +Style -Name 'Caption' -Size 10 -Color '565656' -Italic -Align Center +Style -Name 'Header' -Size 10 -Color '565656' -Align Center +Style -Name 'Footer' -Size 10 -Color '565656' -Align Center +Style -Name 'TOC' -Size 16 -Color '00364D' +#Style -Name 'TableDefaultHeading' -Size 10 -Color '565656' -BackgroundColor 'FAFAFA' # Light Theme +Style -Name 'TableDefaultHeading' -Size 10 -Color 'FAFAFA' -BackgroundColor '00364D' # Dark Theme Style -Name 'TableDefaultRow' -Size 10 -Color '565656' -Style -Name 'Critical' -Size 10 -BackgroundColor 'F5DBD9' -Style -Name 'Warning' -Size 10 -BackgroundColor 'FEF3B5' -Style -Name 'Info' -Size 10 -BackgroundColor 'E1F1F6' -Style -Name 'OK' -Size 10 -BackgroundColor 'DFF0D0' +Style -Name 'Critical' -Size 10 -Color '565656' -BackgroundColor 'FEDDD7' +Style -Name 'Warning' -Size 10 -Color '565656' -BackgroundColor 'FFF4C7' +Style -Name 'Info' -Size 10 -Color '565656' -BackgroundColor 'E3F5FC' +Style -Name 'OK' -Size 10 -Color '565656' -BackgroundColor 'DFF0D0' # Configure Table Styles $TableDefaultProperties = @{ Id = 'TableDefault' HeaderStyle = 'TableDefaultHeading' RowStyle = 'TableDefaultRow' - BorderColor = '485969' + #BorderColor = 'A6A6A6' # Light Theme + BorderColor = '00364D' # Dark Theme Align = 'Left' + CaptionStyle = 'Caption' + CaptionLocation = 'Below' BorderWidth = 0.25 PaddingTop = 1 PaddingBottom = 1.5 @@ -36,16 +43,40 @@ $TableDefaultProperties = @{ } TableStyle @TableDefaultProperties -Default -TableStyle -Id 'Borderless' -BorderWidth 0 +TableStyle -Id 'Borderless' -HeaderStyle Normal -RowStyle Normal -BorderWidth 0 # VMware Cover Page Layout +# Header & Footer +if ($ReportConfig.Report.ShowHeaderFooter) { + Header -Default { + Paragraph -Style Header "$($ReportConfig.Report.Name) - v$($ReportConfig.Report.Version)" + } + + Footer -Default { + Paragraph -Style Footer 'Page ' + } +} + # Set position of report titles and information based on page orientation +if (!($ReportConfig.Report.ShowCoverPageImage)) { + $LineCount = 5 +} if ($Orientation -eq 'Portrait') { BlankLine -Count 11 - $LineCount = 30 + $LineCount = 32 + $LineCount } else { BlankLine -Count 7 - $LineCount = 20 + $LineCount = 15 + $LineCount +} + +# VMware Logo Image +if ($ReportConfig.Report.ShowCoverPageImage) { + Try { + Image -Text 'VMware Logo' -Align 'Center' -Percent 5 -Base64 "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" + BlankLine -Count 2 + } Catch { + Write-PScriboMessage -Message ".NET Core is required for cover page image support. Please install .NET Core or disable 'ShowCoverPageImage' in the report JSON configuration file." + } } # Add Report Name @@ -53,6 +84,7 @@ Paragraph -Style Title $ReportConfig.Report.Name if ($AsBuiltConfig.Company.FullName) { # Add Company Name if specified + BlankLine -Count 2 Paragraph -Style Title2 $AsBuiltConfig.Company.FullName BlankLine -Count $LineCount } else { @@ -65,6 +97,8 @@ Table -Name 'Cover Page' -List -Style Borderless -Width 0 -Hashtable ([Ordered] }) PageBreak -# Add Table of Contents -TOC -Name 'Table of Contents' -PageBreak \ No newline at end of file +if ($ReportConfig.Report.ShowTableOfContents) { + # Add Table of Contents + TOC -Name 'Table of Contents' + PageBreak +} \ No newline at end of file diff --git a/AsBuiltReport.VMware.ESXi.json b/AsBuiltReport.VMware.ESXi.json index 398b6bd..3384559 100644 --- a/AsBuiltReport.VMware.ESXi.json +++ b/AsBuiltReport.VMware.ESXi.json @@ -2,17 +2,21 @@ "Report": { "Name": "VMware ESXi As Built Report", "Version": "1.0", - "Status": "Released" + "Status": "Released", + "ShowCoverPageImage": true, + "ShowTableOfContents": true, + "ShowHeaderFooter": true, + "ShowTableCaptions": true }, "Options": { "ShowLicenseKeys": false, "ShowVMSnapshots": true }, "InfoLevel": { - "_comment_": "0 = Disabled, 1 = Summary, 2 = Informative, 3 = Detailed, 4 = Adv Detailed, 5 = Comprehensive", + "_comment_": "0 = Disabled, 1 = Enabled / Summary, 2 = Adv Summary, 3 = Detailed, 4 = Adv Detailed, 5 = Comprehensive", "VMHost": 3, "Network": 3, - "Datastore": 3, + "Storage": 3, "VM": 3 }, "HealthCheck": { diff --git a/AsBuiltReport.VMware.ESXi.psd1 b/AsBuiltReport.VMware.ESXi.psd1 index e2ced9f..9c66854 100644 Binary files a/AsBuiltReport.VMware.ESXi.psd1 and b/AsBuiltReport.VMware.ESXi.psd1 differ diff --git a/AsBuiltReport.VMware.ESXi.psm1 b/AsBuiltReport.VMware.ESXi.psm1 index d158df3..e22b0dc 100644 --- a/AsBuiltReport.VMware.ESXi.psm1 +++ b/AsBuiltReport.VMware.ESXi.psm1 @@ -1,7 +1,8 @@ -# Get public function definition files and dot source them -$Public = @(Get-ChildItem -Path $PSScriptRoot\Src\Public\*.ps1) +# Get public and private function definition files and dot source them +$Public = @(Get-ChildItem -Path $PSScriptRoot\Src\Public\*.ps1 -ErrorAction SilentlyContinue) +$Private = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\*.ps1 -ErrorAction SilentlyContinue) -foreach ($Module in $Public) { +foreach ($Module in @($Public + $Private)) { try { . $Module.FullName } catch { @@ -9,4 +10,5 @@ foreach ($Module in $Public) { } } -Export-ModuleMember -Function $Public.BaseName \ No newline at end of file +Export-ModuleMember -Function $Public.BaseName +Export-ModuleMember -Function $Private.BaseName \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bc380fc..91c511c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,23 @@ -# AsBuiltReport.VMware.ESXi Changelog +# :arrows_counterclockwise: AsBuiltReport.VMware.ESXi Changelog -## [1.0.0] 2020-04-02 +## [[1.1.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.ESXi/releases/tag/v1.1.0)] - 2021-10-09 + +### Added +- PowerShell 7 compatibility +- PSScriptAnalyzer & PublishPSModule GitHub Action workflows +- VMHost network adapter LLDP reporting +- NSX TCP/IP stacks for VMkernel Adpater reporting +- Include release and issue links in `CHANGELOG.md` + +### Changed +- VMkernel Adapter reporting for enabled services + +### Fixed +- Display issues with highlights in `README.md` + +## [[1.0.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.ESXi/releases/tag/v1.1.0)] - 2020-04-02 ### Added - Initial release of VMware ESXi As Built Report ### Fixed -- Created new VMware ESXi As Built Report (Fix #1) \ No newline at end of file +- Created new VMware ESXi As Built Report ([Fix #1](https://github.com/AsBuiltReport/AsBuiltReport.VMware.ESXi/issues/1)) \ No newline at end of file diff --git a/README.md b/README.md index f57672a..a1c30c4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +

+ + +

@@ -19,49 +23,76 @@

-# AsBuiltReport.VMware.ESXi +# VMware ESXi As Built Report + +VMware ESXi As Built Report is a PowerShell module which works in conjunction with [AsBuiltReport.Core](https://github.com/AsBuiltReport/AsBuiltReport.Core). + +[AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport) is an open-sourced community project which utilises PowerShell to produce as-built documentation in multiple document formats for multiple vendors and technologies. + +The VMware ESXi As Built Report module is used to generate as built documentation for standalone VMware ESXi servers. + +Please refer to the [VMware vSphere AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere) for reporting of VMware vSphere / vCenter Server environments. -# Getting Started +Please refer to the AsBuiltReport [website](https://www.asbuiltreport.com) for more detailed information about this project. + +# :beginner: Getting Started Below are the instructions on how to install, configure and generate a VMware ESXi As Built report. -## Supported ESXi Versions +## :floppy_disk: Supported Versions + +### VMware ESXi The VMware ESXi As Built Report supports the following ESXi versions; -- ESXi 5.0 -- ESXi 5.1 -- ESXi 5.5 -- ESXi 6.0 - ESXi 6.5 - ESXi 6.7 +- ESXi 7.0 + +#### End of Support +The following VMware ESXi versions are no longer being tested and/or supported; +- ESXi 5.5 +- ESXi 6.0 + +### PowerShell +This report is compatible with the following PowerShell versions; -## Pre-requisites -The following PowerShell modules are required for generating a VMware ESXi As Built report. +| Windows PowerShell 5.1 | PowerShell 7 | +|:----------------------:|:--------------------:| +| :white_check_mark: | :white_check_mark: | -Each of these modules can be easily downloaded and installed via the PowerShell Gallery +## :wrench: System Requirements +PowerShell 5.1 or PowerShell 7, and the following PowerShell modules are required for generating a VMware ESXi As Built report. - [VMware PowerCLI Module](https://www.powershellgallery.com/packages/VMware.PowerCLI/) - [AsBuiltReport.VMware.ESXi Module](https://www.powershellgallery.com/packages/AsBuiltReport.VMware.ESXi/) -## Module Installation +### Linux & macOS +* .NET Core is required for cover page image support on Linux and macOS operating systems. + * [Installing .NET Core for macOS](https://docs.microsoft.com/en-us/dotnet/core/install/macos) + * [Installing .NET Core for Linux](https://docs.microsoft.com/en-us/dotnet/core/install/linux) + +❗ If you are unable to install .NET Core, you must set `ShowCoverPageImage` to `False` in the report JSON configuration file. -Open a Windows PowerShell terminal window and install each of the required modules. +### :closed_lock_with_key: Required Privileges +A user with root privileges on the ESXi host is required to generate a VMware ESXi As Built Report. -**Note:** VMware PowerCLI 10.0 or higher required. +## :package: Module Installation + +Open a PowerShell terminal window and install each of the required modules. + +:warning: VMware PowerCLI 12.3 or higher is required. Please ensure older PowerCLI versions have been uninstalled. ```powershell -install-module VMware.PowerCLI -MinimumVersion 10.0 +install-module VMware.PowerCLI -MinimumVersion 12.3 -AllowClobber install-module AsBuiltReport.VMware.ESXi ``` -### Required Privileges -Administrator/root privileges are required on the ESXi host to generate a VMware ESXi As Built Report. - -## Configuration +## :pencil2:Configuration The ESXi As Built Report utilises a JSON file to allow configuration of report information, options, detail and healthchecks. An ESXi report configuration file can be generated by executing the following command; - -New-AsBuiltReportConfig -Report VMware.ESXi -Path -Name +```powershell +New-AsBuiltReportConfig -Report VMware.ESXi -Path -Name +``` Executing this command will copy the default ESXi report JSON configuration to a user specified folder. @@ -70,102 +101,107 @@ All report settings can then be configured via the JSON file. The following provides information of how to configure each schema within the report's JSON file. ### Report -The **Report** sub-schema provides configuration of the ESXi report information +The **Report** schema provides configuration of the ESXi report information -| Schema | Sub-Schema | Description | -| ------ | ---------- | ----------- | -| Report | Name | The name of the As Built Report -| Report | Version | The report version -| Report | Status | The report release status +| Sub-Schema | Setting | Default | Description | +|--------------------|------------- | --------------------------- | --------------------------------------------------------------| +| Name | User defined | VMware ESXi As Built Report | The name of the As Built Report | +| Version | User defined | 1.0 | The report version | +| Status | User defined | Released | The report release status | +| ShowCoverPageImage | true / false | true | Toggle to enable/disable the display of the cover page image | +| ShowHeaderFooter | true / false | true | Toggle to enable/disable document headers & footers | +| ShowTableCaptions | true / false | true | Toggle to enable/disable table captions/numbering | ### Options -The **Options** sub-schema allows certain options within the report to be toggled on or off +The **Options** schema allows certain options within the report to be toggled on or off -| Schema | Sub-Schema | Setting | Description | -| ------ | ---------- | ------- | ----------- | -| Options | ShowLicenseKeys | true / false | Toggle to mask/unmask ESXi license keys

**Masked License Key**
\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-56YDM-AS12K

**Unmasked License Key**
AKLU4-PFG8M-W2D8J-56YDM-AS12K -| Options | ShowVMSnapshots | true / false | Toggle to enable/disable reporting of VM snapshots +| Sub-Schema | Setting | Default | Description | +|--------------------|--------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ShowLicenseKeys | true / false | false | Toggle to mask/unmask ESXi license keys

**Masked License Key**
\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-56YDM-AS12K

**Unmasked License Key**
AKLU4-PFG8M-W2D8J-56YDM-AS12K | +| ShowVMSnapshots | true / false | true | Toggle to enable/disable reporting of VM snapshots | ### InfoLevel -The **InfoLevel** sub-schema allows configuration of each section of the report at a granular level. The following sections can be set - -| Schema | Sub-Schema | Default Setting | -| ------ | ---------- | --------------- | -| InfoLevel | VMHost | 3 -| InfoLevel | Network | 3 -| InfoLevel | Datastore | 3 -| InfoLevel | VM | 3 +The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set There are 6 levels (0-5) of detail granularity for each section as follows; -| Setting | InfoLevel | Description | -| ------- | ---- | ----------- | -| 0 | Disabled | does not collect or display any information -| 1 | Summary | provides summarised information for a collection of objects -| 2 | Informative | provides condensed, detailed information for a collection of objects -| 3 | Detailed | provides detailed information for individual objects -| 4 | Adv Detailed | provides detailed information for individual objects, as well as information for associated objects (Hosts, Datastores, VMs etc) -| 5 | Comprehensive | provides comprehensive information for individual objects, such as advanced configuration settings +| Setting | InfoLevel | Description | +|---------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| 0 | Disabled | Does not collect or display any information | +| 1 | Enabled / Summary | Provides summarised information for a collection of objects | +| 2 | Adv Summary | Provides condensed, detailed information for a collection of objects | +| 3 | Detailed | Provides detailed information for individual objects | +| 4 | Adv Detailed | Provides detailed information for individual objects, as well as information for associated objects (Hosts, Clusters, Datastores, VMs etc) | +| 5 | Comprehensive | Provides comprehensive information for individual objects, such as advanced configuration settings | + +The table below outlines the default and maximum **InfoLevel** settings for each section. + +| Sub-Schema | Default Setting | Maximum Setting | +|------------|:---------------:|:---------------:| +| VMHost | 3 | 5 | +| Network | 3 | 4 | +| Storage | 3 | 4 | +| VM | 3 | 4 | ### Healthcheck -The **Healthcheck** sub-schema is used to toggle health checks on or off. +The **Healthcheck** schema is used to toggle health checks on or off. #### VMHost -The **VMHost** sub-schema is used to configure health checks for VMHosts. - -| Schema | Sub-Schema | Setting | Description | Highlight | -| ------ | ---------- | ------- | ----------- | --------- | -| VMHost | ConnectionState | true / false | Highlights VMHosts connection state | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Maintenance
![Critical](https://placehold.it/15/FFB38F/000000?text=+) Disconnected -| VMHost | HyperThreading | true / false | Highlights VMHosts which have HyperThreading disabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) HyperThreading disabled
-| VMHost | ScratchLocation | true / false | Highlights VMHosts which are configured with the default scratch location | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Scratch location is /tmp/scratch -| VMHost | IPv6 | true / false | Highlights VMHosts which do not have IPv6 enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) IPv6 disabled -| VMHost | UpTimeDays | true / false | Highlights VMHosts with uptime days greater than 9 months | ![Warning](https://placehold.it/15/FFE860/000000?text=+) 9 - 12 months
![Critical](https://placehold.it/15/FFB38F/000000?text=+) >12 months -| VMHost | Licensing | true / false | Highlights VMHosts which are using production evaluation licenses | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Product evaluation license in use -| VMHost | SSH | true / false | Highlights if the SSH service is enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) TSM / TSM-SSH service enabled -| VMHost | ESXiShell | true / false | Highlights if the ESXi Shell service is enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) TSM / TSM-EsxiShell service enabled -| VMHost | NTP | true / false | Highlights if the NTP service has stopped or is disabled on a VMHost | ![Critical](https://placehold.it/15/FFB38F/000000?text=+) NTP service stopped / disabled -| VMHost | StorageAdapter | true / false | Highlights storage adapters which are not 'Online' | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Storage adapter status is 'Unknown'
![Critical](https://placehold.it/15/FFB38F/000000?text=+) Storage adapter status is 'Offline' -| VMHost | NetworkAdapter | true / false | Highlights physical network adapters which are not 'Connected'
Highlights physical network adapters which are 'Down' | ![Critical](https://placehold.it/15/FFB38F/000000?text=+) Network adapter is 'Disconnected'
![Critical](https://placehold.it/15/FFB38F/000000?text=+) Network adapter is 'Down' -| VMHost | LockdownMode | true / false | Highlights VMHosts which do not have Lockdown mode enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Lockdown Mode disabled
+The **VMHost** schema is used to configure health checks for VMHosts. + +| Sub-Schema | Setting | Default | Description | Highlight | +|-----------------|--------------|---------|--------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ConnectionState | true / false | true | Checks VMHosts connection state | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Maintenance
![Critical](http://placehold.it/15/FFB38F/000000?text=+) Disconnected | +| HyperThreading | true / false | true | Highlights VMHosts which have HyperThreading disabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) HyperThreading disabled
| +| ScratchLocation | true / false | true | Highlights VMHosts which are configured with the default scratch location | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Scratch location is /tmp/scratch | +| IPv6 | true / false | true | Highlights VMHosts which do not have IPv6 enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) IPv6 disabled | +| UpTimeDays | true / false | true | Highlights VMHosts with uptime days greater than 9 months | ![Warning](http://placehold.it/15/FFE860/000000?text=+) 9 - 12 months
![Critical](http://placehold.it/15/FFB38F/000000?text=+) >12 months | +| Licensing | true / false | true | Highlights VMHosts which are using production evaluation licenses | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Product evaluation license in use | +| SSH | true / false | true | Highlights if the SSH service is enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) TSM / TSM-SSH service enabled | +| ESXiShell | true / false | true | Highlights if the ESXi Shell service is enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) TSM / TSM-EsxiShell service enabled | +| NTP | true / false | true | Highlights if the NTP service has stopped or is disabled on a VMHost | ![Critical](http://placehold.it/15/FFB38F/000000?text=+) NTP service stopped / disabled | +| StorageAdapter | true / false | true | Highlights storage adapters which are not 'Online' | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Storage adapter status is 'Unknown'
![Critical](http://placehold.it/15/FFB38F/000000?text=+) Storage adapter status is 'Offline' | +| NetworkAdapter | true / false | true | Highlights physical network adapters which are not 'Connected'
Highlights physical network adapters which are 'Down' | ![Critical](http://placehold.it/15/FFB38F/000000?text=+) Network adapter is 'Disconnected'
![Critical](http://placehold.it/15/FFB38F/000000?text=+) Network adapter is 'Down' | +| LockdownMode | true / false | true | Highlights VMHosts which do not have Lockdown mode enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Lockdown Mode disabled
| #### Datastore -The **Datastore** sub-schema is used to configure health checks for Datastores. +The **Datastore** schema is used to configure health checks for Datastores. -| Schema | Sub-Schema | Setting | Description | Highlight | -| ------ | ---------- | ------- | ----------- | --------- | -| Datastore | CapacityUtilization | true / false | Highlights datastores with storage capacity utilization over 75% | ![Warning](https://placehold.it/15/FFE860/000000?text=+) 75 - 90% utilized
![Critical](https://placehold.it/15/FFB38F/000000?text=+) >90% utilized +| Sub-Schema | Setting | Default | Description | Highlight | +|---------------------|--------------|---------|------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| CapacityUtilization | true / false | true | Highlights datastores with storage capacity utilization over 75% | ![Warning](http://placehold.it/15/FFE860/000000?text=+) 75 - 90% utilized
![Critical](http://placehold.it/15/FFB38F/000000?text=+) >90% utilized | #### VM -The **VM** sub-schema is used to configure health checks for virtual machines. - -| Schema | Sub-Schema | Setting | Description | Highlight | -| ------ | ---------- | ------- | ----------- | --------- | -| VM | PowerState | true / false | Enables/Disables checking if the VM is powered on | ![Warning](https://placehold.it/15/FFE860/000000?text=+) VM is powered off -| VM | ConnectionState | true / false | Enables/Disables checking if the VM is orphaned or inaccessible | ![Critical](https://placehold.it/15/FFB38F/000000?text=+) VM is orphaned or inaccessible -| VM | CpuHotAdd | true / false | Highlights virtual machines which have CPU Hot Add enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) CPU Hot Add enabled -| VM | CpuHotRemove | true / false | Highlights virtual machines which have CPU Hot Remove enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) CPU Hot Remove enabled -| VM | MemoryHotAdd | true / false | Highlights VMs which have Memory Hot Add enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Memory Hot Add enabled -| VM | ChangeBlockTracking | true / false | Highlights VMs which do not have Change Block Tracking enabled | ![Warning](https://placehold.it/15/FFE860/000000?text=+) Change Block Tracking disabled -| VM | SpbmPolicyCompliance | true / false | Highlights VMs which do not comply with storage based policies | ![Warning](https://placehold.it/15/FFE860/000000?text=+) VM storage based policy compliance is unknown
![Critical](https://placehold.it/15/FFB38F/000000?text=+) VM does not comply with storage based policies -| VM | VMToolsStatus | true / false | Highlights Virtual Machines which do not have VM Tools installed, are out of date or are not running | ![Warning](https://placehold.it/15/FFE860/000000?text=+) VM Tools not installed, out of date or not running -| VM | VMSnapshots | true / false | Highlights Virtual Machines which have snapshots older than 7 days | ![Warning](https://placehold.it/15/FFE860/000000?text=+) VM Snapshot age >= 7 days
![Critical](https://placehold.it/15/FFB38F/000000?text=+) VM Snapshot age >= 14 days - -## Examples +The **VM** schema is used to configure health checks for virtual machines. + +| Sub-Schema | Setting | Default | Description | Highlight | +|----------------------|--------------|---------|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| PowerState | true / false | true | Highlights VMs which are powered off | ![Warning](http://placehold.it/15/FFE860/000000?text=+) VM is powered off | +| ConnectionState | true / false | true | Highlights VMs which are orphaned or inaccessible | ![Critical](http://placehold.it/15/FFB38F/000000?text=+) VM is orphaned or inaccessible | +| CpuHotAdd | true / false | true | Highlights virtual machines which have CPU Hot Add enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) CPU Hot Add enabled | +| CpuHotRemove | true / false | true | Highlights virtual machines which have CPU Hot Remove enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) CPU Hot Remove enabled | +| MemoryHotAdd | true / false | true | Highlights VMs which have Memory Hot Add enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Memory Hot Add enabled | +| ChangeBlockTracking | true / false | true | Highlights VMs which do not have Change Block Tracking enabled | ![Warning](http://placehold.it/15/FFE860/000000?text=+) Change Block Tracking disabled | +| SpbmPolicyCompliance | true / false | true | Highlights VMs which do not comply with storage based policies | ![Warning](http://placehold.it/15/FFE860/000000?text=+) VM storage based policy compliance is unknown
![Critical](http://placehold.it/15/FFB38F/000000?text=+) VM does not comply with storage based policies | +| VMToolsStatus | true / false | true | Highlights Virtual Machines which do not have VM Tools installed, are out of date or are not running | ![Warning](http://placehold.it/15/FFE860/000000?text=+) VM Tools not installed, out of date or not running | +| VMSnapshots | true / false | true | Highlights Virtual Machines which have snapshots older than 7 days | ![Warning](http://placehold.it/15/FFE860/000000?text=+) VM Snapshot age >= 7 days
![Critical](http://placehold.it/15/FFB38F/000000?text=+) VM Snapshot age >= 14 days | + +## :computer: Examples ```powershell # Generate an ESXi As Built Report for ESXi server 'esxi-01.corp.local' using specified credentials. Export report to HTML & DOCX formats. Use default report style. Append timestamp to report filename. Save reports to 'C:\Users\Tim\Documents' -PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Html,Word -OutputPath 'C:\Users\Tim\Documents' -Timestamp +PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Html,Word -OutputFolderPath 'C:\Users\Tim\Documents' -Timestamp -# Generate an ESXi As Built Report for ESXi server 'esxi-01.corp.local' using specified credentials and report configuration file. Export report to Text, HTML & DOCX formats. Use default report style. Save reports to 'C:\Users\Tim\Documents'. Display Verbose messages to the console. -PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Text,Html,Word -OutputPath 'C:\Users\Tim\Documents' -ReportConfigPath 'C:\Users\Tim\AsBuiltReport\AsBuiltReport.VMware.ESXi.json' -Verbose +# Generate an ESXi As Built Report for ESXi server 'esxi-01.corp.local' using specified credentials and report configuration file. Export report to Text, HTML & DOCX formats. Use default report style. Save reports to 'C:\Users\Tim\Documents'. Display verbose messages to the console. +PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Text,Html,Word -OutputFolderPath 'C:\Users\Tim\Documents' -ReportConfigFilePath 'C:\Users\Tim\AsBuiltReport\AsBuiltReport.VMware.ESXi.json' -Verbose # Generate an ESXi As Built Report for ESXi server 'esxi-01.corp.local' using stored credentials. Export report to HTML & Text formats. Use default report style. Highlight environment issues within the report. Save reports to 'C:\Users\Tim\Documents'. PS C:\> $Creds = Get-Credential -PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Credential $Creds -Format Html,Text -OutputPath 'C:\Users\Tim\Documents' -EnableHealthCheck +PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Credential $Creds -Format Html,Text -OutputFolderPath 'C:\Users\Tim\Documents' -EnableHealthCheck # Generate a single ESXi As Built Report for ESXi servers 'esxi-01.corp.local' and 'esxi-02.corp.local' using specified credentials. Report exports to Word format by default. Apply custom style to the report. Reports are saved to the user profile folder by default. -PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local','esxi-02.corp.local' -Username 'root' -Password 'VMware1!' -StylePath C:\Scripts\Styles\MyCustomStyle.ps1 +PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local','esxi-02.corp.local' -Username 'root' -Password 'VMware1!' -StylePath 'C:\Scripts\Styles\MyCustomStyle.ps1' -# Generate an ESXi As Built Report for ESXi server 'vcenter-01.corp.local' using specified credentials. Export report to HTML & DOCX formats. Use default report style. Reports are saved to the user profile folder by default. Attach and send reports via e-mail. -PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Html,Word -OutputPath C:\Users\Tim\Documents -SendEmail +# Generate an ESXi As Built Report for ESXi server 'esxi-01.corp.local' using specified credentials. Export report to HTML & DOCX formats. Use default report style. Reports are saved to the user profile folder by default. Attach and send reports via e-mail. +PS C:\> New-AsBuiltReport -Report VMware.ESXi -Target 'esxi-01.corp.local' -Username 'root' -Password 'VMware1!' -Format Html,Word -OutputFolderPath 'C:\Users\Tim\Documents' -SendEmail ``` \ No newline at end of file diff --git a/Src/Private/Get-ESXiBootDevice.ps1 b/Src/Private/Get-ESXiBootDevice.ps1 new file mode 100644 index 0000000..7f6afe6 --- /dev/null +++ b/Src/Private/Get-ESXiBootDevice.ps1 @@ -0,0 +1,100 @@ +function Get-ESXiBootDevice { + <# +.NOTES +=========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw +=========================================================================== +.DESCRIPTION + This function identifies how an ESXi host was booted up along with its boot + device (if applicable). This supports both local installation to Auto Deploy as + well as Boot from SAN. +.PARAMETER VMHostname + The name of an individual ESXi host managed by vCenter Server +.EXAMPLE + Get-ESXiBootDevice +.EXAMPLE + Get-ESXiBootDevice -VMHost esxi-01 +#> + param( + [Parameter(Mandatory = $false)][PSObject]$VMHost + ) + + $results = @() + $esxcli = Get-EsxCli -V2 -VMHost $VMHost + $bootDetails = $esxcli.system.boot.device.get.Invoke() + + # Check to see if ESXi booted over the network + $networkBoot = $false + if ($bootDetails.BootNIC) { + $networkBoot = $true + $bootDevice = $bootDetails.BootNIC + } elseif ($bootDetails.StatelessBootNIC) { + $networkBoot = $true + $bootDevice = $bootDetails.StatelessBootNIC + } + + # If ESXi booted over network, check to see if deployment + # is Stateless, Stateless w/Caching or Stateful + if ($networkBoot) { + $option = $esxcli.system.settings.advanced.list.CreateArgs() + $option.option = "/UserVars/ImageCachedSystem" + try { + $optionValue = $esxcli.system.settings.advanced.list.Invoke($option) + } catch { + $bootType = "Stateless" + } + $bootType = $optionValue.StringValue + } + + # Loop through all storage devices to identify boot device + $devices = $esxcli.storage.core.device.list.Invoke() + $foundBootDevice = $false + foreach ($device in $devices) { + if ($device.IsBootDevice -eq $true) { + $foundBootDevice = $true + + if ($device.IsLocal -eq $true -and $networkBoot -and $bootType -ne "Stateful") { + $bootType = "Stateless Caching" + } elseif ($device.IsLocal -eq $true -and $networkBoot -eq $false) { + $bootType = "Local" + } elseif ($device.IsLocal -eq $false -and $networkBoot -eq $false) { + $bootType = "Remote" + } + + $bootDevice = $device.Device + $bootModel = $device.Model + $bootVendor = $device.Vendor + $bootSize = $device.Size + $bootIsSAS = $TextInfo.ToTitleCase($device.IsSAS) + $bootIsSSD = $TextInfo.ToTitleCase($device.IsSSD) + $bootIsUSB = $TextInfo.ToTitleCase($device.IsUSB) + } + } + + # Pure Stateless (e.g. No USB or Disk for boot) + if ($networkBoot -and $foundBootDevice -eq $false) { + $bootModel = "N/A" + $bootVendor = "N/A" + $bootSize = "N/A" + $bootIsSAS = "N/A" + $bootIsSSD = "N/A" + $bootIsUSB = "N/A" + } + + $tmp = [PSCustomObject]@{ + Host = $($VMHost.ExtensionData.Name); + Device = $bootDevice; + BootType = $bootType; + Vendor = $bootVendor; + Model = $bootModel; + SizeMB = $bootSize; + IsSAS = $bootIsSAS; + IsSSD = $bootIsSSD; + IsUSB = $bootIsUSB; + } + $results += $tmp + $results +} \ No newline at end of file diff --git a/Src/Private/Get-InstallDate.ps1 b/Src/Private/Get-InstallDate.ps1 new file mode 100644 index 0000000..50aeda0 --- /dev/null +++ b/Src/Private/Get-InstallDate.ps1 @@ -0,0 +1,10 @@ +function Get-InstallDate { + $esxcli = Get-EsxCli -VMHost $VMHost -V2 + $thisUUID = $esxcli.system.uuid.get.Invoke() + $decDate = [Convert]::ToInt32($thisUUID.Split("-")[0], 16) + $installDate = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($decDate)) + [PSCustomObject][Ordered]@{ + Name = $VMHost.ExtensionData.Name + InstallDate = $installDate + } +} \ No newline at end of file diff --git a/Src/Private/Get-PciDeviceDetail.ps1 b/Src/Private/Get-PciDeviceDetail.ps1 new file mode 100644 index 0000000..7c99425 --- /dev/null +++ b/Src/Private/Get-PciDeviceDetail.ps1 @@ -0,0 +1,81 @@ +Function Get-PciDeviceDetail { + <# + .SYNOPSIS + Helper function to return PCI Devices Drivers & Firmware information for a specific host. + .PARAMETER Server + vCenter VISession object. + .PARAMETER esxcli + Esxcli session object associated to the host. + .EXAMPLE + $Credentials = Get-Credential + $Server = Connect-VIServer -Server vcenter01.example.com -Credentials $Credentials + $VMHost = Get-VMHost -Server $Server -Name esx01.example.com + $esxcli = Get-EsxCli -Server $Server -VMHost $VMHost -V2 + Get-PciDeviceDetail -Server $vCenter -esxcli $esxcli + Device : vmhba0 + Model : Sunrise Point-LP AHCI Controller + Driver : vmw_ahci + Driver Version : 1.0.0-34vmw.650.0.14.5146846 + Firmware Version : N/A + VIB Name : vmw-ahci + VIB Version : 1.0.0-34vmw.650.0.14.5146846 + .NOTES + Author: Erwan Quelin heavily based on the work of the vDocumentation team - https://github.com/arielsanchezmora/vDocumentation/blob/master/powershell/vDocumentation/Public/Get-ESXIODevice.ps1 + #> + [CmdletBinding()] + Param ( + [Parameter(Mandatory = $true)] + $Server, + [Parameter(Mandatory = $true)] + $esxcli + ) + Begin { } + + Process { + # Set default results + $firmwareVersion = "N/A" + $vibName = "N/A" + $driverVib = @{ + Name = "N/A" + Version = "N/A" + } + $pciDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { $_.VMkernelName -match 'vmhba|vmnic|vmgfx' -and $_.ModuleName -ne 'None'} | Sort-Object -Property VMkernelName + $nicList = $esxcli.network.nic.list.Invoke() | Sort-Object Name + foreach ($pciDevice in $pciDevices) { + $driverVersion = $esxcli.system.module.get.Invoke(@{module = $pciDevice.ModuleName }) | Select-Object -ExpandProperty Version + # Get NIC Firmware version + if (($pciDevice.VMkernelName -like 'vmnic*') -and ($nicList.Name -contains $pciDevice.VMkernelName) ) { + $vmnicDetail = $esxcli.network.nic.get.Invoke(@{nicname = $pciDevice.VMkernelName }) + $firmwareVersion = $vmnicDetail.DriverInfo.FirmwareVersion + # Get NIC driver VIB package version + $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net-" + $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net55-" + $vmnicDetail.DriverInfo.Driver } + <# + If HP Smart Array vmhba* (scsi-hpsa driver) then get Firmware version + else skip if VMkernnel is vmhba*. Can't get HBA Firmware from + Powercli at the moment only through SSH or using Putty Plink+PowerCli. + #> + } elseif ($pciDevice.VMkernelName -like 'vmhba*') { + if ($pciDevice.DeviceName -match "smart array") { + $hpsa = $vmhost.ExtensionData.Runtime.HealthSystemRuntime.SystemHealthInfo.NumericSensorInfo | Where-Object { $_.Name -match "HP Smart Array" } + if ($hpsa) { + $firmwareVersion = (($hpsa.Name -split "firmware")[1]).Trim() + } + } + # Get HBA driver VIB package version + $vibName = $pciDevice.ModuleName -replace "_", "-" + $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq "scsi-" + $VibName -or $_.Name -eq "sata-" + $VibName -or $_.Name -eq $VibName } + } + # Output collected data + [PSCustomObject]@{ + 'Device' = $pciDevice.VMkernelName + 'Model' = $pciDevice.DeviceName + 'Driver' = $pciDevice.ModuleName + 'Driver Version' = $driverVersion + 'Firmware Version' = $firmwareVersion + 'VIB Name' = $driverVib.Name + 'VIB Version' = $driverVib.Version + } + } + } + End { } +} \ No newline at end of file diff --git a/Src/Private/Get-RequiredModule.ps1 b/Src/Private/Get-RequiredModule.ps1 new file mode 100644 index 0000000..b723dc7 --- /dev/null +++ b/Src/Private/Get-RequiredModule.ps1 @@ -0,0 +1,34 @@ +function Get-RequiredModule { + <# + .SYNOPSIS + Function to check if the required version of VMware PowerCLI is installed + .DESCRIPTION + Function to check if the required version of VMware PowerCLI is installed + .PARAMETER Name + The name of the required PowerShell module + .PARAMETER Version + The version of the required PowerShell module + #> + [CmdletBinding()] + + Param + ( + [Parameter(Mandatory = $true, ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [String]$Name, + + [Parameter(Mandatory = $true, ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [String]$Version + ) + + # Check if the required version of VMware PowerCLI is installed + $RequiredModule = Get-Module -ListAvailable -Name $Name | Sort-Object -Property Version -Descending | Select-Object -First 1 + $ModuleVersion = "$($RequiredModule.Version.Major)" + "." + "$($RequiredModule.Version.Minor)" + if ($ModuleVersion -eq ".") { + throw "VMware PowerCLI $Version or higher is required to run the VMware ESXi As Built Report. Run 'Install-Module -Name $Name -MinimumVersion $Version' to install the required modules." + } + if ($ModuleVersion -lt $Version) { + throw "VMware PowerCLI $Version or higher is required to run the VMware ESXi As Built Report. Run 'Update-Module -Name $Name -MinimumVersion $Version' to update the required modules." + } +} \ No newline at end of file diff --git a/Src/Private/Get-ScsiDeviceDetail.ps1 b/Src/Private/Get-ScsiDeviceDetail.ps1 new file mode 100644 index 0000000..635f55f --- /dev/null +++ b/Src/Private/Get-ScsiDeviceDetail.ps1 @@ -0,0 +1,61 @@ +function Get-ScsiDeviceDetail { + <# + .SYNOPSIS + Helper function to return Scsi device information for a specific host and a specific datastore. + .PARAMETER VMHosts + This parameter accepts a list of host objects returned from the Get-VMHost cmdlet + .PARAMETER VMHostMoRef + This parameter specifies, by MoRef Id, the specific host of interest from with the $VMHosts array. + .PARAMETER DatastoreDiskName + This parameter specifies, by disk name, the specific datastore of interest. + .EXAMPLE + $VMHosts = Get-VMHost + Get-ScsiDeviceDetail -AllVMHosts $VMHosts -VMHostMoRef 'HostSystem-host-131' -DatastoreDiskName 'naa.6005076801810082480000000001d9fe' + DisplayName : IBM Fibre Channel Disk (naa.6005076801810082480000000001d9fe) + Ssd : False + LocalDisk : False + CanonicalName : naa.6005076801810082480000000001d9fe + Vendor : IBM + Model : 2145 + Multipath Policy : Round Robin + CapacityGB : 512 + .NOTES + Author: Ryan Kowalewski +#> + + [CmdLetBinding()] + param ( + [Parameter(Mandatory = $true)] + $VMHosts, + [Parameter(Mandatory = $true)] + $VMHostMoRef, + [Parameter(Mandatory = $true)] + $DatastoreDiskName + ) + + $VMHostObj = $VMHosts | Where-Object { $_.Id -eq $VMHostMoRef } + $ScsiDisk = $VMHostObj.ExtensionData.Config.StorageDevice.ScsiLun | Where-Object { + $_.CanonicalName -eq $DatastoreDiskName + } + $Multipath = $VMHostObj.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | Where-Object { + $_.Lun -eq $ScsiDisk.Key + } + $CapacityGB = [math]::Round((($ScsiDisk.Capacity.BlockSize * $ScsiDisk.Capacity.Block) / 1024 / 1024 / 1024), 2) + + [PSCustomObject]@{ + 'DisplayName' = $ScsiDisk.DisplayName + 'Ssd' = $ScsiDisk.Ssd + 'LocalDisk' = $ScsiDisk.LocalDisk + 'CanonicalName' = $ScsiDisk.CanonicalName + 'Vendor' = $ScsiDisk.Vendor + 'Model' = $ScsiDisk.Model + 'MultipathPolicy' = Switch ($Multipath.Policy.Policy) { + 'VMW_PSP_RR' { 'Round Robin' } + 'VMW_PSP_FIXED' { 'Fixed' } + 'VMW_PSP_MRU' { 'Most Recently Used' } + default { $Multipath.Policy.Policy } + } + 'Paths' = ($Multipath.Path).Count + 'CapacityGB' = $CapacityGB + } +} \ No newline at end of file diff --git a/Src/Private/Get-Uptime.ps1 b/Src/Private/Get-Uptime.ps1 new file mode 100644 index 0000000..cc1d33b --- /dev/null +++ b/Src/Private/Get-Uptime.ps1 @@ -0,0 +1,24 @@ +function Get-Uptime { + [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] + Param ( + [Parameter(Mandatory = $false, ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [PSObject]$VMHost, [PSObject]$VM + ) + $UptimeObject = @() + $Date = (Get-Date).ToUniversalTime() + If ($VMHost) { + $UptimeObject = Get-View -ViewType hostsystem -Property Name, Runtime.BootTime -Filter @{ + "Name" = "^$($VMHost.ExtensionData.Name)$" + "Runtime.ConnectionState" = "connected" + } | Select-Object Name, @{L = 'UptimeDays'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalDays), 2) } }, @{L = 'UptimeHours'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalHours), 2) } }, @{L = 'UptimeMinutes'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalMinutes), 2) } } + } + + if ($VM) { + $UptimeObject = Get-View -ViewType VirtualMachine -Property Name, Runtime.BootTime -Filter @{ + "Name" = "^$($VM.Name)$" + "Runtime.PowerState" = "poweredOn" + } | Select-Object Name, @{L = 'UptimeDays'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalDays), 2) } }, @{L = 'UptimeHours'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalHours), 2) } }, @{L = 'UptimeMinutes'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalMinutes), 2) } } + } + Write-Output $UptimeObject +} \ No newline at end of file diff --git a/Src/Private/Get-VMHostLicense.ps1 b/Src/Private/Get-VMHostLicense.ps1 new file mode 100644 index 0000000..0e635bd --- /dev/null +++ b/Src/Private/Get-VMHostLicense.ps1 @@ -0,0 +1,61 @@ +function Get-VMHostLicense { + <# +.SYNOPSIS +Function to retrieve VMware ESXi product licensing information. +.DESCRIPTION +Function to retrieve VMware ESXi product licensing information. +.NOTES +Version: 0.1.0 +Author: Tim Carman +Twitter: @tpcarman +Github: tpcarman +.PARAMETER VMHost +A vSphere ESXi Host objects +.INPUTS +System.Management.Automation.PSObject. +.OUTPUTS +System.Management.Automation.PSObject. +.EXAMPLE +PS> Get-VMHostLicense -VMHost ESXi01 +#> + [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] + + Param + ( + [Parameter(Mandatory = $false, ValueFromPipeline = $false)] + [ValidateNotNullOrEmpty()] + [PSObject]$VMHost, + [Parameter(Mandatory = $false, ValueFromPipeline = $false)] + [Switch]$Licenses + ) + + if ($VMHost) { + $LicenseObject = @() + $ServiceInstance = Get-View ServiceInstance -Server $ESXi + $LicenseManager = Get-View $ServiceInstance.Content.LicenseManager -Server $ESXi + #$LicenseManagerAssign = Get-View $LicenseManager.LicenseAssignmentManager + + #$VMHostId = $VMHost.Extensiondata.Config.Host.Value + #$VMHostAssignedLicense = $LicenseManagerAssign.QueryAssignedLicenses($VMHostId) + $VMHostLicense = $LicenseManager.Licenses + $VMHostLicenseExpiration = ($VMHostLicense.Properties | Where-Object { $_.Key -eq 'expirationDate' } | Select-Object Value).Value + if ($VMHostLicense.LicenseKey -and $Options.ShowLicenseKeys) { + $VMHostLicenseKey = $VMHostLicense.LicenseKey + } else { + $VMHostLicenseKey = "*****-*****-*****" + $VMHostLicense.LicenseKey.Substring(17) + } + $LicenseObject = [PSCustomObject]@{ + Product = $VMHostLicense.Name + LicenseKey = $VMHostLicenseKey + Expiration = + if ($VMHostLicenseExpiration -eq $null) { + "Never" + } elseif ($VMHostLicenseExpiration -gt (Get-Date)) { + $VMHostLicenseExpiration.ToShortDateString() + } else { + "Expired" + } + } + } + Write-Output $LicenseObject +} \ No newline at end of file diff --git a/Src/Private/Get-VMHostNetworkAdapterDP.ps1 b/Src/Private/Get-VMHostNetworkAdapterDP.ps1 new file mode 100644 index 0000000..8e93332 --- /dev/null +++ b/Src/Private/Get-VMHostNetworkAdapterDP.ps1 @@ -0,0 +1,85 @@ +function Get-VMHostNetworkAdapterDP { + <# + .SYNOPSIS + Function to retrieve the Network Adapter CDP or LLDP info of a vSphere host. + .DESCRIPTION + Function to retrieve the Network Adapter CDP or LLDP info of a vSphere host. + .PARAMETER VMHost + A vSphere ESXi Host object + .INPUTS + System.Management.Automation.PSObject. + .OUTPUTS + System.Management.Automation.PSObject. + .EXAMPLE + Get-VMHostNetworkAdapterDP -VMHost ESXi01,ESXi02 + .EXAMPLE + Get-VMHost ESXi01,ESXi02 | Get-VMHostNetworkAdapterDP + #> + [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] + + Param + ( + [parameter(Mandatory = $true, ValueFromPipeline = $true)] + [ValidateNotNullOrEmpty()] + [PSObject[]]$VMHost + ) + + begin { + $ObjOutput = @() + } + + process { + try { + foreach ($ObjVMHost in $VMHost) { + $ConfigManagerView = Get-View $ObjVMHost.ExtensionData.ConfigManager.NetworkSystem + $pNics = $ConfigManagerView.NetworkInfo.Pnic + foreach ($pNic in $pNics) { + $PhysicalNicHintInfo = $ConfigManagerView.QueryNetworkHint($pNic.Device) + if ($PhysicalNicHintInfo.ConnectedSwitchPort) { + $Object = [PSCustomObject]@{ + 'Host' = $ObjVMHost.Name + 'Device' = $pNic.Device + 'Status' = if ($PhysicalNicHintInfo.ConnectedSwitchPort) { + 'Connected' + } else { + 'Disconnected' + } + 'SwitchId' = $PhysicalNicHintInfo.ConnectedSwitchPort.DevId + 'Address' = $PhysicalNicHintInfo.ConnectedSwitchPort.Address + 'VLAN' = $PhysicalNicHintInfo.ConnectedSwitchPort.Vlan + 'MTU' = $PhysicalNicHintInfo.ConnectedSwitchPort.Mtu + 'SystemName' = $PhysicalNicHintInfo.ConnectedSwitchPort.SystemName + 'Location' = $PhysicalNicHintInfo.ConnectedSwitchPort.Location + 'HardwarePlatform' = $PhysicalNicHintInfo.ConnectedSwitchPort.HardwarePlatform + 'SoftwareVersion' = $PhysicalNicHintInfo.ConnectedSwitchPort.SoftwareVersion + 'ManagementAddress' = $PhysicalNicHintInfo.ConnectedSwitchPort.MgmtAddr + 'PortId' = $PhysicalNicHintInfo.ConnectedSwitchPort.PortId + } + $ObjOutput += $Object + } + if ($PhysicalNicHintInfo.LldpInfo) { + $Object = [PSCustomObject]@{ + 'Host' = $ObjVMHost.Name + 'Device' = $pNic.Device + 'ChassisId' = $PhysicalNicHintInfo.LldpInfo.ChassisId + 'PortId' = $PhysicalNicHintInfo.LldpInfo.PortId + 'TimeToLive' = $PhysicalNicHintInfo.LldpInfo.TimeToLive + 'TimeOut' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "TimeOut"}).Value + 'Samples' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "Samples"}).Value + 'ManagementAddress' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "Management Address"}).Value + 'PortDescription' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "Port Description"}).Value + 'SystemDescription' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "System Description"}).Value + 'SystemName' = ($PhysicalNicHintInfo.LldpInfo.Parameter | Where-Object {$_.key -eq "System Name"}).Value + } + $ObjOutput += $Object + } + } + } + } catch [Exception] { + throw 'Unable to retrieve CDP/LLDP info' + } + } + end { + Write-Output $ObjOutput + } +} \ No newline at end of file diff --git a/Src/Public/Invoke-AsBuiltReport.VMware.ESXi.ps1 b/Src/Public/Invoke-AsBuiltReport.VMware.ESXi.ps1 index c275766..edea80f 100644 --- a/Src/Public/Invoke-AsBuiltReport.VMware.ESXi.ps1 +++ b/Src/Public/Invoke-AsBuiltReport.VMware.ESXi.ps1 @@ -1,11 +1,11 @@ function Invoke-AsBuiltReport.VMware.ESXi { <# - .SYNOPSIS + .SYNOPSIS PowerShell script to document the configuration of VMware ESXi servers in Word/HTML/XML/Text formats .DESCRIPTION Documents the configuration of VMware ESXi servers in Word/HTML/XML/Text formats using PScribo. .NOTES - Version: 1.0.0 + Version: 1.1.0 Author: Tim Carman Twitter: @tpcarman Github: tpcarman @@ -16,449 +16,28 @@ function Invoke-AsBuiltReport.VMware.ESXi { param ( [String[]] $Target, - [PSCredential] $Credential, - [String] $StylePath + [PSCredential] $Credential ) - # Import JSON Configuration for Options and InfoLevel + # Check if the required version of VMware PowerCLI is installed + Get-RequiredModule -Name 'VMware.PowerCLI' -Version '12.3' + + # Import Report Configuration + $Report = $ReportConfig.Report $InfoLevel = $ReportConfig.InfoLevel $Options = $ReportConfig.Options - + # Used to set values to TitleCase where required $TextInfo = (Get-Culture).TextInfo - # If custom style not set, use default style - if (!$StylePath) { - & "$PSScriptRoot\..\..\AsBuiltReport.VMware.ESXi.Style.ps1" - } - - #region Script Functions - #---------------------------------------------------------------------------------------------# - # SCRIPT FUNCTIONS # - #---------------------------------------------------------------------------------------------# - - function Get-VMHostLicense { - <# - .SYNOPSIS - Function to retrieve VMware ESXi product licensing information. - .DESCRIPTION - Function to retrieve VMware ESXi product licensing information. - .NOTES - Version: 0.1.0 - Author: Tim Carman - Twitter: @tpcarman - Github: tpcarman - .PARAMETER VMHost - A vSphere ESXi Host objects - .INPUTS - System.Management.Automation.PSObject. - .OUTPUTS - System.Management.Automation.PSObject. - .EXAMPLE - PS> Get-VMHostLicense -VMHost ESXi01 - #> - [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] - - Param - ( - [Parameter(Mandatory = $false, ValueFromPipeline = $false)] - [ValidateNotNullOrEmpty()] - [PSObject]$vCenter, - [PSObject]$VMHost, - [Parameter(Mandatory = $false, ValueFromPipeline = $false)] - [Switch]$Licenses - ) - - if ($VMHost) { - $LicenseObject = @() - $ServiceInstance = Get-View ServiceInstance - $LicenseManager = Get-View $ServiceInstance.Content.LicenseManager - #$LicenseManagerAssign = Get-View $LicenseManager.LicenseAssignmentManager - - #$VMHostId = $VMHost.Extensiondata.Config.Host.Value - #$VMHostAssignedLicense = $LicenseManagerAssign.QueryAssignedLicenses($VMHostId) - $VMHostLicense = $LicenseManager.Licenses - $VMHostLicenseExpiration = ($VMHostLicense.Properties | Where-Object { $_.Key -eq 'expirationDate' } | Select-Object Value).Value - if ($VMHostLicense.LicenseKey -and $Options.ShowLicenseKeys) { - $VMHostLicenseKey = $VMHostLicense.LicenseKey - } else { - $VMHostLicenseKey = "*****-*****-*****" + $VMHostLicense.LicenseKey.Substring(17) - } - $LicenseObject = [PSCustomObject]@{ - Product = $VMHostLicense.Name - LicenseKey = $VMHostLicenseKey - Expiration = - if ($VMHostLicenseExpiration -eq $null) { - "Never" - } elseif ($VMHostLicenseExpiration -gt (Get-Date)) { - $VMHostLicenseExpiration.ToShortDateString() - } else { - "Expired" - } - } - } - Write-Output $LicenseObject - } - - function Get-VMHostNetworkAdapterCDP { - <# - .SYNOPSIS - Function to retrieve the Network Adapter CDP info of a vSphere host. - .DESCRIPTION - Function to retrieve the Network Adapter CDP info of a vSphere host. - .PARAMETER VMHost - A vSphere ESXi Host object - .INPUTS - System.Management.Automation.PSObject. - .OUTPUTS - System.Management.Automation.PSObject. - .EXAMPLE - PS> Get-VMHostNetworkAdapterCDP -VMHost ESXi01,ESXi02 - .EXAMPLE - PS> Get-VMHost ESXi01,ESXi02 | Get-VMHostNetworkAdapterCDP - #> - [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] - - Param - ( - [parameter(Mandatory = $true, ValueFromPipeline = $true)] - [ValidateNotNullOrEmpty()] - [PSObject[]]$VMHosts - ) - - begin { - $CDPObject = @() - } - - process { - try { - foreach ($VMHost in $VMHosts) { - $ConfigManagerView = Get-View $VMHost.ExtensionData.ConfigManager.NetworkSystem - $pNics = $ConfigManagerView.NetworkInfo.Pnic - foreach ($pNic in $pNics) { - $PhysicalNicHintInfo = $ConfigManagerView.QueryNetworkHint($pNic.Device) - $Object = [PSCustomObject]@{ - 'VMHost' = $VMHost.ExtensionData.Name - 'Device' = $pNic.Device - 'Status' = if ($PhysicalNicHintInfo.ConnectedSwitchPort) { - 'Connected' - } else { - 'Disconnected' - } - 'SwitchId' = $PhysicalNicHintInfo.ConnectedSwitchPort.DevId - 'Address' = $PhysicalNicHintInfo.ConnectedSwitchPort.Address - 'VLAN' = $PhysicalNicHintInfo.ConnectedSwitchPort.Vlan - 'MTU' = $PhysicalNicHintInfo.ConnectedSwitchPort.Mtu - 'SystemName' = $PhysicalNicHintInfo.ConnectedSwitchPort.SystemName - 'Location' = $PhysicalNicHintInfo.ConnectedSwitchPort.Location - 'HardwarePlatform' = $PhysicalNicHintInfo.ConnectedSwitchPort.HardwarePlatform - 'SoftwareVersion' = $PhysicalNicHintInfo.ConnectedSwitchPort.SoftwareVersion - 'ManagementAddress' = $PhysicalNicHintInfo.ConnectedSwitchPort.MgmtAddr - 'PortId' = $PhysicalNicHintInfo.ConnectedSwitchPort.PortId - } - $CDPObject += $Object - } - } - } catch [Exception] { - throw 'Unable to retrieve CDP info' - } - } - end { - Write-Output $CDPObject - } - } - - function Get-InstallDate { - $esxcli = Get-EsxCli -VMHost $VMHost -V2 - $thisUUID = $esxcli.system.uuid.get.Invoke() - $decDate = [Convert]::ToInt32($thisUUID.Split("-")[0], 16) - $installDate = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($decDate)) - [PSCustomObject][Ordered]@{ - Name = $VMHost.ExtensionData.Name - InstallDate = $installDate - } - } - - function Get-Uptime { - [CmdletBinding()][OutputType('System.Management.Automation.PSObject')] - Param ( - [Parameter(Mandatory = $false, ValueFromPipeline = $false)] - [ValidateNotNullOrEmpty()] - [PSObject]$VMHost, [PSObject]$VM - ) - $UptimeObject = @() - $Date = (Get-Date).ToUniversalTime() - If ($VMHost) { - $UptimeObject = Get-View -ViewType hostsystem -Property Name, Runtime.BootTime -Filter @{ - "Name" = "^$($VMHost.ExtensionData.Name)$" - "Runtime.ConnectionState" = "connected" - } | Select-Object Name, @{L = 'UptimeDays'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalDays), 2) } }, @{L = 'UptimeHours'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalHours), 2) } }, @{L = 'UptimeMinutes'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalMinutes), 2) } } - } - - if ($VM) { - $UptimeObject = Get-View -ViewType VirtualMachine -Property Name, Runtime.BootTime -Filter @{ - "Name" = "^$($VM.Name)$" - "Runtime.PowerState" = "poweredOn" - } | Select-Object Name, @{L = 'UptimeDays'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalDays), 2) } }, @{L = 'UptimeHours'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalHours), 2) } }, @{L = 'UptimeMinutes'; E = { [math]::round(((($Date) - ($_.Runtime.BootTime)).TotalMinutes), 2) } } - } - Write-Output $UptimeObject - } - - function Get-ESXiBootDevice { - <# - .NOTES - =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw - =========================================================================== - .DESCRIPTION - This function identifies how an ESXi host was booted up along with its boot - device (if applicable). This supports both local installation to Auto Deploy as - well as Boot from SAN. - .PARAMETER VMHostname - The name of an individual ESXi host managed by vCenter Server - .EXAMPLE - Get-ESXiBootDevice - .EXAMPLE - Get-ESXiBootDevice -VMHost esxi-01 - #> - param( - [Parameter(Mandatory = $false)][PSObject]$VMHost - ) - - $results = @() - $esxcli = Get-EsxCli -V2 -VMHost $vmhost - $bootDetails = $esxcli.system.boot.device.get.Invoke() - - # Check to see if ESXi booted over the network - $networkBoot = $false - if ($bootDetails.BootNIC) { - $networkBoot = $true - $bootDevice = $bootDetails.BootNIC - } elseif ($bootDetails.StatelessBootNIC) { - $networkBoot = $true - $bootDevice = $bootDetails.StatelessBootNIC - } - - # If ESXi booted over network, check to see if deployment - # is Stateless, Stateless w/Caching or Stateful - if ($networkBoot) { - $option = $esxcli.system.settings.advanced.list.CreateArgs() - $option.option = "/UserVars/ImageCachedSystem" - try { - $optionValue = $esxcli.system.settings.advanced.list.Invoke($option) - } catch { - $bootType = "Stateless" - } - $bootType = $optionValue.StringValue - } - - # Loop through all storage devices to identify boot device - $devices = $esxcli.storage.core.device.list.Invoke() - $foundBootDevice = $false - foreach ($device in $devices) { - if ($device.IsBootDevice -eq $true) { - $foundBootDevice = $true - - if ($device.IsLocal -eq $true -and $networkBoot -and $bootType -ne "Stateful") { - $bootType = "Stateless Caching" - } elseif ($device.IsLocal -eq $true -and $networkBoot -eq $false) { - $bootType = "Local" - } elseif ($device.IsLocal -eq $false -and $networkBoot -eq $false) { - $bootType = "Remote" - } - - $bootDevice = $device.Device - $bootModel = $device.Model - $bootVendor = $device.VEndor - $bootSize = $device.Size - $bootIsSAS = $TextInfo.ToTitleCase($device.IsSAS) - $bootIsSSD = $TextInfo.ToTitleCase($device.IsSSD) - $bootIsUSB = $TextInfo.ToTitleCase($device.IsUSB) - } - } - - # Pure Stateless (e.g. No USB or Disk for boot) - if ($networkBoot -and $foundBootDevice -eq $false) { - $bootModel = "N/A" - $bootVendor = "N/A" - $bootSize = "N/A" - $bootIsSAS = "N/A" - $bootIsSSD = "N/A" - $bootIsUSB = "N/A" - } - - $tmp = [PSCustomObject]@{ - Host = $($VMHost.ExtensionData.Name); - Device = $bootDevice; - BootType = $bootType; - Vendor = $bootVendor; - Model = $bootModel; - SizeMB = $bootSize; - IsSAS = $bootIsSAS; - IsSSD = $bootIsSSD; - IsUSB = $bootIsUSB; - } - $results += $tmp - $results - } - - function Get-ScsiDeviceDetail { - <# - .SYNOPSIS - Helper function to return Scsi device information for a specific host and a specific datastore. - .PARAMETER VMHosts - This parameter accepts a list of host objects returned from the Get-VMHost cmdlet - .PARAMETER VMHostMoRef - This parameter specifies, by MoRef Id, the specific host of interest from with the $VMHosts array. - .PARAMETER DatastoreDiskName - This parameter specifies, by disk name, the specific datastore of interest. - .EXAMPLE - $VMHosts = Get-VMHost - Get-ScsiDeviceDetail -AllVMHosts $VMHosts -VMHostMoRef 'HostSystem-host-131' -DatastoreDiskName 'naa.6005076801810082480000000001d9fe' - DisplayName : IBM Fibre Channel Disk (naa.6005076801810082480000000001d9fe) - Ssd : False - LocalDisk : False - CanonicalName : naa.6005076801810082480000000001d9fe - Vendor : IBM - Model : 2145 - Multipath Policy : Round Robin - CapacityGB : 512 - .NOTES - Author: Ryan Kowalewski - #> - - [CmdLetBinding()] - param ( - [Parameter(Mandatory = $true)] - $VMHosts, - [Parameter(Mandatory = $true)] - $VMHostMoRef, - [Parameter(Mandatory = $true)] - $DatastoreDiskName - ) - - $VMHostObj = $VMHosts | Where-Object { $_.Id -eq $VMHostMoRef } - $ScsiDisk = $VMHostObj.ExtensionData.Config.StorageDevice.ScsiLun | Where-Object { - $_.CanonicalName -eq $DatastoreDiskName - } - $Multipath = $VMHostObj.ExtensionData.Config.StorageDevice.MultipathInfo.Lun | Where-Object { - $_.Lun -eq $ScsiDisk.Key - } - $CapacityGB = [math]::Round((($ScsiDisk.Capacity.BlockSize * $ScsiDisk.Capacity.Block) / 1024 / 1024 / 1024), 2) - - [PSCustomObject]@{ - 'DisplayName' = $ScsiDisk.DisplayName - 'Ssd' = $ScsiDisk.Ssd - 'LocalDisk' = $ScsiDisk.LocalDisk - 'CanonicalName' = $ScsiDisk.CanonicalName - 'Vendor' = $ScsiDisk.Vendor - 'Model' = $ScsiDisk.Model - 'MultipathPolicy' = Switch ($Multipath.Policy.Policy) { - 'VMW_PSP_RR' { 'Round Robin' } - 'VMW_PSP_FIXED' { 'Fixed' } - 'VMW_PSP_MRU' { 'Most Recently Used' } - default { $Multipath.Policy.Policy } - } - 'Paths' = ($Multipath.Path).Count - 'CapacityGB' = $CapacityGB - } - } - - Function Get-PciDeviceDetail { - <# - .SYNOPSIS - Helper function to return PCI Devices Drivers & Firmware information for a specific host. - .PARAMETER Server - vCenter VISession object. - .PARAMETER esxcli - Esxcli session object associated to the host. - .EXAMPLE - $Credentials = Get-Credential - $Server = Connect-VIServer -Server vcenter01.example.com -Credentials $Credentials - $VMHost = Get-VMHost -Server $Server -Name esx01.example.com - $esxcli = Get-EsxCli -Server $Server -VMHost $VMHost -V2 - Get-PciDeviceDetail -Server $vCenter -esxcli $esxcli - VMkernel Name : vmhba0 - Device Name : Sunrise Point-LP AHCI Controller - Driver : vmw_ahci - Driver Version : 1.0.0-34vmw.650.0.14.5146846 - Firmware Version : NA - VIB Name : vmw-ahci - VIB Version : 1.0.0-34vmw.650.0.14.5146846 - .NOTES - Author: Erwan Quelin heavily based on the work of the vDocumentation team - https://github.com/arielsanchezmora/vDocumentation/blob/master/powershell/vDocumentation/Public/Get-ESXIODevice.ps1 - #> - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $true)] - $Server, - [Parameter(Mandatory = $true)] - $esxcli - ) - Begin { } - - Process { - # Set default results - $firmwareVersion = "N/A" - $vibName = "N/A" - $driverVib = @{ - Name = "N/A" - Version = "N/A" - } - $pciDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { $_.VMkernelName -like "vmhba*" -or $_.VMkernelName -like "vmnic*" -or $_.VMkernelName -like "vmgfx*" } | Sort-Object -Property VMkernelName - $nicList = $esxcli.network.nic.list.Invoke() | Sort-Object Name - #$fcoeAdapterList = $esxcli.fcoe.adapter.list.Invoke().PhysicalNIC # Get list of vmnics used for FCoE, because we don't want those vmnics here. - foreach ($pciDevice in $pciDevices) { - $driverVersion = $esxcli.system.module.get.Invoke(@{module = $pciDevice.ModuleName }) | Select-Object -ExpandProperty Version - # Get NIC Firmware version - #if (($pciDevice.VMkernelName -like 'vmnic*') -and ($fcoeAdapterList -notcontains $pciDevice.VMkernelName) -and ($nicList.Name -contains $pciDevice.VMkernelName) ) { - if (($pciDevice.VMkernelName -like 'vmnic*') -and ($nicList.Name -contains $pciDevice.VMkernelName) ) { - $vmnicDetail = $esxcli.network.nic.get.Invoke(@{nicname = $pciDevice.VMkernelName }) - $firmwareVersion = $vmnicDetail.DriverInfo.FirmwareVersion - # Get NIC driver VIB package version - $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net-" + $vmnicDetail.DriverInfo.Driver -or $_.Name -eq "net55-" + $vmnicDetail.DriverInfo.Driver } - <# - If HP Smart Array vmhba* (scsi-hpsa driver) then get Firmware version - else skip if VMkernnel is vmhba*. Can't get HBA Firmware from - Powercli at the moment only through SSH or using Putty Plink+PowerCli. - #> - } elseif ($pciDevice.VMkernelName -like 'vmhba*') { - if ($pciDevice.DeviceName -match "smart array") { - $hpsa = $vmhost.ExtensionData.Runtime.HealthSystemRuntime.SystemHealthInfo.NumericSensorInfo | Where-Object { $_.Name -match "HP Smart Array" } - if ($hpsa) { - $firmwareVersion = (($hpsa.Name -split "firmware")[1]).Trim() - } - } - # Get HBA driver VIB package version - $vibName = $pciDevice.ModuleName -replace "_", "-" - $driverVib = $esxcli.software.vib.list.Invoke() | Select-Object -Property Name, Version | Where-Object { $_.Name -eq "scsi-" + $VibName -or $_.Name -eq "sata-" + $VibName -or $_.Name -eq $VibName } - } - # Output collected data - [PSCustomObject]@{ - 'VMkernel Name' = $pciDevice.VMkernelName - 'Device Name' = $pciDevice.DeviceName - 'Driver' = $pciDevice.ModuleName - 'Driver Version' = $driverVersion - 'Firmware Version' = $firmwareVersion - 'VIB Name' = $driverVib.Name - 'VIB Version' = $driverVib.Version - } - } - } - End { } - } - #endregion Script Functions - #region Script Body #---------------------------------------------------------------------------------------------# # SCRIPT BODY # #---------------------------------------------------------------------------------------------# # Connect to ESXi Server using supplied credentials - foreach ($VIServer in $Target) { + foreach ($VIServer in $Target) { try { - $ESXi = Connect-VIServer $VIServer -Credential $Credential -ErrorAction Stop + Write-PScriboMessage "Connecting to ESXi Server '$VIServer'." + $ESXi = Connect-VIServer $VIServer -Credential $Credential -Protocol https -ErrorAction Stop } catch { Write-Error $_ } @@ -466,6 +45,7 @@ function Invoke-AsBuiltReport.VMware.ESXi { if ($ESXi) { # Create a lookup hashtable to quickly link VM MoRefs to Names # Exclude VMware Site Recovery Manager placeholder VMs + Write-PScriboMessage 'Creating VM lookup hashtable.' $VMs = Get-VM -Server $ESXi | Where-Object { $_.ExtensionData.Config.ManagedBy.ExtensionKey -notlike 'com.vmware.vcDr*' } | Sort-Object Name @@ -476,344 +56,434 @@ function Invoke-AsBuiltReport.VMware.ESXi { # Create a lookup hashtable to link Host MoRefs to Names # Exclude VMware HCX hosts and ESX/ESXi versions prior to vSphere 5.0 from VMHost lookup - $VMHosts = Get-VMHost -Server $ESXi | Where-Object { $_.Model -notlike "*VMware Mobility Platform" -and $_.Version -gt 5 } | Sort-Object Name + Write-PScriboMessage 'Creating VMHost lookup hashtable.' + $VMHost = Get-VMHost -Server $ESXi | Where-Object { $_.Model -notlike "*VMware Mobility Platform" -and $_.Version -gt 5 } | Sort-Object Name $VMHostLookup = @{ } - foreach ($VMHost in $VMHosts) { - $VMHostLookup.($VMHost.Id) = $VMHost.ExtensionData.Name - } + $VMHostLookup.($VMHost.Id) = $VMHost.ExtensionData.Name # Create a lookup hashtable to link Datastore MoRefs to Names + Write-PScriboMessage 'Creating Datastore lookup hashtable.' $Datastores = Get-Datastore -Server $ESXi | Where-Object { ($_.State -eq 'Available') -and ($_.CapacityGB -gt 0) } | Sort-Object Name $DatastoreLookup = @{ } foreach ($Datastore in $Datastores) { $DatastoreLookup.($Datastore.Id) = $Datastore.Name } - # Create a lookup hashtable to link VDS Portgroups MoRefs to Names + # Create a lookup hashtable to link VDS Port Groups MoRefs to Names + Write-PScriboMessage 'Creating VDPortGroup lookup hashtable.' $VDPortGroups = Get-VDPortgroup -Server $ESXi | Sort-Object Name $VDPortGroupLookup = @{ } foreach ($VDPortGroup in $VDPortGroups) { $VDPortGroupLookup.($VDPortGroup.Key) = $VDPortGroup.Name } - if ($InfoLevel.VMHost -ge 1) { - if ($VMHosts) { - #region Hosts Section - Section -Style Heading1 $($VMHost.ExtensionData.Name) { - Paragraph "The following sections detail the configuration of VMware ESXi host $($VMHost.ExtensionData.Name)." - #region ESXi Host Detailed Information - foreach ($VMHost in ($VMHosts | Where-Object { $_.ConnectionState -eq 'Connected' -or $_.ConnectionState -eq 'Maintenance' })) { - ### TODO: Host Certificate, Swap File Location - #region ESXi Host Hardware Section - Section -Style Heading2 'Hardware' { - Paragraph "The following section details the host hardware configuration for $($VMHost.ExtensionData.Name)." - BlankLine - - #region ESXi Host Specifications - $VMHostUptime = Get-Uptime -VMHost $VMHost - $esxcli = Get-EsxCli -VMHost $VMHost -V2 - $VMHostHardware = Get-VMHostHardware -VMHost $VMHost - $VMHostLicense = Get-VMHostLicense -VMHost $VMHost - $ScratchLocation = Get-AdvancedSetting -Entity $VMHost | Where-Object { $_.Name -eq 'ScratchConfig.CurrentScratchLocation' } - $VMHostDetail = [PSCustomObject]@{ - 'Host' = $VMHost.ExtensionData.Name - 'Connection State' = Switch ($VMHost.ConnectionState) { - 'NotResponding' { 'Not Responding' } - default { $VMHost.ConnectionState } - } - 'ID' = $VMHost.Id - 'Manufacturer' = $VMHost.Manufacturer - 'Model' = $VMHost.Model - 'Serial Number' = $VMHostHardware.SerialNumber - 'Asset Tag' = Switch ($VMHostHardware.AssetTag) { - '' { 'Unknown' } - default { $VMHostHardware.AssetTag } - } - 'Processor Type' = $VMHost.Processortype - 'HyperThreading' = Switch ($VMHost.HyperthreadingActive) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Number of CPU Sockets' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages - 'Number of CPU Cores' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores - 'Number of CPU Threads' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuThreads - 'CPU Total / Used' = "$([math]::Round(($VMHost.CpuTotalMhz) / 1000, 2)) GHz / $([math]::Round(($VMHost.CpuUsageMhz) / 1000, 2)) GHz" - 'Memory Total / Used' = "$([math]::Round($VMHost.MemoryTotalGB, 2)) GB / $([math]::Round($VMHost.MemoryUsageGB, 2)) GB" - 'NUMA Nodes' = $VMHost.ExtensionData.Hardware.NumaInfo.NumNodes - 'Number of NICs' = $VMHostHardware.NicCount - 'Number of Datastores' = $VMHost.ExtensionData.Datastore.Count - 'Number of VMs' = $VMHost.ExtensionData.VM.Count - 'Power Management Policy' = $VMHost.ExtensionData.Hardware.CpuPowerManagementInfo.CurrentPolicy - 'Scratch Location' = $ScratchLocation.Value - 'Bios Version' = $VMHost.ExtensionData.Hardware.BiosInfo.BiosVersion - 'Bios Release Date' = $VMHost.ExtensionData.Hardware.BiosInfo.ReleaseDate - 'ESXi Version' = $VMHost.Version - 'ESXi Build' = $VMHost.build - 'Product' = $VMHostLicense.Product -join ', ' - 'License Key' = $VMHostLicense.LicenseKey - 'License Expiration' = $VMHostLicense.Expiration - 'Boot Time' = ($VMHost.ExtensionData.Runtime.Boottime).ToLocalTime() - 'Uptime Days' = $VMHostUptime.UptimeDays + Write-PScriboMessage "VMHost InfoLevel set at $($InfoLevel.VMHost)." + #region Hosts Section + if ($VMHost | Where-Object { $_.ConnectionState -eq 'Connected' -or $_.ConnectionState -eq 'Maintenance' }) { + #region ESXi Host Detailed Information + Section -Style Heading1 $($VMHost.ExtensionData.Name) { + Paragraph "The following sections detail the configuration of VMware ESXi host $($VMHost.ExtensionData.Name)." + # TODO: Host Certificate, Swap File Location + if ($InfoLevel.VMHost -ge 1) { + #region ESXi Host Hardware Section + Section -Style Heading2 'Hardware' { + Paragraph "The following section details the host hardware configuration for $($VMHost.ExtensionData.Name)." + BlankLine + + #region ESXi Host Specifications + $VMHostUptime = Get-Uptime -VMHost $VMHost + $esxcli = Get-EsxCli -VMHost $VMHost -V2 + $VMHostLicense = Get-VMHostLicense -VMHost $VMHost + $ScratchLocation = Get-AdvancedSetting -Entity $VMHost | Where-Object { $_.Name -eq 'ScratchConfig.CurrentScratchLocation' } + $VMHostDetail = [PSCustomObject]@{ + 'Host' = $VMHost.ExtensionData.Name + 'Connection State' = Switch ($VMHost.ConnectionState) { + 'NotResponding' { 'Not Responding' } + default { $VMHost.ConnectionState } } - if ($Healthcheck.VMHost.ConnectionState) { - $VMHostDetail | Where-Object { $_.'Connection State' -eq 'Maintenance' } | Set-Style -Style Warning -Property 'Connection State' + 'ID' = $VMHost.Id + 'Manufacturer' = $VMHost.Manufacturer + 'Model' = $VMHost.Model + 'Serial Number' = Switch ($VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber) { + $null { '--' } + default { $VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber } } - if ($Healthcheck.VMHost.HyperThreading) { - $VMHostDetail | Where-Object { $_.'HyperThreading' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Disabled' + 'Asset Tag' = Switch ($VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue) { + '' { 'Unknown' } + $null { 'Unknown' } + default { $VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue } } - if ($Healthcheck.VMHost.Licensing) { - $VMHostDetail | Where-Object { $_.'Product' -like '*Evaluation*' } | Set-Style -Style Warning -Property 'Product' - $VMHostDetail | Where-Object { $_.'License Key' -like '*-00000-00000' } | Set-Style -Style Warning -Property 'License Key' - $VMHostDetail | Where-Object { $_.'License Expiration' -eq 'Expired' } | Set-Style -Style Critical -Property 'License Expiration' + 'Processor Type' = $VMHost.Processortype + 'HyperThreading' = Switch ($VMHost.HyperthreadingActive) { + $true { 'Enabled' } + $false { 'Disabled' } } - if ($Healthcheck.VMHost.ScratchLocation) { - $VMHostDetail | Where-Object { $_.'Scratch Location' -eq '/tmp/scratch' } | Set-Style -Style Warning -Property 'Scratch Location' + 'Number of CPU Sockets' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages + 'Number of CPU Cores' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores + 'Number of CPU Threads' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuThreads + 'CPU Total / Used' = "$([math]::Round(($VMHost.CpuTotalMhz) / 1000, 2)) GHz / $([math]::Round(($VMHost.CpuUsageMhz) / 1000, 2)) GHz" + 'Memory Total / Used' = "$([math]::Round($VMHost.MemoryTotalGB, 2)) GB / $([math]::Round($VMHost.MemoryUsageGB, 2)) GB" + 'NUMA Nodes' = $VMHost.ExtensionData.Hardware.NumaInfo.NumNodes + 'Number of NICs' = $VMHost.ExtensionData.Summary.Hardware.NumNics + 'Number of Datastores' = $VMHost.ExtensionData.Datastore.Count + 'Number of VMs' = $VMHost.ExtensionData.VM.Count + 'Power Management Policy' = $VMHost.ExtensionData.Hardware.CpuPowerManagementInfo.CurrentPolicy + 'Scratch Location' = $ScratchLocation.Value + 'Bios Version' = $VMHost.ExtensionData.Hardware.BiosInfo.BiosVersion + 'Bios Release Date' = $VMHost.ExtensionData.Hardware.BiosInfo.ReleaseDate + 'ESXi Version' = $VMHost.Version + 'ESXi Build' = $VMHost.build + 'Product' = $VMHostLicense.Product -join ', ' + 'License Key' = $VMHostLicense.LicenseKey + 'License Expiration' = $VMHostLicense.Expiration + 'Boot Time' = ($VMHost.ExtensionData.Runtime.Boottime).ToLocalTime() + 'Uptime Days' = $VMHostUptime.UptimeDays + } + if ($Healthcheck.VMHost.ConnectionState) { + $VMHostDetail | Where-Object { $_.'Connection State' -eq 'Maintenance' } | Set-Style -Style Warning -Property 'Connection State' + } + if ($Healthcheck.VMHost.HyperThreading) { + $VMHostDetail | Where-Object { $_.'HyperThreading' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Disabled' + } + if ($Healthcheck.VMHost.Licensing) { + $VMHostDetail | Where-Object { $_.'Product' -like '*Evaluation*' } | Set-Style -Style Warning -Property 'Product' + $VMHostDetail | Where-Object { $_.'License Key' -like '*-00000-00000' } | Set-Style -Style Warning -Property 'License Key' + $VMHostDetail | Where-Object { $_.'License Expiration' -eq 'Expired' } | Set-Style -Style Critical -Property 'License Expiration' + } + if ($Healthcheck.VMHost.ScratchLocation) { + $VMHostDetail | Where-Object { $_.'Scratch Location' -eq '/tmp/scratch' } | Set-Style -Style Warning -Property 'Scratch Location' + } + if ($Healthcheck.VMHost.UpTimeDays) { + $VMHostDetail | Where-Object { $_.'Uptime Days' -ge 275 -and $_.'Uptime Days' -lt 365 } | Set-Style -Style Warning -Property 'Uptime Days' + $VMHostDetail | Where-Object { $_.'Uptime Days' -ge 365 } | Set-Style -Style Critical -Property 'Uptime Days' + } + $TableParams = @{ + Name = "ESXi Host Configuration - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostDetail | Table @TableParams + #endregion ESXi Host Specifications + + #region ESXi Host Boot Device + Section -Style Heading3 'Boot Device' { + $ESXiBootDevice = Get-ESXiBootDevice -VMHost $VMHost + $VMHostBootDevice = [PSCustomObject]@{ + 'Host' = $ESXiBootDevice.Host + 'Device' = $ESXiBootDevice.Device + 'Boot Type' = $ESXiBootDevice.BootType + 'Vendor' = $ESXiBootDevice.Vendor + 'Model' = $ESXiBootDevice.Model + 'Size' = "$([math]::Round($ESXiBootDevice.SizeMB / 1024, 2)) GB" + 'Is SAS' = $ESXiBootDevice.IsSAS + 'Is SSD' = $ESXiBootDevice.IsSSD + 'Is USB' = $ESXiBootDevice.IsUSB } - if ($Healthcheck.VMHost.UpTimeDays) { - $VMHostDetail | Where-Object { $_.'Uptime Days' -ge 275 -and $_.'Uptime Days' -lt 365 } | Set-Style -Style Warning -Property 'Uptime Days' - $VMHostDetail | Where-Object { $_.'Uptime Days' -ge 365 } | Set-Style -Style Critical -Property 'Uptime Days' + $TableParams = @{ + Name = "Boot Device - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 } - $VMHostDetail | Table -Name "$($VMHost.ExtensionData.Name) ESXi Host Detailed Information" -List -ColumnWidths 50, 50 - #endregion ESXi Host Specifications - - #region ESXi Host Boot Device - Section -Style Heading3 'Boot Device' { - $ESXiBootDevice = Get-ESXiBootDevice -VMHost $VMHost - $VMHostBootDevice = [PSCustomObject]@{ - 'Host' = $ESXiBootDevice.Host - 'Device' = $ESXiBootDevice.Device - 'Boot Type' = $ESXiBootDevice.BootType - 'Vendor' = $ESXiBootDevice.Vendor - 'Model' = $ESXiBootDevice.Model - 'Size' = "$([math]::Round($ESXiBootDevice.SizeMB / 1024, 2)) GB" - 'Is SAS' = $ESXiBootDevice.IsSAS - 'Is SSD' = $ESXiBootDevice.IsSSD - 'Is USB' = $ESXiBootDevice.IsUSB - } - $VMHostBootDevice | Table -Name "$($VMHost.ExtensionData.Name) Boot Device" -List -ColumnWidths 50, 50 + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - #endregion ESXi Host Boot Devices - - #region ESXi Host PCI Devices - Section -Style Heading3 'PCI Devices' { - $PciHardwareDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { $_.VMkernelName -like "vmhba*" -OR $_.VMkernelName -like "vmnic*" -OR $_.VMkernelName -like "vmgfx*" } - $VMHostPciDevices = foreach ($PciHardwareDevice in $PciHardwareDevices) { - [PSCustomObject]@{ - 'VMkernel Name' = $PciHardwareDevice.VMkernelName - 'PCI Address' = $PciHardwareDevice.Address - 'Device Class' = $PciHardwareDevice.DeviceClassName - 'Device Name' = $PciHardwareDevice.DeviceName - 'Vendor Name' = $PciHardwareDevice.VendorName - 'Slot Description' = $PciHardwareDevice.SlotDescription - } + $VMHostBootDevice | Table @TableParams + } + #endregion ESXi Host Boot Devices + + #region ESXi Host PCI Devices + Section -Style Heading3 'PCI Devices' { + $PciHardwareDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { $_.VMkernelName -match 'vmhba|vmnic|vmgfx' -and $_.ModuleName -ne 'None'} | Sort-Object -Property VMkernelName + $VMHostPciDevices = foreach ($PciHardwareDevice in $PciHardwareDevices) { + [PSCustomObject]@{ + 'Device' = $PciHardwareDevice.VMkernelName + 'PCI Address' = $PciHardwareDevice.Address + 'Device Class' = $PciHardwareDevice.DeviceClassName + 'Device Name' = $PciHardwareDevice.DeviceName + 'Vendor Name' = $PciHardwareDevice.VendorName + 'Slot Description' = $PciHardwareDevice.SlotDescription } - $VMHostPciDevices | Sort-Object 'VMkernel Name' | Table -Name "$($VMHost.ExtensionData.Name) PCI Devices" } - #endregion ESXi Host PCI Devices - - #region ESXi Host PCI Devices Drivers & Firmware - Section -Style Heading3 'PCI Devices Drivers & Firmware' { - $VMHostPciDevicesDetails = Get-PciDeviceDetail -Server $VMHost -esxcli $esxcli - $VMHostPciDevicesDetails | Sort-Object 'VMkernel Name' | Table -Name "$($VMHost.ExtensionData.Name) PCI Devices Drivers & Firmware" + $TableParams = @{ + Name = "PCI Devices - $($VMHost.ExtensionData.Name)" + ColumnWidths = 12, 13, 15, 25, 20, 15 } - #endregion ESXi Host PCI Devices Drivers & Firmware - #> + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPciDevices | Table @TableParams } - #endregion ESXi Host Hardware Section - - #region ESXi Host System Section - Section -Style Heading2 'System' { - Paragraph "The following section details the host system configuration for $($VMHost.ExtensionData.Name)." - #region ESXi Host Image Profile Information - Section -Style Heading3 'Image Profile' { - $installdate = Get-InstallDate - $esxcli = Get-EsxCli -VMHost $VMHost -V2 - $ImageProfile = $esxcli.software.profile.get.Invoke() - $SecurityProfile = [PSCustomObject]@{ - 'Image Profile' = $ImageProfile.Name - 'Vendor' = $ImageProfile.Vendor - 'Installation Date' = $InstallDate.InstallDate + #endregion ESXi Host PCI Devices + + #region ESXi Host PCI Devices Drivers & Firmware + Section -Style Heading3 'PCI Devices Drivers & Firmware' { + $VMHostPciDevicesDetails = Get-PciDeviceDetail -Server $ESXi -esxcli $esxcli | Sort-Object 'Device' + $TableParams = @{ + Name = "PCI Devices Drivers & Firmware - $($VMHost.ExtensionData.Name)" + ColumnWidths = 12, 20, 11, 19, 11, 11, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPciDevicesDetails | Table @TableParams + } + #endregion ESXi Host PCI Devices Drivers & Firmware + #> + } + #endregion ESXi Host Hardware Section + + #region ESXi Host System Section + Section -Style Heading2 'System' { + Paragraph "The following section details the host system configuration for $($VMHost.ExtensionData.Name)." + #region ESXi Host Image Profile Information + Section -Style Heading3 'Image Profile' { + $installdate = Get-InstallDate + $esxcli = Get-EsxCli -VMHost $VMHost -V2 + $ImageProfile = $esxcli.software.profile.get.Invoke() + $SecurityProfile = [PSCustomObject]@{ + 'Image Profile' = $ImageProfile.Name + 'Vendor' = $ImageProfile.Vendor + 'Installation Date' = $InstallDate.InstallDate + } + $TableParams = @{ + Name = "Image Profile - $($VMHost.ExtensionData.Name)" + #ColumnWidths = 50, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SecurityProfile | Table @TableParams + } + #endregion ESXi Host Image Profile Information + + #region ESXi Host Time Configuration + Section -Style Heading3 'Time Configuration' { + $VMHostTimeSettings = [PSCustomObject]@{ + 'Time Zone' = $VMHost.timezone + 'NTP Service' = Switch ((Get-VMHostService -VMHost $VMHost | Where-Object { $_.key -eq 'ntpd' }).Running) { + $true { 'Running' } + $false { 'Stopped' } } - $SecurityProfile | Table -Name "$($VMHost.ExtensionData.Name) Image Profile" -ColumnWidths 50, 25, 25 + 'NTP Server(s)' = (Get-VMHostNtpServer -VMHost $VMHost | Sort-Object) -join ', ' } - #endregion ESXi Host Image Profile Information - - #region ESXi Host Time Configuration - Section -Style Heading3 'Time Configuration' { - $VMHostTimeSettings = [PSCustomObject]@{ - 'Time Zone' = $VMHost.timezone - 'NTP Service' = Switch ((Get-VMHostService -VMHost $VMHost | Where-Object { $_.key -eq 'ntpd' }).Running) { - $true { 'Running' } - $false { 'Stopped' } - } - 'NTP Server(s)' = (Get-VMHostNtpServer -VMHost $VMHost | Sort-Object) -join ', ' + if ($Healthcheck.VMHost.NTP) { + $VMHostTimeSettings | Where-Object { $_.'NTP Service' -eq 'Stopped' } | Set-Style -Style Critical -Property 'NTP Service' + } + $TableParams = @{ + Name = "Time Configuration - $($VMHost.ExtensionData.Name)" + ColumnWidths = 30, 30, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostTimeSettings | Table @TableParams + } + #endregion ESXi Host Time Configuration + + #region ESXi Host Syslog Configuration + $SyslogConfig = $VMHost | Get-VMHostSysLogServer + if ($SyslogConfig) { + Section -Style Heading3 'Syslog Configuration' { + # TODO: Syslog Rotate & Size, Log Directory (Adv Settings) + $SyslogConfig = $SyslogConfig | Select-Object @{L = 'SysLog Server'; E = { $_.Host } }, Port + $TableParams = @{ + Name = "Syslog Configuration - $($VMHost.ExtensionData.Name)" + ColumnWidths = 50, 50 } - if ($Healthcheck.VMHost.NTP) { - $VMHostTimeSettings | Where-Object { $_.'NTP Service' -eq 'Stopped' } | Set-Style -Style Critical -Property 'NTP Service' + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - $VMHostTimeSettings | Table -Name "$($VMHost.ExtensionData.Name) Time Configuration" -ColumnWidths 30, 30, 40 + $SyslogConfig | Table @TableParams } - #endregion ESXi Host Time Configuration - - #region ESXi Host Syslog Configuration - $SyslogConfig = $VMHost | Get-VMHostSysLogServer - if ($SyslogConfig) { - Section -Style Heading3 'Syslog Configuration' { - ### TODO: Syslog Rotate & Size, Log Directory (Adv Settings) - $SyslogConfig = $SyslogConfig | Select-Object @{L = 'SysLog Server'; E = { $_.Host } }, Port - $SyslogConfig | Table -Name "$($VMHost.ExtensionData.Name) Syslog Configuration" -ColumnWidths 50, 50 + } + #endregion ESXi Host Syslog Configuration + + #region ESXi Host Comprehensive Information Section + if ($InfoLevel.VMHost -ge 5) { + #region ESXi Host Advanced System Settings + Section -Style Heading3 'Advanced System Settings' { + $AdvSettings = $VMHost | Get-AdvancedSetting | Select-Object Name, Value + $TableParams = @{ + Name = "Advanced System Settings - $($VMHost.ExtensionData.Name)" + ColumnWidths = 50, 50 } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $AdvSettings | Sort-Object Name | Table @TableParams } - #endregion ESXi Host Syslog Configuration + #endregion ESXi Host Advanced System Settings - #region ESXi Host Comprehensive Information Section - if ($InfoLevel.VMHost -ge 5) { - #region ESXi Host Advanced System Settings - Section -Style Heading3 'Advanced System Settings' { - $AdvSettings = $VMHost | Get-AdvancedSetting | Select-Object Name, Value - $AdvSettings | Sort-Object Name | Table -Name "$($VMHost.ExtensionData.Name) Advanced System Settings" -ColumnWidths 50, 50 + #region ESXi Host Software VIBs + Section -Style Heading3 'Software VIBs' { + $esxcli = Get-EsxCli -VMHost $VMHost -V2 + $VMHostVibs = $esxcli.software.vib.list.Invoke() + $VMHostVibs = foreach ($VMHostVib in $VMHostVibs) { + [PSCustomObject]@{ + 'VIB' = $VMHostVib.Name + 'ID' = $VMHostVib.Id + 'Version' = $VMHostVib.Version + 'Acceptance Level' = $VMHostVib.AcceptanceLevel + 'Creation Date' = $VMHostVib.CreationDate + 'Install Date' = $VMHostVib.InstallDate + } } - #endregion ESXi Host Advanced System Settings - - #region ESXi Host Software VIBs - Section -Style Heading3 'Software VIBs' { - $esxcli = Get-EsxCli -VMHost $VMHost -V2 - $VMHostVibs = $esxcli.software.vib.list.Invoke() - $VMHostVibs = foreach ($VMHostVib in $VMHostVibs) { - [PSCustomObject]@{ - 'VIB' = $VMHostVib.Name - 'ID' = $VMHostVib.Id - 'Version' = $VMHostVib.Version - 'Acceptance Level' = $VMHostVib.AcceptanceLevel - 'Creation Date' = $VMHostVib.CreationDate - 'Install Date' = $VMHostVib.InstallDate - } - } - $VMHostVibs | Sort-Object 'Install Date' -Descending | Table -Name "$($VMHost.ExtensionData.Name) Software VIBs" -ColumnWidths 15, 25, 15, 15, 15, 15 + $TableParams = @{ + Name = "Software VIBs - $($VMHost.ExtensionData.Name)" + ColumnWidths = 15, 25, 15, 15, 15, 15 } - #endregion ESXi Host Software VIBs + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostVibs | Sort-Object 'Install Date' -Descending | Table @TableParams } - #endregion ESXi Host Comprehensive Information Section + #endregion ESXi Host Software VIBs } - #endregion ESXi Host System Section + #endregion ESXi Host Comprehensive Information Section + } + #endregion ESXi Host System Section - #region ESXi Host Storage Section + #region ESXi Host Storage Section + if ($InfoLevel.Storage -ge 1) { Section -Style Heading2 'Storage' { Paragraph "The following section details the host storage configuration for $($VMHost.ExtensionData.Name)." - + #region Datastore Section - # Currently there is no Datastore InfoLevel 1 - if ($InfoLevel.Datastore -ge 2) { - if ($Datastores) { - Section -Style Heading3 'Datastores' { - #region Datastore Infomative Information - if ($InfoLevel.Datastore -eq 2) { - $DatastoreInfo = foreach ($Datastore in $Datastores) { - [PSCustomObject]@{ + Write-PScriboMessage "Storage InfoLevel set at $($InfoLevel.Storage)." + + if ($Datastores) { + Section -Style Heading3 'Datastores' { + #region Datastore Infomative Information + if (($InfoLevel.Storage -ge 1) -and ($InfoLevel.Storage -lt 3)) { + $DatastoreInfo = foreach ($Datastore in $Datastores) { + [PSCustomObject]@{ + 'Datastore' = $Datastore.Name + 'Type' = $Datastore.Type + 'Version' = Switch ($Datastore.FileSystemVersion) { + $null { '--' } + default { $Datastore.FileSystemVersion } + } + '# of VMs' = $Datastore.ExtensionData.VM.Count + 'Total Capacity GB' = [math]::Round($Datastore.CapacityGB, 2) + 'Used Capacity GB' = [math]::Round((($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB)), 2) + 'Free Space GB' = [math]::Round($Datastore.FreeSpaceGB, 2) + '% Used' = [math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2) + } + } + if ($Healthcheck.Datastore.CapacityUtilization) { + $DatastoreInfo | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property '% Used' + $DatastoreInfo | Where-Object { $_.'% Used' -ge 75 -and $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property '% Used' + } + $TableParams = @{ + Name = "Datastores - $($VMHost.ExtensionData.Name)" + ColumnWidths = 20, 8, 9, 8, 15, 15, 15, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DatastoreInfo | Sort-Object 'Datastore' | Table @TableParams + } + #endregion Datastore Advanced Summary + + #region Datastore Detailed Information + if ($InfoLevel.Storage -ge 3) { + foreach ($Datastore in $Datastores) { + #region Datastore Section + Section -Style Heading4 $Datastore.Name { + $DatastoreDetail = [PSCustomObject]@{ 'Datastore' = $Datastore.Name + 'ID' = $Datastore.Id 'Type' = $Datastore.Type 'Version' = Switch ($Datastore.FileSystemVersion) { $null { '--' } default { $Datastore.FileSystemVersion } } - '# of VMs' = $Datastore.ExtensionData.VM.Count - 'Total Capacity GB' = [math]::Round($Datastore.CapacityGB, 2) - 'Used Capacity GB' = [math]::Round((($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB)), 2) - 'Free Space GB' = [math]::Round($Datastore.FreeSpaceGB, 2) + 'State' = $Datastore.State + 'Number of VMs' = $Datastore.ExtensionData.VM.Count + 'Storage I/O Control' = Switch ($Datastore.StorageIOControlEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } + } + 'Congestion Threshold' = Switch ($Datastore.CongestionThresholdMillisecond) { + $null { '--' } + default { "$($Datastore.CongestionThresholdMillisecond) ms" } + } + 'Total Capacity' = "$([math]::Round($Datastore.CapacityGB, 2)) GB" + 'Used Capacity' = "$([math]::Round((($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB)), 2)) GB" + 'Free Space' = "$([math]::Round($Datastore.FreeSpaceGB, 2)) GB" '% Used' = [math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2) } - } - if ($Healthcheck.Datastore.CapacityUtilization) { - $DatastoreInfo | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property '% Used' - $DatastoreInfo | Where-Object { $_.'% Used' -ge 75 -and $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property '% Used' - } - $DatastoreInfo | Sort-Object Datastore | Table -Name 'Datastore Information' - } - #endregion Datastore Informative Information + if ($Healthcheck.Datastore.CapacityUtilization) { + $DatastoreDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property '% Used' + $DatastoreDetail | Where-Object { $_.'% Used' -ge 75 -and + $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property '% Used' + } - #region Datastore Detailed Information - if ($InfoLevel.Datastore -ge 3) { - foreach ($Datastore in $Datastores) { - #region Datastore Section - Section -Style Heading4 $Datastore.Name { - $DatastoreDetail = [PSCustomObject]@{ - 'Datastore' = $Datastore.Name - 'ID' = $Datastore.Id - 'Type' = $Datastore.Type - 'Version' = Switch ($Datastore.FileSystemVersion) { - $null { '--' } - default { $Datastore.FileSystemVersion } - } - 'State' = $Datastore.State - 'Number of VMs' = $Datastore.ExtensionData.VM.Count - 'Storage I/O Control' = Switch ($Datastore.StorageIOControlEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Congestion Threshold' = Switch ($Datastore.CongestionThresholdMillisecond) { - $null { '--' } - default { "$($Datastore.CongestionThresholdMillisecond) ms" } - } - 'Total Capacity' = "$([math]::Round($Datastore.CapacityGB, 2)) GB" - 'Used Capacity' = "$([math]::Round((($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB)), 2)) GB" - 'Free Space' = "$([math]::Round($Datastore.FreeSpaceGB, 2)) GB" - '% Used' = [math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2) + #region Datastore Advanced Detailed Information + if ($InfoLevel.Storage -ge 4) { + $MemberProps = @{ + 'InputObject' = $DatastoreDetail + 'MemberType' = 'NoteProperty' } - if ($Healthcheck.Datastore.CapacityUtilization) { - $DatastoreDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property '% Used' - $DatastoreDetail | Where-Object { $_.'% Used' -ge 75 -and - $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property '% Used' + $DatastoreVMs = foreach ($DatastoreVM in $Datastore.ExtensionData.VM) { + $VMLookup."$($DatastoreVM.Type)-$($DatastoreVM.Value)" } - - #region Datastore Advanced Detailed Information - if ($InfoLevel.Datastore -ge 4) { - $MemberProps = @{ - 'InputObject' = $DatastoreDetail - 'MemberType' = 'NoteProperty' - } - $DatastoreVMs = foreach ($DatastoreVM in $Datastore.ExtensionData.VM) { - $VMLookup."$($DatastoreVM.Type)-$($DatastoreVM.Value)" - } - Add-Member @MemberProps -Name 'Virtual Machines' -Value (($DatastoreVMs | Sort-Object) -join ', ') - } - #endregion Datastore Advanced Detailed Information - - $DatastoreDetail | Sort-Object Datacenter, Datastore | Table -List -Name 'Datastore Specifications' -ColumnWidths 50, 50 - - # Get VMFS volumes. Ignore local SCSILuns. - if (($Datastore.Type -eq 'VMFS') -and ($Datastore.ExtensionData.Info.Vmfs.Local -eq $false)) { - #region SCSI LUN Information Section - Section -Style Heading4 'SCSI LUN Information' { - $ScsiLuns = foreach ($DatastoreHost in $Datastore.ExtensionData.Host.Key) { - $DiskName = $Datastore.ExtensionData.Info.Vmfs.Extent.DiskName - $ScsiDeviceDetailProps = @{ - 'VMHosts' = $VMHosts - 'VMHostMoRef' = "$($DatastoreHost.Type)-$($DatastoreHost.Value)" - 'DatastoreDiskName' = $DiskName - } - $ScsiDeviceDetail = Get-ScsiDeviceDetail @ScsiDeviceDetailProps + Add-Member @MemberProps -Name 'Virtual Machines' -Value (($DatastoreVMs | Sort-Object) -join ', ') + } + #endregion Datastore Advanced Detailed Information + $TableParams = @{ + Name = "Datastore $($Datastore.Name) - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DatastoreDetail | Sort-Object Datacenter, Datastore | Table @TableParams + + # Get VMFS volumes. Ignore local SCSILuns. + if (($Datastore.Type -eq 'VMFS') -and ($Datastore.ExtensionData.Info.Vmfs.Local -eq $false)) { + #region SCSI LUN Information Section + Section -Style Heading4 'SCSI LUNs' { + $ScsiLuns = foreach ($DatastoreHost in $Datastore.ExtensionData.Host.Key) { + $DiskName = $Datastore.ExtensionData.Info.Vmfs.Extent.DiskName + $ScsiDeviceDetailProps = @{ + 'VMHosts' = $VMHost + 'VMHostMoRef' = "$($DatastoreHost.Type)-$($DatastoreHost.Value)" + 'DatastoreDiskName' = $DiskName + } + $ScsiDeviceDetail = Get-ScsiDeviceDetail @ScsiDeviceDetailProps - [PSCustomObject]@{ - 'Host' = $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" - 'Canonical Name' = $DiskName - 'Capacity GB' = $ScsiDeviceDetail.CapacityGB - 'Vendor' = $ScsiDeviceDetail.Vendor - 'Model' = $ScsiDeviceDetail.Model - 'Is SSD' = $ScsiDeviceDetail.Ssd - 'Multipath Policy' = $ScsiDeviceDetail.MultipathPolicy - 'Paths' = $ScsiDeviceDetail.Paths - } + [PSCustomObject]@{ + 'Host' = $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" + 'Canonical Name' = $DiskName + 'Capacity GB' = $ScsiDeviceDetail.CapacityGB + 'Vendor' = $ScsiDeviceDetail.Vendor + 'Model' = $ScsiDeviceDetail.Model + 'Is SSD' = $ScsiDeviceDetail.Ssd + 'Multipath Policy' = $ScsiDeviceDetail.MultipathPolicy + 'Paths' = $ScsiDeviceDetail.Paths } - $ScsiLuns | Sort-Object Host | Table -Name 'SCSI LUN Information' } - #endregion SCSI LUN Information Section + $TableParams = @{ + Name = "SCSI LUNs - $($VMHost.ExtensionData.Name)" + ColumnWidths = 18, 18, 10, 14, 12, 8, 12, 8 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ScsiLuns | Sort-Object Host | Table @TableParams } + #endregion SCSI LUN Information Section } - #endregion Datastore Section } + #endregion Datastore Section } - #endregion Datastore Detailed Information } + #endregion Datastore Detailed Information } } #endregion Datastore Section @@ -823,1163 +493,1515 @@ function Invoke-AsBuiltReport.VMware.ESXi { if ($VMHostHbas) { #region ESXi Host Storage Adapters Section Section -Style Heading3 'Storage Adapters' { - foreach ($VMHostHba in $VMHostHbas) { - $Target = ((Get-View $VMHostHba.VMhost).Config.StorageDevice.ScsiTopology.Adapter | Where-Object { $_.Adapter -eq $VMHostHba.Key }).Target - $LUNs = Get-ScsiLun -Hba $VMHostHba -LunType "disk" -ErrorAction SilentlyContinue - $Paths = ($Target | foreach { $_.Lun.Count } | Measure-Object -Sum) - Section -Style Heading4 "$($VMHostHba.Device)" { - $VMHostStorageAdapter = [PSCustomObject]@{ - 'Adapter' = $VMHostHba.Device - 'Type' = Switch ($VMHostHba.Type) { - 'FibreChannel' { 'Fibre Channel' } - 'IScsi' { 'iSCSI' } - 'ParallelScsi' { 'Parallel SCSI' } - default { $TextInfo.ToTitleCase($VMHostHba.Type) } - } - 'Model' = $VMHostHba.Model - 'Status' = $TextInfo.ToTitleCase($VMHostHba.Status) - 'Targets' = $Target.Count - 'Devices' = $LUNs.Count - 'Paths' = $Paths.Sum - } - $MemberProps = @{ - 'InputObject' = $VMHostStorageAdapter - 'MemberType' = 'NoteProperty' - } - if ($VMHostStorageAdapter.Type -eq 'iSCSI') { - $iScsiAuthenticationMethod = Switch ($VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType) { - 'chapProhibited' { 'None' } - 'chapPreferred' { 'Use unidirectional CHAP unless prohibited by target' } - 'chapDiscouraged' { 'Use unidirectional CHAP if required by target' } - 'chapRequired' { - Switch ($VMHostHba.ExtensionData.AuthenticationProperties.MutualChapAuthenticationType) { - 'chapProhibited' { 'Use unidirectional CHAP' } - 'chapRequired' { 'Use bidirectional CHAP' } - } + if ($InfoLevel.VMHost -ge 3) { + foreach ($VMHostHba in $VMHostHbas) { + $Target = ((Get-View $VMHostHba.VMhost).Config.StorageDevice.ScsiTopology.Adapter | Where-Object { $_.Adapter -eq $VMHostHba.Key }).Target + $LUNs = Get-ScsiLun -Hba $VMHostHba -LunType "disk" -ErrorAction SilentlyContinue + $Paths = ($Target | ForEach-Object { $_.Lun.Count } | Measure-Object -Sum) + Section -Style Heading4 "$($VMHostHba.Device)" { + $VMHostStorageAdapter = [PSCustomObject]@{ + 'Adapter' = $VMHostHba.Device + 'Type' = Switch ($VMHostHba.Type) { + 'FibreChannel' { 'Fibre Channel' } + 'IScsi' { 'iSCSI' } + 'ParallelScsi' { 'Parallel SCSI' } + default { $TextInfo.ToTitleCase($VMHostHba.Type) } } - default { $VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType } + 'Model' = $VMHostHba.Model + 'Status' = $TextInfo.ToTitleCase($VMHostHba.Status) + 'Targets' = $Target.Count + 'Devices' = $LUNs.Count + 'Paths' = $Paths.Sum } - Add-Member @MemberProps -Name 'iSCSI Name' -Value $VMHostHba.IScsiName - if ($VMHostHba.IScsiAlias) { - Add-Member @MemberProps -Name 'iSCSI Alias' -Value $VMHostHba.IScsiAlias - } else { - Add-Member @MemberProps -Name 'iSCSI Alias' -Value '--' + $MemberProps = @{ + 'InputObject' = $VMHostStorageAdapter + 'MemberType' = 'NoteProperty' } - if ($VMHostHba.CurrentSpeedMb) { - Add-Member @MemberProps -Name 'Speed' -Value "$($VMHostHba.CurrentSpeedMb) Mb" - } else { - Add-Member @MemberProps -Name 'Speed' -Value '--' + if ($VMHostStorageAdapter.Type -eq 'iSCSI') { + $iScsiAuthenticationMethod = Switch ($VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType) { + 'chapProhibited' { 'None' } + 'chapPreferred' { 'Use unidirectional CHAP unless prohibited by target' } + 'chapDiscouraged' { 'Use unidirectional CHAP if required by target' } + 'chapRequired' { + Switch ($VMHostHba.ExtensionData.AuthenticationProperties.MutualChapAuthenticationType) { + 'chapProhibited' { 'Use unidirectional CHAP' } + 'chapRequired' { 'Use bidirectional CHAP' } + } + } + default { $VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType } + } + Add-Member @MemberProps -Name 'iSCSI Name' -Value $VMHostHba.IScsiName + if ($VMHostHba.IScsiAlias) { + Add-Member @MemberProps -Name 'iSCSI Alias' -Value $VMHostHba.IScsiAlias + } else { + Add-Member @MemberProps -Name 'iSCSI Alias' -Value '--' + } + if ($VMHostHba.CurrentSpeedMb) { + Add-Member @MemberProps -Name 'Speed' -Value "$($VMHostHba.CurrentSpeedMb) Mb" + } else { + Add-Member @MemberProps -Name 'Speed' -Value '--' + } + if ($VMHostHba.ExtensionData.ConfiguredSendTarget) { + Add-Member @MemberProps -Name 'Dynamic Discovery' -Value (($VMHostHba.ExtensionData.ConfiguredSendTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" }) -join [Environment]::NewLine) + } else { + Add-Member @MemberProps -Name 'Dynamic Discovery' -Value '--' + } + if ($VMHostHba.ExtensionData.ConfiguredStaticTarget) { + Add-Member @MemberProps -Name 'Static Discovery' -Value (($VMHostHba.ExtensionData.ConfiguredStaticTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" + " " + "$($_.IScsiName)" }) -join [Environment]::NewLine) + } else { + Add-Member @MemberProps -Name 'Static Discovery' -Value '--' + } + if ($iScsiAuthenticationMethod -eq 'None') { + Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod + } elseif ($iScsiAuthenticationMethod -eq 'Use bidirectional CHAP') { + Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod + Add-Member @MemberProps -Name 'Outgoing CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName + Add-Member @MemberProps -Name 'Incoming CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.MutualChapName + } else { + Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod + Add-Member @MemberProps -Name 'Outgoing CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName + } + if ($InfoLevel.VMHost -eq 4) { + Add-Member @MemberProps -Name 'Advanced Options' -Value (($VMHostHba.ExtensionData.AdvancedOptions | ForEach-Object { "$($_.Key) = $($_.Value)" }) -join [Environment]::NewLine) + } } - if ($VMHostHba.ExtensionData.ConfiguredSendTarget) { - Add-Member @MemberProps -Name 'Dynamic Discovery' -Value (($VMHostHba.ExtensionData.ConfiguredSendTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" }) -join [Environment]::NewLine) - } else { - Add-Member @MemberProps -Name 'Dynamic Discovery' -Value '--' + if ($VMHostStorageAdapter.Type -eq 'Fibre Channel') { + Add-Member @MemberProps -Name 'Node WWN' -Value (([String]::Format("{0:X}", $VMHostHba.NodeWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") + Add-Member @MemberProps -Name 'Port WWN' -Value (([String]::Format("{0:X}", $VMHostHba.PortWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") + Add-Member @MemberProps -Name 'Speed' -Value $VMHostHba.Speed } - if ($VMHostHba.ExtensionData.ConfiguredStaticTarget) { - Add-Member @MemberProps -Name 'Static Discovery' -Value (($VMHostHba.ExtensionData.ConfiguredStaticTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" + " " + "$($_.IScsiName)" }) -join [Environment]::NewLine) - } else { - Add-Member @MemberProps -Name 'Static Discovery' -Value '--' + if ($Healthcheck.VMHost.StorageAdapter) { + $VMHostStorageAdapter | Where-Object { $_.'Status' -ne 'Online' } | Set-Style -Style Warning -Property 'Status' + $VMHostStorageAdapter | Where-Object { $_.'Status' -eq 'Offline' } | Set-Style -Style Critical -Property 'Status' } - if ($iScsiAuthenticationMethod -eq 'None') { - Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod - } elseif ($iScsiAuthenticationMethod -eq 'Use bidirectional CHAP') { - Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod - Add-Member @MemberProps -Name 'Outgoing CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName - Add-Member @MemberProps -Name 'Incoming CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.MutualChapName - } else { - Add-Member @MemberProps -Name 'Authentication Method' -Value $iScsiAuthenticationMethod - Add-Member @MemberProps -Name 'Outgoing CHAP Name' -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName + $TableParams = @{ + Name = "Storage Adapter $($VMHostStorageAdapter.Adapter) - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 25, 75 } - if ($InfoLevel.VMHost -eq 4) { - Add-Member @MemberProps -Name 'Advanced Options' -Value (($VMHostHba.ExtensionData.AdvancedOptions | ForEach-Object { "$($_.Key) = $($_.Value)" }) -join [Environment]::NewLine) + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } + $VMHostStorageAdapter | Table @TableParams } - if ($VMHostStorageAdapter.Type -eq 'Fibre Channel') { - Add-Member @MemberProps -Name 'Node WWN' -Value (([String]::Format("{0:X}", $VMHostHba.NodeWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") - Add-Member @MemberProps -Name 'Port WWN' -Value (([String]::Format("{0:X}", $VMHostHba.PortWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") - Add-Member @MemberProps -Name 'Speed' -Value $VMHostHba.Speed - } - if ($Healthcheck.VMHost.StorageAdapter) { - $VMHostStorageAdapter | Where-Object { $_.'Status' -ne 'Online' } | Set-Style -Style Warning -Property 'Status' - $VMHostStorageAdapter | Where-Object { $_.'Status' -eq 'Offline' } | Set-Style -Style Critical -Property 'Status' + } + } else { + $VMHostStorageAdapters = foreach ($VMHostHba in $VMHostHbas) { + [PSCustomObject]@{ + 'Adapter' = $VMHostHba.Device + 'Type' = Switch ($VMHostHba.Type) { + 'FibreChannel' { 'Fibre Channel' } + 'IScsi' { 'iSCSI' } + 'ParallelScsi' { 'Parallel SCSI' } + default { $TextInfo.ToTitleCase($VMHostHba.Type) } + } + 'Model' = $VMHostHba.Model + 'Status' = $TextInfo.ToTitleCase($VMHostHba.Status) } - $VMHostStorageAdapter | Table -List -Name "$($VMHost.ExtensionData.Name) storage adapter $($VMHostStorageAdapter.Adapter)" -ColumnWidths 25, 75 } + if ($Healthcheck.VMHost.StorageAdapter) { + $VMHostStorageAdapters | Where-Object { $_.'Status' -ne 'Online' } | Set-Style -Style Warning -Property 'Status' + $VMHostStorageAdapters | Where-Object { $_.'Status' -eq 'Offline' } | Set-Style -Style Critical -Property 'Status' + } + $TableParams = @{ + Name = "Storage Adapters - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostStorageAdapters | Table @TableParams } } #endregion ESXi Host Storage Adapters Section } #endregion ESXi Host Storage Adapter Information } - #endregion ESXi Host Storage Section + } + #endregion ESXi Host Storage Section + } - #region ESXi Host Network Section - Section -Style Heading2 'Network' { - Paragraph "The following section details the host network configuration for $($VMHost.ExtensionData.Name)." - BlankLine - #region ESXi Host Network Configuration - $VMHostNetwork = $VMHost.ExtensionData.Config.Network - $VMHostVirtualSwitch = @() - $VMHostVss = foreach ($vSwitch in $VMHost.ExtensionData.Config.Network.Vswitch) { - $VMHostVirtualSwitch += $vSwitch.Name - } - $VMHostDvs = foreach ($dvSwitch in $VMHost.ExtensionData.Config.Network.ProxySwitch) { - $VMHostVirtualSwitch += $dvSwitch.DvsName - } - $VMHostNetworkDetail = [PSCustomObject]@{ - 'Host' = $($VMHost.ExtensionData.Name) - 'Virtual Switches' = ($VMHostVirtualSwitch | Sort-Object) -join ', ' - 'VMkernel Adapters' = ($VMHostNetwork.Vnic.Device | Sort-Object) -join ', ' - 'Physical Adapters' = ($VMHostNetwork.Pnic.Device | Sort-Object) -join ', ' - 'VMkernel Gateway' = $VMHostNetwork.IpRouteConfig.DefaultGateway - 'IPv6' = Switch ($VMHostNetwork.IPv6Enabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'VMkernel IPv6 Gateway' = Switch ($VMHostNetwork.IpRouteConfig.IpV6DefaultGateway) { - $null { '--' } - default { $VMHostNetwork.IpRouteConfig.IpV6DefaultGateway } - } - 'DNS Servers' = ($VMHostNetwork.DnsConfig.Address | Sort-Object) -join ', ' - 'Host Name' = $VMHostNetwork.DnsConfig.HostName - 'Domain Name' = $VMHostNetwork.DnsConfig.DomainName - 'Search Domain' = ($VMHostNetwork.DnsConfig.SearchDomain | Sort-Object) -join ', ' + #region ESXi Host Network Section + if ($InfoLevel.Network -ge 1) { + Section -Style Heading2 'Network' { + Paragraph "The following section details the host network configuration for $($VMHost.ExtensionData.Name)." + BlankLine + #region ESXi Host Network Configuration + $VMHostNetwork = $VMHost.ExtensionData.Config.Network + $VMHostVirtualSwitch = @() + $VMHostVss = foreach ($vSwitch in $VMHost.ExtensionData.Config.Network.Vswitch) { + $VMHostVirtualSwitch += $vSwitch.Name + } + $VMHostDvs = foreach ($dvSwitch in $VMHost.ExtensionData.Config.Network.ProxySwitch) { + $VMHostVirtualSwitch += $dvSwitch.DvsName + } + $VMHostNetworkDetail = [PSCustomObject]@{ + 'Host' = $($VMHost.ExtensionData.Name) + 'Virtual Switches' = ($VMHostVirtualSwitch | Sort-Object) -join ', ' + 'VMkernel Adapters' = ($VMHostNetwork.Vnic.Device | Sort-Object) -join ', ' + 'Physical Adapters' = ($VMHostNetwork.Pnic.Device | Sort-Object) -join ', ' + 'VMkernel Gateway' = $VMHostNetwork.IpRouteConfig.DefaultGateway + 'IPv6' = Switch ($VMHostNetwork.IPv6Enabled) { + $true { 'Enabled' } + $false { 'Disabled' } } - if ($Healthcheck.VMHost.IPv6) { - $VMHostNetworkDetail | Where-Object { $_.'IPv6' -eq $false } | Set-Style -Style Warning -Property 'IPv6' + 'VMkernel IPv6 Gateway' = Switch ($VMHostNetwork.IpRouteConfig.IpV6DefaultGateway) { + $null { '--' } + default { $VMHostNetwork.IpRouteConfig.IpV6DefaultGateway } } - $VMHostNetworkDetail | Table -Name "$($VMHost.ExtensionData.Name) Network Configuration" -List -ColumnWidths 50, 50 - #endregion ESXi Host Network Configuration - - #region ESXi Host Physical Adapters - Section -Style Heading3 'Physical Adapters' { - $PhysicalNetAdapters = $VMHost.ExtensionData.Config.Network.Pnic | Sort-Object Device - $VMHostPhysicalNetAdapters = foreach ($PhysicalNetAdapter in $PhysicalNetAdapters) { - [PSCustomObject]@{ - 'Adapter' = $PhysicalNetAdapter.Device - 'Status' = Switch ($PhysicalNetAdapter.Linkspeed) { - $null { 'Disconnected' } - default { 'Connected' } - } - 'Virtual Switch' = $( - if ($VMHost.ExtensionData.Config.Network.Vswitch.Pnic -contains $PhysicalNetAdapter.Key) { - ($VMHost.ExtensionData.Config.Network.Vswitch | Where-Object { $_.Pnic -eq $PhysicalNetAdapter.Key }).Name - } elseif ($VMHost.ExtensionData.Config.Network.ProxySwitch.Pnic -contains $PhysicalNetAdapter.Key) { - ($VMHost.ExtensionData.Config.Network.ProxySwitch | Where-Object { $_.Pnic -eq $PhysicalNetAdapter.Key }).DvsName + 'DNS Servers' = ($VMHostNetwork.DnsConfig.Address | Sort-Object) -join ', ' + 'Host Name' = $VMHostNetwork.DnsConfig.HostName + 'Domain Name' = $VMHostNetwork.DnsConfig.DomainName + 'Search Domain' = ($VMHostNetwork.DnsConfig.SearchDomain | Sort-Object) -join ', ' + } + if ($Healthcheck.VMHost.IPv6) { + $VMHostNetworkDetail | Where-Object { $_.'IPv6' -eq $false } | Set-Style -Style Warning -Property 'IPv6' + } + $TableParams = @{ + Name = "Network Configuration - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostNetworkDetail | Table @TableParams + #endregion ESXi Host Network Configuration + + #region ESXi Host Physical Adapters + Section -Style Heading3 'Physical Adapters' { + $PhysicalNetAdapters = $VMHost.ExtensionData.Config.Network.Pnic | Sort-Object Device + $VMHostPhysicalNetAdapters = foreach ($PhysicalNetAdapter in $PhysicalNetAdapters) { + [PSCustomObject]@{ + 'Adapter' = $PhysicalNetAdapter.Device + 'Status' = Switch ($PhysicalNetAdapter.Linkspeed) { + $null { 'Disconnected' } + default { 'Connected' } + } + 'Virtual Switch' = $( + if ($VMHost.ExtensionData.Config.Network.Vswitch.Pnic -contains $PhysicalNetAdapter.Key) { + ($VMHost.ExtensionData.Config.Network.Vswitch | Where-Object { $_.Pnic -eq $PhysicalNetAdapter.Key }).Name + } elseif ($VMHost.ExtensionData.Config.Network.ProxySwitch.Pnic -contains $PhysicalNetAdapter.Key) { + ($VMHost.ExtensionData.Config.Network.ProxySwitch | Where-Object { $_.Pnic -eq $PhysicalNetAdapter.Key }).DvsName + } else { + '--' + } + ) + 'MAC Address' = $PhysicalNetAdapter.Mac + 'Actual Speed, Duplex' = Switch ($PhysicalNetAdapter.LinkSpeed.SpeedMb) { + $null { 'Down' } + default { + if ($PhysicalNetAdapter.LinkSpeed.Duplex) { + "$($PhysicalNetAdapter.LinkSpeed.SpeedMb) Mbps, Full Duplex" } else { - '--' - } - ) - 'MAC Address' = $PhysicalNetAdapter.Mac - 'Actual Speed, Duplex' = Switch ($PhysicalNetAdapter.LinkSpeed.SpeedMb) { - $null { 'Down' } - default { - if ($PhysicalNetAdapter.LinkSpeed.Duplex) { - "$($PhysicalNetAdapter.LinkSpeed.SpeedMb) Mbps, Full Duplex" - } else { - 'Auto negotiate' - } + 'Auto negotiate' } } - 'Configured Speed, Duplex' = Switch ($PhysicalNetAdapter.Spec.LinkSpeed) { - $null { 'Auto negotiate' } - default { - if ($PhysicalNetAdapter.Spec.LinkSpeed.Duplex) { - "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps, Full Duplex" - } else { - "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps" - } + } + 'Configured Speed, Duplex' = Switch ($PhysicalNetAdapter.Spec.LinkSpeed) { + $null { 'Auto negotiate' } + default { + if ($PhysicalNetAdapter.Spec.LinkSpeed.Duplex) { + "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps, Full Duplex" + } else { + "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps" } } - 'Wake on LAN' = Switch ($PhysicalNetAdapter.WakeOnLanSupported) { - $true { 'Supported' } - $false { 'Not Supported' } - } + } + 'Wake on LAN' = Switch ($PhysicalNetAdapter.WakeOnLanSupported) { + $true { 'Supported' } + $false { 'Not Supported' } } } - if ($Healthcheck.VMHost.NetworkAdapter) { - $VMHostPhysicalNetAdapters | Where-Object { $_.'Status' -ne 'Connected' } | Set-Style -Style Critical -Property 'Status' - $VMHostPhysicalNetAdapters | Where-Object { $_.'Actual Speed, Duplex' -eq 'Down' } | Set-Style -Style Critical -Property 'Actual Speed, Duplex' - } - if ($InfoLevel.VMHost -ge 4) { - foreach ($VMHostPhysicalNetAdapter in $VMHostPhysicalNetAdapters) { - Section -Style Heading4 "$($VMHostPhysicalNetAdapter.Adapter)" { - $VMHostPhysicalNetAdapter | Table -List -Name "$($VMHost.ExtensionData.Name) Physical Adapter $($VMHostPhysicalNetAdapter.Adapter)" -ColumnWidths 50, 50 + } + if ($Healthcheck.VMHost.NetworkAdapter) { + $VMHostPhysicalNetAdapters | Where-Object { $_.'Status' -ne 'Connected' } | Set-Style -Style Critical -Property 'Status' + $VMHostPhysicalNetAdapters | Where-Object { $_.'Actual Speed, Duplex' -eq 'Down' } | Set-Style -Style Critical -Property 'Actual Speed, Duplex' + } + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostPhysicalNetAdapter in $VMHostPhysicalNetAdapters) { + Section -Style Heading4 "$($VMHostPhysicalNetAdapter.Adapter)" { + $TableParams = @{ + Name = "Physical Adapter $($VMHostPhysicalNetAdapter.Adapter) - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } + $VMHostPhysicalNetAdapter | Table @TableParams } - } else { - $VMHostPhysicalNetAdapters | Table -Name "$($VMHost.ExtensionData.Name) Physical Adapters" } + } else { + $TableParams = @{ + Name = "Physical Adapters - $($VMHost.ExtensionData.Name)" + ColumnWidths = 11, 13, 15, 19, 14, 14, 14 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPhysicalNetAdapters | Table @TableParams } - #endregion ESXi Host Physical Adapters - - #region ESXi Host Cisco Discovery Protocol - $VMHostNetworkAdapterCDP = $VMHost | Get-VMHostNetworkAdapterCDP | Where-Object { $_.Status -eq 'Connected' } | Sort-Object Device - if ($VMHostNetworkAdapterCDP) { - Section -Style Heading3 'Cisco Discovery Protocol' { - if ($InfoLevel.VMHost -ge 4) { - foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { - Section -Style Heading4 "$($VMHostNetworkAdapter.Device)" { - $VMHostCDP = [PSCustomObject]@{ - 'Status' = $VMHostNetworkAdapter.Status - 'System Name' = $VMHostNetworkAdapter.SystemName - 'Hardware Platform' = $VMHostNetworkAdapter.HardwarePlatform - 'Switch ID' = $VMHostNetworkAdapter.SwitchId - 'Software Version' = $VMHostNetworkAdapter.SoftwareVersion - 'Management Address' = $VMHostNetworkAdapter.ManagementAddress - 'Address' = $VMHostNetworkAdapter.Address - 'Port ID' = $VMHostNetworkAdapter.PortId - 'VLAN' = $VMHostNetworkAdapter.Vlan - 'MTU' = $VMHostNetworkAdapter.Mtu - } - $VMHostCDP | Table -List -Name "$($VMHost.ExtensionData.Name) Network Adapter $($VMHostNetworkAdapter.Device) CDP Information" -ColumnWidths 50, 50 - } - } - } else { - $VMHostCDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { - [PSCustomObject]@{ - 'Adapter' = $VMHostNetworkAdapter.Device + } + #endregion ESXi Host Physical Adapters + + #region ESXi Host Cisco Discovery Protocol + $VMHostNetworkAdapterCDP = $VMHost | Get-VMHostNetworkAdapterDP | Where-Object { $_.Status -eq 'Connected' } | Sort-Object Device + if ($VMHostNetworkAdapterCDP) { + Section -Style Heading3 'Cisco Discovery Protocol' { + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { + Section -Style Heading5 "$($VMHostNetworkAdapter.Device)" { + $VMHostCDP = [PSCustomObject]@{ 'Status' = $VMHostNetworkAdapter.Status + 'System Name' = $VMHostNetworkAdapter.SystemName 'Hardware Platform' = $VMHostNetworkAdapter.HardwarePlatform 'Switch ID' = $VMHostNetworkAdapter.SwitchId + 'Software Version' = $VMHostNetworkAdapter.SoftwareVersion + 'Management Address' = $VMHostNetworkAdapter.ManagementAddress 'Address' = $VMHostNetworkAdapter.Address 'Port ID' = $VMHostNetworkAdapter.PortId + 'VLAN' = $VMHostNetworkAdapter.Vlan + 'MTU' = $VMHostNetworkAdapter.Mtu + } + $TableParams = @{ + Name = "Network Adapter $($VMHostNetworkAdapter.Device) CDP Information - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostCDP | Table @TableParams } - $VMHostCDP | Table -Name "$($VMHost.ExtensionData.Name) Network Adapter CDP Information" } - } - } - #endregion ESXi Host Cisco Discovery Protocol - - #region ESXi Host VMkernel Adapaters - Section -Style Heading3 'VMkernel Adapters' { - $VMkernelAdapters = $VMHost | Get-View | ForEach-Object -Process { - $esx = $_ - $netSys = Get-View -Id $_.ConfigManager.NetworkSystem - $vnicMgr = Get-View -Id $_.ConfigManager.VirtualNicManager - $netSys.NetworkInfo.Vnic | - ForEach-Object -Process { - $device = $_.Device + } else { + $VMHostCDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { [PSCustomObject]@{ - 'Adapter' = $_.Device - 'Port Group' = & { - if ($_.Spec.Portgroup) { - $script:pg = $_.Spec.Portgroup - } else { - $script:pg = Get-View -ViewType DistributedVirtualPortgroup -Property Name, Key -Filter @{'Key' = "$($_.Spec.DistributedVirtualPort.PortgroupKey)" } | - Select-Object -ExpandProperty Name - } - $script:pg - } - 'Virtual Switch' = & { - if ($_.Spec.Portgroup) { - (Get-VirtualPortGroup -Standard -Name $script:pg -VMHost $VMHost).VirtualSwitchName - } else { - (Get-VDPortgroup -Name $script:pg).VDSwitch.Name - } - } - 'TCP/IP Stack' = Switch ($_.Spec.NetstackInstanceKey) { - 'defaultTcpipStack' { 'Default' } - 'vSphereProvisioning' { 'Provisioning' } - 'vmotion' { 'vMotion' } - $null { 'Not Applicable' } - default { $_.Spec.NetstackInstanceKey } - } - 'MTU' = $_.Spec.Mtu - 'MAC Address' = $_.Spec.Mac - 'DHCP' = Switch ($_.Spec.Ip.Dhcp) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'IP Address' = $_.Spec.IP.IPAddress - 'Subnet Mask' = $_.Spec.IP.SubnetMask - 'Default Gateway' = Switch ($_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway) { - $null { '--' } - default { $_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway } - } - 'vMotion' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vmotion' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Provisioning' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vSphereProvisioning' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + 'Adapter' = $VMHostNetworkAdapter.Device + 'Status' = $VMHostNetworkAdapter.Status + 'Hardware Platform' = $VMHostNetworkAdapter.HardwarePlatform + 'Switch ID' = $VMHostNetworkAdapter.SwitchId + 'Address' = $VMHostNetworkAdapter.Address + 'Port ID' = $VMHostNetworkAdapter.PortId + } + } + $TableParams = @{ + Name = "Network Adapter CDP Information - $($VMHost.ExtensionData.Name)" + ColumnWidths = 11, 13, 26, 22, 17, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostCDP | Table @TableParams + } + } + } + #endregion ESXi Host Cisco Discovery Protocol + + #region ESXi Host Link Layer Discovery Protocol + $VMHostNetworkAdapterLLDP = $VMHost | Get-VMHostNetworkAdapterDP | Where-Object { $null -ne $_.ChassisId } | Sort-Object Device + if ($VMHostNetworkAdapterLLDP) { + Section -Style Heading3 'Link Layer Discovery Protocol' { + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterLLDP) { + Section -Style Heading5 "$($VMHostNetworkAdapter.Device)" { + $VMHostLLDP = [PSCustomObject]@{ + 'Chassis ID' = $VMHostNetworkAdapter.ChassisId + 'Port ID' = $VMHostNetworkAdapter.PortId + 'Time to live' = $VMHostNetworkAdapter.TimeToLive + 'TimeOut' = $VMHostNetworkAdapter.TimeOut + 'Samples' = $VMHostNetworkAdapter.Samples + 'Management Address' = $VMHostNetworkAdapter.ManagementAddress + 'Port Description' = $VMHostNetworkAdapter.PortDescription + 'System Description' = $VMHostNetworkAdapter.SystemDescription + 'System Name' = $VMHostNetworkAdapter.SystemName } - 'FT Logging' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'faultToleranceLogging' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + $TableParams = @{ + Name = "Network Adapter $($VMHostNetworkAdapter.Device) LLDP Information - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 } - 'Management' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'management' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - 'vSphere Replication' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vSphereReplication' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + $VMHostLLDP | Table @TableParams + } + } + } else { + $VMHostLLDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterLLDP) { + [PSCustomObject]@{ + 'Adapter' = $VMHostNetworkAdapter.Device + 'Chassis ID' = $VMHostNetworkAdapter.ChassisId + 'Port ID' = $VMHostNetworkAdapter.PortId + 'Management Address' = $VMHostNetworkAdapter.ManagementAddress + 'Port Description' = $VMHostNetworkAdapter.PortDescription + 'System Name' = $VMHostNetworkAdapter.SystemName + } + } + $TableParams = @{ + Name = "Network Adapter LLDP Information - $($VMHost.ExtensionData.Name)" + ColumnWidths = 11, 19, 16, 19, 18, 17 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostLLDP | Table @TableParams + } + } + } + #endregion ESXi Host Link Layer Discovery Protocol + + #region ESXi Host VMkernel Adapaters + Section -Style Heading3 'VMkernel Adapters' { + $VMkernelAdapters = $VMHost | Get-View | ForEach-Object -Process { + $esx = $_ + $netSys = Get-View -Id $_.ConfigManager.NetworkSystem + $vnicMgr = Get-View -Id $_.ConfigManager.VirtualNicManager + $netSys.NetworkInfo.Vnic | + ForEach-Object -Process { + $device = $_.Device + [PSCustomObject]@{ + 'Adapter' = $_.Device + 'Port Group' = & { + if ($_.Spec.Portgroup) { + $script:pg = $_.Spec.Portgroup + } else { + $script:pg = Get-View -ViewType DistributedVirtualPortgroup -Property Name, Key -Filter @{'Key' = "$($_.Spec.DistributedVirtualPort.PortgroupKey)" } | + Select-Object -ExpandProperty Name } - 'vSphere Replication NFC' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vSphereReplicationNFC' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + $script:pg + } + 'Virtual Switch' = & { + if ($_.Spec.Portgroup) { + (Get-VirtualPortGroup -Standard -Name $script:pg -VMHost $VMHost).VirtualSwitchName + } else { + (Get-VDPortgroup -Name $script:pg).VDSwitch.Name | Select-Object -Unique } - 'vSAN' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vsan' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + } + 'TCP/IP Stack' = Switch ($_.Spec.NetstackInstanceKey) { + 'defaultTcpipStack' { 'Default' } + 'vSphereProvisioning' { 'Provisioning' } + 'vmotion' { 'vMotion' } + 'vxlan' { 'nsx-overlay' } + 'hyperbus' { 'nsx-hyperbus' } + $null { 'Not Applicable' } + default { $_.Spec.NetstackInstanceKey } + } + 'Enabled Services' = Switch ( $vnicMgr.Info.NetConfig | Where-Object { $_.SelectedVnic -match $device } | ForEach-Object { $_.NicType } ) { + 'vmotion' { 'vMotion' } + 'vSphereProvisioning' { 'Provisioning' } + 'faultToleranceLogging' { 'FT Logging' } + 'management' { 'Management' } + 'vSphereReplication' { 'vSphere Replication' } + 'vSphereReplicationNFC' { 'vSphere Replication NFC' } + 'vsan' { 'vSAN' } + 'vsanWitness' { 'vSAN Witness' } + } + 'MTU' = $_.Spec.Mtu + 'MAC Address' = $_.Spec.Mac + 'DHCP' = Switch ($_.Spec.Ip.Dhcp) { + $true { 'Enabled' } + $false { 'Disabled' } + } + 'IP Address' = & { + if ($_.Spec.IP.IPAddress) { + $script:ip = $_.Spec.IP.IPAddress + } else { + $script:ip = '--' } - 'vSAN Witness' = Switch ((($vnicMgr.Info.NetConfig | where { $_.NicType -eq 'vsanWitness' }).SelectedVnic | % { $_ -match $device } ) -contains $true) { - $true { 'Enabled' } - $false { 'Disabled' } + $script:ip + } + 'Subnet Mask' = & { + if ($_.Spec.IP.SubnetMask) { + $script:netmask = $_.Spec.IP.SubnetMask + } else { + $script:netmask = '--' } + $script:netmask + } + 'Default Gateway' = Switch ($_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway) { + $null { '--' } + default { $_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway } } } } + } + + if ($InfoLevel.VMHost -ge 3) { foreach ($VMkernelAdapter in ($VMkernelAdapters | Sort-Object 'Adapter')) { Section -Style Heading4 "$($VMkernelAdapter.Adapter)" { - $VMkernelAdapter | Table -List -Name "$($VMHost.ExtensionData.Name) VMkernel Adapter $($VMkernelAdapter.Adapter)" -ColumnWidths 50, 50 + $TableParams = @{ + Name = "VMkernel Adapter $($VMkernelAdapter.Adapter) - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMkernelAdapter | Table @TableParams } } + } else { + $TableParams = @{ + Name = "VMkernel Adapters - $($VMHost.ExtensionData.Name)" + Columns = 'Adapter', 'Port Group', 'TCP/IP Stack', 'Enabled Services','IP Address' + ColumnWidths = 11, 35, 18, 18, 18 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMkernelAdapters | Sort-Object 'Adapter' | Table @TableParams } - #endregion ESXi Host VMkernel Adapaters + } + #endregion ESXi Host VMkernel Adapaters + + #region ESXi Host Standard Virtual Switches + $VSSwitches = $VMHost | Get-VirtualSwitch -Standard | Sort-Object Name + if ($VSSwitches) { + #region Section Standard Virtual Switches + Section -Style Heading5 'Standard Virtual Switches' { + Paragraph "The following section details the standard virtual switch configuration for $VMHost." + BlankLine + $VSSwitchNicTeaming = $VSSwitches | Get-NicTeamingPolicy + #region ESXi Host Standard Virtual Switch Properties + $VSSProperties = foreach ($VSSwitchNicTeam in $VSSwitchNicTeaming) { + [PSCustomObject]@{ + 'Virtual Switch' = $VSSwitchNicTeam.VirtualSwitch + 'MTU' = $VSSwitchNicTeam.VirtualSwitch.Mtu + 'Number of Ports' = $VSSwitchNicTeam.VirtualSwitch.NumPorts + 'Number of Ports Available' = $VSSwitchNicTeam.VirtualSwitch.NumPortsAvailable + } + } + $TableParams = @{ + Name = "Standard Virtual Switches - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VSSProperties | Table @TableParams + #endregion ESXi Host Standard Virtual Switch Properties + + #region ESXi Host Virtual Switch Security Policy + $VssSecurity = $VSSwitches | Get-SecurityPolicy + if ($VssSecurity) { + #region Virtual Switch Security Policy + Section -Style Heading5 'Virtual Switch Security' { + $VssSecurity = foreach ($VssSec in $VssSecurity) { + [PSCustomObject]@{ + 'Virtual Switch' = $VssSec.VirtualSwitch + 'Promiscuous Mode' = Switch ($VssSec.AllowPromiscuous) { + $true { 'Accept' } + $false { 'Reject' } + } + 'MAC Address Changes' = Switch ($VssSec.MacChanges) { + $true { 'Accept' } + $false { 'Reject' } + } + 'Forged Transmits' = Switch ($VssSec.ForgedTransmits) { + $true { 'Accept' } + $false { 'Reject' } + } + } + } + $TableParams = @{ + Name = "Virtual Switch Security Policy - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssSecurity | Sort-Object 'Virtual Switch' | Table @TableParams + } + #endregion Virtual Switch Security Policy + } + #endregion ESXi Host Virtual Switch Security Policy - #region ESXi Host Standard Virtual Switches - $VSSwitches = $VMHost | Get-VirtualSwitch -Standard | Sort-Object Name - if ($VSSwitches) { - #region Section Standard Virtual Switches - Section -Style Heading5 'Standard Virtual Switches' { - Paragraph "The following section details the standard virtual switch configuration for $VMHost." - BlankLine - $VSSwitchNicTeaming = $VSSwitches | Get-NicTeamingPolicy - #region ESXi Host Standard Virtual Switch Properties - $VSSProperties = foreach ($VSSwitchNicTeam in $VSSwitchNicTeaming) { + #region ESXi Host Virtual Switch Traffic Shaping Policy + Section -Style Heading5 'Virtual Switch Traffic Shaping' { + $VssTrafficShapingPolicy = foreach ($VSSwitch in $VSSwitches) { [PSCustomObject]@{ - 'Virtual Switch' = $VSSwitchNicTeam.VirtualSwitch - 'MTU' = $VSSwitchNicTeam.VirtualSwitch.Mtu - 'Number of Ports' = $VSSwitchNicTeam.VirtualSwitch.NumPorts - 'Number of Ports Available' = $VSSwitchNicTeam.VirtualSwitch.NumPortsAvailable + 'Virtual Switch' = $VSSwitch.Name + 'Status' = Switch ($VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { + $True { 'Enabled' } + $False { 'Disabled' } + } + 'Average Bandwidth (kbit/s)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth + 'Peak Bandwidth (kbit/s)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth + 'Burst Size (KB)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize + } + } + $TableParams = @{ + Name = "Virtual Switch Traffic Shaping Policy - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 15, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssTrafficShapingPolicy | Sort-Object 'Virtual Switch' | Table @TableParams + } + #endregion ESXi Host Virtual Switch Traffic Shaping Policy + + #region ESXi Host Virtual Switch Teaming & Failover + $VssNicTeamingPolicy = $VSSwitches | Get-NicTeamingPolicy + if ($VssNicTeamingPolicy) { + #region Virtual Switch Teaming & Failover Section + Section -Style Heading5 'Virtual Switch Teaming & Failover' { + $VssNicTeaming = foreach ($VssNicTeam in $VssNicTeamingPolicy) { + [PSCustomObject]@{ + 'Virtual Switch' = $VssNicTeam.VirtualSwitch + 'Load Balancing' = Switch ($VssNicTeam.LoadBalancingPolicy) { + 'LoadbalanceSrcId' { 'Route based on the originating port ID' } + 'LoadbalanceSrcMac' { 'Route based on source MAC hash' } + 'LoadbalanceIP' { 'Route based on IP hash' } + 'ExplicitFailover' { 'Explicit Failover' } + default { $VssNicTeam.LoadBalancingPolicy } + } + 'Network Failure Detection' = Switch ($VssNicTeam.NetworkFailoverDetectionPolicy) { + 'LinkStatus' { 'Link status only' } + 'BeaconProbing' { 'Beacon probing' } + default { $VssNicTeam.NetworkFailoverDetectionPolicy } + } + 'Notify Switches' = Switch ($VssNicTeam.NotifySwitches) { + $true { 'Yes' } + $false { 'No' } + } + 'Failback' = Switch ($VssNicTeam.FailbackEnabled) { + $true { 'Yes' } + $false { 'No' } + } + 'Active NICs' = ($VssNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine + 'Standby NICs' = ($VssNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine + 'Unused NICs' = ($VssNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine + } } + $TableParams = @{ + Name = "Virtual Switch Teaming & Failover - $($VMHost.ExtensionData.Name)" + ColumnWidths = 20, 17, 12, 11, 10, 10, 10, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssNicTeaming | Sort-Object 'Virtual Switch' | Table @TableParams } - $VSSProperties | Table -Name "$VMHost Standard Virtual Switches" - #endregion ESXi Host Standard Virtual Switch Properties - - #region ESXi Host Virtual Switch Security Policy - $VssSecurity = $VSSwitches | Get-SecurityPolicy - if ($VssSecurity) { - #region Virtual Switch Security Policy - Section -Style Heading5 'Virtual Switch Security' { - $VssSecurity = foreach ($VssSec in $VssSecurity) { + #endregion Virtual Switch Teaming & Failover Section + } + #endregion ESXi Host Virtual Switch Teaming & Failover + + #region ESXi Host Virtual Switch Port Groups + $VssPortgroups = $VSSwitches | Get-VirtualPortGroup -Standard + if ($VssPortgroups) { + Section -Style Heading5 'Virtual Switch Port Groups' { + $VssPortgroups = foreach ($VssPortgroup in $VssPortgroups) { + [PSCustomObject]@{ + 'Port Group' = $VssPortgroup.Name + 'VLAN ID' = $VssPortgroup.VLanId + 'Virtual Switch' = $VssPortgroup.VirtualSwitchName + '# of VMs' = ($VssPortgroup | Get-VM).Count + } + } + $TableParams = @{ + Name = "Virtual Switch Port Group Information - $($VMHost.ExtensionData.Name)" + ColumnWidths = 40, 10, 40, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroups | Sort-Object 'Port Group', 'VLAN ID', 'Virtual Switch' | Table @TableParams + } + #endregion ESXi Host Virtual Switch Port Groups + + #region ESXi Host Virtual Switch Port Group Security Policy + $VssPortgroupSecurity = $VSSwitches | Get-VirtualPortGroup | Get-SecurityPolicy + if ($VssPortgroupSecurity) { + #region Virtual Port Group Security Policy Section + Section -Style Heading5 'Virtual Switch Port Group Security' { + $VssPortgroupSecurity = foreach ($VssPortgroupSec in $VssPortgroupSecurity) { [PSCustomObject]@{ - 'Virtual Switch' = $VssSec.VirtualSwitch - 'Promiscuous Mode' = Switch ($VssSec.AllowPromiscuous) { + 'Port Group' = $VssPortgroupSec.VirtualPortGroup + 'Virtual Switch' = $VssPortgroupSec.virtualportgroup.virtualswitchname + 'Promiscuous Mode' = Switch ($VssPortgroupSec.AllowPromiscuous) { $true { 'Accept' } $false { 'Reject' } } - 'MAC Address Changes' = Switch ($VssSec.MacChanges) { + 'MAC Changes' = Switch ($VssPortgroupSec.MacChanges) { $true { 'Accept' } $false { 'Reject' } - } - 'Forged Transmits' = Switch ($VssSec.ForgedTransmits) { + } + 'Forged Transmits' = Switch ($VssPortgroupSec.ForgedTransmits) { $true { 'Accept' } $false { 'Reject' } - } + } } } - $VssSecurity | Sort-Object 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Security Policy" + $TableParams = @{ + Name = "Virtual Switch Port Group Security Policy - $($VMHost.ExtensionData.Name)" + ColumnWidths = 27, 25, 16, 16, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupSecurity | Sort-Object 'Port Group', 'Virtual Switch' | Table @TableParams } - #endregion Virtual Switch Security Policy + #endregion Virtual Port Group Security Policy Section } - #endregion ESXi Host Virtual Switch Security Policy + #endregion ESXi Host Virtual Switch Port Group Security Policy - #region ESXi Host Virtual Switch Traffic Shaping Policy - Section -Style Heading5 'Virtual Switch Traffic Shaping' { - $VssTrafficShapingPolicy = foreach ($VSSwitch in $VSSwitches) { + #region ESXi Host Virtual Switch Port Group Traffic Shaping Policy + Section -Style Heading5 'Virtual Switch Port Group Traffic Shaping' { + $VssPortgroupTrafficShapingPolicy = foreach ($VssPortgroup in $VssPortgroups) { [PSCustomObject]@{ - 'Virtual Switch' = $VSSwitch.Name - 'Status' = Switch ($VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { + 'Port Group' = $VssPortgroup.Name + 'Virtual Switch' = $VssPortgroup.VirtualSwitchName + 'Status' = Switch ($VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { $True { 'Enabled' } $False { 'Disabled' } + $null { 'Inherited' } } - 'Average Bandwidth (kbit/s)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth - 'Peak Bandwidth (kbit/s)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth - 'Burst Size (KB)' = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize + 'Average Bandwidth (kbit/s)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth + 'Peak Bandwidth (kbit/s)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth + 'Burst Size (KB)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize } } - $VssTrafficShapingPolicy | Sort-Object 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Traffic Shaping Policy" + $TableParams = @{ + Name = "Virtual Switch Port Group Traffic Shaping Policy - $($VMHost.ExtensionData.Name)" + ColumnWidths = 19, 19, 11, 17, 17, 17 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupTrafficShapingPolicy | Sort-Object 'Port Group', 'Virtual Switch' | Table @TableParams } - #endregion ESXi Host Virtual Switch Traffic Shaping Policy - - #region ESXi Host Virtual Switch Teaming & Failover - $VssNicTeamingPolicy = $VSSwitches | Get-NicTeamingPolicy - if ($VssNicTeamingPolicy) { - #region Virtual Switch Teaming & Failover Section - Section -Style Heading5 'Virtual Switch Teaming & Failover' { - $VssNicTeaming = foreach ($VssNicTeam in $VssNicTeamingPolicy) { + #endregion ESXi Host Virtual Switch Port Group Traffic Shaping Policy + + #region ESXi Host Virtual Switch Port Group Teaming & Failover + $VssPortgroupNicTeaming = $VSSwitches | Get-VirtualPortGroup | Get-NicTeamingPolicy + if ($VssPortgroupNicTeaming) { + #region Virtual Switch Port Group Teaming & Failover Section + Section -Style Heading5 'Virtual Switch Port Group Teaming & Failover' { + $VssPortgroupNicTeaming = foreach ($VssPortgroupNicTeam in $VssPortgroupNicTeaming) { [PSCustomObject]@{ - 'Virtual Switch' = $VssNicTeam.VirtualSwitch - 'Load Balancing' = Switch ($VssNicTeam.LoadBalancingPolicy) { + 'Port Group' = $VssPortgroupNicTeam.VirtualPortGroup + 'Virtual Switch' = $VssPortgroupNicTeam.virtualportgroup.virtualswitchname + 'Load Balancing' = Switch ($VssPortgroupNicTeam.LoadBalancingPolicy) { 'LoadbalanceSrcId' { 'Route based on the originating port ID' } 'LoadbalanceSrcMac' { 'Route based on source MAC hash' } 'LoadbalanceIP' { 'Route based on IP hash' } 'ExplicitFailover' { 'Explicit Failover' } - default { $VssNicTeam.LoadBalancingPolicy } + default { $VssPortgroupNicTeam.LoadBalancingPolicy } } - 'Network Failure Detection' = Switch ($VssNicTeam.NetworkFailoverDetectionPolicy) { + 'Network Failure Detection' = Switch ($VssPortgroupNicTeam.NetworkFailoverDetectionPolicy) { 'LinkStatus' { 'Link status only' } 'BeaconProbing' { 'Beacon probing' } - default { $VssNicTeam.NetworkFailoverDetectionPolicy } - } - 'Notify Switches' = Switch ($VssNicTeam.NotifySwitches) { + default { $VssPortgroupNicTeam.NetworkFailoverDetectionPolicy } + } + 'Notify Switches' = Switch ($VssPortgroupNicTeam.NotifySwitches) { $true { 'Yes' } $false { 'No' } } - 'Failback' = Switch ($VssNicTeam.FailbackEnabled) { + 'Failback' = Switch ($VssPortgroupNicTeam.FailbackEnabled) { $true { 'Yes' } $false { 'No' } } - 'Active NICs' = ($VssNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine - 'Standby NICs' = ($VssNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine - 'Unused NICs' = ($VssNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine + 'Active NICs' = ($VssPortgroupNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine + 'Standby NICs' = ($VssPortgroupNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine + 'Unused NICs' = ($VssPortgroupNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine } } - $VssNicTeaming | Sort-Object 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Teaming & Failover" + $TableParams = @{ + Name = "Virtual Switch Port Group Teaming & Failover - $($VMHost.ExtensionData.Name)" + ColumnWidths = 12, 11, 11, 11, 11, 11, 11, 11, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupNicTeaming | Sort-Object 'Port Group', 'Virtual Switch' | Table @TableParams } - #endregion Virtual Switch Teaming & Failover Section + #endregion Virtual Switch Port Group Teaming & Failover Section } - #endregion ESXi Host Virtual Switch Teaming & Failover - - #region ESXi Host Virtual Switch Port Groups - $VssPortgroups = $VSSwitches | Get-VirtualPortGroup -Standard - if ($VssPortgroups) { - Section -Style Heading5 'Virtual Switch Port Groups' { - $VssPortgroups = foreach ($VssPortgroup in $VssPortgroups) { - [PSCustomObject]@{ - 'Port Group' = $VssPortgroup.Name - 'VLAN ID' = $VssPortgroup.VLanId - 'Virtual Switch' = $VssPortgroup.VirtualSwitchName - '# of VMs' = ($VssPortgroup | Get-VM).Count + #endregion ESXi Host Virtual Switch Port Group Teaming & Failover + } + } + #endregion Section Standard Virtual Switches + } + #endregion ESXi Host Standard Virtual Switches + + #region Distributed Virtual Switch Section + # Create Distributed Switch Section if they exist + $VDSwitches = Get-VDSwitch -Server $ESXi + if ($VDSwitches) { + Section -Style Heading3 'Distributed Virtual Switches' { + #region Distributed Virtual Switch Advanced Summary + if ($InfoLevel.Network -le 2) { + $VDSInfo = foreach ($VDS in $VDSwitches) { + [PSCustomObject]@{ + 'Distributed Switch' = $VDS.Name + 'Number of Ports' = $VDS.NumPorts + 'Number of Port Groups' = ($VDS.ExtensionData.Summary.PortGroupName).Count + 'MTU' = $VDS.Mtu + 'Discovery Protocol Type' = $VDS.LinkDiscoveryProtocol + 'Discovery Protocol Operation' = $VDS.LinkDiscoveryProtocolOperation + } + } + $TableParams = @{ + Name = "Distributed Switch Information - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 15, 15, 15, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSInfo | Table @TableParams + } + #endregion Distributed Switch Advanced Summary + + #region Distributed Switch Detailed Information + if ($InfoLevel.Network -ge 3) { + # TODO: LACP, NetFlow, NIOC + foreach ($VDS in ($VDSwitches)) { + $VdsVmCount = ($VDS | Get-VM).Count + #region VDS Section + Section -Style Heading4 $VDS { + #region Distributed Switch General Properties + $VDSwitchDetail = [PSCustomObject]@{ + 'Distributed Switch' = $VDS.Name + 'ID' = $VDS.Id + 'Number of Ports' = $VDS.NumPorts + 'Number of Port Groups' = ($VDS.ExtensionData.Summary.PortGroupName).Count + 'Number of VMs' = $VdsVmCount + 'MTU' = $VDS.Mtu + 'Network I/O Control' = Switch ($VDS.ExtensionData.Config.NetworkResourceManagementEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } } + 'Discovery Protocol' = $VDS.LinkDiscoveryProtocol + 'Discovery Protocol Operation' = $VDS.LinkDiscoveryProtocolOperation } - $VssPortgroups | Sort-Object 'Port Group', 'VLAN ID', 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Port Group Information" - } - #endregion ESXi Host Virtual Switch Port Groups - - #region ESXi Host Virtual Switch Port Group Security Policy - $VssPortgroupSecurity = $VSSwitches | Get-VirtualPortGroup | Get-SecurityPolicy - if ($VssPortgroupSecurity) { - #region Virtual Port Group Security Policy Section - Section -Style Heading5 'Virtual Switch Port Group Security' { - $VssPortgroupSecurity = foreach ($VssPortgroupSec in $VssPortgroupSecurity) { - [PSCustomObject]@{ - 'Port Group' = $VssPortgroupSec.VirtualPortGroup - 'Virtual Switch' = $VssPortgroupSec.virtualportgroup.virtualswitchname - 'Promiscuous Mode' = Switch ($VssPortgroupSec.AllowPromiscuous) { - $true { 'Accept' } - $false { 'Reject' } - } - 'MAC Changes' = Switch ($VssPortgroupSec.MacChanges) { - $true { 'Accept' } - $false { 'Reject' } + # TODO: Fix this, incorrect reporting! + #region Network Advanced Detail Information + if ($InfoLevel.Network -ge 4) { + $VDSwitchVMs = $VDS | Get-VM | Sort-Object + Add-Member -InputObject $VDSwitchDetail -MemberType NoteProperty -Name 'Virtual Machines' -Value ($VDSwitchVMs.Name -join ', ') + } + #endregion Network Advanced Detail Information + $TableParams = @{ + Name = "$VDS Distributed Switch General Properties - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSwitchDetail | Table @TableParams + #endregion Distributed Switch General Properties + + #region Distributed Switch Uplink Ports + $VdsUplinks = $VDS | Get-VDPortgroup | Where-Object { $_.IsUplink -eq $true } | Get-VDPort + if ($VdsUplinks) { + Section -Style Heading4 'Distributed Switch Uplink Ports' { + $VdsUplinkDetail = foreach ($VdsUplink in $VdsUplinks) { + [PSCustomObject]@{ + 'Distributed Switch' = $VdsUplink.Switch + 'Uplink Name' = $VdsUplink.Name + 'Physical Network Adapter' = $VdsUplink.ConnectedEntity + 'Uplink Port Group' = $VdsUplink.Portgroup } - 'Forged Transmits' = Switch ($VssPortgroupSec.ForgedTransmits) { - $true { 'Accept' } - $false { 'Reject' } - } } + $TableParams = @{ + Name = "$VDS Distributed Switch Uplink Ports - $($VMHost.ExtensionData.Name)" + ColumnWidths = 30, 20, 20, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VdsUplinkDetail | Sort-Object 'Distributed Switch', 'Uplink Name' | Table @TableParams } - $VssPortgroupSecurity | Sort-Object 'Port Group', 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Port Group Security Policy" } - #endregion Virtual Port Group Security Policy Section - } - #endregion ESXi Host Virtual Switch Port Group Security Policy - - #region ESXi Host Virtual Switch Port Group Traffic Shaping Policy - Section -Style Heading5 'Virtual Switch Port Group Traffic Shaping' { - $VssPortgroupTrafficShapingPolicy = foreach ($VssPortgroup in $VssPortgroups) { - [PSCustomObject]@{ - 'Port Group' = $VssPortgroup.Name - 'Virtual Switch' = $VssPortgroup.VirtualSwitchName - 'Status' = Switch ($VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { - $True { 'Enabled' } - $False { 'Disabled' } - $null { 'Inherited' } + #endregion Distributed Virtual Switch Uplink Ports + + #region Distributed Switch Port Groups + $VDSPortgroups = $VDS | Get-VDPortgroup + if ($VDSPortgroups) { + Section -Style Heading4 'Distributed Switch Port Groups' { + $VDSPortgroupDetail = foreach ($VDSPortgroup in $VDSPortgroups) { + [PSCustomObject]@{ + 'Port Group' = $VDSPortgroup.Name + 'Distributed Switch' = $VDSPortgroup.VDSwitch.Name + 'VLAN Configuration' = Switch ($VDSPortgroup.VlanConfiguration) { + $null { '--' } + default { $VDSPortgroup.VlanConfiguration } + } + 'Port Binding' = $VDSPortgroup.PortBinding + } + } + $TableParams = @{ + Name = "$VDS Distributed Switch Port Groups - $($VMHost.ExtensionData.Name)" + ColumnWidths = 35, 35, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - 'Average Bandwidth (kbit/s)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth - 'Peak Bandwidth (kbit/s)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth - 'Burst Size (KB)' = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize + $VDSPortgroupDetail | Sort-Object 'Port Group' | Table @TableParams } } - $VssPortgroupTrafficShapingPolicy | Sort-Object 'Port Group', 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Port Group Traffic Shaping Policy" - } - #endregion ESXi Host Virtual Switch Port Group Traffic Shaping Policy - - #region ESXi Host Virtual Switch Port Group Teaming & Failover - $VssPortgroupNicTeaming = $VSSwitches | Get-VirtualPortGroup | Get-NicTeamingPolicy - if ($VssPortgroupNicTeaming) { - #region Virtual Switch Port Group Teaming & Failover Section - Section -Style Heading5 'Virtual Switch Port Group Teaming & Failover' { - $VssPortgroupNicTeaming = foreach ($VssPortgroupNicTeam in $VssPortgroupNicTeaming) { - [PSCustomObject]@{ - 'Port Group' = $VssPortgroupNicTeam.VirtualPortGroup - 'Virtual Switch' = $VssPortgroupNicTeam.virtualportgroup.virtualswitchname - 'Load Balancing' = Switch ($VssPortgroupNicTeam.LoadBalancingPolicy) { - 'LoadbalanceSrcId' { 'Route based on the originating port ID' } - 'LoadbalanceSrcMac' { 'Route based on source MAC hash' } - 'LoadbalanceIP' { 'Route based on IP hash' } - 'ExplicitFailover' { 'Explicit Failover' } - default { $VssPortgroupNicTeam.LoadBalancingPolicy } - } - 'Network Failure Detection' = Switch ($VssPortgroupNicTeam.NetworkFailoverDetectionPolicy) { - 'LinkStatus' { 'Link status only' } - 'BeaconProbing' { 'Beacon probing' } - default { $VssPortgroupNicTeam.NetworkFailoverDetectionPolicy } - } - 'Notify Switches' = Switch ($VssPortgroupNicTeam.NotifySwitches) { - $true { 'Yes' } - $false { 'No' } + #endregion Distributed Switch Port Groups + + #region Distributed Switch Private VLANs + $VDSwitchPrivateVLANs = $VDS | Get-VDSwitchPrivateVlan + if ($VDSwitchPrivateVLANs) { + Section -Style Heading4 'Distributed Switch Private VLANs' { + $VDSPvlan = foreach ($VDSwitchPrivateVLAN in $VDSwitchPrivateVLANs) { + [PSCustomObject]@{ + 'Primary VLAN ID' = $VDSwitchPrivateVLAN.PrimaryVlanId + 'Private VLAN Type' = $VDSwitchPrivateVLAN.PrivateVlanType + 'Secondary VLAN ID' = $VDSwitchPrivateVLAN.SecondaryVlanId } - 'Failback' = Switch ($VssPortgroupNicTeam.FailbackEnabled) { - $true { 'Yes' } - $false { 'No' } - } - 'Active NICs' = ($VssPortgroupNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine - 'Standby NICs' = ($VssPortgroupNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine - 'Unused NICs' = ($VssPortgroupNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine } + $TableParams = @{ + Name = "$VDS Distributed Switch Private VLANs - $($VMHost.ExtensionData.Name)" + ColumnWidths = 33, 34, 33 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSPvlan | Sort-Object 'Primary VLAN ID', 'Secondary VLAN ID' | Table @TableParams } - $VssPortgroupNicTeaming | Sort-Object 'Port Group', 'Virtual Switch' | Table -Name "$VMHost Virtual Switch Port Group Teaming & Failover" } - #endregion Virtual Switch Port Group Teaming & Failover Section + #endregion Distributed Switch Private VLANs } - #endregion ESXi Host Virtual Switch Port Group Teaming & Failover + #endregion VDS Section } } - #endregion Section Standard Virtual Switches + #endregion Distributed Virtual Switch Detailed Information } - #endregion ESXi Host Standard Virtual Switches - - #region Distributed Virtual Switch Section - # Create Distributed Switch Section if they exist - $VDSwitches = Get-VDSwitch -Server $ESXi - if ($VDSwitches) { - Section -Style Heading3 'Distributed Virtual Switches' { - #region Distributed Virtual Switch Informative Information - if ($InfoLevel.Network -eq 2) { - $VDSInfo = foreach ($VDS in $VDSwitches) { - [PSCustomObject]@{ - 'Distributed Switch' = $VDS.Name - '# of Uplinks' = $VDS.NumUplinkPorts - '# of Ports' = $VDS.NumPorts - '# of Hosts' = $VDS.ExtensionData.Summary.HostMember.Count - '# of VMs' = $VDS.ExtensionData.Summary.VM.Count + } + #endregion Distributed Virtual Switch Section + } + } + #endregion ESXi Host Network Section + + #region ESXi Host Security Section + if ($InfoLevel.VMHost -ge 1) { + Section -Style Heading2 'Security' { + Paragraph "The following section details the host security configuration for $($VMHost.ExtensionData.Name)." + #region ESXi Host Lockdown Mode + if ($VMHost.ExtensionData.Config.LockdownMode -ne $null) { + Section -Style Heading3 'Lockdown Mode' { + $LockdownMode = [PSCustomObject]@{ + 'Lockdown Mode' = Switch ($VMHost.ExtensionData.Config.LockdownMode) { + 'lockdownDisabled' { 'Disabled' } + 'lockdownNormal' { 'Enabled (Normal)' } + 'lockdownStrict' { 'Enabled (Strict)' } + default { $VMHost.ExtensionData.Config.LockdownMode } + } + } + if ($Healthcheck.VMHost.LockdownMode) { + $LockdownMode | Where-Object { $_.'Lockdown Mode' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Lockdown Mode' + } + $TableParams = @{ + Name = "Lockdown Mode - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $LockdownMode | Table @TableParams + } + } + #endregion ESXi Host Lockdown Mode + + #region ESXi Host Services + Section -Style Heading3 'Services' { + $VMHostServices = $VMHost | Get-VMHostService + $Services = foreach ($VMHostService in $VMHostServices) { + [PSCustomObject]@{ + 'Service' = $VMHostService.Label + 'Daemon' = Switch ($VMHostService.Running) { + $true { 'Running' } + $false { 'Stopped' } + } + 'Startup Policy' = Switch ($VMHostService.Policy) { + 'automatic' { 'Start and stop with port usage' } + 'on' { 'Start and stop with host' } + 'off' { 'Start and stop manually' } + default { $VMHostService.Policy } + } + } + } + if ($Healthcheck.VMHost.NTP) { + $Services | Where-Object { ($_.'Service' -eq 'NTP Daemon') -and ($_.Daemon -eq 'Stopped') } | Set-Style -Style Critical -Property 'Daemon' + $Services | Where-Object { ($_.'Service' -eq 'NTP Daemon') -and ($_.'Startup Policy' -ne 'Start and stop with host') } | Set-Style -Style Critical -Property 'Startup Policy' + } + if ($Healthcheck.VMHost.SSH) { + $Services | Where-Object { ($_.'Service' -eq 'SSH') -and ($_.Daemon -eq 'Running') } | Set-Style -Style Warning -Property 'Daemon' + $Services | Where-Object { ($_.'Service' -eq 'SSH') -and ($_.'Startup Policy' -ne 'Start and stop manually') } | Set-Style -Style Warning -Property 'Startup Policy' + } + if ($Healthcheck.VMHost.ESXiShell) { + $Services | Where-Object { ($_.'Service' -eq 'ESXi Shell') -and ($_.Daemon -eq 'Running') } | Set-Style -Style Warning -Property 'Daemon' + $Services | Where-Object { ($_.'Service' -eq 'ESXi Shell') -and ($_.'Startup Policy' -ne 'Start and stop manually') } | Set-Style -Style Warning -Property 'Startup Policy' + } + $TableParams = @{ + Name = "Services - $($VMHost.ExtensionData.Name)" + ColumnWidths = 40, 20, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $Services | Sort-Object 'Service' | Table @TableParams + } + #endregion ESXi Host Services + + #region ESXi Host Advanced Detail Information + if ($InfoLevel.VMHost -ge 4) { + #region ESXi Host Firewall + $VMHostFirewallExceptions = $VMHost | Get-VMHostFirewallException + if ($VMHostFirewallExceptions) { + #region Friewall Section + Section -Style Heading3 'Firewall' { + $VMHostFirewall = foreach ($VMHostFirewallException in $VMHostFirewallExceptions) { + [PScustomObject]@{ + 'Service' = $VMHostFirewallException.Name + 'Status' = Switch ($VMHostFirewallException.Enabled) { + $true { 'Enabled' } + $false { 'Disabled' } } - } - $VDSInfo | Table -Name 'Distributed Switch Information' - } - #endregion Distributed Switch Informative Information - - #region Distributed Switch Detailed Information - if ($InfoLevel.Network -ge 3) { - ## TODO: LACP, NetFlow, NIOC - foreach ($VDS in ($VDSwitches)) { - #region VDS Section - Section -Style Heading4 $VDS { - #region Distributed Switch General Properties - $VDSwitchDetail = [PSCustomObject]@{ - 'Distributed Switch' = $VDS.Name - 'ID' = $VDS.Id - 'Number of Ports' = $VDS.NumPorts - 'Number of Port Groups' = $VDS.ExtensionData.Summary.PortGroupName.Count - 'Number of VMs' = $VDS.ExtensionData.Summary.VM.Count - 'MTU' = $VDS.Mtu - 'Network I/O Control' = Switch ($VDS.ExtensionData.Config.NetworkResourceManagementEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Discovery Protocol' = $VDS.LinkDiscoveryProtocol - 'Discovery Protocol Operation' = $VDS.LinkDiscoveryProtocolOperation - } - - #region Network Advanced Detail Information - if ($InfoLevel.Network -ge 4) { - $VDSwitchDetail | ForEach-Object { - $VDSwitchVMs = $VDS | Get-VM | Sort-Object - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Virtual Machines' -Value ($VDSwitchVMs.Name -join ', ') - } - } - #endregion Network Advanced Detail Information - $VDSwitchDetail | Table -Name "$VDS Distributed Switch General Properties" -List -ColumnWidths 50, 50 - #endregion Distributed Switch General Properties - - #region Distributed Switch Uplink Ports - $VdsUplinks = $VDS | Get-VDPortgroup | Where-Object { $_.IsUplink -eq $true } | Get-VDPort - if ($VdsUplinks) { - Section -Style Heading4 'Distributed Switch Uplink Ports' { - $VdsUplinkDetail = foreach ($VdsUplink in $VdsUplinks) { - [PSCustomObject]@{ - 'Distributed Switch' = $VdsUplink.Switch - 'Uplink Name' = $VdsUplink.Name - 'Physical Network Adapter' = $VdsUplink.ConnectedEntity - 'Uplink Port Group' = $VdsUplink.Portgroup - } - } - $VdsUplinkDetail | Sort-Object 'Distributed Switch', 'Uplink Name' | Table -Name "$VDS Distributed Switch Uplink Ports" - } - } - #endregion Distributed Virtual Switch Uplink Ports - - #region Distributed Switch Port Groups - $VDSPortgroups = $VDS | Get-VDPortgroup - if ($VDSPortgroups) { - Section -Style Heading4 'Distributed Switch Port Groups' { - $VDSPortgroupDetail = foreach ($VDSPortgroup in $VDSPortgroups) { - [PSCustomObject]@{ - 'Port Group' = $VDSPortgroup.Name - 'Distributed Switch' = $VDSPortgroup.VDSwitch.Name - 'VLAN Configuration' = Switch ($VDSPortgroup.VlanConfiguration) { - $null { '--' } - default { $VDSPortgroup.VlanConfiguration } - } - 'Port Binding' = $VDSPortgroup.PortBinding - } - } - $VDSPortgroupDetail | Sort-Object 'Port Group' | Table -Name "$VDS Distributed Switch Port Groups" - } - } - #endregion Distributed Switch Port Groups - - #region Distributed Switch Private VLANs - $VDSwitchPrivateVLANs = $VDS | Get-VDSwitchPrivateVlan - if ($VDSwitchPrivateVLANs) { - Section -Style Heading4 'Distributed Switch Private VLANs' { - $VDSPvlan = foreach ($VDSwitchPrivateVLAN in $VDSwitchPrivateVLANs) { - [PSCustomObject]@{ - 'Primary VLAN ID' = $VDSwitchPrivateVLAN.PrimaryVlanId - 'Private VLAN Type' = $VDSwitchPrivateVLAN.PrivateVlanType - 'Secondary VLAN ID' = $VDSwitchPrivateVLAN.SecondaryVlanId - } - } - $VDSPvlan | Sort-Object 'Primary VLAN ID', 'Secondary VLAN ID' | Table -Name "$VDS Distributed Switch Private VLANs" - } - } - #endregion Distributed Switch Private VLANs + 'Incoming Ports' = $VMHostFirewallException.IncomingPorts + 'Outgoing Ports' = $VMHostFirewallException.OutgoingPorts + 'Protocols' = $VMHostFirewallException.Protocols + 'Daemon' = Switch ($VMHostFirewallException.ServiceRunning) { + $true { 'Running' } + $false { 'Stopped' } + $null { 'N/A' } + default { $VMHostFirewallException.ServiceRunning } } - #endregion VDS Section } } - #endregion Distributed Virtual Switch Detailed Information + $TableParams = @{ + Name = "Firewall Configuration - $($VMHost.ExtensionData.Name)" + ColumnWidths = 22, 12, 21, 21, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostFirewall | Sort-Object 'Service' | Table @TableParams } + #endregion Friewall Section } - #endregion Distributed Virtual Switch Section - } - #endregion ESXi Host Network Section - - #region ESXi Host Security Section - Section -Style Heading2 'Security' { - Paragraph "The following section details the host security configuration for $($VMHost.ExtensionData.Name)." - #region ESXi Host Lockdown Mode - if ($VMHost.ExtensionData.Config.LockdownMode -ne $null) { - Section -Style Heading3 'Lockdown Mode' { - $LockdownMode = [PSCustomObject]@{ - 'Lockdown Mode' = Switch ($VMHost.ExtensionData.Config.LockdownMode) { - 'lockdownDisabled' { 'Disabled' } - 'lockdownNormal' { 'Enabled (Normal)' } - 'lockdownStrict' { 'Enabled (Strict)' } - default { $VMHost.ExtensionData.Config.LockdownMode } - } + #endregion ESXi Host Firewall + + #region ESXi Host Authentication + $AuthServices = $VMHost | Get-VMHostAuthentication + if ($AuthServices.DomainMembershipStatus) { + Section -Style Heading3 'Authentication Services' { + $AuthServices = $AuthServices | Select-Object Domain, @{L = 'Domain Membership'; E = { $_.DomainMembershipStatus } }, @{L = 'Trusted Domains'; E = { $_.TrustedDomains } } + $TableParams = @{ + Name = "Authentication Services - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 25, 50 } - if ($Healthcheck.VMHost.LockdownMode) { - $LockdownMode | Where-Object { $_.'Lockdown Mode' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Lockdown Mode' + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - $LockdownMode | Table -Name "$($VMHost.ExtensionData.Name) Lockdown Mode" -List -ColumnWidths 50, 50 + $AuthServices | Table @TableParams + } + } + #endregion ESXi Host Authentication + } + #endregion ESXi Host Advanced Detail Information + } + } + #endregion ESXi Host Security Section + + #region Virtual Machine Section + Write-PScriboMessage "VM InfoLevel set at $($InfoLevel.VM)." + if ($InfoLevel.VM -ge 1) { + if ($VMs) { + Section -Style Heading2 'Virtual Machines' { + Paragraph "The following section details the configuration of virtual machines managed by $($VMHost.ExtensionData.Name)." + #region Virtual Machine Summary Information + if ($InfoLevel.VM -eq 1) { + BlankLine + $VMSummary = [PSCustomObject]@{ + 'Total VMs' = $VMs.Count + 'Total vCPUs' = ($VMs | Measure-Object -Property NumCpu -Sum).Sum + 'Total Memory' = "$([math]::Round(($VMs | Measure-Object -Property MemoryGB -Sum).Sum, 2)) GB" + 'Total Provisioned Space' = "$([math]::Round(($VMs | Measure-Object -Property ProvisionedSpaceGB -Sum).Sum, 2)) GB" + 'Total Used Space' = "$([math]::Round(($VMs | Measure-Object -Property UsedSpaceGB -Sum).Sum, 2)) GB" + 'VMs Powered On' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOn' }).Count + 'VMs Powered Off' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOff' }).Count + 'VMs Suspended' = ($VMs | Where-Object { $_.PowerState -eq 'Suspended' }).Count + 'VMs with Snapshots' = ($VMs | Where-Object { $_.ExtensionData.Snapshot }).Count + 'Guest Operating System Types' = (($VMs | Get-View).Summary.Config.GuestFullName | Select-Object -Unique).Count + 'VM Tools OK' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOK' }).Count + 'VM Tools Old' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOld' }).Count + 'VM Tools Not Running' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotRunning' }).Count + 'VM Tools Not Installed' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotInstalled' }).Count + } + $TableParams = @{ + Name = "VM Summary - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } + $VMSummary | Table @TableParams } - #endregion ESXi Host Lockdown Mode + #endregion Virtual Machine Summary Information - #region ESXi Host Services - Section -Style Heading3 'Services' { - $VMHostServices = $VMHost | Get-VMHostService - $Services = foreach ($VMHostService in $VMHostServices) { + #region Virtual Machine Advanced Summary + if ($InfoLevel.VM -eq 2) { + BlankLine + $VMSnapshotList = $VMs.Extensiondata.Snapshot.RootSnapshotList + $VMInfo = foreach ($VM in $VMs) { + $VMView = $VM | Get-View [PSCustomObject]@{ - 'Service' = $VMHostService.Label - 'Daemon' = Switch ($VMHostService.Running) { - $true { 'Running' } - $false { 'Stopped' } + 'Virtual Machine' = $VM.Name + 'Power State' = Switch ($VM.PowerState) { + 'PoweredOn' { 'On' } + 'PoweredOff' { 'Off' } + default { $VM.PowerState } + } + 'IP Address' = Switch ($VMView.Guest.IpAddress) { + $null { '--' } + default { $VMView.Guest.IpAddress } } - 'Startup Policy' = Switch ($VMHostService.Policy) { - 'automatic' { 'Start and stop with port usage' } - 'on' { 'Start and stop with host' } - 'off' { 'Start and stop manually' } - default { $VMHostService.Policy } + 'vCPUs' = $VM.NumCpu + 'Memory GB' = [math]::Round(($VM.MemoryGB), 0) + 'Provisioned GB' = [math]::Round(($VM.ProvisionedSpaceGB), 0) + 'Used GB' = [math]::Round(($VM.UsedSpaceGB), 0) + 'HW Version' = ($VM.HardwareVersion).Replace('vmx-', 'v') + 'VM Tools Status' = Switch ($VMView.Guest.ToolsStatus) { + 'toolsOld' { 'Old' } + 'toolsOK' { 'OK' } + 'toolsNotRunning' { 'Not Running' } + 'toolsNotInstalled' { 'Not Installed' } + default { $VMView.Guest.ToolsStatus } } } } - if ($Healthcheck.VMHost.NTP) { - $Services | Where-Object { ($_.'Service' -eq 'NTP Daemon') -and ($_.Daemon -eq 'Stopped') } | Set-Style -Style Critical -Property 'Daemon' - $Services | Where-Object { ($_.'Service' -eq 'NTP Daemon') -and ($_.'Startup Policy' -ne 'Start and stop with host') } | Set-Style -Style Critical -Property 'Startup Policy' + if ($Healthcheck.VM.VMToolsStatus) { + $VMInfo | Where-Object { $_.'VM Tools Status' -ne 'OK' } | Set-Style -Style Warning -Property 'VM Tools Status' } - if ($Healthcheck.VMHost.SSH) { - $Services | Where-Object { ($_.'Service' -eq 'SSH') -and ($_.Daemon -eq 'Running') } | Set-Style -Style Warning -Property 'Daemon' - $Services | Where-Object { ($_.'Service' -eq 'SSH') -and ($_.'Startup Policy' -ne 'Start and stop manually') } | Set-Style -Style Warning -Property 'Startup Policy' + if ($Healthcheck.VM.PowerState) { + $VMInfo | Where-Object { $_.'Power State' -ne 'On' } | Set-Style -Style Warning -Property 'Power State' } - if ($Healthcheck.VMHost.ESXiShell) { - $Services | Where-Object { ($_.'Service' -eq 'ESXi Shell') -and ($_.Daemon -eq 'Running') } | Set-Style -Style Warning -Property 'Daemon' - $Services | Where-Object { ($_.'Service' -eq 'ESXi Shell') -and ($_.'Startup Policy' -ne 'Start and stop manually') } | Set-Style -Style Warning -Property 'Startup Policy' + $TableParams = @{ + Name = "VM Advanced Summary - $($VMHost.ExtensionData.Name)" + ColumnWidths = 21, 8, 16, 9, 9, 9, 9, 9, 10 } - $Services | Sort-Object 'Service' | Table -Name "$($VMHost.ExtensionData.Name) Services" - } - #endregion ESXi Host Services + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMInfo | Table @TableParams - #region ESXi Host Advanced Detail Information - if ($InfoLevel.VMHost -ge 4) { - #region ESXi Host Firewall - $VMHostFirewallExceptions = $VMHost | Get-VMHostFirewallException - if ($VMHostFirewallExceptions) { - #region Friewall Section - Section -Style Heading3 'Firewall' { - $VMHostFirewall = foreach ($VMHostFirewallException in $VMHostFirewallExceptions) { - [PScustomObject]@{ - 'Service' = $VMHostFirewallException.Name - 'Status' = Switch ($VMHostFirewallException.Enabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Incoming Ports' = $VMHostFirewallException.IncomingPorts - 'Outgoing Ports' = $VMHostFirewallException.OutgoingPorts - 'Protocols' = $VMHostFirewallException.Protocols - 'Daemon' = Switch ($VMHostFirewallException.ServiceRunning) { - $true { 'Running' } - $false { 'Stopped' } - $null { 'N/A' } - default { $VMHostFirewallException.ServiceRunning } - } + #region VM Snapshot Information + if ($VMSnapshotList -and $Options.ShowVMSnapshots) { + Section -Style Heading3 'Snapshots' { + $VMSnapshotInfo = foreach ($VMSnapshot in $VMSnapshotList) { + [PSCustomObject]@{ + 'Virtual Machine' = $VMLookup."$($VMSnapshot.VM)" + 'Snapshot Name' = $VMSnapshot.Name + 'Description' = $VMSnapshot.Description + 'Days Old' = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days } } - $VMHostFirewall | Sort-Object 'Service' | Table -Name "$($VMHost.ExtensionData.Name) Firewall Configuration" + if ($Healthcheck.VM.VMSnapshots) { + $VMSnapshotInfo | Where-Object { $_.'Days Old' -ge 7 } | Set-Style -Style Warning + $VMSnapshotInfo | Where-Object { $_.'Days Old' -ge 14 } | Set-Style -Style Critical + } + $TableParams = @{ + Name = "VM Snapshot Information - $($VMHost.ExtensionData.Name)" + ColumnWidths = 30, 30, 30, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMSnapshotInfo | Table @TableParams } - #endregion Friewall Section - } - #endregion ESXi Host Firewall - - #region ESXi Host Authentication - $AuthServices = $VMHost | Get-VMHostAuthentication - if ($AuthServices.DomainMembershipStatus) { - Section -Style Heading3 'Authentication Services' { - $AuthServices = $AuthServices | Select-Object Domain, @{L = 'Domain Membership'; E = { $_.DomainMembershipStatus } }, @{L = 'Trusted Domains'; E = { $_.TrustedDomains } } - $AuthServices | Table -Name "$($VMHost.ExtensionData.Name) Authentication Services" -ColumnWidths 25, 25, 50 - } } - #endregion ESXi Host Authentication + #endregion VM Snapshot Information } - #endregion ESXi Host Advanced Detail Information - } - #endregion ESXi Host Security Section - - #region Virtual Machine Section - if ($InfoLevel.VM -ge 1) { - if ($VMs) { - Section -Style Heading2 'Virtual Machines' { - Paragraph "The following section details the configuration of virtual machines managed by $($VMHost.ExtensionData.Name)." - #region Virtual Machine Summary Information - if ($InfoLevel.VM -eq 1) { - BlankLine - $VMSummary = [PSCustomObject]@{ - 'Total VMs' = $VMs.Count - 'Total vCPUs' = ($VMs | Measure-Object -Property NumCpu -Sum).Sum - 'Total Memory' = "$([math]::Round(($VMs | Measure-Object -Property MemoryGB -Sum).Sum, 2)) GB" - 'Total Provisioned Space' = "$([math]::Round(($VMs | Measure-Object -Property ProvisionedSpaceGB -Sum).Sum, 2)) GB" - 'Total Used Space' = "$([math]::Round(($VMs | Measure-Object -Property UsedSpaceGB -Sum).Sum, 2)) GB" - 'VMs Powered On' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOn' }).Count - 'VMs Powered Off' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOff' }).Count - 'VMs Suspended' = ($VMs | Where-Object { $_.PowerState -eq 'Suspended' }).Count - 'VMs with Snapshots' = ($VMs | Where-Object { $_.ExtensionData.Snapshot }).Count - 'Guest Operating System Types' = (($VMs | Get-View).Summary.Config.GuestFullName | Select-Object -Unique).Count - 'VM Tools OK' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOK' }).Count - 'VM Tools Old' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOld' }).Count - 'VM Tools Not Running' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotRunning' }).Count - 'VM Tools Not Installed' = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotInstalled' }).Count - } - $VMSummary | Table -List -Name 'VM Summary' -ColumnWidths 50, 50 - } - #endregion Virtual Machine Summary Information - - #region Virtual Machine Informative Information - if ($InfoLevel.VM -eq 2) { - BlankLine - $VMSnapshotList = $VMs.Extensiondata.Snapshot.RootSnapshotList - $VMInfo = foreach ($VM in $VMs) { - $VMView = $VM | Get-View - [PSCustomObject]@{ - 'Virtual Machine' = $VM.Name - 'Power State' = Switch ($VM.PowerState) { - 'PoweredOn' { 'On' } - 'PoweredOff' { 'Off' } - default { $VM.PowerState } - } - 'IP Address' = Switch ($VMView.Guest.IpAddress) { - $null { '--' } - default { $VMView.Guest.IpAddress } - } - 'vCPUs' = $VM.NumCpu - 'Memory GB' = [math]::Round(($VM.MemoryGB), 0) - 'Provisioned GB' = [math]::Round(($VM.ProvisionedSpaceGB), 0) - 'Used GB' = [math]::Round(($VM.UsedSpaceGB), 0) - 'HW Version' = ($VM.HardwareVersion).Replace('vmx-', 'v') - 'VM Tools Status' = Switch ($VMView.Guest.ToolsStatus) { - 'toolsOld' { 'Old' } - 'toolsOK' { 'OK' } - 'toolsNotRunning' { 'Not Running' } - 'toolsNotInstalled' { 'Not Installed' } - default { $VMView.Guest.ToolsStatus } - } + #endregion Virtual Machine Advanced Summary + + #region Virtual Machine Detailed Information + if ($InfoLevel.VM -ge 3) { + foreach ($VM in $VMs) { + Section -Style Heading3 $VM.name { + $VMUptime = @() + $VMUptime = Get-Uptime -VM $VM + $VMSpbmPolicy = $VMSpbmConfig | Where-Object { $_.entity -eq $vm } + $VMView = $VM | Get-View + $VMSnapshotList = $vmview.Snapshot.RootSnapshotList + $VMDetail = [PSCustomObject]@{ + 'Virtual Machine' = $VM.Name + 'ID' = $VM.Id + 'Operating System' = $VMView.Summary.Config.GuestFullName + 'Hardware Version' = ($VM.HardwareVersion).Replace('vmx-', 'v') + 'Power State' = Switch ($VM.PowerState) { + 'PoweredOn' { 'On' } + 'PoweredOff' { 'Off' } + default { $VM.PowerState } + } + 'Connection State' = $TextInfo.ToTitleCase($VM.ExtensionData.Runtime.ConnectionState) + 'VM Tools Status' = Switch ($VMView.Guest.ToolsStatus) { + 'toolsOld' { 'Old' } + 'toolsOK' { 'OK' } + 'toolsNotRunning' { 'Not Running' } + 'toolsNotInstalled' { 'Not Installed' } + default { $VMView.Guest.ToolsStatus } + } + 'Fault Tolerance State' = Switch ($VMView.Runtime.FaultToleranceState) { + 'notConfigured' { 'Not Configured' } + 'needsSecondary' { 'Needs Secondary' } + 'running' { 'Running' } + 'disabled' { 'Disabled' } + 'starting' { 'Starting' } + 'enabled' { 'Enabled' } + default { $VMview.Runtime.FaultToleranceState } + } + 'vCPUs' = $VM.NumCpu + 'Cores per Socket' = $VM.CoresPerSocket + 'CPU Shares' = "$($VM.VMResourceConfiguration.CpuSharesLevel) / $($VM.VMResourceConfiguration.NumCpuShares)" + 'CPU Reservation' = $VM.VMResourceConfiguration.CpuReservationMhz + 'CPU Limit' = "$($VM.VMResourceConfiguration.CpuReservationMhz) MHz" + 'CPU Hot Add' = Switch ($VMView.Config.CpuHotAddEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } + } + 'CPU Hot Remove' = Switch ($VMView.Config.CpuHotRemoveEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } + } + 'Memory Allocation' = "$([math]::Round(($VM.memoryGB), 2)) GB" + 'Memory Shares' = "$($VM.VMResourceConfiguration.MemSharesLevel) / $($VM.VMResourceConfiguration.NumMemShares)" + 'Memory Hot Add' = Switch ($VMView.Config.MemoryHotAddEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } + } + 'vNICs' = $VMView.Summary.Config.NumEthernetCards + 'DNS Name' = if ($VMView.Guest.HostName) { + $VMView.Guest.HostName + } else { + '--' + } + 'Networks' = if ($VMView.Guest.Net.Network) { + (($VMView.Guest.Net | Where-Object { $_.Network -ne $null } | Select-Object Network | Sort-Object Network).Network -join ', ') + } else { + '--' + } + 'IP Address' = if ($VMView.Guest.Net.IpAddress) { + (($VMView.Guest.Net | Where-Object { ($_.Network -ne $null) -and ($_.IpAddress -ne $null) } | Select-Object IpAddress | Sort-Object IpAddress).IpAddress -join ', ') + } else { + '--' + } + 'MAC Address' = if ($VMView.Guest.Net.MacAddress) { + (($VMView.Guest.Net | Where-Object { $_.Network -ne $null } | Select-Object -Property MacAddress).MacAddress -join ', ') + } else { + '--' + } + 'vDisks' = $VMView.Summary.Config.NumVirtualDisks + 'Provisioned Space' = "$([math]::Round(($VM.ProvisionedSpaceGB), 2)) GB" + 'Used Space' = "$([math]::Round(($VM.UsedSpaceGB), 2)) GB" + 'Changed Block Tracking' = Switch ($VMView.Config.ChangeTrackingEnabled) { + $true { 'Enabled' } + $false { 'Disabled' } } } + $MemberProps = @{ + 'InputObject' = $VMDetail + 'MemberType' = 'NoteProperty' + } + #if ($VMView.Config.CreateDate) { + # Add-Member @MemberProps -Name 'Creation Date' -Value ($VMView.Config.CreateDate).ToLocalTime() + #} + if ($VM.Notes) { + Add-Member @MemberProps -Name 'Notes' -Value $VM.Notes + } + if ($VMView.Runtime.BootTime) { + Add-Member @MemberProps -Name 'Boot Time' -Value ($VMView.Runtime.BootTime).ToLocalTime() + } + if ($VMUptime.UptimeDays) { + Add-Member @MemberProps -Name 'Uptime Days' -Value $VMUptime.UptimeDays + } + + #region VM Health Checks if ($Healthcheck.VM.VMToolsStatus) { - $VMInfo | Where-Object { $_.'VM Tools Status' -ne 'OK' } | Set-Style -Style Warning -Property 'VM Tools Status' + $VMDetail | Where-Object { $_.'VM Tools Status' -ne 'OK' } | Set-Style -Style Warning -Property 'VM Tools Status' } if ($Healthcheck.VM.PowerState) { - $VMInfo | Where-Object { $_.'Power State' -ne 'On' } | Set-Style -Style Warning -Property 'Power State' + $VMDetail | Where-Object { $_.'Power State' -ne 'On' } | Set-Style -Style Warning -Property 'Power State' } - $VMInfo | Table -Name 'VM Informative Information' - - #region VM Snapshot Information - if ($VMSnapshotList -and $Options.ShowVMSnapshots) { - Section -Style Heading3 'Snapshots' { - $VMSnapshotInfo = foreach ($VMSnapshot in $VMSnapshotList) { - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($VMSnapshot.VM)" - 'Snapshot Name' = $VMSnapshot.Name - 'Description' = $VMSnapshot.Description - 'Days Old' = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days - } - } - if ($Healthcheck.VM.VMSnapshots) { - $VMSnapshotInfo | Where-Object { $_.'Days Old' -ge 7 } | Set-Style -Style Warning - $VMSnapshotInfo | Where-Object { $_.'Days Old' -ge 14 } | Set-Style -Style Critical - } - $VMSnapshotInfo | Table -Name 'VM Snapshot Information' - } + if ($Healthcheck.VM.ConnectionState) { + $VMDetail | Where-Object { $_.'Connection State' -ne 'Connected' } | Set-Style -Style Critical -Property 'Connection State' } - #endregion VM Snapshot Information - } - #endregion Virtual Machine Informative Information - - #region Virtual Machine Detailed Information - if ($InfoLevel.VM -ge 3) { - foreach ($VM in $VMs) { - Section -Style Heading3 $VM.name { - $VMUptime = @() - $VMUptime = Get-Uptime -VM $VM - $VMSpbmPolicy = $VMSpbmConfig | Where-Object { $_.entity -eq $vm } - $VMView = $VM | Get-View - $VMSnapshotList = $vmview.Snapshot.RootSnapshotList - $VMDetail = [PSCustomObject]@{ - 'Virtual Machine' = $VM.Name - 'ID' = $VM.Id - 'Operating System' = $VMView.Summary.Config.GuestFullName - 'Hardware Version' = ($VM.HardwareVersion).Replace('vmx-', 'v') - 'Power State' = Switch ($VM.PowerState) { - 'PoweredOn' { 'On' } - 'PoweredOff' { 'Off' } - default { $VM.PowerState } - } - 'Connection State' = $TextInfo.ToTitleCase($VM.ExtensionData.Runtime.ConnectionState) - 'VM Tools Status' = Switch ($VMView.Guest.ToolsStatus) { - 'toolsOld' { 'Old' } - 'toolsOK' { 'OK' } - 'toolsNotRunning' { 'Not Running' } - 'toolsNotInstalled' { 'Not Installed' } - default { $VMView.Guest.ToolsStatus } - } - 'Fault Tolerance State' = Switch ($VMView.Runtime.FaultToleranceState) { - 'notConfigured' { 'Not Configured' } - 'needsSecondary' { 'Needs Secondary' } - 'running' { 'Running' } - 'disabled' { 'Disabled' } - 'starting' { 'Starting' } - 'enabled' { 'Enabled' } - default { $VMview.Runtime.FaultToleranceState } - } - 'vCPUs' = $VM.NumCpu - 'Cores per Socket' = $VM.CoresPerSocket - 'CPU Shares' = "$($VM.VMResourceConfiguration.CpuSharesLevel) / $($VM.VMResourceConfiguration.NumCpuShares)" - 'CPU Reservation' = $VM.VMResourceConfiguration.CpuReservationMhz - 'CPU Limit' = "$($VM.VMResourceConfiguration.CpuReservationMhz) MHz" - 'CPU Hot Add' = Switch ($VMView.Config.CpuHotAddEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'CPU Hot Remove' = Switch ($VMView.Config.CpuHotRemoveEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } - } - 'Memory Allocation' = "$([math]::Round(($VM.memoryGB), 2)) GB" - 'Memory Shares' = "$($VM.VMResourceConfiguration.MemSharesLevel) / $($VM.VMResourceConfiguration.NumMemShares)" - 'Memory Hot Add' = Switch ($VMView.Config.MemoryHotAddEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } + if ($Healthcheck.VM.CpuHotAdd) { + $VMDetail | Where-Object { $_.'CPU Hot Add' -eq 'Enabled' } | Set-Style -Style Warning -Property 'CPU Hot Add' + } + if ($Healthcheck.VM.CpuHotRemove) { + $VMDetail | Where-Object { $_.'CPU Hot Remove' -eq 'Enabled' } | Set-Style -Style Warning -Property 'CPU Hot Remove' + } + if ($Healthcheck.VM.MemoryHotAdd) { + $VMDetail | Where-Object { $_.'Memory Hot Add' -eq 'Enabled' } | Set-Style -Style Warning -Property 'Memory Hot Add' + } + if ($Healthcheck.VM.ChangeBlockTracking) { + $VMDetail | Where-Object { $_.'Changed Block Tracking' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Changed Block Tracking' + } + #endregion VM Health Checks + $TableParams = @{ + Name = "$($VM.Name) VM Configuration - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMDetail | Table @TableParams + + if ($InfoLevel.VM -ge 4) { + $VMnics = $VM.Guest.Nics | Where-Object { $_.Device -ne $null } | Sort-Object Device + $VMHdds = $VMHardDisks | Where-Object { $_.ParentId -eq $VM.Id } | Sort-Object Name + $SCSIControllers = $VMView.Config.Hardware.Device | Where-Object { $_.DeviceInfo.Label -match "SCSI Controller" } + $VMGuestVols = $VM.Guest.Disks | Sort-Object Path + if ($VMnics) { + Section -Style Heading4 "Network Adapters" { + $VMnicInfo = foreach ($VMnic in $VMnics) { + [PSCustomObject]@{ + 'Adapter' = $VMnic.Device + 'Connected' = $VMnic.Connected + 'Network Name' = Switch -wildcard ($VMnic.Device.NetworkName) { + 'dvportgroup*' { $VDPortgroupLookup."$($VMnic.Device.NetworkName)" } + default { $VMnic.Device.NetworkName } + } + 'Adapter Type' = $VMnic.Device.Type + 'IP Address' = $VMnic.IpAddress -join [Environment]::NewLine + 'MAC Address' = $VMnic.Device.MacAddress + } } - 'vNICs' = $VMView.Summary.Config.NumEthernetCards - 'DNS Name' = if ($VMView.Guest.HostName) { - $VMView.Guest.HostName - } else { - '--' + $TableParams = @{ + Name = "$($VM.Name) Network Adapters - $($VMHost.ExtensionData.Name)" + ColumnWidths = 20, 12, 16, 12, 20, 20 } - 'Networks' = if ($VMView.Guest.Net.Network) { - (($VMView.Guest.Net | Where-Object { $_.Network -ne $null } | Select-Object Network | Sort-Object Network).Network -join ', ') - } else { - '--' + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } - 'IP Address' = if ($VMView.Guest.Net.IpAddress) { - (($VMView.Guest.Net | Where-Object { ($_.Network -ne $null) -and ($_.IpAddress -ne $null) } | Select-Object IpAddress | Sort-Object IpAddress).IpAddress -join ', ') - } else { - '--' + $VMnicInfo | Table @TableParams + } + } + if ($SCSIControllers) { + Section -Style Heading4 "SCSI Controllers" { + $VMScsiControllers = foreach ($VMSCSIController in $SCSIControllers) { + [PSCustomObject]@{ + 'Device' = $VMSCSIController.DeviceInfo.Label + 'Controller Type' = $VMSCSIController.DeviceInfo.Summary + 'Bus Sharing' = Switch ($VMSCSIController.SharedBus) { + 'noSharing' { 'None' } + default { $VMSCSIController.SharedBus } + } + } } - 'MAC Address' = if ($VMView.Guest.Net.MacAddress) { - (($VMView.Guest.Net | Where-Object { $_.Network -ne $null } | Select-Object -Property MacAddress).MacAddress -join ', ') - } else { - '--' + $TableParams = @{ + Name = "$($VM.Name) SCSI Controllers - $($VMHost.ExtensionData.Name)" + ColumnWidths = 33, 34, 33 } - 'vDisks' = $VMView.Summary.Config.NumVirtualDisks - 'Provisioned Space' = "$([math]::Round(($VM.ProvisionedSpaceGB), 2)) GB" - 'Used Space' = "$([math]::Round(($VM.UsedSpaceGB), 2)) GB" - 'Changed Block Tracking' = Switch ($VMView.Config.ChangeTrackingEnabled) { - $true { 'Enabled' } - $false { 'Disabled' } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" } + $VMScsiControllers | Sort-Object 'Device' | Table @TableParams } - $MemberProps = @{ - 'InputObject' = $VMDetail - 'MemberType' = 'NoteProperty' - } - #if ($VMView.Config.CreateDate) { - # Add-Member @MemberProps -Name 'Creation Date' -Value ($VMView.Config.CreateDate).ToLocalTime() - #} - if ($VM.Notes) { - Add-Member @MemberProps -Name 'Notes' -Value $VM.Notes - } - if ($VMView.Runtime.BootTime) { - Add-Member @MemberProps -Name 'Boot Time' -Value ($VMView.Runtime.BootTime).ToLocalTime() - } - if ($VMUptime.UptimeDays) { - Add-Member @MemberProps -Name 'Uptime Days' -Value $VMUptime.UptimeDays - } - - #region VM Health Checks - if ($Healthcheck.VM.VMToolsStatus) { - $VMDetail | Where-Object { $_.'VM Tools Status' -ne 'OK' } | Set-Style -Style Warning -Property 'VM Tools Status' - } - if ($Healthcheck.VM.PowerState) { - $VMDetail | Where-Object { $_.'Power State' -ne 'On' } | Set-Style -Style Warning -Property 'Power State' - } - if ($Healthcheck.VM.ConnectionState) { - $VMDetail | Where-Object { $_.'Connection State' -ne 'Connected' } | Set-Style -Style Critical -Property 'Connection State' - } - if ($Healthcheck.VM.CpuHotAdd) { - $VMDetail | Where-Object { $_.'CPU Hot Add' -eq 'Enabled' } | Set-Style -Style Warning -Property 'CPU Hot Add' - } - if ($Healthcheck.VM.CpuHotRemove) { - $VMDetail | Where-Object { $_.'CPU Hot Remove' -eq 'Enabled' } | Set-Style -Style Warning -Property 'CPU Hot Remove' - } - if ($Healthcheck.VM.MemoryHotAdd) { - $VMDetail | Where-Object { $_.'Memory Hot Add' -eq 'Enabled' } | Set-Style -Style Warning -Property 'Memory Hot Add' - } - if ($Healthcheck.VM.ChangeBlockTracking) { - $VMDetail | Where-Object { $_.'Changed Block Tracking' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Changed Block Tracking' - } - #endregion VM Health Checks - - $VMDetail | Table -Name "$($VM.Name) Detailed Information" -List -ColumnWidths 50, 50 - - if ($InfoLevel.VM -ge 4) { - $VMnics = $VM.Guest.Nics | Where-Object { $_.Device -ne $null } | Sort-Object Device - $VMHdds = $VMHardDisks | Where-Object { $_.ParentId -eq $VM.Id } | Sort-Object Name - $SCSIControllers = $VMView.Config.Hardware.Device | Where-Object { $_.DeviceInfo.Label -match "SCSI Controller" } - $VMGuestVols = $VM.Guest.Disks | Sort-Object Path - if ($VMnics) { - Section -Style Heading4 "Network Adapters" { - $VMnicInfo = foreach ($VMnic in $VMnics) { - [PSCustomObject]@{ - 'Adapter' = $VMnic.Device - 'Connected' = $VMnic.Connected - 'Network Name' = Switch -wildcard ($VMnic.Device.NetworkName) { - 'dvportgroup*' { $VDPortgroupLookup."$($VMnic.Device.NetworkName)" } - default { $VMnic.Device.NetworkName } - } - 'Adapter Type' = $VMnic.Device.Type - 'IP Address' = $VMnic.IpAddress -join [Environment]::NewLine - 'MAC Address' = $VMnic.Device.MacAddress + } + if ($VMHdds) { + Section -Style Heading4 "Hard Disks" { + If ($InfoLevel.VM -eq 4) { + $VMHardDiskInfo = foreach ($VMHdd in $VMHdds) { + $SCSIDevice = $VMView.Config.Hardware.Device | Where-Object { $_.Key -eq $VMHdd.ExtensionData.Key -and $_.Backing.FileName -eq $VMHdd.FileName } + $SCSIController = $SCSIControllers | Where-Object { $SCSIDevice.ControllerKey -eq $_.Key } + [PSCustomObject]@{ + 'Disk' = $VMHdd.Name + 'Datastore' = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) + 'Capacity' = "$([math]::Round(($VMHdd.CapacityGB), 2)) GB" + 'Disk Provisioning' = Switch ($VMHdd.StorageFormat) { + 'EagerZeroedThick' { 'Thick Eager Zeroed' } + 'LazyZeroedThick' { 'Thick Lazy Zeroed' } + $null { '--' } + default { $VMHdd.StorageFormat } } - } - $VMnicInfo | Table -Name "$($VM.Name) Network Adapters" - } - } - if ($SCSIControllers) { - Section -Style Heading4 "SCSI Controllers" { - $VMScsiControllers = foreach ($VMSCSIController in $SCSIControllers) { - [PSCustomObject]@{ - 'Device' = $VMSCSIController.DeviceInfo.Label - 'Controller Type' = $VMSCSIController.DeviceInfo.Summary - 'Bus Sharing' = Switch ($VMSCSIController.SharedBus) { - 'noSharing' { 'None' } - default { $VMSCSIController.SharedBus } - } + 'Disk Type' = Switch ($VMHdd.DiskType) { + 'RawPhysical' { 'Physical RDM' } + 'RawVirtual' { "Virtual RDM" } + 'Flat' { 'VMDK' } + default { $VMHdd.DiskType } + } + 'Disk Mode' = Switch ($VMHdd.Persistence) { + 'IndependentPersistent' { 'Independent - Persistent' } + 'IndependentNonPersistent' { 'Independent - Nonpersistent' } + 'Persistent' { 'Dependent' } + default { $VMHdd.Persistence } } } - $VMScsiControllers | Sort-Object 'Device' | Table -Name "$($VM.Name) SCSI Controllers" } - } - if ($VMHdds) { - Section -Style Heading4 "Hard Disks" { - If ($InfoLevel.VM -eq 4) { - $VMHardDiskInfo = foreach ($VMHdd in $VMHdds) { - $SCSIDevice = $VMView.Config.Hardware.Device | Where-Object { $_.Key -eq $VMHdd.ExtensionData.Key -and $_.Backing.FileName -eq $VMHdd.FileName } - $SCSIController = $SCSIControllers | Where-Object { $SCSIDevice.ControllerKey -eq $_.Key } - [PSCustomObject]@{ - 'Disk' = $VMHdd.Name - 'Datastore' = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) - 'Capacity' = "$([math]::Round(($VMHdd.CapacityGB), 2)) GB" - 'Disk Provisioning' = Switch ($VMHdd.StorageFormat) { - 'EagerZeroedThick' { 'Thick Eager Zeroed' } - 'LazyZeroedThick' { 'Thick Lazy Zeroed' } - $null { '--' } - default { $VMHdd.StorageFormat } - } - 'Disk Type' = Switch ($VMHdd.DiskType) { - 'RawPhysical' { 'Physical RDM' } - 'RawVirtual' { "Virtual RDM" } - 'Flat' { 'VMDK' } - default { $VMHdd.DiskType } - } - 'Disk Mode' = Switch ($VMHdd.Persistence) { - 'IndependentPersistent' { 'Independent - Persistent' } - 'IndependentNonPersistent' { 'Independent - Nonpersistent' } - 'Persistent' { 'Dependent' } - default { $VMHdd.Persistence } - } + $TableParams = @{ + Name = "$($VM.Name) Hard Disks - $($VMHost.ExtensionData.Name)" + ColumnWidths = 15, 25, 15, 15, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHardDiskInfo | Table @TableParams + } else { + foreach ($VMHdd in $VMHdds) { + Section -Style Heading4 "$($VMHdd.Name)" { + $SCSIDevice = $VMView.Config.Hardware.Device | Where-Object { $_.Key -eq $VMHdd.ExtensionData.Key -and $_.Backing.FileName -eq $VMHdd.FileName } + $SCSIController = $SCSIControllers | Where-Object { $SCSIDevice.ControllerKey -eq $_.Key } + $VMHardDiskInfo = [PSCustomObject]@{ + 'Datastore' = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) + 'Capacity' = "$([math]::Round(($VMHdd.CapacityGB), 2)) GB" + 'Disk Path' = $VMHdd.Filename.Substring($VMHdd.Filename.IndexOf("]") + 2) + 'Disk Shares' = "$($TextInfo.ToTitleCase($VMHdd.ExtensionData.Shares.Level)) / $($VMHdd.ExtensionData.Shares.Shares)" + 'Disk Limit IOPs' = Switch ($VMHdd.ExtensionData.StorageIOAllocation.Limit) { + '-1' { 'Unlimited' } + default { $VMHdd.ExtensionData.StorageIOAllocation.Limit } } - } - $VMHardDiskInfo | Table -Name "$($VM.Name) Hard Disk Information" - } else { - foreach ($VMHdd in $VMHdds) { - Section -Style Heading4 "$($VMHdd.Name)" { - $SCSIDevice = $VMView.Config.Hardware.Device | Where-Object { $_.Key -eq $VMHdd.ExtensionData.Key -and $_.Backing.FileName -eq $VMHdd.FileName } - $SCSIController = $SCSIControllers | Where-Object { $SCSIDevice.ControllerKey -eq $_.Key } - $VMHardDiskInfo = [PSCustomObject]@{ - 'Datastore' = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) - 'Capacity' = "$([math]::Round(($VMHdd.CapacityGB), 2)) GB" - 'Disk Path' = $VMHdd.Filename.Substring($VMHdd.Filename.IndexOf("]") + 2) - 'Disk Shares' = "$($TextInfo.ToTitleCase($VMHdd.ExtensionData.Shares.Level)) / $($VMHdd.ExtensionData.Shares.Shares)" - 'Disk Limit IOPs' = Switch ($VMHdd.ExtensionData.StorageIOAllocation.Limit) { - '-1' { 'Unlimited' } - default { $VMHdd.ExtensionData.StorageIOAllocation.Limit } - } - 'Disk Provisioning' = Switch ($VMHdd.StorageFormat) { - 'EagerZeroedThick' { 'Thick Eager Zeroed' } - 'LazyZeroedThick' { 'Thick Lazy Zeroed' } - $null { '--' } - default { $VMHdd.StorageFormat } - } - 'Disk Type' = Switch ($VMHdd.DiskType) { - 'RawPhysical' { 'Physical RDM' } - 'RawVirtual' { "Virtual RDM" } - 'Flat' { 'VMDK' } - default { $VMHdd.DiskType } - } - 'Disk Mode' = Switch ($VMHdd.Persistence) { - 'IndependentPersistent' { 'Independent - Persistent' } - 'IndependentNonPersistent' { 'Independent - Nonpersistent' } - 'Persistent' { 'Dependent' } - default { $VMHdd.Persistence } - } - 'SCSI Controller' = $SCSIController.DeviceInfo.Label - 'SCSI Address' = "$($SCSIController.BusNumber):$($VMHdd.ExtensionData.UnitNumber)" - } - $VMHardDiskInfo | Table -List "$($VM.Name) $($VMHdd.Name) Information" -ColumnWidths 25, 75 + 'Disk Provisioning' = Switch ($VMHdd.StorageFormat) { + 'EagerZeroedThick' { 'Thick Eager Zeroed' } + 'LazyZeroedThick' { 'Thick Lazy Zeroed' } + $null { '--' } + default { $VMHdd.StorageFormat } + } + 'Disk Type' = Switch ($VMHdd.DiskType) { + 'RawPhysical' { 'Physical RDM' } + 'RawVirtual' { "Virtual RDM" } + 'Flat' { 'VMDK' } + default { $VMHdd.DiskType } + } + 'Disk Mode' = Switch ($VMHdd.Persistence) { + 'IndependentPersistent' { 'Independent - Persistent' } + 'IndependentNonPersistent' { 'Independent - Nonpersistent' } + 'Persistent' { 'Dependent' } + default { $VMHdd.Persistence } } + 'SCSI Controller' = $SCSIController.DeviceInfo.Label + 'SCSI Address' = "$($SCSIController.BusNumber):$($VMHdd.ExtensionData.UnitNumber)" } + $TableParams = @{ + Name = "$($VM.Name) $($VMHdd.Name) HDD Configuration - $($VMHost.ExtensionData.Name)" + List = $true + ColumnWidths = 25, 75 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHardDiskInfo | Table @TableParams } } } - if ($VMGuestVols) { - Section -Style Heading4 "Guest Volumes" { - $VMGuestDiskInfo = foreach ($VMGuestVol in $VMGuestVols) { - [PSCustomObject]@{ - 'Path' = $VMGuestVol.Path - 'Capacity' = "$([math]::Round(($VMGuestVol.CapacityGB), 2)) GB" - 'Used Space' = "$([math]::Round((($VMGuestVol.CapacityGB) - ($VMGuestVol.FreeSpaceGB)), 2)) GB" - 'Free Space' = "$([math]::Round($VMGuestVol.FreeSpaceGB, 2)) GB" - } - } - $VMGuestDiskInfo | Table -Name "$($VM.Name) Guest Volumes" -ColumnWidths 25, 25, 25, 25 + } + } + if ($VMGuestVols) { + Section -Style Heading4 "Guest Volumes" { + $VMGuestDiskInfo = foreach ($VMGuestVol in $VMGuestVols) { + [PSCustomObject]@{ + 'Path' = $VMGuestVol.Path + 'Capacity' = "$([math]::Round(($VMGuestVol.CapacityGB), 2)) GB" + 'Used Space' = "$([math]::Round((($VMGuestVol.CapacityGB) - ($VMGuestVol.FreeSpaceGB)), 2)) GB" + 'Free Space' = "$([math]::Round($VMGuestVol.FreeSpaceGB, 2)) GB" } } + $TableParams = @{ + Name = "$($VM.Name) Guest Volumes - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMGuestDiskInfo | Table @TableParams } + } + } - - if ($VMSnapshotList -and $Options.ShowVMSnapshots) { - Section -Style Heading4 "Snapshots" { - $VMSnapshots = foreach ($VMSnapshot in $VMSnapshotList) { - [PSCustomObject]@{ - 'Snapshot Name' = $VMSnapshot.Name - 'Description' = $VMSnapshot.Description - 'Days Old' = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days - } - } - if ($Healthcheck.VM.VMSnapshots) { - $VMSnapshots | Where-Object { $_.'Days Old' -ge 7 } | Set-Style -Style Warning - $VMSnapshots | Where-Object { $_.'Days Old' -ge 14 } | Set-Style -Style Critical - } - $VMSnapshots | Table -Name "$($VM.Name) Snapshots" + + if ($VMSnapshotList -and $Options.ShowVMSnapshots) { + Section -Style Heading4 "Snapshots" { + $VMSnapshots = foreach ($VMSnapshot in $VMSnapshotList) { + [PSCustomObject]@{ + 'Snapshot Name' = $VMSnapshot.Name + 'Description' = $VMSnapshot.Description + 'Days Old' = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days } } + if ($Healthcheck.VM.VMSnapshots) { + $VMSnapshots | Where-Object { $_.'Days Old' -ge 7 } | Set-Style -Style Warning + $VMSnapshots | Where-Object { $_.'Days Old' -ge 14 } | Set-Style -Style Critical + } + $TableParams = @{ + Name = "$($VM.Name) VM Snapshots - $($VMHost.ExtensionData.Name)" + ColumnWidths = 45, 45, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMSnapshots | Table @TableParams } } } - #endregion Virtual Machine Detailed Information } } + #endregion Virtual Machine Detailed Information } - #endregion Virtual Machine Section - - #region ESXi Host VM Startup/Shutdown Information - $VMStartPolicy = $VMHost | Get-VMStartPolicy | Where-Object { $_.StartAction -ne 'None' } - if ($VMStartPolicy) { - #region VM Startup/Shutdown Section - Section -Style Heading2 'VM Startup/Shutdown' { - Paragraph "The following section details the VM startup/shutdown configuration for $($VMHost.ExtensionData.Name)." - BlankLine - $VMStartPolicies = foreach ($VMStartPol in $VMStartPolicy) { - [PSCustomObject]@{ - 'Start Order' = $VMStartPol.StartOrder - 'VM Name' = $VMStartPol.VirtualMachineName - 'Startup' = Switch ($VMStartPol.StartAction) { - 'PowerOn' { 'Enabled' } - 'None' { 'Disabled' } - default { $VMStartPol.StartAction } - } - 'Startup Delay' = "$($VMStartPol.StartDelay) seconds" - 'VMware Tools' = Switch ($VMStartPol.WaitForHeartbeat) { - $true { 'Continue if VMware Tools is started' } - $false { 'Wait for startup delay' } - } - 'Shutdown Behavior' = Switch ($VMStartPol.StopAction) { - 'PowerOff' { 'Power Off' } - 'GuestShutdown' { 'Guest Shutdown' } - default { $VMStartPol.StopAction } - } - 'Shutdown Delay' = "$($VMStartPol.StopDelay) seconds" + } + } + #endregion Virtual Machine Section + + #region ESXi Host VM Autostart Information + if ($InfoLevel.VMHost -ge 1) { + $VMStartPolicy = $VMHost | Get-VMStartPolicy | Sort-Object VirtualMachineName + if ($VMStartPolicy) { + #region VM Autostart Section + Section -Style Heading2 'VM Autostart' { + Paragraph "The following section details the VM autostart configuration for $($VMHost.ExtensionData.Name)." + BlankLine + $VMStartPolicies = foreach ($VMStartPol in $VMStartPolicy) { + [PSCustomObject]@{ + 'Virtual Machine' = $VMStartPol.VirtualMachineName + 'Autostart Enabled' = Switch ($VMStartPol.StartAction) { + 'PowerOn' { 'Yes' } + 'None' { 'No' } + default { $VMStartPol.StartAction } + } + 'Autostart Order' = Switch ($VMStartPol.StartOrder) { + $null { 'Unset' } + default { $VMStartPol.StartOrder } + } + 'Shutdown Behavior' = Switch ($VMStartPol.StopAction) { + 'PowerOff' { 'Power Off' } + 'GuestShutdown' { 'Shutdown' } + default { $VMStartPol.StopAction } + } + 'Start Delay' = "$($VMStartPol.StartDelay) sec" + 'Stop Delay' = "$($VMStartPol.StopDelay) sec" + 'Wait for Heartbeat' = Switch ($VMStartPol.WaitForHeartbeat) { + $true { 'Yes' } + $false { 'No' } } } - $VMStartPolicies | Table -Name "$($VMHost.ExtensionData.Name) VM Startup/Shutdown Policy" } - #endregion VM Startup/Shutdown Section + $TableParams = @{ + Name = "VM Autostart Policy - $($VMHost.ExtensionData.Name)" + ColumnWidths = 25, 12, 13, 15, 12, 12, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMStartPolicies | Table @TableParams } - #endregion ESXi Host VM Startup/Shutdown Information + #endregion VM Autostart Section } - #endregion ESXi Host Detailed Information } - #endregion Hosts Section - } # end if ($VMHosts) - } # end if ($InfoLevel.VMHost -ge 1) + #endregion ESXi Host VM Autostart Information + } + #endregion ESXi Host Detailed Information + } + #endregion Hosts Section } # end if ($ESXi) # Disconnect ESXi Server