diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bfda8eb..3d4492b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -90,7 +90,7 @@ body: I have read and followed the [bug reporting guidelines](https://www.asbuiltreport.com/dev-guide/contributing/#reporting-issues-and-bugs). required: true - label: >- - I have read [the documentation](https://www.asbuiltreport.com/user-guide/new-asbuiltconfig), + I have read [the documentation](https://www.asbuiltreport.com/user-guide/quickstart/), and referred to the [known issues](https://www.asbuiltreport.com/support/known-issues) before submitting this bug report. required: true - label: >- diff --git a/.github/ISSUE_TEMPLATE/change_request.yml b/.github/ISSUE_TEMPLATE/change_request.yml index 003552f..bf86a4c 100644 --- a/.github/ISSUE_TEMPLATE/change_request.yml +++ b/.github/ISSUE_TEMPLATE/change_request.yml @@ -26,7 +26,7 @@ body: If you are unsure of what a specific requirement means, please follow the links to learn about it and understand why it is necessary before submitting. options: - label: >- - I have read [the documentation](https://www.asbuiltreport.com/user-guide/new-asbuiltconfig), + I have read [the documentation](https://www.asbuiltreport.com/user-guide/quickstart/), and referred to the [known issues](https://www.asbuiltreport.com/support/known-issues) before submitting this change request. required: true - label: >- diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e237f46..6622e9b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -28,7 +28,7 @@ ## Checklist: -- [ ] My code follows the code style of this project. +- [ ] My code follows the [code style](https://www.asbuiltreport.com/dev-guide/contributing/#coding-style-guidelines) of this project. - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. -- [ ] I have read the [**CONTRIBUTING**](https://www.asbuiltreport.com/about/contributing/) document. +- [ ] I have read the [contributing](https://www.asbuiltreport.com/dev-guide/contributing/) documentation. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..959a9f3 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,32 @@ +# Dependabot configuration for AsBuiltReport.VMware.vSphere +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + # Monitor GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + labels: + - "dependencies" + - "github-actions" + commit-message: + prefix: "ci" + include: "scope" + open-pull-requests-limit: 5 + + # Monitor PowerShell modules (via manifest) + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + labels: + - "dependencies" + - "powershell" + commit-message: + prefix: "deps" + include: "scope" + open-pull-requests-limit: 5 diff --git a/.github/workflows/PSScriptAnalyzer.yml b/.github/workflows/PSScriptAnalyzer.yml index a73694f..0cbba0f 100644 --- a/.github/workflows/PSScriptAnalyzer.yml +++ b/.github/workflows/PSScriptAnalyzer.yml @@ -5,9 +5,9 @@ jobs: name: Run PSScriptAnalyzer runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: lint - uses: devblackops/github-action-psscriptanalyzer@master + uses: alagoutte/github-action-psscriptanalyzer@master with: sendComment: true failOnErrors: true diff --git a/.github/workflows/Pester.yml b/.github/workflows/Pester.yml new file mode 100644 index 0000000..33843da --- /dev/null +++ b/.github/workflows/Pester.yml @@ -0,0 +1,79 @@ +name: Pester Tests + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + - dev + workflow_dispatch: + +jobs: + test: + name: Pester Tests - ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + + defaults: + run: + shell: pwsh + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up PowerShell Gallery + run: | + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted + + - name: Install Pester + run: | + Install-Module -Name Pester -MinimumVersion 5.0.0 -Repository PSGallery -Force -AllowClobber -Scope CurrentUser + + - name: Install PScribo + run: | + Install-Module -Name PScribo -MinimumVersion 0.11.1 -Repository PSGallery -Force -AllowClobber -Scope CurrentUser + + - name: Install PSScriptAnalyzer + run: | + Install-Module -Name PSScriptAnalyzer -MinimumVersion 1.0.0 -Repository PSGallery -Force -AllowClobber -Scope CurrentUser + + - name: Install AsBuiltReport.Core + run: | + Install-Module -Name AsBuiltReport.Core -MinimumVersion 1.6.2 -Repository PSGallery -Force -AllowClobber -Scope CurrentUser + + - name: Run Pester Tests + run: | + $CodeCoverageParam = @{} + $OutputFormatParam = @{ OutputFormat = 'NUnitXml' } + + # Only enable code coverage for Windows + if ('${{ matrix.os }}' -eq 'windows-latest') { + $CodeCoverageParam = @{ CodeCoverage = $true } + } + + .\Tests\Invoke-Tests.ps1 @CodeCoverageParam @OutputFormatParam + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.os }} + path: Tests/testResults.xml + retention-days: 30 + + - name: Upload code coverage to Codecov + if: matrix.os == 'windows-latest' + uses: codecov/codecov-action@v5 + with: + files: ./Tests/coverage.xml + flags: unit + name: codecov-${{ matrix.os }} + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 4adaf43..75925ce 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -5,7 +5,7 @@ on: types: [published] jobs: - publish-to-gallery: + publish-to-psgallery: runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -17,16 +17,28 @@ jobs: shell: pwsh run: | Install-Module -Name AsBuiltReport.Core -Repository PSGallery -Force + - name: Set Prerelease string in manifest + if: ${{ github.event.release.prerelease }} + shell: pwsh + run: | + $tag = '${{ github.event.release.tag_name }}' + if ($tag -match '-(.+)$') { + $prerelease = $Matches[1] + Update-ModuleManifest ` + -Path .\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1 ` + -Prerelease $prerelease + } - name: Test Module Manifest shell: pwsh run: | - Test-ModuleManifest .\AsBuiltReport.VMware.vSphere.psd1 + Test-ModuleManifest .\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1 - name: Publish module to PowerShell Gallery shell: pwsh run: | - Publish-Module -Path ./ -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose + Publish-Module -Path .\AsBuiltReport.VMware.vSphere -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose tweet: - needs: publish-to-gallery + needs: publish-to-psgallery + if: ${{ !github.event.release.prerelease }} runs-on: ubuntu-latest steps: - uses: Eomm/why-don-t-you-tweet@v2 @@ -41,13 +53,40 @@ jobs: TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }} TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }} TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }} + tweet-prerelease: + needs: publish-to-psgallery + if: ${{ github.event.release.prerelease }} + runs-on: ubuntu-latest + steps: + - uses: Eomm/why-don-t-you-tweet@v2 + # We don't want to tweet if the repository is not a public one + if: ${{ !github.event.repository.private }} + with: + tweet-message: "[Pre-release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} is now available for testing! Install with -AllowPrerelease ${{ github.event.release.html_url }} #VMware #vSphere #AsBuiltReport #vExpert" + env: + TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }} + TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }} + TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }} + TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }} bsky-post: - needs: publish-to-gallery + needs: publish-to-psgallery + if: ${{ !github.event.release.prerelease }} runs-on: ubuntu-latest steps: - uses: zentered/bluesky-post-action@v0.2.0 with: post: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #VMware #vSphere #AsBuiltReport #vExpert" + env: + BSKY_IDENTIFIER: ${{ secrets.BSKY_IDENTIFIER }} + BSKY_PASSWORD: ${{ secrets.BSKY_PASSWORD }} + bsky-post-prerelease: + needs: publish-to-psgallery + if: ${{ github.event.release.prerelease }} + runs-on: ubuntu-latest + steps: + - uses: zentered/bluesky-post-action@v0.2.0 + with: + post: "[Pre-release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} is now available for testing! Install with -AllowPrerelease ${{ github.event.release.html_url }} #VMware #vSphere #AsBuiltReport #vExpert" env: BSKY_IDENTIFIER: ${{ secrets.BSKY_IDENTIFIER }} BSKY_PASSWORD: ${{ secrets.BSKY_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/Stale.yml b/.github/workflows/Stale.yml new file mode 100644 index 0000000..c351e4d --- /dev/null +++ b/.github/workflows/Stale.yml @@ -0,0 +1,19 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' + days-before-stale: 90 + days-before-close: 7 + exempt-pr-labels: 'help wanted,enhancement,security,pinned' + stale-pr-label: 'wontfix' + stale-issue-label: 'wontfix' + exempt-issue-labels: 'help wanted,enhancement,security,pinned' + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c5f206 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.claude/ diff --git a/AsBuiltReport.VMware.vSphere.json b/AsBuiltReport.VMware.vSphere.json deleted file mode 100644 index 8a0bc7b..0000000 Binary files a/AsBuiltReport.VMware.vSphere.json and /dev/null differ diff --git a/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.json b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.json new file mode 100644 index 0000000..2006636 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.json @@ -0,0 +1,100 @@ +{ + "Report": { + "Name": "VMware vSphere As Built Report", + "Version": "1.0", + "Status": "Released", + "Language": "en-US", + "ShowCoverPageImage": true, + "ShowTableOfContents": true, + "ShowHeaderFooter": true, + "ShowTableCaptions": true + }, + "Options": { + "ShowLicenseKeys": false, + "ShowEncryptionKeys": false, + "ShowVMSnapshots": true, + "ShowRoles": true, + "ShowAlarms": true, + "ShowTags": true + }, + "InfoLevel": { + "_comment_": "0 = Disabled, 1 = Enabled / Summary, 2 = Adv Summary, 3 = Detailed, 4 = Adv Detailed, 5 = Comprehensive", + "vCenter": 3, + "Cluster": 3, + "ResourcePool": 3, + "VMHost": 3, + "Network": 3, + "vSAN": 3, + "Datastore": 3, + "DSCluster": 3, + "VM": 2, + "VUM": 3 + }, + "HealthCheck": { + "vCenter": { + "Mail": true, + "Licensing": true, + "Alarms": true, + "Backup": true, + "Certificate": true, + "ContentLibrary": true + }, + "Cluster": { + "HAEnabled": true, + "HAAdmissionControl": true, + "HostFailureResponse": true, + "HostMonitoring": true, + "DatastoreOnPDL": true, + "DatastoreOnAPD": true, + "APDTimeOut": true, + "vmMonitoring": true, + "DRSEnabled": true, + "DRSAutomationLevelFullyAuto": true, + "PredictiveDRS": false, + "DRSVMHostRules": true, + "DRSRules": true, + "vSANEnabled": false, + "EVCEnabled": true, + "VUMCompliance": true, + "LCMCompliance": true + }, + "VMHost": { + "ConnectionState": true, + "HyperThreading": true, + "ScratchLocation": true, + "IPv6": true, + "UpTimeDays": true, + "Licensing": true, + "SSH": true, + "ESXiShell": true, + "NTP": true, + "StorageAdapter": true, + "NetworkAdapter": true, + "LockdownMode": true, + "VUMCompliance": true, + "TpmAttestation": true + }, + "vSAN": { + "CapacityUtilization": true + }, + "Datastore": { + "CapacityUtilization": true + }, + "DSCluster": { + "CapacityUtilization": true, + "SDRSAutomationLevelFullyAuto": true + }, + "VM": { + "PowerState": true, + "ConnectionState": true, + "CpuHotAdd": true, + "CpuHotRemove": true, + "MemoryHotAdd": true, + "ChangeBlockTracking": true, + "SpbmPolicyCompliance": true, + "VMToolsStatus": true, + "VMSnapshots": true, + "VUMCompliance": true + } + } +} diff --git a/AsBuiltReport.VMware.vSphere.psd1 b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psd1 similarity index 79% rename from AsBuiltReport.VMware.vSphere.psd1 rename to AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psd1 index 2375c12..c2b86ba 100644 --- a/AsBuiltReport.VMware.vSphere.psd1 +++ b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psd1 @@ -12,10 +12,10 @@ RootModule = 'AsBuiltReport.VMware.vSphere.psm1' # Version number of this module. - ModuleVersion = '1.3.6' + ModuleVersion = '2.0.0' # Supported PSEditions - # CompatiblePSEditions = 'Desktop' + CompatiblePSEditions = @('Core') # ID used to uniquely identify this module GUID = 'e1cbf1ce-cf01-4b6e-9cc2-56323da3c351' @@ -27,23 +27,17 @@ # CompanyName = '' # Copyright statement for this module - Copyright = '(c) 2025 Tim Carman. All rights reserved.' + Copyright = '(c) 2026 Tim Carman. All rights reserved.' # Description of the functionality provided by this module Description = 'A PowerShell module to generate an as built report on the configuration of VMware vSphere.' - # Minimum version of the Windows PowerShell engine required by this module - # PowerShellVersion = '5.1' + # Minimum version of the PowerShell engine required by this module + PowerShellVersion = '7.4' - # Name of the Windows PowerShell host required by this module + # Name of the PowerShell host required by this module # PowerShellHostName = '' - # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. - # DotNetFrameworkVersion = '4.5' - - # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. - # CLRVersion = '' - # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' @@ -51,7 +45,7 @@ RequiredModules = @( @{ ModuleName = 'AsBuiltReport.Core'; - ModuleVersion = '1.4.3' + ModuleVersion = '1.6.2' } ) @@ -96,22 +90,22 @@ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. - Tags = 'AsBuiltReport', 'Report', 'VMware', 'vSphere', 'vCenter', 'Documentation', 'PScribo', 'PSEdition_Desktop', 'PSEdition_Core', 'Windows', 'MacOS', 'Linux' + Tags = 'AsBuiltReport', 'Report', 'VMware', 'vSphere', 'vCenter', 'Documentation', 'PScribo', 'PSEdition_Core', 'Windows', 'MacOS', 'Linux' # A URL to the license for this module. - LicenseUri = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/master/LICENSE' + LicenseUri = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/main/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere' # A URL to an icon representing this module. - IconUri = ' https://github.com/AsBuiltReport.png' + IconUri = 'AsBuiltReport.png' # ReleaseNotes of this module - ReleaseNotes = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/master/CHANGELOG.md' + ReleaseNotes = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/main/CHANGELOG.md' # Prerelease string of this module - # Prerelease = '' + Prerelease = 'beta1' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false diff --git a/AsBuiltReport.VMware.vSphere.psm1 b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psm1 similarity index 82% rename from AsBuiltReport.VMware.vSphere.psm1 rename to AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psm1 index e22b0dc..880ef3c 100644 --- a/AsBuiltReport.VMware.vSphere.psm1 +++ b/AsBuiltReport.VMware.vSphere/AsBuiltReport.VMware.vSphere.psm1 @@ -10,5 +10,4 @@ foreach ($Module in @($Public + $Private)) { } } -Export-ModuleMember -Function $Public.BaseName -Export-ModuleMember -Function $Private.BaseName \ No newline at end of file +Export-ModuleMember -Function $Public.BaseName \ No newline at end of file diff --git a/AsBuiltReport.VMware.vSphere/AsBuiltReport.png b/AsBuiltReport.VMware.vSphere/AsBuiltReport.png new file mode 100644 index 0000000..dd4ee29 Binary files /dev/null and b/AsBuiltReport.VMware.vSphere/AsBuiltReport.png differ diff --git a/AsBuiltReport.VMware.vSphere/Language/de-DE/VMwarevSphere.psd1 b/AsBuiltReport.VMware.vSphere/Language/de-DE/VMwarevSphere.psd1 new file mode 100644 index 0000000..23192c3 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Language/de-DE/VMwarevSphere.psd1 @@ -0,0 +1,1625 @@ +# culture = 'de-DE' +@{ + +# Module-wide strings +InvokeAsBuiltReportVMwarevSphere = ConvertFrom-StringData @' + Connecting = Verbindung zum vCenter Server '{0}' wird hergestellt. + CheckPrivileges = vCenter-Benutzerberechtigungen werden überprüft. + UnablePrivileges = vCenter-Benutzerberechtigungen konnten nicht abgerufen werden. + VMHashtable = VM-Nachschlagetabelle wird erstellt. + VMHostHashtable = VMHost-Nachschlagetabelle wird erstellt. + DatastoreHashtable = Datenspeicher-Nachschlagetabelle wird erstellt. + VDPortGrpHashtable = VDPortGroup-Nachschlagetabelle wird erstellt. + EVCHashtable = EVC-Nachschlagetabelle wird erstellt. + CheckVUM = Suche nach VMware Update Manager Server. + CheckVxRail = Suche nach VxRail Manager Server. + CheckSRM = Suche nach VMware Site Recovery Manager Server. + CheckNSXT = Suche nach VMware NSX-T Manager Server. + CollectingTags = Tag-Informationen werden gesammelt. + TagError = Fehler beim Sammeln von Tag-Informationen. + CollectingAdvSettings = Erweiterte Einstellungen von {0} werden gesammelt. +'@ + +# Get-AbrVSpherevCenter +GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = vCenter-Informationsebene auf {0} gesetzt. + Collecting = vCenter Server-Informationen werden gesammelt. + SectionHeading = vCenter Server + ParagraphSummaryBrief = Die folgenden Abschnitte fassen die Konfiguration des vCenter Servers {0} zusammen. + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration des vCenter Servers {0}. + InsufficientPrivLicense = Unzureichende Benutzerberechtigungen für den Bericht über vCenter Server-Lizenzierung. Stellen Sie sicher, dass dem Benutzerkonto das Privileg 'Global > Lizenzen' zugewiesen ist. + InsufficientPrivStoragePolicy = Unzureichende Benutzerberechtigungen für den Bericht über VM-Speicherrichtlinien. Stellen Sie sicher, dass dem Benutzerkonto das Privileg 'Speicherprofil > Anzeigen' zugewiesen ist. + vCenterServer = vCenter Server + IPAddress = IP-Adresse + Version = Version + Build = Build + Product = Produkt + LicenseKey = Lizenzschlüssel + LicenseExpiration = Lizenzablauf + InstanceID = Instanz-ID + HTTPPort = HTTP-Port + HTTPSPort = HTTPS-Port + PSC = Plattformdienstcontroller + UpdateManagerServer = Update Manager Server + SRMServer = Site Recovery Manager Server + NSXTServer = NSX-T Manager Server + VxRailServer = VxRail Manager Server + DatabaseSettings = Datenbankeinstellungen + DatabaseType = Datenbanktyp + DataSourceName = Datenquellenname + MaxDBConnection = Maximale Datenbankverbindungen + MailSettings = E-Mail-Einstellungen + SMTPServer = SMTP-Server + SMTPPort = SMTP-Port + MailSender = Absender + HistoricalStatistics = Verlaufsstatistiken + IntervalDuration = Intervalldauer + IntervalEnabled = Intervall aktiviert + SaveDuration = Speicherdauer + StatisticsLevel = Statistikebene + Licensing = Lizenzierung + Total = Gesamt + Used = Verwendet + Available = Verfügbar + Expiration = Ablauf + Certificate = Zertifikat + Subject = Betreff + Issuer = Aussteller + ValidFrom = Gültig ab + ValidTo = Gültig bis + Thumbprint = Fingerabdruck + CertStatus = Status + InsufficientPrivCertificate = Das vCenter Server-Zertifikat konnte nicht abgerufen werden. {0} + Mode = Modus + SoftThreshold = Weicher Schwellenwert + HardThreshold = Harter Schwellenwert + MinutesBefore = Minuten vorher + PollInterval = Abfrageintervall + Roles = Rollen + Role = Rolle + SystemRole = Systemrolle + PrivilegeList = Berechtigungsliste + Tags = Tags + TagName = Name + TagCategory = Kategorie + TagDescription = Beschreibung + TagCategories = Tag-Kategorien + TagCardinality = Kardinalität + TagAssignments = Tag-Zuweisungen + TagEntity = Entität + TagEntityType = Entitätstyp + VMStoragePolicies = VM-Speicherrichtlinien + StoragePolicy = Speicherrichtlinie + Description = Beschreibung + ReplicationEnabled = Replikation aktiviert + CommonRulesName = Name der gemeinsamen Regeln + CommonRulesDescription = Beschreibung der gemeinsamen Regeln + Alarms = Alarme + Alarm = Alarm + AlarmDescription = Beschreibung + AlarmEnabled = Aktiviert + AlarmTriggered = Ausgelöst + AlarmAction = Aktion + AdvancedSystemSettings = Erweiterte Systemeinstellungen + Key = Schlüssel + Value = Wert + Enabled = Aktiviert + Disabled = Deaktiviert + Yes = Ja + No = Nein + None = Keine + TablevCenterSummary = vCenter Server Summary - {0} + TablevCenterConfig = vCenter Server Configuration - {0} + TableDatabaseSettings = Database Settings - {0} + TableMailSettings = Mail Settings - {0} + TableHistoricalStatistics = Historical Statistics - {0} + TableLicensing = Licensing - {0} + TableCertificate = Certificate - {0} + TableRole = Role {0} - {1} + TableRoles = Roles - {0} + TableTags = Tags - {0} + TableTagCategories = Tag Categories - {0} + TableTagAssignments = Tag Assignments - {0} + TableVMStoragePolicies = VM Storage Policies - {0} + TableAlarm = {0} - {1} + TableAlarms = Alarms - {0} + TableAdvancedSystemSettings = vCenter Advanced System Settings - {0} + RestApiSessionError = Unable to establish vCenter REST API session. {0} + BackupSettings = Sicherungseinstellungen + BackupSchedule = Sicherungszeitplan + BackupJobHistory = Sicherungsauftragsverlauf + BackupNotConfigured = Es ist kein Sicherungszeitplan konfiguriert. + BackupNoJobs = Keine Sicherungsaufträge gefunden. + BackupApiNotAvailable = Der vCenter-Sicherungsstatus erfordert vSphere 7.0 oder höher. + BackupApiError = Sicherungsinformationen konnten nicht abgerufen werden. {0} + BackupScheduleID = Zeitplan-ID + BackupLocation = Speicherort + BackupLocationUser = Speicherortbenutzer + BackupEnabled = Status + BackupActivated = Aktiviert + BackupDeactivated = Deaktiviert + BackupParts = Sicherungsdaten + BackupPartSeat = Supervisors Control Plane + BackupPartCommon = Bestand und Konfiguration + BackupPartStats = Statistiken, Ereignisse und Aufgaben + BackupRecurrence = Zeitplan + BackupRetentionCount = Anzahl der aufzubewahrenden Sicherungen + BackupDaily = Täglich + BackupSendEmail = E-Mail-Benachrichtigung + BackupJobLocation = Sicherungsort + BackupJobType = Typ + BackupJobStatus = Status + BackupJobComplete = Abgeschlossen + BackupJobScheduled = Geplant + BackupJobDataTransferred = Übertragene Daten + BackupJobDuration = Dauer + BackupJobEndTime = Endzeit + TableBackupSchedule = Sicherungszeitplan - {0} + TableBackupJobHistory = Sicherungsauftragsverlauf - {0} + ResourceSummary = Ressourcen + SummaryResource = Ressource + Free = Frei + CPU = CPU + Memory = Arbeitsspeicher + Storage = Speicher + VirtualMachines = Virtuelle Maschinen + Hosts = Hosts + PoweredOn = Eingeschaltet + PoweredOff = Ausgeschaltet + Suspended = Angehalten + Connected = Verbunden + Disconnected = Getrennt + Maintenance = Wartungsmodus + ContentLibraries = Inhaltsbibliotheken + ContentLibrary = Inhaltsbibliothek + LibraryType = Typ + Datastore = Datenspeicher + LibraryLocal = Lokal + LibrarySubscribed = Abonniert + ItemCount = Elemente + SubscriptionUrl = Abonnement-URL + AutomaticSync = Automatische Synchronisierung + OnDemandSync = Bedarfsgesteuerte Synchronisierung + LibraryItems = Bibliothekselemente + ItemName = Element + ContentType = Inhaltstyp + ItemSize = Größe + CreationTime = Erstellungszeit + LastModified = Zuletzt geändert + ContentLibraryNoItems = Keine Elemente in dieser Inhaltsbibliothek gefunden. + ContentLibraryNone = Keine Inhaltsbibliotheken gefunden. + CollectingContentLibrary = Informationen zur Inhaltsbibliothek werden gesammelt. + ContentLibraryError = Inhaltsbibliotheksinformationen konnten nicht abgerufen werden. {0} + ContentLibraryItemError = Elemente für Inhaltsbibliothek '{0}' konnten nicht abgerufen werden. {1} + TableContentLibraries = Content Libraries - {0} + TableContentLibrary = Content Library {0} - {1} + TableLibraryItems = Library Items - {0} + TableLibraryItem = {0} - {1} + TablevCenterResourceSummary = Ressourcenübersicht - {0} + TablevCenterVMSummary = Übersicht Virtuelle Maschinen - {0} + TablevCenterHostSummary = Host-Übersicht - {0} +'@ + +# Get-AbrVSphereCluster +GetAbrVSphereCluster = ConvertFrom-StringData @' + InfoLevel = Cluster-Informationsebene auf {0} gesetzt. + Collecting = Cluster-Informationen werden gesammelt. + Processing = Cluster '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Cluster + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der vSphere HA/DRS-Cluster, die vom vCenter Server {0} verwaltet werden. + ParagraphDetail = Die folgende Tabelle beschreibt die Konfiguration des Clusters {0}. + Cluster = Cluster + ID = ID + Datacenter = Rechenzentrum + NumHosts = Anzahl Hosts + NumVMs = Anzahl VMs + HAEnabled = vSphere HA + DRSEnabled = vSphere DRS + VSANEnabled = Virtual SAN + EVCMode = EVC-Modus + VMSwapFilePolicy = VM-Auslagerungsdateirichtlinie + NumberOfHosts = Anzahl der Hosts + NumberOfVMs = Anzahl der VMs + Hosts = Hosts + VirtualMachines = Virtuelle Maschinen + Permissions = Berechtigungen + Principal = Prinzipal + Role = Rolle + Propagate = Weitergeben + IsGroup = Ist Gruppe + Enabled = Aktiviert + Disabled = Deaktiviert + SwapWithVM = Mit VM + SwapInHostDatastore = Im Host-Datenspeicher + SwapVMDirectory = Verzeichnis der virtuellen Maschine + SwapHostDatastore = Vom Host angegebener Datenspeicher + TableClusterSummary = Cluster Summary - {0} + TableClusterConfig = Cluster Configuration - {0} +'@ + +# Get-AbrVSphereClusterHA +GetAbrVSphereClusterHA = ConvertFrom-StringData @' + Collecting = Cluster-HA-Informationen werden gesammelt. + SectionHeading = vSphere HA-Konfiguration + ParagraphSummary = Der folgende Abschnitt beschreibt die vSphere HA-Konfiguration für Cluster {0}. + FailuresAndResponses = Fehler und Antworten + HostMonitoring = Host-Überwachung + HostFailureResponse = Antwort auf Host-Ausfall + HostIsolationResponse = Antwort auf Host-Isolierung + VMRestartPriority = VM-Neustartreihenfolge + PDLProtection = Datenspeicher mit permanentem Geräteverlust + APDProtection = Datenspeicher mit allen inaktiven Pfaden + VMMonitoring = VM-Überwachung + VMMonitoringSensitivity = VM-Überwachungsempfindlichkeit + AdmissionControl = Zugangskontrolle + FailoverLevel = Tolerierte Host-Ausfälle im Cluster + ACPolicy = Richtlinie + ACHostPercentage = CPU % + ACMemPercentage = Arbeitsspeicher % + PerformanceDegradation = VM-Leistungsverschlechterung + HeartbeatDatastores = Heartbeat-Datenspeicher + Datastore = Datenspeicher + HAAdvancedOptions = Erweiterte vSphere HA-Optionen + Key = Schlüssel + Value = Wert + APDRecovery = APD-Wiederherstellung nach APD-Timeout + Disabled = Deaktiviert + Enabled = Aktiviert + RestartVMs = VMs neu starten + ShutdownAndRestart = VMs herunterfahren und neu starten + PowerOffAndRestart = VMs ausschalten und neu starten + IssueEvents = Ereignisse ausgeben + PowerOffRestartConservative = VMs ausschalten und neu starten (konservativ) + PowerOffRestartAggressive = VMs ausschalten und neu starten (aggressiv) + ResetVMs = VMs zurücksetzen + VMMonitoringOnly = Nur VM-Überwachung + VMAndAppMonitoring = VM- und Anwendungsüberwachung + DedicatedFailoverHosts = Dedizierte Failover-Hosts + ClusterResourcePercentage = Clusterressourcen-Prozentsatz + SlotPolicy = Slot-Richtlinie + Yes = Ja + No = Nein + FixedSlotSize = Feste Slot-Größe + CoverAllPoweredOnVMs = Alle eingeschalteten VMs abdecken + NoneSpecified = Keine angegeben + OverrideFailoverCapacity = Override Calculated Failover Capacity + CPUSlotSize = CPU Slot Size (MHz) + MemorySlotSize = Memory Slot Size (MB) + PerfDegradationTolerate = Performance Degradation VMs Tolerate + HeartbeatSelectionPolicy = Heartbeat Selection Policy + HBPolicyAllFeasibleDsWithUserPreference = Use datastores from the specified list and complement automatically if needed + HBPolicyAllFeasibleDs = Automatically select datastores accessible from the host + HBPolicyUserSelectedDs = Use datastores only from the specified list + TableHAFailures = vSphere HA Failures and Responses - {0} + TableHAAdmissionControl = vSphere HA Admission Control - {0} + TableHAHeartbeat = vSphere HA Heartbeat Datastores - {0} + TableHAAdvanced = vSphere HA Advanced Options - {0} +'@ + +# Get-AbrVSphereClusterProactiveHA +GetAbrVSphereClusterProactiveHA = ConvertFrom-StringData @' + Collecting = Proaktive HA-Informationen des Clusters werden gesammelt. + SectionHeading = Proaktive HA + ParagraphSummary = Der folgende Abschnitt beschreibt die Konfiguration der proaktiven HA für Cluster {0}. + FailuresAndResponses = Fehler und Antworten + Provider = Anbieter + Remediation = Korrekturmaßnahme + HealthUpdates = Zustandsaktualisierungen + ProactiveHA = Proaktive HA + AutomationLevel = Automatisierungsstufe + ModerateRemediation = Moderate Korrektur + SevereRemediation = Schwerwiegende Korrektur + Enabled = Aktiviert + Disabled = Deaktiviert + MaintenanceMode = Wartungsmodus + QuarantineMode = Quarantänemodus + MixedMode = Gemischter Modus + TableProactiveHA = Proactive HA - {0} + Providers = Anbieter + HealthUpdateCount = Integritätsaktualisierungen + TableProactiveHAProviders = Proaktive HA-Anbieter - {0} +'@ + +# Get-AbrVSphereClusterDRS +GetAbrVSphereClusterDRS = ConvertFrom-StringData @' + Collecting = Cluster-DRS-Informationen werden gesammelt. + SectionHeading = vSphere DRS-Konfiguration + ParagraphSummary = Die folgende Tabelle beschreibt die vSphere DRS-Konfiguration für Cluster {0}. + AutomationLevel = DRS-Automatisierungsebene + MigrationThreshold = Migrationsschwellenwert + PredictiveDRS = Prädiktiver DRS + VirtualMachineAutomation = Individuelle Maschinenautomatisierung + AdditionalOptions = Zusätzliche Optionen + VMDistribution = VM-Verteilung + MemoryMetricForLB = Arbeitsspeichermetrik für Lastenausgleich + CPUOverCommitment = CPU-Überbelegung + PowerManagement = Energieverwaltung + DPMAutomationLevel = DPM-Automatisierungsebene + DPMThreshold = DPM-Schwellenwert + AdvancedOptions = Erweiterte Optionen + Key = Schlüssel + Value = Wert + DRSClusterGroups = DRS-Clustergruppen + GroupName = Gruppenname + GroupType = Gruppentyp + GroupMembers = Mitglieder + DRSVMHostRules = DRS VM/Host-Regeln + RuleName = Regelname + RuleType = Regeltyp + RuleEnabled = Aktiviert + VMGroup = VM-Gruppe + HostGroup = Host-Gruppe + DRSRules = DRS-Regeln + RuleVMs = Virtuelle Maschinen + VMOverrides = VM-Überschreibungen + VirtualMachine = Virtuelle Maschine + DRSAutomationLevel = DRS-Automatisierungsebene + DRSBehavior = DRS-Verhalten + HARestartPriority = HA-Neustartreihenfolge + HAIsolationResponse = HA-Isolierungsantwort + PDLProtection = Datenspeicher mit PDL + APDProtection = Datenspeicher mit APD + VMMonitoring = VM-Überwachung + VMMonitoringFailureInterval = Fehlerintervall + VMMonitoringMinUpTime = Mindestbetriebszeit + VMMonitoringMaxFailures = Maximale Fehleranzahl + VMMonitoringMaxFailureWindow = Maximales Fehlerzeitfenster + Enabled = Aktiviert + Disabled = Deaktiviert + Yes = Ja + No = Nein + FullyAutomated = Vollautomatisch + PartiallyAutomated = Teilweise automatisiert + Manual = Manuell + Off = Aus + DRS = vSphere DRS + DPM = DPM + Automated = Automated + None = None + VMGroupType = VM Group + VMHostGroupType = Host Group + MustRunOn = Must run on hosts in group + ShouldRunOn = Should run on hosts in group + MustNotRunOn = Must not run on hosts in group + ShouldNotRunOn = Should not run on hosts in group + VMAffinity = Keep Virtual Machines Together + VMAntiAffinity = Separate Virtual Machines + Mandatory = Mandatory + OverCommitmentRatio = Over-Commitment Ratio + OverCommitmentRatioCluster = Over-Commitment Ratio (% of cluster capacity) + Lowest = Lowest + Low = Low + Medium = Medium + High = High + Highest = Highest + ClusterDefault = Cluster default + VMDependencyTimeout = VM Dependency Restart Condition Timeout + Seconds = {0} seconds + SectionVSphereHA = vSphere HA + IssueEvents = Issue events + PowerOffAndRestart = Power off and restart VMs + ShutdownAndRestartVMs = Shutdown and restart VMs + PowerOffRestartConservative = Power off and restart VMs - Conservative restart policy + PowerOffRestartAggressive = Power off and restart VMs - Aggressive restart policy + PDLFailureResponse = PDL Failure Response + APDFailureResponse = APD Failure Response + VMFailoverDelay = VM Failover Delay + Minutes = {0} minutes + ResponseRecovery = Response Recovery + ResetVMs = Reset VMs + SectionPDLAPD = PDL/APD Protection Settings + NoWindow = No window + WithinHours = Within {0} hrs + VMMonitoringOnly = VM Monitoring Only + VMAndAppMonitoring = VM and Application Monitoring + UserGroup = User/Group + IsGroup = Is Group? + Role = Role + DefinedIn = Defined In + Propagate = Propagate + Permissions = Permissions + ParagraphPermissions = The following table details the permissions for {0}. + TableDRSConfig = vSphere DRS Configuration - {0} + TableDRSAdditional = DRS Additional Options - {0} + TableDPM = vSphere DPM - {0} + TableDRSAdvanced = vSphere DRS Advanced Options - {0} + TableDRSGroups = DRS Cluster Groups - {0} + TableDRSVMHostRules = DRS VM/Host Rules - {0} + TableDRSRules = DRS Rules - {0} + TableDRSVMOverrides = DRS VM Overrides - {0} + TableHAVMOverrides = HA VM Overrides - {0} + TableHAPDLAPD = HA VM Overrides PDL/APD Settings - {0} + TableHAVMMonitoring = HA VM Overrides VM Monitoring - {0} + TablePermissions = Permissions - {0} +'@ + +# Get-AbrVSphereClusterVUM +GetAbrVSphereClusterVUM = ConvertFrom-StringData @' + UpdateManagerBaselines = Update Manager-Baselines + Baseline = Baseline + Description = Beschreibung + Type = Typ + TargetType = Zieltyp + LastUpdate = Letzte Aktualisierungszeit + NumPatches = Anzahl Patches + UpdateManagerCompliance = Update Manager-Compliance + Entity = Entität + Status = Compliance-Status + BaselineInfo = Baseline + VUMPrivilegeMsgBaselines = Unzureichende Benutzerberechtigungen für den Bericht über Cluster-Baselines. Stellen Sie sicher, dass dem Benutzerkonto das Privileg 'VMware Update Manager / VMware vSphere Lifecycle Manager > Patches und Upgrades verwalten > Compliance-Status anzeigen' zugewiesen ist. + VUMPrivilegeMsgCompliance = Unzureichende Benutzerberechtigungen für den Bericht über Cluster-Compliance. Stellen Sie sicher, dass dem Benutzerkonto das Privileg 'VMware Update Manager / VMware vSphere Lifecycle Manager > Patches und Upgrades verwalten > Compliance-Status anzeigen' zugewiesen ist. + VUMBaselineNotAvailable = Cluster-VUM-Baseline-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + VUMComplianceNotAvailable = Cluster-VUM-Compliance-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + NotCompliant = Nicht konform + Unknown = Unbekannt + Incompatible = Inkompatibel + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} +'@ + +# Get-AbrVSphereResourcePool +GetAbrVSphereResourcePool = ConvertFrom-StringData @' + InfoLevel = Ressourcenpool-Informationsebene auf {0} gesetzt. + Collecting = Ressourcenpool-Informationen werden gesammelt. + Processing = Ressourcenpool '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Ressourcenpools + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der Ressourcenpools, die vom vCenter Server {0} verwaltet werden. + ResourcePool = Ressourcenpool + Parent = Übergeordnet + CPUSharesLevel = CPU-Freigabeebene + CPUReservationMHz = CPU-Reservierung (MHz) + CPULimitMHz = CPU-Limit (MHz) + MemSharesLevel = Arbeitsspeicher-Freigabeebene + MemReservation = Arbeitsspeicherreservierung + MemLimit = Arbeitsspeicherlimit + ID = ID + NumCPUShares = Anzahl der CPU-Freigaben + CPUReservation = CPU-Reservierung + CPUExpandable = CPU-Reservierung erweiterbar + NumMemShares = Anzahl der Arbeitsspeicherfreigaben + MemExpandable = Arbeitsspeicherreservierung erweiterbar + NumVMs = Anzahl VMs + VirtualMachines = Virtuelle Maschinen + Enabled = Aktiviert + Disabled = Deaktiviert + Unlimited = Unbegrenzt + TableResourcePoolSummary = Resource Pool Summary - {0} + TableResourcePoolConfig = Resource Pool Configuration - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSphereVMHost +GetAbrVSphereVMHost = ConvertFrom-StringData @' + InfoLevel = VMHost-Informationsebene auf {0} gesetzt. + Collecting = VMHost-Informationen werden gesammelt. + Processing = VMHost '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Hosts + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der VMware ESXi-Hosts, die vom vCenter Server {0} verwaltet werden. + VMHost = Host + Manufacturer = Hersteller + Model = Modell + ProcessorType = Prozessortyp + NumCPUSockets = CPU-Sockel + NumCPUCores = CPU-Kerne + NumCPUThreads = CPU-Threads + MemoryGB = Arbeitsspeicher (GB) + NumNICs = Anzahl NICs + NumHBAs = Anzahl HBAs + NumDatastores = Anzahl Datenspeicher + NumVMs = Anzahl VMs + ConnectionState = Verbindungsstatus + PowerState = Energiezustand + ErrorCollecting = Fehler beim Sammeln von VMHost-Informationen mit VMHost-Informationsebene {0}. + NotResponding = Antwortet nicht + Maintenance = Wartung + Disconnected = Getrennt + Version = Version + Build = Build + Parent = Parent + TableHostSummary = Host Summary - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSphereVMHostHardware +GetAbrVSphereVMHostHardware = ConvertFrom-StringData @' + Collecting = VMHost-Hardware-Informationen werden gesammelt. + SectionHeading = Hardware + ParagraphSummary = Der folgende Abschnitt beschreibt die Hardware-Konfiguration des Hosts {0}. + InsufficientPrivLicense = Unzureichende Benutzerberechtigungen für den Bericht über ESXi-Host-Lizenzierung. Stellen Sie sicher, dass dem Benutzerkonto das Privileg 'Global > Lizenzen' zugewiesen ist. + LicenseError = Lizenzinformationen für VMHost '{0}' konnten nicht abgerufen werden. Fehler: {1} + Specifications = Spezifikationen + Manufacturer = Hersteller + Model = Modell + SerialNumber = Seriennummer + AssetTag = Asset-Tag + ProcessorType = Prozessortyp + CPUSockets = CPU-Sockel + CPUCores = CPU-Kerne + CPUThreads = CPU-Threads + HyperthreadingActive = Hyperthreading aktiv + MemoryGB = Arbeitsspeicher (GB) + NUMANodes = NUMA-Knoten + NICs = NICs + HBAs = HBAs + Version = Version + Build = Build + LicenseKey = Lizenzschlüssel + Product = Produkt + LicenseExpiration = Lizenzablauf + IPMIBMC = IPMI / BMC + IPMIBMCError = Fehler beim Sammeln von IPMI/BMC-Informationen für {0}. + IPMIBMCManufacturer = Hersteller + IPMIBMCType = Typ + IPMIBMCIPAddress = IP-Adresse + IPMIBMCMACAddress = MAC-Adresse + BootDevice = Startgerät + BootDeviceError = Fehler beim Sammeln von Startgerätinformationen für {0}. + BootDeviceDescription = Beschreibung + BootDeviceType = Typ + BootDeviceSize = Größe (GB) + BootDeviceIsSAS = Ist SAS + BootDeviceIsUSB = Ist USB + BootDeviceIsSSD = Ist SSD + BootDeviceFromSAN = Von SAN + PCIDevices = PCI-Geräte + PCIDeviceId = PCI-ID + PCIVendorName = Herstellername + PCIDeviceName = Gerätename + PCIDriverName = Treibername + PCIDriverVersion = Treiberversion + PCIFirmware = Firmware-Version + PCIDriversFirmware = PCI-Gerätetreiber und Firmware + Enabled = Aktiviert + Disabled = Deaktiviert + NotApplicable = Nicht zutreffend + Unknown = Unbekannt + Maintenance = Wartung + NotResponding = Not Responding + Host = Host + ConnectionState = Connection State + ID = ID + Parent = Parent + HyperThreading = HyperThreading + NumberOfCPUSockets = Number of CPU Sockets + NumberOfCPUCores = Number of CPU Cores + NumberOfCPUThreads = Number of CPU Threads + CPUTotalUsedFree = CPU Total / Used / Free + MemoryTotalUsedFree = Memory Total / Used / Free + NumberOfNICs = Number of NICs + NumberOfHBAs = Number of HBAs + NumberOfDatastores = Number of Datastores + NumberOfVMs = Number of VMs + MaximumEVCMode = Maximum EVC Mode + EVCGraphicsMode = EVC Graphics Mode + PowerManagementPolicy = Power Management Policy + ScratchLocation = Scratch Location + BiosVersion = BIOS Version + BiosReleaseDate = BIOS Release Date + BootTime = Boot Time + UptimeDays = Uptime Days + MACAddress = MAC Address + SubnetMask = Subnet Mask + Gateway = Gateway + FirmwareVersion = Firmware Version + Device = Device + BootType = Boot Type + Vendor = Vendor + Size = Size + PCIAddress = PCI Address + DeviceClass = Device Class + TableHardwareConfig = Hardware Configuration - {0} + TableIPMIBMC = IPMI / BMC - {0} + TableBootDevice = Boot Device - {0} + TablePCIDevices = PCI Devices - {0} + TablePCIDriversFirmware = PCI Devices Drivers & Firmware - {0} + PCIDeviceError = Error collecting PCI device information for {0}. {1} + PCIDriversFirmwareError = Error collecting PCI device driver & firmware information for {0}. {1} + HardwareError = Error collecting host hardware information for {0}. {1} + IODeviceIdentifiers = E/A-Gerätekennungen + VendorID = VID + DeviceID = DID + SubVendorID = SVID + SubDeviceID = SSID + TableIODeviceIdentifiers = E/A-Gerätekennungen - {0} + IODeviceIdentifiersError = Fehler beim Sammeln der E/A-Gerätekennungen für {0}. {1} +'@ + +# Get-AbrVSphereVMHostSystem +GetAbrVSphereVMHostSystem = ConvertFrom-StringData @' + Collecting = VMHost-System-Informationen werden gesammelt. + HostProfile = Host-Profil + ProfileName = Host-Profil + ProfileCompliance = Compliance + ProfileRemediating = Korrekturmaßnahme + ImageProfile = Image-Profil + ImageProfileName = Name + ImageProfileVendor = Hersteller + ImageProfileAcceptance = Akzeptanzebene + TimeConfiguration = Zeitkonfiguration + NTPServer = NTP-Server + TimeZone = Zeitzone + Syslog = Syslog + SyslogHost = Syslog-Host + VUMBaseline = Update Manager-Baselines + VUMBaselineNotAvailable = VMHost-VUM-Baseline-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + VUMBaselineName = Baseline + VUMBaselineType = Typ + VUMBaselinePatches = Anzahl Patches + VUMCompliance = Update Manager-Compliance + VUMComplianceNotAvailable = VMHost-VUM-Compliance-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + VUMStatus = Status + AdvancedSettings = Erweiterte Systemeinstellungen + Key = Schlüssel + Value = Wert + VIBs = VMware-Installationspakete (VIBs) + VIBName = Name + VIBVersion = Version + VIBVendor = Hersteller + VIBInstallDate = Installationsdatum + VIBAcceptanceLevel = Akzeptanzebene + SectionHeading = System + ParagraphSummary = Der folgende Abschnitt enthält Details zur Systemkonfiguration des Hosts {0}. + NTPService = NTP-Dienst + NTPServers = NTP-Server + SyslogPort = Port + VUMDescription = Beschreibung + VUMTargetType = Zieltyp + VUMLastUpdate = Letzte Aktualisierungszeit + InstallDate = Installationsdatum + ImageName = Image-Profil + ImageVendor = Anbieter + Running = Wird ausgeführt + Stopped = Gestoppt + NotCompliant = Nicht konform + Unknown = Unbekannt + Incompatible = Inkompatibel + ProfileDescription = Description + VIBID = ID + VIBCreationDate = Creation Date + TableHostProfile = Host Profile - {0} + TableImageProfile = Image Profile - {0} + TableTimeConfig = Time Configuration - {0} + TableSyslog = Syslog Configuration - {0} + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} + TableAdvancedSettings = Advanced System Settings - {0} + TableVIBs = Software VIBs - {0} + HostProfileError = Error collecting host profile information for {0}. {1} + ImageProfileError = Error collecting image profile information for {0}. {1} + TimeConfigError = Error collecting time configuration for {0}. {1} + SyslogError = Error collecting syslog configuration for {0}. {1} + VUMBaselineError = Error collecting Update Manager baseline information for {0}. {1} + VUMComplianceError = Error collecting Update Manager compliance information for {0}. {1} + AdvancedSettingsError = Error collecting host advanced settings information for {0}. {1} + VIBsError = Error collecting software VIB information for {0}. {1} + InsufficientPrivImageProfile = Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned. + InsufficientPrivVUMBaseline = Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + InsufficientPrivVUMCompliance = Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + SwapFileLocation = VM-Auslagerungsdateispeicherort + SwapFilePlacement = VM-Auslagerungsdateiplatzierung + SwapDatastore = Auslagerungs-Datenspeicher + WithVM = Mit VM (Standard) + HostLocal = Lokal auf dem Host + TableSwapFileLocation = VM-Auslagerungsdateispeicherort - {0} + SwapFileLocationError = Fehler beim Erfassen des VM-Auslagerungsdateispeicherorts für {0}. {1} + HostCertificate = Host-Zertifikat + CertSubject = Betreff + CertIssuer = Aussteller + CertValidFrom = Gültig ab + CertValidTo = Gültig bis + CertThumbprint = SHA-256-Fingerabdruck + TableHostCertificate = Host-Zertifikat - {0} + HostCertificateError = Fehler beim Erfassen der Host-Zertifikatsinformationen für {0}. {1} + LogDir = Protokollverzeichnis + LogRotations = Protokollrotationen + LogSize = Protokollgröße (KB) +'@ + +# Get-AbrVSphereVMHostStorage +GetAbrVSphereVMHostStorage = ConvertFrom-StringData @' + Collecting = VMHost-Speicher-Informationen werden gesammelt. + SectionHeading = Speicher + DatastoreSpecs = Datenspeicher-Spezifikationen + Datastore = Datenspeicher + DatastoreType = Typ + DatastoreCapacity = Kapazität (GB) + DatastoreFreeSpace = Freier Speicherplatz (GB) + DatastoreState = Status + DatastoreShared = Freigegeben + StorageAdapters = Speicheradapter + AdapterName = Adapter + AdapterType = Typ + AdapterDriver = Treiber + AdapterUID = UID + AdapterModel = Modell + AdapterStatus = Status + AdapterSASAddress = SAS-Adresse + AdapterWWN = WWN + AdapterDevices = Geräte + AdapterTargets = Ziele + ParagraphSummary = Der folgende Abschnitt enthält Details zur Speicherkonfiguration des Hosts {0}. + FC = Fibre Channel + iSCSI = iSCSI + ParallelSCSI = Paralleles SCSI + ChapNone = Keine + ChapUniPreferred = Unidirektionales CHAP verwenden, sofern vom Ziel nicht untersagt + ChapUniRequired = Unidirektionales CHAP verwenden, wenn vom Ziel erforderlich + ChapUnidirectional = Unidirektionales CHAP verwenden + ChapBidirectional = Bidirektionales CHAP verwenden + Online = Online + Offline = Offline + Type = Type + Version = Version + NumberOfVMs = # of VMs + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + TableDatastores = Datastores - {0} + ParagraphStorageAdapters = The following section details the storage adapter configuration for {0}. + AdapterPaths = Paths + iSCSIName = iSCSI Name + iSCSIAlias = iSCSI Alias + AdapterSpeed = Speed + DynamicDiscovery = Dynamic Discovery + StaticDiscovery = Static Discovery + AuthMethod = Authentication Method + CHAPOutgoing = Outgoing CHAP Name + CHAPIncoming = Incoming CHAP Name + AdvancedOptions = Advanced Options + NodeWWN = Node WWN + PortWWN = Port WWN + TableStorageAdapter = Storage Adapter {0} - {1} +'@ + +# Get-AbrVSphereVMHostNetwork +GetAbrVSphereVMHostNetwork = ConvertFrom-StringData @' + Collecting = VMHost-Netzwerk-Informationen werden gesammelt. + SectionHeading = Netzwerk + NetworkConfig = Netzwerkkonfiguration + VMKernelAdapters = VMkernel-Adapter + PhysicalAdapters = Physische Adapter + CDP = Cisco Discovery Protocol + LLDP = Link Layer Discovery Protocol + StandardvSwitches = Standardmäßige virtuelle Switches + AdapterName = Adapter + AdapterMAC = MAC-Adresse + AdapterLinkSpeed = Verbindungsgeschwindigkeit + AdapterDriver = Treiber + AdapterPCIID = PCI-Gerät + AdapterStatus = Status + VMKName = VMkernel-Adapter + VMKIP = IP-Adresse + VMKSubnet = Subnetzmaske + VMKGateway = Standardgateway + VMKMTU = MTU + VMKPortGroup = Portgruppe + VMKVirtualSwitch = Virtueller Switch + VMKDHCPEnabled = DHCP aktiviert + VMKServicesEnabled = Aktivierte Dienste + vSwitch = Virtueller Switch + vSwitchPorts = Gesamtports + vSwitchUsedPorts = Verwendete Ports + vSwitchAvailablePorts = Verfügbare Ports + vSwitchMTU = MTU + vSwitchCDPStatus = CDP-Status + vSwitchSecurity = Sicherheitsrichtlinie + vSwitchFailover = Failover-Richtlinie + vSwitchLoadBalancing = Lastenausgleich + vSwitchPortGroups = Portgruppen + PortGroup = Portgruppe + VLAN = VLAN-ID + ActiveAdapters = Aktive Adapter + StandbyAdapters = Standby-Adapter + UnusedAdapters = Nicht verwendete Adapter + ParagraphSummary = Der folgende Abschnitt enthält Details zur Netzwerkkonfiguration des Hosts {0}. + Enabled = Aktiviert + Disabled = Deaktiviert + Connected = Verbunden + Disconnected = Getrennt + Yes = Ja + No = Nein + Accept = Akzeptieren + Reject = Ablehnen + Supported = Unterstützt + NotSupported = Nicht unterstützt + Inherited = Vererbt + TCPDefault = Standard + TCPProvisioning = Bereitstellung + TCPvMotion = vMotion + TCPNsxOverlay = nsx-overlay + TCPNsxHyperbus = nsx-hyperbus + TCPNotApplicable = Nicht zutreffend + LBSrcId = Route basierend auf der ursprünglichen Port-ID + LBSrcMac = Route basierend auf Source-MAC-Hash + LBIP = Route basierend auf IP-Hash + LBExplicitFailover = Explizites Failover + NFDLinkStatus = Nur Link-Status + NFDBeaconProbing = Beacon-Probing + FullDuplex = Vollduplex + AutoNegotiate = Automatisch verhandeln + Down = Deaktiviert + Host = Host + VirtualSwitches = Virtual Switches + VMkernelGateway = VMkernel Gateway + IPv6 = IPv6 + VMkernelIPv6Gateway = VMkernel IPv6 Gateway + DNSServers = DNS Servers + HostName = Host Name + DomainName = Domain Name + SearchDomain = Search Domain + TableNetworkConfig = Network Configuration - {0} + ParagraphPhysicalAdapters = The following section details the physical network adapter configuration for {0}. + VirtualSwitch = Virtual Switch + ActualSpeedDuplex = Actual Speed, Duplex + ConfiguredSpeedDuplex = Configured Speed, Duplex + WakeOnLAN = Wake on LAN + TablePhysicalAdapter = Physical Adapter {0} - {1} + TablePhysicalAdapters = Physical Adapters - {0} + ParagraphCDP = The following section details the CDP information for {0}. + Status = Status + SystemName = System Name + HardwarePlatform = Hardware Platform + SwitchID = Switch ID + SoftwareVersion = Software Version + ManagementAddress = Management Address + Address = Address + PortID = Port ID + MTU = MTU + TableAdapterCDP = Network Adapter {0} CDP Information - {1} + TableAdaptersCDP = Network Adapter CDP Information - {0} + ParagraphLLDP = The following section details the LLDP information for {0}. + ChassisID = Chassis ID + TimeToLive = Time to live + TimeOut = TimeOut + Samples = Samples + PortDescription = Port Description + SystemDescription = System Description + TableAdapterLLDP = Network Adapter {0} LLDP Information - {1} + TableAdaptersLLDP = Network Adapter LLDP Information - {0} + ParagraphVMKernelAdapters = The following section details the VMkernel adapter configuration for {0}. + NetworkLabel = Network Label + TCPIPStack = TCP/IP Stack + DHCP = DHCP + IPAddress = IP Address + SubnetMask = Subnet Mask + DefaultGateway = Default Gateway + vMotion = vMotion + Provisioning = Provisioning + FTLogging = FT Logging + Management = Management + vSphereReplication = vSphere Replication + vSphereReplicationNFC = vSphere Replication NFC + vSAN = vSAN + vSANWitness = vSAN Witness + vSphereBackupNFC = vSphere Backup NFC + TableVMKernelAdapter = VMkernel Adapter {0} - {1} + ParagraphStandardvSwitches = The following section details the standard virtual switch configuration for {0}. + NumberOfPorts = Number of Ports + NumberOfPortsAvailable = Number of Ports Available + TableStandardvSwitches = Standard Virtual Switches - {0} + VSSecurity = Virtual Switch Security + PromiscuousMode = Promiscuous Mode + MACAddressChanges = MAC Address Changes + ForgedTransmits = Forged Transmits + TableVSSecurity = Virtual Switch Security Policy - {0} + VSTrafficShaping = Virtual Switch Traffic Shaping + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + TableVSTrafficShaping = Virtual Switch Traffic Shaping Policy - {0} + VSTeamingFailover = Virtual Switch Teaming & Failover + LoadBalancing = Load Balancing + NetworkFailureDetection = Network Failure Detection + NotifySwitches = Notify Switches + Failback = Failback + ActiveNICs = Active NICs + StandbyNICs = Standby NICs + UnusedNICs = Unused NICs + TableVSTeamingFailover = Virtual Switch Teaming & Failover - {0} + VSPortGroups = Virtual Switch Port Groups + NumberOfVMs = # of VMs + TableVSPortGroups = Virtual Switch Port Groups - {0} + VSPGSecurity = Virtual Switch Port Group Security + MACChanges = MAC Changes + TableVSPGSecurity = Virtual Switch Port Group Security Policy - {0} + VSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping + TableVSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping Policy - {0} + VSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover + TableVSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover - {0} +'@ + +# Get-AbrVSphereVMHostSecurity +GetAbrVSphereVMHostSecurity = ConvertFrom-StringData @' + Collecting = VMHost-Sicherheits-Informationen werden gesammelt. + SectionHeading = Sicherheit + LockdownMode = Sperrmodus + Services = Dienste + ServiceName = Dienst + ServiceRunning = Wird ausgeführt + ServicePolicy = Startrichtlinie + ServiceRequired = Erforderlich + Firewall = Firewall + FirewallRule = Regel + FirewallAllowed = Erlaubte Hosts + Authentication = Authentifizierung + Domain = Domäne + Trust = Vertrauenswürdige Domänen + Membership = Domänenmitgliedschaft + VMInfoSection = Virtuelle Maschinen + VMName = Virtuelle Maschine + VMPowerState = Energiezustand + VMIPAddress = IP-Adresse + VMOS = Betriebssystem + VMGuestID = Gast-ID + VMCPUs = CPUs + VMMemoryGB = Arbeitsspeicher (GB) + VMDisks = Festplatten (GB) + VMNICs = NICs + StartupShutdown = VM-Start/Herunterfahren + StartupEnabled = Start aktiviert + StartupOrder = Startreihenfolge + StartupDelay = Startverzögerung + StopAction = Stoppaktion + StopDelay = Stoppverzögerung + WaitForHeartbeat = Auf Heartbeat warten + ParagraphSummary = Der folgende Abschnitt enthält Details zur Sicherheitskonfiguration des Hosts {0}. + LockdownDisabled = Deaktiviert + LockdownNormal = Aktiviert (Normal) + LockdownStrict = Aktiviert (Streng) + Running = Wird ausgeführt + Stopped = Gestoppt + SvcPortUsage = Mit Portnutzung starten und stoppen + SvcWithHost = Mit Host starten und stoppen + SvcManually = Manuell starten und stoppen + On = Ein + Off = Aus + Enabled = Aktiviert + Disabled = Deaktiviert + WaitHeartbeat = Fortfahren wenn VMware Tools gestartet + WaitDelay = Auf Startverzögerung warten + PowerOff = Ausschalten + GuestShutdown = Gast herunterfahren + ToolsOld = Veraltet + ToolsOK = OK + ToolsNotRunning = Wird nicht ausgeführt + ToolsNotInstalled = Nicht installiert + TableLockdownMode = Lockdown Mode - {0} + TableServices = Services - {0} + FirewallService = Service + Status = Status + IncomingPorts = Incoming Ports + OutgoingPorts = Outgoing Ports + Protocols = Protocols + Daemon = Daemon + TableFirewall = Firewall Configuration - {0} + DomainMembership = Domain Membership + TrustedDomains = Trusted Domains + TableAuthentication = Authentication Services - {0} + ParagraphVMInfo = The following section details the virtual machine configuration for {0}. + VMProvisioned = Provisioned + VMUsed = Used + VMHWVersion = HW Version + VMToolsStatus = VM Tools Status + TableVMs = Virtual Machines - {0} + TableStartupShutdown = VM Startup/Shutdown Policy - {0} + TpmEncryption = TPM & Verschlüsselung + TpmPresent = TPM vorhanden + TpmStatus = TPM-Attestierungsstatus + EncryptionMode = Verschlüsselungsmodus + RequireSecureBoot = Sicheres Booten erforderlich + RequireSignedVIBs = Ausführbare Dateien nur von installierten VIBs + RecoveryKeys = Verschlüsselungs-Wiederherstellungsschlüssel + RecoveryID = Wiederherstellungs-ID + RecoveryKey = Wiederherstellungsschlüssel + TpmEncryptionError = TPM- und Verschlüsselungsinformationen für Host {0} konnten nicht abgerufen werden. {1} + TableTpmEncryption = TPM & Verschlüsselung - {0} + TableRecoveryKeys = Verschlüsselungs-Wiederherstellungsschlüssel - {0} + Yes = Ja + No = Nein +'@ + +# Get-AbrVSphereNetwork +GetAbrVSphereNetwork = ConvertFrom-StringData @' + InfoLevel = Netzwerk-Informationsebene auf {0} gesetzt. + Collecting = Informationen über verteilte Switches werden gesammelt. + Processing = Verteilter Switch '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Verteilte Switches + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der verteilten Switches, die vom vCenter Server {0} verwaltet werden. + VDSwitch = Verteilter Switch + Datacenter = Rechenzentrum + Manufacturer = Hersteller + NumUplinks = Anzahl Uplinks + NumPorts = Anzahl Ports + NumHosts = Anzahl Hosts + NumVMs = Anzahl VMs + Version = Version + MTU = MTU + ID = ID + NumberOfUplinks = Anzahl der Uplinks + NumberOfPorts = Anzahl der Ports + NumberOfPortGroups = Anzahl der Portgruppen + NumberOfHosts = Anzahl der Hosts + NumberOfVMs = Anzahl der VMs + Hosts = Hosts + VirtualMachines = Virtuelle Maschinen + NIOC = Netzwerk-E/A-Steuerung + DiscoveryProtocol = Erkennungsprotokoll + DiscoveryOperation = Erkennungsvorgang + NumPortGroups = Anzahl Portgruppen + MaxPorts = Maximale Ports + Contact = Kontakt + Location = Standort + VDPortGroups = Verteilte Portgruppen + PortGroup = Portgruppe + PortGroupType = Portgruppentyp + VLANID = VLAN-ID + VLANConfiguration = VLAN-Konfiguration + PortBinding = Portbindung + Host = Host + UplinkName = Uplink-Name + UplinkPortGroup = Uplink-Portgruppe + PhysicalNetworkAdapter = Physischer Netzwerkadapter + ActiveUplinks = Aktive Uplinks + StandbyUplinks = Standby-Uplinks + UnusedUplinks = Nicht verwendete Uplinks + AllowPromiscuous = Promiskuitätsmodus erlauben + ForgedTransmits = Gefälschte Übertragungen + MACAddressChanges = MAC-Adressänderungen + Accept = Akzeptieren + Reject = Ablehnen + Direction = Richtung + Status = Status + AverageBandwidth = Durchschnittliche Bandbreite (kbit/s) + PeakBandwidth = Spitzenbandbreite (kbit/s) + BurstSize = Burst-Größe (KB) + LoadBalancing = Lastausgleich + LoadBalanceSrcId = Route basierend auf der ursprünglichen Port-ID + LoadBalanceSrcMac = Route basierend auf Source-MAC-Hash + LoadBalanceIP = Route basierend auf IP-Hash + ExplicitFailover = Explizites Failover + NetworkFailureDetection = Netzwerkfehler-Erkennung + LinkStatus = Nur Link-Status + BeaconProbing = Beacon-Probing + NotifySwitches = Switches benachrichtigen + FailbackEnabled = Failback aktiviert + Yes = Ja + No = Nein + PrimaryVLANID = Primäre VLAN-ID + PrivateVLANType = Privater VLAN-Typ + SecondaryVLANID = Sekundäre VLAN-ID + UplinkPorts = Uplink-Ports des verteilten Switches + VDSSecurity = Sicherheit des verteilten Switches + VDSTrafficShaping = Datenverkehrsformung des verteilten Switches + VDSPortGroups = Portgruppen des verteilten Switches + VDSPortGroupSecurity = Sicherheit der Portgruppe des verteilten Switches + VDSPortGroupTrafficShaping = Datenverkehrsformung der Portgruppe des verteilten Switches + VDSPortGroupTeaming = Teaming und Failover der Portgruppe des verteilten Switches + VDSPrivateVLANs = Private VLANs des verteilten Switches + Enabled = Aktiviert + Disabled = Deaktiviert + Listen = Lauschen + Advertise = Ankündigen + Both = Beides + TableVDSSummary = Übersicht des verteilten Switches - {0} + TableVDSGeneral = Allgemeine Eigenschaften des verteilten Switches - {0} + TableVDSUplinkPorts = Uplink-Ports des verteilten Switches - {0} + TableVDSSecurity = Sicherheit des verteilten Switches - {0} + TableVDSTrafficShaping = Datenverkehrsformung des verteilten Switches - {0} + TableVDSPortGroups = Portgruppen des verteilten Switches - {0} + TableVDSPortGroupSecurity = Sicherheit der Portgruppe des verteilten Switches - {0} + TableVDSPortGroupTrafficShaping = Datenverkehrsformung der Portgruppe des verteilten Switches - {0} + TableVDSPortGroupTeaming = Teaming und Failover der Portgruppe des verteilten Switches - {0} + TableVDSPrivateVLANs = Private VLANs des verteilten Switches - {0} + VDSLACP = LACP des verteilten Switches + LACPEnabled = LACP aktiviert + LACPMode = LACP-Modus + LACPActive = Aktiv + LACPPassive = Passiv + VDSNetFlow = NetFlow des verteilten Switches + CollectorIP = Collector-IP-Adresse + CollectorPort = Collector-Port + ActiveFlowTimeout = Aktiver Flow-Timeout (s) + IdleFlowTimeout = Inaktiver Flow-Timeout (s) + SamplingRate = Abtastrate + InternalFlowsOnly = Nur interne Flows + NIOCResourcePools = Netzwerk-E/A-Steuerungs-Ressourcenpools + NIOCResourcePool = Ressourcenpool + NIOCSharesLevel = Freigaben-Ebene + NIOCSharesValue = Freigaben + NIOCLimitMbps = Limit (Mbps) + Unlimited = Unbegrenzt + TableVDSLACP = LACP des verteilten Switches - {0} + TableVDSNetFlow = NetFlow des verteilten Switches - {0} + TableNIOCResourcePools = Netzwerk-E/A-Steuerungs-Ressourcenpools - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSpherevSAN +GetAbrVSpherevSAN = ConvertFrom-StringData @' + InfoLevel = vSAN-Informationsebene auf {0} gesetzt. + Collecting = vSAN-Informationen werden gesammelt. + CollectingESA = vSAN ESA-Informationen für '{0}' werden gesammelt. + CollectingOSA = vSAN OSA-Informationen für '{0}' werden gesammelt. + CollectingDisks = vSAN-Festplatteninformationen für '{0}' werden gesammelt. + CollectingDiskGroups = vSAN-Festplattengruppeninformationen für '{0}' werden gesammelt. + CollectingiSCSITargets = vSAN-iSCSI-Zielinformationen für '{0}' werden gesammelt. + CollectingiSCSILUNs = vSAN-iSCSI-LUN-Informationen für '{0}' werden gesammelt. + Processing = vSAN-Cluster '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = vSAN + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration von VMware vSAN, das vom vCenter Server {0} verwaltet wird. + ParagraphDetail = Die folgende Tabelle beschreibt die vSAN-Konfiguration für Cluster {0}. + DisksSection = Festplatten + DiskGroupsSection = Festplattengruppen + iSCSITargetsSection = iSCSI-Ziele + iSCSILUNsSection = iSCSI-LUNs + Cluster = Cluster + StorageType = Speichertyp + ClusterType = Clustertyp + NumHosts = Anzahl Hosts + ID = ID + NumberOfHosts = Anzahl der Hosts + NumberOfDisks = Anzahl der Festplatten + NumberOfDiskGroups = Anzahl der Festplattengruppen + DiskClaimMode = Festplattenanforderungsmodus + PerformanceService = Leistungsdienst + FileService = Dateidienst + iSCSITargetService = iSCSI-Zieldienst + HistoricalHealthService = Verlaufsstatusdienst + HealthCheck = Statusprüfung + TotalCapacity = Gesamtkapazität + UsedCapacity = Verwendete Kapazität + FreeCapacity = Freie Kapazität + PercentUsed = % verwendet + HCLLastUpdated = HCL zuletzt aktualisiert + Hosts = Hosts + Version = Version + Stretched = Gestreckter Cluster + VSANEnabled = vSAN aktiviert + VSANESAEnabled = vSAN ESA aktiviert + DisksFormat = Festplattenformatversion + Deduplication = Deduplizierung und Komprimierung + AllFlash = All-Flash + FaultDomains = Fehlerdomänen + PFTT = Zu tolerierende primäre Fehler + SFTT = Zu tolerierende sekundäre Fehler + NetworkDiagnosticMode = Netzwerkdiagnosemodus + HybridMode = Hybridmodus + AutoRebalance = Automatisches Neuausgleichen + ProactiveDisk = Proaktives Neuausgleichen von Festplatten + ResyncThrottle = Resynchronisierungsdrosselung + SpaceEfficiency = Speichereffizienz + Encryption = Verschlüsselung + FileServiceEnabled = Dateidienst aktiviert + iSCSITargetEnabled = iSCSI-Ziel aktiviert + VMHostSpecs = VMHost vSAN-Spezifikationen + VMHost = VMHost + DiskGroup = Festplattengruppe + CacheDisks = Cache-Festplatten + DataDisks = Datenfestplatten + DiskGroups = Festplattengruppen + CacheTier = Cache-Ebene + DataTier = Daten-Ebene + Status = Status + FaultDomainName = Fehlerdomäne + VSANAdvancedOptions = Erweiterte vSAN-Konfigurationsoptionen + Key = Schlüssel + Value = Wert + IDs = Identifikatoren + VSAN_UUID = vSAN-UUID + CapacityTier = Kapazitätsebene (GB) + BufferTier = Pufferebene (GB) + DiskName = Festplatte + Name = Name + DriveType = Laufwerkstyp + Host = Host + State = Status + Encrypted = Verschlüsselt + Capacity = Kapazität + SerialNumber = Seriennummer + Vendor = Hersteller + Model = Modell + DiskType = Festplattentyp + DiskFormatVersion = Festplattenformatversion + ClaimedAs = Beansprucht als + NumDisks = Anzahl Festplatten + Type = Typ + IQN = IQN + Alias = Alias + LUNsCount = LUNs + NetworkInterface = Netzwerkschnittstelle + IOOwnerHost = E/A-Eigentümer-Host + TCPPort = TCP-Port + Health = Zustand + StoragePolicy = Speicherrichtlinie + ComplianceStatus = Compliance-Status + Authentication = Authentifizierung + LUNName = LUN + LUNID = LUN-ID + Yes = Ja + No = Nein + Enabled = Aktiviert + Disabled = Deaktiviert + Online = Online + Offline = Offline + Mounted = Eingehängt + Unmounted = Ausgehängt + Flash = Flash + HDD = HDD + Cache = Cache + TableVSANClusterSummary = vSAN-Cluster-Zusammenfassung - {0} + TableVSANConfiguration = vSAN-Konfiguration - {0} + TableDisk = Festplatte {0} - {1} + TableVSANDisks = vSAN-Festplatten - {0} + TableVSANDiskGroups = vSAN-Festplattengruppen - {0} + TableVSANiSCSITargets = vSAN-iSCSI-Ziele - {0} + TableVSANiSCSILUNs = vSAN-iSCSI-LUNs - {0} + ESAError = Fehler beim Sammeln von vSAN ESA-Informationen für '{0}'. {1} + OSAError = Fehler beim Sammeln von vSAN OSA-Informationen für '{0}'. {1} + DiskError = Fehler beim Sammeln von vSAN-Festplatteninformationen für '{0}'. {1} + DiskGroupError = Fehler beim Sammeln von vSAN-Festplattengruppeninformationen für '{0}'. {1} + iSCSITargetError = Fehler beim Sammeln von vSAN-iSCSI-Zielinformationen für '{0}'. {1} + iSCSILUNError = Fehler beim Sammeln von vSAN-iSCSI-LUN-Informationen für '{0}'. {1} + ServicesSection = vSAN-Dienste + Service = Dienst + TableVSANServices = vSAN-Dienste - {0} + ServicesError = Fehler beim Sammeln von vSAN-Dienstinformationen für '{0}'. {1} +'@ + +# Get-AbrVSphereDatastore +GetAbrVSphereDatastore = ConvertFrom-StringData @' + InfoLevel = Datenspeicher-Informationsebene auf {0} gesetzt. + Collecting = Datenspeicher-Informationen werden gesammelt. + Processing = Datenspeicher '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Datenspeicher + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der Datenspeicher, die vom vCenter Server {0} verwaltet werden. + Datastore = Datenspeicher + Type = Typ + DatastoreURL = URL + FileSystem = Dateisystemversion + CapacityGB = Gesamtkapazität (GB) + FreeSpaceGB = Freier Speicherplatz (GB) + UsedSpaceGB = Verwendeter Speicherplatz (GB) + State = Status + Accessible = Zugänglich + NumHosts = Anzahl Hosts + NumVMs = Anzahl VMs + SIOC = Speicher-E/A-Steuerung + IOLatencyThreshold = E/A-Latenzschwellenwert (ms) + IOLoadBalancing = E/A-Lastenausgleich + Enabled = Aktiviert + Disabled = Deaktiviert + Normal = Normal + Maintenance = Wartung + Unmounted = Ausgehängt + ID = ID + Datacenter = Rechenzentrum + Version = Version + NumberOfHosts = Anzahl der Hosts + NumberOfVMs = Anzahl der VMs + CongestionThreshold = Überlastungsschwelle + TotalCapacity = Gesamtkapazität + UsedCapacity = Verwendete Kapazität + FreeCapacity = Freie Kapazität + PercentUsed = % verwendet + Hosts = Hosts + VirtualMachines = Virtuelle Maschinen + SCSILUNInfo = SCSI-LUN-Informationen + Host = Host + CanonicalName = Kanonischer Name + Capacity = Kapazität + Vendor = Hersteller + Model = Modell + IsSSD = Ist SSD + MultipathPolicy = Multipath-Richtlinie + Paths = Pfade + TableDatastoreSummary = Datenspeicher-Übersicht - {0} + TableDatastoreConfig = Datenspeicher-Konfiguration - {0} + TableSCSILUN = SCSI-LUN-Informationen - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSphereDSCluster +GetAbrVSphereDSCluster = ConvertFrom-StringData @' + InfoLevel = Datenspeicher-Cluster-Informationsebene auf {0} gesetzt. + Collecting = Datenspeicher-Cluster-Informationen werden gesammelt. + Processing = Datenspeicher-Cluster '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Datenspeicher-Cluster + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der Datenspeicher-Cluster, die vom vCenter Server {0} verwaltet werden. + DSCluster = Datenspeicher-Cluster + Datacenter = Rechenzentrum + CapacityGB = Gesamtkapazität (GB) + FreeSpaceGB = Freier Speicherplatz (GB) + SDRSEnabled = SDRS + SDRSAutomationLevel = SDRS-Automatisierungsebene + IOLoadBalancing = E/A-Lastenausgleich + SpaceThreshold = Speicherschwellenwert (%) + IOLatencyThreshold = E/A-Latenzschwellenwert (ms) + SDRSRules = SDRS-Regeln + RuleName = Regel + RuleEnabled = Aktiviert + RuleVMs = Virtuelle Maschinen + FullyAutomated = Vollautomatisch + NoAutomation = Keine Automatisierung (Manueller Modus) + Manual = Manuell + Enabled = Aktiviert + Disabled = Deaktiviert + Yes = Ja + No = Nein + ID = ID + TotalCapacity = Gesamtkapazität + UsedCapacity = Verwendete Kapazität + FreeCapacity = Freie Kapazität + PercentUsed = % verwendet + ParagraphDSClusterDetail = Die folgende Tabelle enthält Details zur Konfiguration des Datenspeicher-Clusters {0}. + TableDSClusterConfig = Datenspeicher-Cluster-Konfiguration - {0} + TableSDRSVMOverrides = SDRS-VM-Überschreibungen - {0} + SDRSVMOverrides = SDRS-VM-Überschreibungen + VirtualMachine = Virtuelle Maschine + KeepVMDKsTogether = VMDKs zusammenhalten + DefaultBehavior = Standard ({0}) + RuleType = Typ + RuleAffinity = Affinität + RuleAntiAffinity = Anti-Affinität + TableSDRSRules = SDRS-Regeln - {0} + SpaceLoadBalanceConfig = Konfiguration des Speicher-Lastenausgleichs + SpaceMinDiff = Minimaler Unterschied der Speicherauslastung (%) + SpaceThresholdMode = Speicherschwellenwert-Modus + UtilizationMode = Auslastungsschwellenwert + FreeSpaceMode = Freispeicherschwellenwert + UtilizationThreshold = Speicherauslastungsschwellenwert (%) + FreeSpaceThreshold = Freispeicherschwellenwert (GB) + IOLoadBalanceConfig = Konfiguration des E/A-Lastenausgleichs + IOCongestionThreshold = E/A-Überlastungsschwellenwert (ms) + IOReservationMode = Reservierungsschwellenwert-Modus + IOPSThresholdMode = Anzahl der E/A-Operationen + ReservationMbpsMode = Reservierung in Mbps + ReservationIopsMode = Reservierung in IOPS + TableSpaceLoadBalance = Konfiguration des Speicher-Lastenausgleichs - {0} + TableIOLoadBalance = Konfiguration des E/A-Lastenausgleichs - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSphereVM +GetAbrVSphereVM = ConvertFrom-StringData @' + InfoLevel = VM-Informationsebene auf {0} gesetzt. + Collecting = Informationen über virtuelle Maschinen werden gesammelt. + Processing = Virtuelle Maschine '{0}' wird verarbeitet ({1}/{2}). + SectionHeading = Virtuelle Maschinen + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration der virtuellen Maschinen, die vom vCenter Server {0} verwaltet werden. + VirtualMachine = Virtuelle Maschine + PowerState = Energiezustand + Template = Vorlage + OS = Betriebssystem + Version = VM-Hardwareversion + GuestID = Gast-ID + Cluster = Cluster + ResourcePool = Ressourcenpool + VMHost = Host + Folder = Ordner + IPAddress = IP-Adresse + CPUs = CPUs + MemoryGB = Arbeitsspeicher (GB) + ProvisionedGB = Bereitgestellt (GB) + UsedGB = Verwendet (GB) + NumDisks = Anzahl Festplatten + NumNICs = Anzahl NICs + NumSnapshots = Anzahl Snapshots + VMwareTools = VMware Tools + ToolsVersion = Tools-Version + ToolsStatus = Tools-Status + ToolsRunningStatus = Tools-Ausführungsstatus + VMAdvancedDetail = Erweiterte Konfiguration + BootOptions = Startoptionen + BootDelay = Startverzögerung (ms) + BootRetryEnabled = Startwiederholung aktiviert + BootRetryDelay = Wiederholungsverzögerung (ms) + EFISecureBoot = EFI Secure Boot + EnterBIOSSetup = BIOS-Setup beim nächsten Start aufrufen + HardDisks = Festplatten + DiskName = Festplatte + DiskCapacityGB = Kapazität (GB) + DiskFormat = Format + DiskStoragePolicy = Speicherrichtlinie + DiskDatastore = Datenspeicher + DiskController = Controller + NetworkAdapters = Netzwerkadapter + NICName = Netzwerkadapter + NICType = Adaptertyp + NICPortGroup = Portgruppe + NICMAC = MAC-Adresse + NICConnected = Verbunden + NICConnectionPolicy = Bei Einschalten verbinden + SnapshotHeading = Snapshots + SnapshotName = Snapshot + SnapshotDescription = Beschreibung + SnapshotSize = Größe (GB) + SnapshotDate = Erstellt + SnapshotParent = Übergeordnet + On = Ein + Off = Aus + ToolsOld = Veraltet + ToolsOK = OK + ToolsNotRunning = Wird nicht ausgeführt + ToolsNotInstalled = Nicht installiert + Yes = Ja + No = Nein + Connected = Verbunden + NotConnected = Nicht verbunden + Thin = Thin + Thick = Thick + Enabled = Aktiviert + Disabled = Deaktiviert + TotalVMs = Gesamt VMs + TotalvCPUs = Gesamt vCPUs + TotalMemory = Gesamtspeicher + TotalProvisionedSpace = Gesamt bereitgestellter Speicherplatz + TotalUsedSpace = Gesamt verwendeter Speicherplatz + VMsPoweredOn = Eingeschaltete VMs + VMsPoweredOff = Ausgeschaltete VMs + VMsOrphaned = Verwaiste VMs + VMsInaccessible = Nicht zugängliche VMs + VMsSuspended = Angehaltene VMs + VMsWithSnapshots = VMs mit Snapshots + GuestOSTypes = Gastbetriebssystemtypen + VMToolsOKCount = VM Tools OK + VMToolsOldCount = VM Tools veraltet + VMToolsNotRunningCount = VM Tools wird nicht ausgeführt + VMToolsNotInstalledCount = VM Tools nicht installiert + vCPUs = vCPUs + Memory = Arbeitsspeicher + Provisioned = Bereitgestellt + Used = Verwendet + HWVersion = HW-Version + VMToolsStatus = VM Tools Status + ID = ID + OperatingSystem = Betriebssystem + HardwareVersion = Hardwareversion + ConnectionState = Verbindungsstatus + FaultToleranceState = Fehlertoleranzstatus + FTNotConfigured = Nicht konfiguriert + FTNeedsSecondary = Sekundäres erforderlich + FTRunning = Wird ausgeführt + FTDisabled = Deaktiviert + FTStarting = Wird gestartet + FTEnabled = Aktiviert + Parent = Übergeordnet + ParentFolder = Übergeordneter Ordner + ParentResourcePool = Übergeordneter Ressourcenpool + CoresPerSocket = Kerne pro Socket + CPUShares = CPU-Anteile + CPUReservation = CPU-Reservierung + CPULimit = CPU-Limit + CPUHotAdd = CPU-Hot-Add + CPUHotRemove = CPU-Hot-Remove + MemoryAllocation = Speicherzuweisung + MemoryShares = Speicheranteile + MemoryHotAdd = Speicher-Hot-Add + vNICs = vNICs + DNSName = DNS-Name + Networks = Netzwerke + MACAddress = MAC-Adresse + vDisks = Virtuelle Festplatten + ProvisionedSpace = Bereitgestellter Speicherplatz + UsedSpace = Verwendeter Speicherplatz + ChangedBlockTracking = Geändertes Block-Tracking + StorageBasedPolicy = Speicherbasierte Richtlinie + StorageBasedPolicyCompliance = Konformität der speicherbasierten Richtlinie + Compliant = Konform + NonCompliant = Nicht konform + Unknown = Unbekannt + Notes = Notizen + BootTime = Startzeit + UptimeDays = Betriebstage + NetworkName = Netzwerkname + SCSIControllers = SCSI-Controller + Device = Gerät + ControllerType = Controller-Typ + BusSharing = Bus-Sharing + None = Keine + GuestVolumes = Gast-Volumes + Capacity = Kapazität + DiskProvisioning = Festplatten-Bereitstellung + ThickEagerZeroed = Thick Eager Zeroed + ThickLazyZeroed = Thick Lazy Zeroed + DiskType = Festplattentyp + PhysicalRDM = Physisches RDM + VirtualRDM = Virtuelles RDM + VMDK = VMDK + DiskMode = Festplattenmodus + IndependentPersistent = Unabhängig - Persistent + IndependentNonpersistent = Unabhängig - Nicht persistent + Dependent = Abhängig + DiskPath = Festplattenpfad + DiskShares = Festplatten-Anteile + DiskLimitIOPs = Festplatten-IOPS-Limit + Unlimited = Unbegrenzt + SCSIController = SCSI-Controller + SCSIAddress = SCSI-Adresse + Path = Pfad + FreeSpace = Freier Speicherplatz + DaysOld = Alter in Tagen + TableVMSummary = VM-Übersicht - {0} + TableVMAdvancedSummary = Erweiterte VM-Übersicht - {0} + TableVMSnapshotSummary = Snapshot-Übersicht der VMs - {0} + TableVMConfig = VM-Konfiguration - {0} + TableVMNetworkAdapters = Netzwerkadapter - {0} + TableVMSCSIControllers = SCSI-Controller - {0} + TableVMHardDiskConfig = Festplattenkonfiguration - {0} + TableVMHardDisk = {0} - {1} + TableVMGuestVolumes = Gast-Volumes - {0} + TableVMSnapshots = VM-Snapshots - {0} + VUMCompliance = VM Update Manager-Compliance + VUMBaselineName = Baseline + VUMStatus = Status + NotCompliant = Nicht konform + Incompatible = Inkompatibel + VUMComplianceError = Unable to retrieve VUM compliance information for virtual machines. + InsufficientPrivVUMCompliance = Insufficient privileges to collect VUM compliance information for virtual machines. + TableVUMCompliance = VUM-Baseline-Compliance - {0} + Tags = Schlagwörter +'@ + +# Get-AbrVSphereVUM +GetAbrVSphereVUM = ConvertFrom-StringData @' + InfoLevel = VUM-Informationsebene auf {0} gesetzt. + Collecting = VMware Update Manager-Informationen werden gesammelt. + NotAvailable = VUM-Patch-Baseline-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + PatchNotAvailable = VUM-Patch-Informationen sind mit Ihrer PowerShell-Version derzeit nicht verfügbar. + SectionHeading = VMware Update Manager + ParagraphSummary = Die folgenden Abschnitte beschreiben die Konfiguration von VMware Update Manager, der vom vCenter Server {0} verwaltet wird. + Baselines = Baselines + BaselineName = Baseline + Description = Beschreibung + Type = Typ + TargetType = Zieltyp + LastUpdate = Letzte Aktualisierungszeit + NumPatches = Anzahl Patches + Patches = Patches + PatchName = Patch + PatchProduct = Produkt + PatchDescription = Beschreibung + PatchReleaseDate = Veröffentlichungsdatum + PatchVendorID = Hersteller-ID + TableVUMBaselines = VMware Update Manager Baseline-Zusammenfassung - {0} + TableVUMPatches = VMware Update Manager Patch-Informationen - {0} + SoftwareDepots = Software-Depots + OnlineDepots = Online-Depots + OfflineDepots = Offline-Depots + DepotUrl = URL + SystemDefined = Systemdefiniert + DepotEnabled = Aktiviert + DepotLocation = Speicherort + DepotError = Software-Depot-Informationen konnten nicht abgerufen werden. {0} + TableOnlineDepots = Online-Software-Depots - {0} + TableOfflineDepots = Offline-Software-Depots - {0} +'@ + +# Get-AbrVSphereClusterLCM +GetAbrVSphereClusterLCM = ConvertFrom-StringData @' + Collecting = Lifecycle Manager-Informationen werden gesammelt. + ImageComposition = Image-Komposition + BaseImage = Basis-Image + VendorAddOn = Anbieter-Add-On + None = Keine + Components = Komponenten + ComponentName = Komponente + ComponentVersion = Version + HardwareSupportManager = Hardware-Support-Manager + HsmName = Name + HsmVersion = Version + HsmPackages = Hardware-Support-Pakete + ImageCompliance = Image-Konformität + Cluster = Cluster + VMHost = VMHost + ComplianceStatus = Konformitätsstatus + LcmError = Lifecycle Manager-Informationen für Cluster {0} konnten nicht abgerufen werden. {1} + ComplianceError = Konformitätsinformationen für Cluster {0} konnten nicht abgerufen werden. {1} + TableImageComposition = Image-Komposition - {0} + TableComponents = Image-Komponenten - {0} + TableHardwareSupportManager = Hardware-Support-Manager - {0} + TableImageCompliance = Image-Konformität - {0} + TableHostCompliance = Host-Image-Konformität - {0} +'@ + +} diff --git a/AsBuiltReport.VMware.vSphere/Language/en-GB/VMwarevSphere.psd1 b/AsBuiltReport.VMware.vSphere/Language/en-GB/VMwarevSphere.psd1 new file mode 100644 index 0000000..cb3611b --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Language/en-GB/VMwarevSphere.psd1 @@ -0,0 +1,1625 @@ +# culture = 'en-GB' +@{ + +# Module-wide strings +InvokeAsBuiltReportVMwarevSphere = ConvertFrom-StringData @' + Connecting = Connecting to vCenter Server '{0}'. + CheckPrivileges = Checking vCenter user privileges. + UnablePrivileges = Unable to obtain vCenter user privileges. + VMHashtable = Creating VM lookup hashtable. + VMHostHashtable = Creating VMHost lookup hashtable. + DatastoreHashtable = Creating Datastore lookup hashtable. + VDPortGrpHashtable = Creating VDPortGroup lookup hashtable. + EVCHashtable = Creating EVC lookup hashtable. + CheckVUM = Checking for VMware Update Manager Server. + CheckVxRail = Checking for VxRail Manager Server. + CheckSRM = Checking for VMware Site Recovery Manager Server. + CheckNSXT = Checking for VMware NSX-T Manager Server. + CollectingTags = Collecting tag information. + TagError = Error collecting tag information. + CollectingAdvSettings = Collecting {0} advanced settings. +'@ + +# Get-AbrVSpherevCenter +GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = vCenter InfoLevel set to {0}. + Collecting = Collecting vCenter Server information. + SectionHeading = vCenter Server + ParagraphSummaryBrief = The following sections summarise the configuration of vCenter Server {0}. + ParagraphSummary = The following sections detail the configuration of vCenter Server {0}. + InsufficientPrivLicense = Insufficient user privileges to report vCenter Server licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned. + InsufficientPrivStoragePolicy = Insufficient user privileges to report VM storage policies. Please ensure the user account has the 'Storage Profile > View' privilege assigned. + vCenterServer = vCenter Server + IPAddress = IP Address + Version = Version + Build = Build + Product = Product + LicenseKey = License Key + LicenseExpiration = License Expiration + InstanceID = Instance ID + HTTPPort = HTTP Port + HTTPSPort = HTTPS Port + PSC = Platform Services Controller + UpdateManagerServer = Update Manager Server + SRMServer = Site Recovery Manager Server + NSXTServer = NSX-T Manager Server + VxRailServer = VxRail Manager Server + DatabaseSettings = Database Settings + DatabaseType = Database Type + DataSourceName = Data Source Name + MaxDBConnection = Maximum Database Connection + MailSettings = Mail Settings + SMTPServer = SMTP Server + SMTPPort = SMTP Port + MailSender = Mail Sender + HistoricalStatistics = Historical Statistics + IntervalDuration = Interval Duration + IntervalEnabled = Interval Enabled + SaveDuration = Save Duration + StatisticsLevel = Statistics Level + Licensing = Licensing + Total = Total + Used = Used + Available = Available + Expiration = Expiration + Certificate = Certificate + Subject = Subject + Issuer = Issuer + ValidFrom = Valid From + ValidTo = Valid To + Thumbprint = Thumbprint + CertStatus = Status + InsufficientPrivCertificate = Unable to retrieve vCenter Server certificate. {0} + Mode = Mode + SoftThreshold = Soft Threshold + HardThreshold = Hard Threshold + MinutesBefore = Minutes Before + PollInterval = Poll Interval + Roles = Roles + Role = Role + SystemRole = System Role + PrivilegeList = Privilege List + Tags = Tags + TagName = Name + TagCategory = Category + TagDescription = Description + TagCategories = Tag Categories + TagCardinality = Cardinality + TagAssignments = Tag Assignments + TagEntity = Entity + TagEntityType = Entity Type + VMStoragePolicies = VM Storage Policies + StoragePolicy = Storage Policy + Description = Description + ReplicationEnabled = Replication Enabled + CommonRulesName = Common Rules Name + CommonRulesDescription = Common Rules Description + Alarms = Alarms + Alarm = Alarm + AlarmDescription = Description + AlarmEnabled = Enabled + AlarmTriggered = Triggered + AlarmAction = Action + AdvancedSystemSettings = Advanced System Settings + Key = Key + Value = Value + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + None = None + TablevCenterSummary = vCenter Server Summary - {0} + TablevCenterConfig = vCenter Server Configuration - {0} + TableDatabaseSettings = Database Settings - {0} + TableMailSettings = Mail Settings - {0} + TableHistoricalStatistics = Historical Statistics - {0} + TableLicensing = Licensing - {0} + TableCertificate = Certificate - {0} + TableRole = Role {0} - {1} + TableRoles = Roles - {0} + TableTags = Tags - {0} + TableTagCategories = Tag Categories - {0} + TableTagAssignments = Tag Assignments - {0} + TableVMStoragePolicies = VM Storage Policies - {0} + TableAlarm = {0} - {1} + TableAlarms = Alarms - {0} + TableAdvancedSystemSettings = vCenter Advanced System Settings - {0} + RestApiSessionError = Unable to establish vCenter REST API session. {0} + BackupSettings = Backup Settings + BackupSchedule = Backup Schedule + BackupJobHistory = Backup Job History + BackupNotConfigured = No backup schedule is configured. + BackupNoJobs = No backup jobs found. + BackupApiNotAvailable = vCenter backup status requires vSphere 7.0 or later. + BackupApiError = Unable to retrieve backup information. {0} + BackupScheduleID = Schedule ID + BackupLocation = Location + BackupLocationUser = Location User + BackupEnabled = Status + BackupActivated = Activated + BackupDeactivated = Deactivated + BackupParts = Backup Data + BackupPartSeat = Supervisors Control Plane + BackupPartCommon = Inventory and Configuration + BackupPartStats = Stats, Events, and Tasks + BackupRecurrence = Schedule + BackupRetentionCount = Number of Backups to Retain + BackupDaily = Daily + BackupSendEmail = Email Notification + BackupJobLocation = Backup Location + BackupJobType = Type + BackupJobStatus = Status + BackupJobComplete = Complete + BackupJobScheduled = Scheduled + BackupJobDataTransferred = Data Transferred + BackupJobDuration = Duration + BackupJobEndTime = End Time + TableBackupSchedule = Backup Schedule - {0} + TableBackupJobHistory = Backup Job History - {0} + ResourceSummary = Resources + SummaryResource = Resource + Free = Free + CPU = CPU + Memory = Memory + Storage = Storage + VirtualMachines = Virtual Machines + Hosts = Hosts + PoweredOn = Powered On + PoweredOff = Powered Off + Suspended = Suspended + Connected = Connected + Disconnected = Disconnected + Maintenance = Maintenance + ContentLibraries = Content Libraries + ContentLibrary = Content Library + LibraryType = Type + Datastore = Datastore + LibraryLocal = Local + LibrarySubscribed = Subscribed + ItemCount = Items + SubscriptionUrl = Subscription URL + AutomaticSync = Automatic Synchronisation + OnDemandSync = On-Demand Synchronisation + LibraryItems = Library Items + ItemName = Item + ContentType = Content Type + ItemSize = Size + CreationTime = Creation Time + LastModified = Last Modified + ContentLibraryNoItems = No items found in this content library. + ContentLibraryNone = No content libraries found. + CollectingContentLibrary = Collecting Content Library information. + ContentLibraryError = Unable to retrieve Content Library information. {0} + ContentLibraryItemError = Unable to retrieve items for Content Library '{0}'. {1} + TableContentLibraries = Content Libraries - {0} + TableContentLibrary = Content Library {0} - {1} + TableLibraryItems = Library Items - {0} + TableLibraryItem = {0} - {1} + TablevCenterResourceSummary = Resource Summary - {0} + TablevCenterVMSummary = Virtual Machine Summary - {0} + TablevCenterHostSummary = Host Summary - {0} +'@ + +# Get-AbrVSphereCluster +GetAbrVSphereCluster = ConvertFrom-StringData @' + InfoLevel = Cluster InfoLevel set to {0}. + Collecting = Collecting Cluster information. + Processing = Processing Cluster '{0}' ({1}/{2}). + SectionHeading = Clusters + ParagraphSummary = The following sections detail the configuration of vSphere HA/DRS clusters managed by vCenter Server {0}. + ParagraphDetail = The following table details the configuration for cluster {0}. + Cluster = Cluster + ID = ID + Datacenter = Datacenter + NumHosts = # of Hosts + NumVMs = # of VMs + HAEnabled = vSphere HA + DRSEnabled = vSphere DRS + VSANEnabled = Virtual SAN + EVCMode = EVC Mode + VMSwapFilePolicy = VM Swap File Policy + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + Hosts = Hosts + VirtualMachines = Virtual Machines + Permissions = Permissions + Principal = Principal + Role = Role + Propagate = Propagate + IsGroup = Is Group + Enabled = Enabled + Disabled = Disabled + SwapWithVM = With VM + SwapInHostDatastore = In Host Datastore + SwapVMDirectory = Virtual machine directory + SwapHostDatastore = Datastore specified by host + TableClusterSummary = Cluster Summary - {0} + TableClusterConfig = Cluster Configuration - {0} +'@ + +# Get-AbrVSphereClusterHA +GetAbrVSphereClusterHA = ConvertFrom-StringData @' + Collecting = Collecting Cluster HA information. + SectionHeading = vSphere HA Configuration + ParagraphSummary = The following section details the vSphere HA configuration for {0} cluster. + FailuresAndResponses = Failures and Responses + HostMonitoring = Host Monitoring + HostFailureResponse = Host Failure Response + HostIsolationResponse = Host Isolation Response + VMRestartPriority = VM Restart Priority + PDLProtection = Datastore with Permanent Device Loss + APDProtection = Datastore with All Paths Down + VMMonitoring = VM Monitoring + VMMonitoringSensitivity = VM Monitoring Sensitivity + AdmissionControl = Admission Control + FailoverLevel = Host Failures Cluster Tolerates + ACPolicy = Policy + ACHostPercentage = CPU % + ACMemPercentage = Memory % + PerformanceDegradation = VM Performance Degradation + HeartbeatDatastores = Heartbeat Datastores + Datastore = Datastore + HAAdvancedOptions = vSphere HA Advanced Options + Key = Key + Value = Value + APDRecovery = APD recovery after APD timeout + Disabled = Disabled + Enabled = Enabled + RestartVMs = Restart VMs + ShutdownAndRestart = Shutdown and restart VMs + PowerOffAndRestart = Power off and restart VMs + IssueEvents = Issue events + PowerOffRestartConservative = Power off and restart VMs (conservative) + PowerOffRestartAggressive = Power off and restart VMs (aggressive) + ResetVMs = Reset VMs + VMMonitoringOnly = VM monitoring only + VMAndAppMonitoring = VM and application monitoring + DedicatedFailoverHosts = Dedicated failover hosts + ClusterResourcePercentage = Cluster resource percentage + SlotPolicy = Slot policy + Yes = Yes + No = No + FixedSlotSize = Fixed slot size + CoverAllPoweredOnVMs = Cover all powered-on virtual machines + NoneSpecified = None specified + OverrideFailoverCapacity = Override Calculated Failover Capacity + CPUSlotSize = CPU Slot Size (MHz) + MemorySlotSize = Memory Slot Size (MB) + PerfDegradationTolerate = Performance Degradation VMs Tolerate + HeartbeatSelectionPolicy = Heartbeat Selection Policy + HBPolicyAllFeasibleDsWithUserPreference = Use datastores from the specified list and complement automatically if needed + HBPolicyAllFeasibleDs = Automatically select datastores accessible from the host + HBPolicyUserSelectedDs = Use datastores only from the specified list + TableHAFailures = vSphere HA Failures and Responses - {0} + TableHAAdmissionControl = vSphere HA Admission Control - {0} + TableHAHeartbeat = vSphere HA Heartbeat Datastores - {0} + TableHAAdvanced = vSphere HA Advanced Options - {0} +'@ + +# Get-AbrVSphereClusterProactiveHA +GetAbrVSphereClusterProactiveHA = ConvertFrom-StringData @' + Collecting = Collecting Cluster Proactive HA information. + SectionHeading = Proactive HA + ParagraphSummary = The following section details the Proactive HA configuration for {0} cluster. + FailuresAndResponses = Failures and Responses + Provider = Provider + Remediation = Remediation + HealthUpdates = Health Updates + ProactiveHA = Proactive HA + AutomationLevel = Automation Level + ModerateRemediation = Moderate Remediation + SevereRemediation = Severe Remediation + Enabled = Enabled + Disabled = Disabled + MaintenanceMode = Maintenance Mode + QuarantineMode = Quarantine Mode + MixedMode = Mixed Mode + TableProactiveHA = Proactive HA - {0} + Providers = Providers + HealthUpdateCount = Health Updates + TableProactiveHAProviders = Proactive HA Providers - {0} +'@ + +# Get-AbrVSphereClusterDRS +GetAbrVSphereClusterDRS = ConvertFrom-StringData @' + Collecting = Collecting Cluster DRS information. + SectionHeading = vSphere DRS Configuration + ParagraphSummary = The following table details the vSphere DRS configuration for {0} cluster. + AutomationLevel = DRS Automation Level + MigrationThreshold = Migration Threshold + PredictiveDRS = Predictive DRS + VirtualMachineAutomation = Individual Machine Automation + AdditionalOptions = Additional Options + VMDistribution = VM Distribution + MemoryMetricForLB = Memory Metric for Load Balancing + CPUOverCommitment = CPU Over-Commitment + PowerManagement = Power Management + DPMAutomationLevel = DPM Automation Level + DPMThreshold = DPM Threshold + AdvancedOptions = Advanced Options + Key = Key + Value = Value + DRSClusterGroups = DRS Cluster Groups + GroupName = Group Name + GroupType = Group Type + GroupMembers = Members + DRSVMHostRules = DRS VM/Host Rules + RuleName = Rule Name + RuleType = Rule Type + RuleEnabled = Enabled + VMGroup = VM Group + HostGroup = Host Group + DRSRules = DRS Rules + RuleVMs = Virtual Machines + VMOverrides = VM Overrides + VirtualMachine = Virtual Machine + DRSAutomationLevel = DRS Automation Level + DRSBehavior = DRS Behavior + HARestartPriority = HA Restart Priority + HAIsolationResponse = HA Isolation Response + PDLProtection = Datastore with PDL + APDProtection = Datastore with APD + VMMonitoring = VM Monitoring + VMMonitoringFailureInterval = Failure Interval + VMMonitoringMinUpTime = Minimum Uptime + VMMonitoringMaxFailures = Maximum Failures + VMMonitoringMaxFailureWindow = Maximum Failure Window + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + FullyAutomated = Fully Automated + PartiallyAutomated = Partially Automated + Manual = Manual + Off = Off + DRS = vSphere DRS + DPM = DPM + Automated = Automated + None = None + VMGroupType = VM Group + VMHostGroupType = Host Group + MustRunOn = Must run on hosts in group + ShouldRunOn = Should run on hosts in group + MustNotRunOn = Must not run on hosts in group + ShouldNotRunOn = Should not run on hosts in group + VMAffinity = Keep Virtual Machines Together + VMAntiAffinity = Separate Virtual Machines + Mandatory = Mandatory + OverCommitmentRatio = Over-Commitment Ratio + OverCommitmentRatioCluster = Over-Commitment Ratio (% of cluster capacity) + Lowest = Lowest + Low = Low + Medium = Medium + High = High + Highest = Highest + ClusterDefault = Cluster default + VMDependencyTimeout = VM Dependency Restart Condition Timeout + Seconds = {0} seconds + SectionVSphereHA = vSphere HA + IssueEvents = Issue events + PowerOffAndRestart = Power off and restart VMs + ShutdownAndRestartVMs = Shutdown and restart VMs + PowerOffRestartConservative = Power off and restart VMs - Conservative restart policy + PowerOffRestartAggressive = Power off and restart VMs - Aggressive restart policy + PDLFailureResponse = PDL Failure Response + APDFailureResponse = APD Failure Response + VMFailoverDelay = VM Failover Delay + Minutes = {0} minutes + ResponseRecovery = Response Recovery + ResetVMs = Reset VMs + SectionPDLAPD = PDL/APD Protection Settings + NoWindow = No window + WithinHours = Within {0} hrs + VMMonitoringOnly = VM Monitoring Only + VMAndAppMonitoring = VM and Application Monitoring + UserGroup = User/Group + IsGroup = Is Group? + Role = Role + DefinedIn = Defined In + Propagate = Propagate + Permissions = Permissions + ParagraphPermissions = The following table details the permissions for {0}. + TableDRSConfig = vSphere DRS Configuration - {0} + TableDRSAdditional = DRS Additional Options - {0} + TableDPM = vSphere DPM - {0} + TableDRSAdvanced = vSphere DRS Advanced Options - {0} + TableDRSGroups = DRS Cluster Groups - {0} + TableDRSVMHostRules = DRS VM/Host Rules - {0} + TableDRSRules = DRS Rules - {0} + TableDRSVMOverrides = DRS VM Overrides - {0} + TableHAVMOverrides = HA VM Overrides - {0} + TableHAPDLAPD = HA VM Overrides PDL/APD Settings - {0} + TableHAVMMonitoring = HA VM Overrides VM Monitoring - {0} + TablePermissions = Permissions - {0} +'@ + +# Get-AbrVSphereClusterVUM +GetAbrVSphereClusterVUM = ConvertFrom-StringData @' + UpdateManagerBaselines = Update Manager Baselines + Baseline = Baseline + Description = Description + Type = Type + TargetType = Target Type + LastUpdate = Last Update Time + NumPatches = # of Patches + UpdateManagerCompliance = Update Manager Compliance + Entity = Entity + Status = Compliance Status + BaselineInfo = Baseline + VUMPrivilegeMsgBaselines = Insufficient user privileges to report Cluster baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + VUMPrivilegeMsgCompliance = Insufficient user privileges to report Cluster compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + VUMBaselineNotAvailable = Cluster VUM baseline information is not currently available with your version of PowerShell. + VUMComplianceNotAvailable = Cluster VUM compliance information is not currently available with your version of PowerShell. + NotCompliant = Not Compliant + Unknown = Unknown + Incompatible = Incompatible + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} +'@ + +# Get-AbrVSphereResourcePool +GetAbrVSphereResourcePool = ConvertFrom-StringData @' + InfoLevel = ResourcePool InfoLevel set to {0}. + Collecting = Collecting Resource Pool information. + Processing = Processing Resource Pool '{0}' ({1}/{2}). + SectionHeading = Resource Pools + ParagraphSummary = The following sections detail the configuration of resource pools managed by vCenter Server {0}. + ResourcePool = Resource Pool + Parent = Parent + CPUSharesLevel = CPU Shares Level + CPUReservationMHz = CPU Reservation MHz + CPULimitMHz = CPU Limit MHz + MemSharesLevel = Memory Shares Level + MemReservation = Memory Reservation + MemLimit = Memory Limit + ID = ID + NumCPUShares = Number of CPU Shares + CPUReservation = CPU Reservation + CPUExpandable = CPU Expandable Reservation + NumMemShares = Number of Memory Shares + MemExpandable = Memory Expandable Reservation + NumVMs = Number of VMs + VirtualMachines = Virtual Machines + Enabled = Enabled + Disabled = Disabled + Unlimited = Unlimited + TableResourcePoolSummary = Resource Pool Summary - {0} + TableResourcePoolConfig = Resource Pool Configuration - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVMHost +GetAbrVSphereVMHost = ConvertFrom-StringData @' + InfoLevel = VMHost InfoLevel set to {0}. + Collecting = Collecting VMHost information. + Processing = Processing VMHost '{0}' ({1}/{2}). + SectionHeading = Hosts + ParagraphSummary = The following sections detail the configuration of VMware ESXi hosts managed by vCenter Server {0}. + VMHost = Host + Manufacturer = Manufacturer + Model = Model + ProcessorType = Processor Type + NumCPUSockets = CPU Sockets + NumCPUCores = CPU Cores + NumCPUThreads = CPU Threads + MemoryGB = Memory GB + NumNICs = # NICs + NumHBAs = # HBAs + NumDatastores = # Datastores + NumVMs = # VMs + ConnectionState = Connection State + PowerState = Power State + ErrorCollecting = Error collecting VMHost information using VMHost InfoLevel {0}. + NotResponding = Not Responding + Maintenance = Maintenance + Disconnected = Disconnected + Version = Version + Build = Build + Parent = Parent + TableHostSummary = Host Summary - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVMHostHardware +GetAbrVSphereVMHostHardware = ConvertFrom-StringData @' + Collecting = Collecting VMHost Hardware information. + SectionHeading = Hardware + ParagraphSummary = The following section details the host hardware configuration for {0}. + InsufficientPrivLicense = Insufficient user privileges to report ESXi host licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned. + LicenseError = Unable to retrieve licence information for VMHost '{0}'. Error: {1} + Specifications = Specifications + Manufacturer = Manufacturer + Model = Model + SerialNumber = Serial Number + AssetTag = Asset Tag + ProcessorType = Processor Type + CPUSockets = CPU Sockets + CPUCores = CPU Cores + CPUThreads = CPU Threads + HyperthreadingActive = Hyperthreading Active + MemoryGB = Memory GB + NUMANodes = NUMA Nodes + NICs = NICs + HBAs = HBAs + Version = Version + Build = Build + LicenseKey = License Key + Product = Product + LicenseExpiration = License Expiration + IPMIBMC = IPMI / BMC + IPMIBMCError = Error collecting IPMI/BMC information for {0}. + IPMIBMCManufacturer = Manufacturer + IPMIBMCType = Type + IPMIBMCIPAddress = IP Address + IPMIBMCMACAddress = MAC Address + BootDevice = Boot Device + BootDeviceError = Error collecting boot device information for {0}. + BootDeviceDescription = Description + BootDeviceType = Type + BootDeviceSize = Size (GB) + BootDeviceIsSAS = Is SAS + BootDeviceIsUSB = Is USB + BootDeviceIsSSD = Is SSD + BootDeviceFromSAN = From SAN + PCIDevices = PCI Devices + PCIDeviceId = PCI ID + PCIVendorName = Vendor Name + PCIDeviceName = Device Name + PCIDriverName = Driver Name + PCIDriverVersion = Driver Version + PCIFirmware = Firmware Version + PCIDriversFirmware = PCI Devices Drivers & Firmware + Enabled = Enabled + Disabled = Disabled + NotApplicable = Not applicable + Unknown = Unknown + Maintenance = Maintenance + NotResponding = Not Responding + Host = Host + ConnectionState = Connection State + ID = ID + Parent = Parent + HyperThreading = HyperThreading + NumberOfCPUSockets = Number of CPU Sockets + NumberOfCPUCores = Number of CPU Cores + NumberOfCPUThreads = Number of CPU Threads + CPUTotalUsedFree = CPU Total / Used / Free + MemoryTotalUsedFree = Memory Total / Used / Free + NumberOfNICs = Number of NICs + NumberOfHBAs = Number of HBAs + NumberOfDatastores = Number of Datastores + NumberOfVMs = Number of VMs + MaximumEVCMode = Maximum EVC Mode + EVCGraphicsMode = EVC Graphics Mode + PowerManagementPolicy = Power Management Policy + ScratchLocation = Scratch Location + BiosVersion = BIOS Version + BiosReleaseDate = BIOS Release Date + BootTime = Boot Time + UptimeDays = Uptime Days + MACAddress = MAC Address + SubnetMask = Subnet Mask + Gateway = Gateway + FirmwareVersion = Firmware Version + Device = Device + BootType = Boot Type + Vendor = Vendor + Size = Size + PCIAddress = PCI Address + DeviceClass = Device Class + TableHardwareConfig = Hardware Configuration - {0} + TableIPMIBMC = IPMI / BMC - {0} + TableBootDevice = Boot Device - {0} + TablePCIDevices = PCI Devices - {0} + TablePCIDriversFirmware = PCI Devices Drivers & Firmware - {0} + PCIDeviceError = Error collecting PCI device information for {0}. {1} + PCIDriversFirmwareError = Error collecting PCI device driver & firmware information for {0}. {1} + HardwareError = Error collecting host hardware information for {0}. {1} + IODeviceIdentifiers = I/O Device Identifiers + VendorID = VID + DeviceID = DID + SubVendorID = SVID + SubDeviceID = SSID + TableIODeviceIdentifiers = I/O Device Identifiers - {0} + IODeviceIdentifiersError = Error collecting I/O device identifier information for {0}. {1} +'@ + +# Get-AbrVSphereVMHostSystem +GetAbrVSphereVMHostSystem = ConvertFrom-StringData @' + Collecting = Collecting VMHost System information. + HostProfile = Host Profile + ProfileName = Host Profile + ProfileCompliance = Compliance + ProfileRemediating = Remediating + ImageProfile = Image Profile + ImageProfileName = Name + ImageProfileVendor = Vendor + ImageProfileAcceptance = Acceptance Level + TimeConfiguration = Time Configuration + NTPServer = NTP Server + TimeZone = Time Zone + Syslog = Syslog + SyslogHost = Syslog Host + VUMBaseline = Update Manager Baselines + VUMBaselineNotAvailable = VMHost VUM baseline information is not currently available with your version of PowerShell. + VUMBaselineName = Baseline + VUMBaselineType = Type + VUMBaselinePatches = # of Patches + VUMCompliance = Update Manager Compliance + VUMComplianceNotAvailable = VMHost VUM compliance information is not currently available with your version of PowerShell. + VUMStatus = Status + AdvancedSettings = Advanced System Settings + Key = Key + Value = Value + VIBs = VMware Installation Bundles (VIBs) + VIBName = Name + VIBVersion = Version + VIBVendor = Vendor + VIBInstallDate = Install Date + VIBAcceptanceLevel = Acceptance Level + SectionHeading = System + ParagraphSummary = The following section details the host system configuration for {0}. + NTPService = NTP Service + NTPServers = NTP Server(s) + SyslogPort = Port + VUMDescription = Description + VUMTargetType = Target Type + VUMLastUpdate = Last Update Time + InstallDate = Installation Date + ImageName = Image Profile + ImageVendor = Vendor + Running = Running + Stopped = Stopped + NotCompliant = Not Compliant + Unknown = Unknown + Incompatible = Incompatible + ProfileDescription = Description + VIBID = ID + VIBCreationDate = Creation Date + TableHostProfile = Host Profile - {0} + TableImageProfile = Image Profile - {0} + TableTimeConfig = Time Configuration - {0} + TableSyslog = Syslog Configuration - {0} + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} + TableAdvancedSettings = Advanced System Settings - {0} + TableVIBs = Software VIBs - {0} + HostProfileError = Error collecting host profile information for {0}. {1} + ImageProfileError = Error collecting image profile information for {0}. {1} + TimeConfigError = Error collecting time configuration for {0}. {1} + SyslogError = Error collecting syslog configuration for {0}. {1} + VUMBaselineError = Error collecting Update Manager baseline information for {0}. {1} + VUMComplianceError = Error collecting Update Manager compliance information for {0}. {1} + AdvancedSettingsError = Error collecting host advanced settings information for {0}. {1} + VIBsError = Error collecting software VIB information for {0}. {1} + InsufficientPrivImageProfile = Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned. + InsufficientPrivVUMBaseline = Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + InsufficientPrivVUMCompliance = Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + SwapFileLocation = VM Swap File Location + SwapFilePlacement = VM Swap File Placement + SwapDatastore = Swap Datastore + WithVM = With VM (Default) + HostLocal = Host Local + TableSwapFileLocation = VM Swap File Location - {0} + SwapFileLocationError = Error collecting VM swap file location for {0}. {1} + HostCertificate = Host Certificate + CertSubject = Subject + CertIssuer = Issuer + CertValidFrom = Valid From + CertValidTo = Valid To + CertThumbprint = SHA-256 Thumbprint + TableHostCertificate = Host Certificate - {0} + HostCertificateError = Error collecting host certificate information for {0}. {1} + LogDir = Log Directory + LogRotations = Log Rotations + LogSize = Log Size (KB) +'@ + +# Get-AbrVSphereVMHostStorage +GetAbrVSphereVMHostStorage = ConvertFrom-StringData @' + Collecting = Collecting VMHost Storage information. + SectionHeading = Storage + DatastoreSpecs = Datastore Specifications + Datastore = Datastore + DatastoreType = Type + DatastoreCapacity = Capacity (GB) + DatastoreFreeSpace = Free Space (GB) + DatastoreState = State + DatastoreShared = Shared + StorageAdapters = Storage Adapters + AdapterName = Adapter + AdapterType = Type + AdapterDriver = Driver + AdapterUID = UID + AdapterModel = Model + AdapterStatus = Status + AdapterSASAddress = SAS Address + AdapterWWN = WWN + AdapterDevices = Devices + AdapterTargets = Targets + ParagraphSummary = The following section details the host storage configuration for {0}. + FC = Fibre Channel + iSCSI = iSCSI + ParallelSCSI = Parallel SCSI + ChapNone = None + ChapUniPreferred = Use unidirectional CHAP unless prohibited by target + ChapUniRequired = Use unidirectional CHAP if required by target + ChapUnidirectional = Use unidirectional CHAP + ChapBidirectional = Use bidirectional CHAP + Online = Online + Offline = Offline + Type = Type + Version = Version + NumberOfVMs = # of VMs + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + TableDatastores = Datastores - {0} + ParagraphStorageAdapters = The following section details the storage adapter configuration for {0}. + AdapterPaths = Paths + iSCSIName = iSCSI Name + iSCSIAlias = iSCSI Alias + AdapterSpeed = Speed + DynamicDiscovery = Dynamic Discovery + StaticDiscovery = Static Discovery + AuthMethod = Authentication Method + CHAPOutgoing = Outgoing CHAP Name + CHAPIncoming = Incoming CHAP Name + AdvancedOptions = Advanced Options + NodeWWN = Node WWN + PortWWN = Port WWN + TableStorageAdapter = Storage Adapter {0} - {1} +'@ + +# Get-AbrVSphereVMHostNetwork +GetAbrVSphereVMHostNetwork = ConvertFrom-StringData @' + Collecting = Collecting VMHost Network information. + SectionHeading = Network + NetworkConfig = Network Configuration + VMKernelAdapters = VMkernel Adapters + PhysicalAdapters = Physical Adapters + CDP = Cisco Discovery Protocol + LLDP = Link Layer Discovery Protocol + StandardvSwitches = Standard Virtual Switches + AdapterName = Adapter + AdapterMAC = MAC Address + AdapterLinkSpeed = Link Speed + AdapterDriver = Driver + AdapterPCIID = PCI Device + AdapterStatus = Status + VMKName = VMkernel Adapter + VMKIP = IP Address + VMKSubnet = Subnet Mask + VMKGateway = Default Gateway + VMKMTU = MTU + VMKPortGroup = Port Group + VMKVirtualSwitch = Virtual Switch + VMKDHCPEnabled = DHCP Enabled + VMKServicesEnabled = Enabled Services + vSwitch = Virtual Switch + vSwitchPorts = Total Ports + vSwitchUsedPorts = Used Ports + vSwitchAvailablePorts = Available Ports + vSwitchMTU = MTU + vSwitchCDPStatus = CDP Status + vSwitchSecurity = Security Policy + vSwitchFailover = Failover Policy + vSwitchLoadBalancing = Load Balancing + vSwitchPortGroups = Port Groups + PortGroup = Port Group + VLAN = VLAN ID + ActiveAdapters = Active Adapters + StandbyAdapters = Standby Adapters + UnusedAdapters = Unused Adapters + ParagraphSummary = The following section details the host network configuration for {0}. + Enabled = Enabled + Disabled = Disabled + Connected = Connected + Disconnected = Disconnected + Yes = Yes + No = No + Accept = Accept + Reject = Reject + Supported = Supported + NotSupported = Not Supported + Inherited = Inherited + TCPDefault = Default + TCPProvisioning = Provisioning + TCPvMotion = vMotion + TCPNsxOverlay = nsx-overlay + TCPNsxHyperbus = nsx-hyperbus + TCPNotApplicable = Not Applicable + LBSrcId = Route based on the originating port ID + LBSrcMac = Route based on source MAC hash + LBIP = Route based on IP hash + LBExplicitFailover = Explicit Failover + NFDLinkStatus = Link status only + NFDBeaconProbing = Beacon probing + FullDuplex = Full Duplex + AutoNegotiate = Auto negotiate + Down = Down + Host = Host + VirtualSwitches = Virtual Switches + VMkernelGateway = VMkernel Gateway + IPv6 = IPv6 + VMkernelIPv6Gateway = VMkernel IPv6 Gateway + DNSServers = DNS Servers + HostName = Host Name + DomainName = Domain Name + SearchDomain = Search Domain + TableNetworkConfig = Network Configuration - {0} + ParagraphPhysicalAdapters = The following section details the physical network adapter configuration for {0}. + VirtualSwitch = Virtual Switch + ActualSpeedDuplex = Actual Speed, Duplex + ConfiguredSpeedDuplex = Configured Speed, Duplex + WakeOnLAN = Wake on LAN + TablePhysicalAdapter = Physical Adapter {0} - {1} + TablePhysicalAdapters = Physical Adapters - {0} + ParagraphCDP = The following section details the CDP information for {0}. + Status = Status + SystemName = System Name + HardwarePlatform = Hardware Platform + SwitchID = Switch ID + SoftwareVersion = Software Version + ManagementAddress = Management Address + Address = Address + PortID = Port ID + MTU = MTU + TableAdapterCDP = Network Adapter {0} CDP Information - {1} + TableAdaptersCDP = Network Adapter CDP Information - {0} + ParagraphLLDP = The following section details the LLDP information for {0}. + ChassisID = Chassis ID + TimeToLive = Time to live + TimeOut = TimeOut + Samples = Samples + PortDescription = Port Description + SystemDescription = System Description + TableAdapterLLDP = Network Adapter {0} LLDP Information - {1} + TableAdaptersLLDP = Network Adapter LLDP Information - {0} + ParagraphVMKernelAdapters = The following section details the VMkernel adapter configuration for {0}. + NetworkLabel = Network Label + TCPIPStack = TCP/IP Stack + DHCP = DHCP + IPAddress = IP Address + SubnetMask = Subnet Mask + DefaultGateway = Default Gateway + vMotion = vMotion + Provisioning = Provisioning + FTLogging = FT Logging + Management = Management + vSphereReplication = vSphere Replication + vSphereReplicationNFC = vSphere Replication NFC + vSAN = vSAN + vSANWitness = vSAN Witness + vSphereBackupNFC = vSphere Backup NFC + TableVMKernelAdapter = VMkernel Adapter {0} - {1} + ParagraphStandardvSwitches = The following section details the standard virtual switch configuration for {0}. + NumberOfPorts = Number of Ports + NumberOfPortsAvailable = Number of Ports Available + TableStandardvSwitches = Standard Virtual Switches - {0} + VSSecurity = Virtual Switch Security + PromiscuousMode = Promiscuous Mode + MACAddressChanges = MAC Address Changes + ForgedTransmits = Forged Transmits + TableVSSecurity = Virtual Switch Security Policy - {0} + VSTrafficShaping = Virtual Switch Traffic Shaping + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + TableVSTrafficShaping = Virtual Switch Traffic Shaping Policy - {0} + VSTeamingFailover = Virtual Switch Teaming & Failover + LoadBalancing = Load Balancing + NetworkFailureDetection = Network Failure Detection + NotifySwitches = Notify Switches + Failback = Failback + ActiveNICs = Active NICs + StandbyNICs = Standby NICs + UnusedNICs = Unused NICs + TableVSTeamingFailover = Virtual Switch Teaming & Failover - {0} + VSPortGroups = Virtual Switch Port Groups + NumberOfVMs = # of VMs + TableVSPortGroups = Virtual Switch Port Groups - {0} + VSPGSecurity = Virtual Switch Port Group Security + MACChanges = MAC Changes + TableVSPGSecurity = Virtual Switch Port Group Security Policy - {0} + VSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping + TableVSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping Policy - {0} + VSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover + TableVSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover - {0} +'@ + +# Get-AbrVSphereVMHostSecurity +GetAbrVSphereVMHostSecurity = ConvertFrom-StringData @' + Collecting = Collecting VMHost Security information. + SectionHeading = Security + LockdownMode = Lockdown Mode + Services = Services + ServiceName = Service + ServiceRunning = Running + ServicePolicy = Startup Policy + ServiceRequired = Required + Firewall = Firewall + FirewallRule = Rule + FirewallAllowed = Allowed Hosts + Authentication = Authentication + Domain = Domain + Trust = Trusted Domains + Membership = Domain Membership + VMInfoSection = Virtual Machines + VMName = Virtual Machine + VMPowerState = Power State + VMIPAddress = IP Address + VMOS = OS + VMGuestID = Guest ID + VMCPUs = CPUs + VMMemoryGB = Memory GB + VMDisks = Disks (GB) + VMNICs = NICs + StartupShutdown = VM Startup/Shutdown + StartupEnabled = Startup Enabled + StartupOrder = Startup Order + StartupDelay = Startup Delay + StopAction = Stop Action + StopDelay = Stop Delay + WaitForHeartbeat = Wait For Heartbeat + ParagraphSummary = The following section details the host security configuration for {0}. + LockdownDisabled = Disabled + LockdownNormal = Enabled (Normal) + LockdownStrict = Enabled (Strict) + Running = Running + Stopped = Stopped + SvcPortUsage = Start and stop with port usage + SvcWithHost = Start and stop with host + SvcManually = Start and stop manually + On = On + Off = Off + Enabled = Enabled + Disabled = Disabled + WaitHeartbeat = Continue if VMware Tools is started + WaitDelay = Wait for startup delay + PowerOff = Power Off + GuestShutdown = Guest Shutdown + ToolsOld = Old + ToolsOK = OK + ToolsNotRunning = Not Running + ToolsNotInstalled = Not Installed + TableLockdownMode = Lockdown Mode - {0} + TableServices = Services - {0} + FirewallService = Service + Status = Status + IncomingPorts = Incoming Ports + OutgoingPorts = Outgoing Ports + Protocols = Protocols + Daemon = Daemon + TableFirewall = Firewall Configuration - {0} + DomainMembership = Domain Membership + TrustedDomains = Trusted Domains + TableAuthentication = Authentication Services - {0} + ParagraphVMInfo = The following section details the virtual machine configuration for {0}. + VMProvisioned = Provisioned + VMUsed = Used + VMHWVersion = HW Version + VMToolsStatus = VM Tools Status + TableVMs = Virtual Machines - {0} + TableStartupShutdown = VM Startup/Shutdown Policy - {0} + TpmEncryption = TPM & Encryption + TpmPresent = TPM Present + TpmStatus = TPM Attestation Status + EncryptionMode = Encryption Mode + RequireSecureBoot = Require Secure Boot + RequireSignedVIBs = Require Executables From Installed VIBs Only + RecoveryKeys = Encryption Recovery Keys + RecoveryID = Recovery ID + RecoveryKey = Recovery Key + TpmEncryptionError = Unable to retrieve TPM & Encryption information for host {0}. {1} + TableTpmEncryption = TPM & Encryption - {0} + TableRecoveryKeys = Encryption Recovery Keys - {0} + Yes = Yes + No = No +'@ + +# Get-AbrVSphereNetwork +GetAbrVSphereNetwork = ConvertFrom-StringData @' + InfoLevel = Network InfoLevel set to {0}. + Collecting = Collecting Distributed Switch information. + Processing = Processing Distributed Switch '{0}' ({1}/{2}). + SectionHeading = Distributed Switches + ParagraphSummary = The following sections detail the configuration of distributed switches managed by vCenter Server {0}. + VDSwitch = Distributed Switch + Datacenter = Datacenter + Manufacturer = Manufacturer + NumUplinks = # Uplinks + NumPorts = # Ports + NumHosts = # Hosts + NumVMs = # VMs + Version = Version + MTU = MTU + ID = ID + NumberOfUplinks = Number of Uplinks + NumberOfPorts = Number of Ports + NumberOfPortGroups = Number of Port Groups + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + Hosts = Hosts + VirtualMachines = Virtual Machines + NIOC = Network I/O Control + DiscoveryProtocol = Discovery Protocol + DiscoveryOperation = Discovery Operation + NumPortGroups = # Port Groups + MaxPorts = Max Ports + Contact = Contact + Location = Location + VDPortGroups = Distributed Port Groups + PortGroup = Port Group + PortGroupType = Port Group Type + VLANID = VLAN ID + VLANConfiguration = VLAN Configuration + PortBinding = Port Binding + Host = Host + UplinkName = Uplink Name + UplinkPortGroup = Uplink Port Group + PhysicalNetworkAdapter = Physical Network Adapter + ActiveUplinks = Active Uplinks + StandbyUplinks = Standby Uplinks + UnusedUplinks = Unused Uplinks + AllowPromiscuous = Allow Promiscuous + ForgedTransmits = Forged Transmits + MACAddressChanges = MAC Address Changes + Accept = Accept + Reject = Reject + Direction = Direction + Status = Status + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + LoadBalancing = Load Balancing + LoadBalanceSrcId = Route based on the originating port ID + LoadBalanceSrcMac = Route based on source MAC hash + LoadBalanceIP = Route based on IP hash + ExplicitFailover = Explicit Failover + NetworkFailureDetection = Network Failure Detection + LinkStatus = Link status only + BeaconProbing = Beacon probing + NotifySwitches = Notify Switches + FailbackEnabled = Failback Enabled + Yes = Yes + No = No + PrimaryVLANID = Primary VLAN ID + PrivateVLANType = Private VLAN Type + SecondaryVLANID = Secondary VLAN ID + UplinkPorts = Distributed Switch Uplink Ports + VDSSecurity = Distributed Switch Security + VDSTrafficShaping = Distributed Switch Traffic Shaping + VDSPortGroups = Distributed Switch Port Groups + VDSPortGroupSecurity = Distributed Switch Port Group Security + VDSPortGroupTrafficShaping = Distributed Switch Port Group Traffic Shaping + VDSPortGroupTeaming = Distributed Switch Port Group Teaming & Failover + VDSPrivateVLANs = Distributed Switch Private VLANs + Enabled = Enabled + Disabled = Disabled + Listen = Listen + Advertise = Advertise + Both = Both + TableVDSSummary = Distributed Switch Summary - {0} + TableVDSGeneral = Distributed Switch General Properties - {0} + TableVDSUplinkPorts = Distributed Switch Uplink Ports - {0} + TableVDSSecurity = Distributed Switch Security - {0} + TableVDSTrafficShaping = Distributed Switch Traffic Shaping - {0} + TableVDSPortGroups = Distributed Switch Port Groups - {0} + TableVDSPortGroupSecurity = Distributed Switch Port Group Security - {0} + TableVDSPortGroupTrafficShaping = Distributed Switch Port Group Traffic Shaping - {0} + TableVDSPortGroupTeaming = Distributed Switch Port Group Teaming & Failover - {0} + TableVDSPrivateVLANs = Distributed Switch Private VLANs - {0} + VDSLACP = Distributed Switch LACP + LACPEnabled = LACP Enabled + LACPMode = LACP Mode + LACPActive = Active + LACPPassive = Passive + VDSNetFlow = Distributed Switch NetFlow + CollectorIP = Collector IP Address + CollectorPort = Collector Port + ActiveFlowTimeout = Active Flow Timeout (s) + IdleFlowTimeout = Idle Flow Timeout (s) + SamplingRate = Sampling Rate + InternalFlowsOnly = Internal Flows Only + NIOCResourcePools = Network I/O Control Resource Pools + NIOCResourcePool = Resource Pool + NIOCSharesLevel = Shares Level + NIOCSharesValue = Shares + NIOCLimitMbps = Limit (Mbps) + Unlimited = Unlimited + TableVDSLACP = Distributed Switch LACP - {0} + TableVDSNetFlow = Distributed Switch NetFlow - {0} + TableNIOCResourcePools = Network I/O Control Resource Pools - {0} + Tags = Tags +'@ + +# Get-AbrVSpherevSAN +GetAbrVSpherevSAN = ConvertFrom-StringData @' + InfoLevel = vSAN InfoLevel set to {0}. + Collecting = Collecting vSAN information. + CollectingESA = Collecting vSAN ESA information for '{0}'. + CollectingOSA = Collecting vSAN OSA information for '{0}'. + CollectingDisks = Collecting vSAN disk information for '{0}'. + CollectingDiskGroups = Collecting vSAN disk group information for '{0}'. + CollectingiSCSITargets = Collecting vSAN iSCSI target information for '{0}'. + CollectingiSCSILUNs = Collecting vSAN iSCSI LUN information for '{0}'. + Processing = Processing vSAN Cluster '{0}' ({1}/{2}). + SectionHeading = vSAN + ParagraphSummary = The following sections detail the configuration of VMware vSAN managed by vCenter Server {0}. + ParagraphDetail = The following table details the vSAN configuration for cluster {0}. + DisksSection = Disks + DiskGroupsSection = Disk Groups + iSCSITargetsSection = iSCSI Targets + iSCSILUNsSection = iSCSI LUNs + Cluster = Cluster + StorageType = Storage Type + ClusterType = Cluster Type + NumHosts = # of Hosts + ID = ID + NumberOfHosts = Number of Hosts + NumberOfDisks = Number of Disks + NumberOfDiskGroups = Number of Disk Groups + DiskClaimMode = Disk Claim Mode + PerformanceService = Performance Service + FileService = File Service + iSCSITargetService = iSCSI Target Service + HistoricalHealthService = Historical Health Service + HealthCheck = Health Check + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + HCLLastUpdated = HCL Last Updated + Hosts = Hosts + Version = Version + Stretched = Stretched Cluster + VSANEnabled = vSAN Enabled + VSANESAEnabled = vSAN ESA Enabled + DisksFormat = Disk Format Version + Deduplication = Deduplication and Compression + AllFlash = All Flash + FaultDomains = Fault Domains + PFTT = Primary Failures to Tolerate + SFTT = Secondary Failures to Tolerate + NetworkDiagnosticMode = Network Diagnostic Mode + HybridMode = Hybrid Mode + AutoRebalance = Automatic Rebalance + ProactiveDisk = Proactive Disk Rebalance + ResyncThrottle = Resync Throttle + SpaceEfficiency = Space Efficiency + Encryption = Encryption + FileServiceEnabled = File Service Enabled + iSCSITargetEnabled = iSCSI Target Enabled + VMHostSpecs = VMHost vSAN Specifications + VMHost = VMHost + DiskGroup = Disk Group + CacheDisks = Cache Disks + DataDisks = Data Disks + DiskGroups = Disk Groups + CacheTier = Cache Tier + DataTier = Data Tier + Status = Status + FaultDomainName = Fault Domain + VSANAdvancedOptions = vSAN Advanced Configuration Options + Key = Key + Value = Value + IDs = Identifiers + VSAN_UUID = vSAN UUID + CapacityTier = Capacity Tier (GB) + BufferTier = Buffer Tier (GB) + DiskName = Disk + Name = Name + DriveType = Drive Type + Host = Host + State = State + Encrypted = Encrypted + Capacity = Capacity + SerialNumber = Serial Number + Vendor = Vendor + Model = Model + DiskType = Disk Type + DiskFormatVersion = Disk Format Version + ClaimedAs = Claimed As + NumDisks = # of Disks + Type = Type + IQN = IQN + Alias = Alias + LUNsCount = LUNs + NetworkInterface = Network Interface + IOOwnerHost = I/O Owner Host + TCPPort = TCP Port + Health = Health + StoragePolicy = Storage Policy + ComplianceStatus = Compliance Status + Authentication = Authentication + LUNName = LUN + LUNID = LUN ID + Yes = Yes + No = No + Enabled = Enabled + Disabled = Disabled + Online = Online + Offline = Offline + Mounted = Mounted + Unmounted = Unmounted + Flash = Flash + HDD = HDD + Cache = Cache + TableVSANClusterSummary = vSAN Cluster Summary - {0} + TableVSANConfiguration = vSAN Configuration - {0} + TableDisk = Disk {0} - {1} + TableVSANDisks = vSAN Disks - {0} + TableVSANDiskGroups = vSAN Disk Groups - {0} + TableVSANiSCSITargets = vSAN iSCSI Targets - {0} + TableVSANiSCSILUNs = vSAN iSCSI LUNs - {0} + ESAError = Error collecting vSAN ESA information for '{0}'. {1} + OSAError = Error collecting vSAN OSA information for '{0}'. {1} + DiskError = Error collecting vSAN disk information for '{0}'. {1} + DiskGroupError = Error collecting vSAN disk group information for '{0}'. {1} + iSCSITargetError = Error collecting vSAN iSCSI target information for '{0}'. {1} + iSCSILUNError = Error collecting vSAN iSCSI LUN information for '{0}'. {1} + ServicesSection = vSAN Services + Service = Service + TableVSANServices = vSAN Services - {0} + ServicesError = Error collecting vSAN services information for '{0}'. {1} +'@ + +# Get-AbrVSphereDatastore +GetAbrVSphereDatastore = ConvertFrom-StringData @' + InfoLevel = Datastore InfoLevel set to {0}. + Collecting = Collecting Datastore information. + Processing = Processing Datastore '{0}' ({1}/{2}). + SectionHeading = Datastores + ParagraphSummary = The following sections detail the configuration of datastores managed by vCenter Server {0}. + Datastore = Datastore + Type = Type + DatastoreURL = URL + FileSystem = File System Version + CapacityGB = Total Capacity (GB) + FreeSpaceGB = Free Space (GB) + UsedSpaceGB = Used Space (GB) + State = State + Accessible = Accessible + NumHosts = # Hosts + NumVMs = # VMs + SIOC = Storage I/O Control + IOLatencyThreshold = I/O Latency Threshold (ms) + IOLoadBalancing = I/O Load Balancing + Enabled = Enabled + Disabled = Disabled + Normal = Normal + Maintenance = Maintenance + Unmounted = Unmounted + ID = ID + Datacenter = Datacenter + Version = Version + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + CongestionThreshold = Congestion Threshold + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + Hosts = Hosts + VirtualMachines = Virtual Machines + SCSILUNInfo = SCSI LUN Information + Host = Host + CanonicalName = Canonical Name + Capacity = Capacity + Vendor = Vendor + Model = Model + IsSSD = Is SSD + MultipathPolicy = Multipath Policy + Paths = Paths + TableDatastoreSummary = Datastore Summary - {0} + TableDatastoreConfig = Datastore Configuration - {0} + TableSCSILUN = SCSI LUN Information - {0} + Tags = Tags +'@ + +# Get-AbrVSphereDSCluster +GetAbrVSphereDSCluster = ConvertFrom-StringData @' + InfoLevel = DSCluster InfoLevel set to {0}. + Collecting = Collecting Datastore Cluster information. + Processing = Processing Datastore Cluster '{0}' ({1}/{2}). + SectionHeading = Datastore Clusters + ParagraphSummary = The following sections detail the configuration of datastore clusters managed by vCenter Server {0}. + DSCluster = Datastore Cluster + Datacenter = Datacenter + CapacityGB = Total Capacity (GB) + FreeSpaceGB = Free Space (GB) + SDRSEnabled = SDRS + SDRSAutomationLevel = SDRS Automation Level + IOLoadBalancing = I/O Load Balancing + SpaceThreshold = Space Threshold (%) + IOLatencyThreshold = I/O Latency Threshold (ms) + SDRSRules = SDRS Rules + RuleName = Rule + RuleEnabled = Enabled + RuleVMs = Virtual Machines + FullyAutomated = Fully Automated + NoAutomation = No Automation (Manual Mode) + Manual = Manual + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + ID = ID + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + ParagraphDSClusterDetail = The following table details the configuration for datastore cluster {0}. + TableDSClusterConfig = Datastore Cluster Configuration - {0} + TableSDRSVMOverrides = SDRS VM Overrides - {0} + SDRSVMOverrides = SDRS VM Overrides + VirtualMachine = Virtual Machine + KeepVMDKsTogether = Keep VMDKs Together + DefaultBehavior = Default ({0}) + RuleType = Type + RuleAffinity = Affinity + RuleAntiAffinity = Anti-Affinity + TableSDRSRules = SDRS Rules - {0} + SpaceLoadBalanceConfig = Space Load Balance Configuration + SpaceMinDiff = Min Space Utilisation Difference (%) + SpaceThresholdMode = Space Threshold Mode + UtilizationMode = Utilisation Threshold + FreeSpaceMode = Free Space Threshold + UtilizationThreshold = Space Utilisation Threshold (%) + FreeSpaceThreshold = Free Space Threshold (GB) + IOLoadBalanceConfig = I/O Load Balance Configuration + IOCongestionThreshold = I/O Congestion Threshold (ms) + IOReservationMode = Reservation Threshold Mode + IOPSThresholdMode = I/O Operations Count + ReservationMbpsMode = Reservation in Mbps + ReservationIopsMode = Reservation in IOPS + TableSpaceLoadBalance = Space Load Balance Configuration - {0} + TableIOLoadBalance = I/O Load Balance Configuration - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVM +GetAbrVSphereVM = ConvertFrom-StringData @' + InfoLevel = VM InfoLevel set to {0}. + Collecting = Collecting Virtual Machine information. + Processing = Processing Virtual Machine '{0}' ({1}/{2}). + SectionHeading = Virtual Machines + ParagraphSummary = The following sections detail the configuration of virtual machines managed by vCenter Server {0}. + VirtualMachine = Virtual Machine + PowerState = Power State + Template = Template + OS = OS + Version = VM Hardware Version + GuestID = Guest ID + Cluster = Cluster + ResourcePool = Resource Pool + VMHost = Host + Folder = Folder + IPAddress = IP Address + CPUs = CPUs + MemoryGB = Memory GB + ProvisionedGB = Provisioned (GB) + UsedGB = Used (GB) + NumDisks = # Disks + NumNICs = # NICs + NumSnapshots = # Snapshots + VMwareTools = VMware Tools + ToolsVersion = Tools Version + ToolsStatus = Tools Status + ToolsRunningStatus = Tools Running Status + VMAdvancedDetail = Advanced Configuration + BootOptions = Boot Options + BootDelay = Boot Delay (ms) + BootRetryEnabled = Boot Retry Enabled + BootRetryDelay = Boot Retry Delay (ms) + EFISecureBoot = EFI Secure Boot + EnterBIOSSetup = Enter BIOS Setup on Next Boot + HardDisks = Hard Disks + DiskName = Disk + DiskCapacityGB = Capacity (GB) + DiskFormat = Format + DiskStoragePolicy = Storage Policy + DiskDatastore = Datastore + DiskController = Controller + NetworkAdapters = Network Adapters + NICName = Network Adapter + NICType = Adapter Type + NICPortGroup = Port Group + NICMAC = MAC Address + NICConnected = Connected + NICConnectionPolicy = Connect at Power On + SnapshotHeading = Snapshots + SnapshotName = Snapshot + SnapshotDescription = Description + SnapshotSize = Size (GB) + SnapshotDate = Created + SnapshotParent = Parent + On = On + Off = Off + ToolsOld = Old + ToolsOK = OK + ToolsNotRunning = Not Running + ToolsNotInstalled = Not Installed + Yes = Yes + No = No + Connected = Connected + NotConnected = Not Connected + Thin = Thin + Thick = Thick + Enabled = Enabled + Disabled = Disabled + TotalVMs = Total VMs + TotalvCPUs = Total vCPUs + TotalMemory = Total Memory + TotalProvisionedSpace = Total Provisioned Space + TotalUsedSpace = Total Used Space + VMsPoweredOn = VMs Powered On + VMsPoweredOff = VMs Powered Off + VMsOrphaned = VMs Orphaned + VMsInaccessible = VMs Inaccessible + VMsSuspended = VMs Suspended + VMsWithSnapshots = VMs with Snapshots + GuestOSTypes = Guest Operating System Types + VMToolsOKCount = VM Tools OK + VMToolsOldCount = VM Tools Old + VMToolsNotRunningCount = VM Tools Not Running + VMToolsNotInstalledCount = VM Tools Not Installed + vCPUs = vCPUs + Memory = Memory + Provisioned = Provisioned + Used = Used + HWVersion = HW Version + VMToolsStatus = VM Tools Status + ID = ID + OperatingSystem = Operating System + HardwareVersion = Hardware Version + ConnectionState = Connection State + FaultToleranceState = Fault Tolerance State + FTNotConfigured = Not Configured + FTNeedsSecondary = Needs Secondary + FTRunning = Running + FTDisabled = Disabled + FTStarting = Starting + FTEnabled = Enabled + Parent = Parent + ParentFolder = Parent Folder + ParentResourcePool = Parent Resource Pool + CoresPerSocket = Cores per Socket + CPUShares = CPU Shares + CPUReservation = CPU Reservation + CPULimit = CPU Limit + CPUHotAdd = CPU Hot Add + CPUHotRemove = CPU Hot Remove + MemoryAllocation = Memory Allocation + MemoryShares = Memory Shares + MemoryHotAdd = Memory Hot Add + vNICs = vNICs + DNSName = DNS Name + Networks = Networks + MACAddress = MAC Address + vDisks = vDisks + ProvisionedSpace = Provisioned Space + UsedSpace = Used Space + ChangedBlockTracking = Changed Block Tracking + StorageBasedPolicy = Storage Based Policy + StorageBasedPolicyCompliance = Storage Based Policy Compliance + Compliant = Compliant + NonCompliant = Non Compliant + Unknown = Unknown + Notes = Notes + BootTime = Boot Time + UptimeDays = Uptime Days + NetworkName = Network Name + SCSIControllers = SCSI Controllers + Device = Device + ControllerType = Controller Type + BusSharing = Bus Sharing + None = None + GuestVolumes = Guest Volumes + Capacity = Capacity + DiskProvisioning = Disk Provisioning + ThickEagerZeroed = Thick Eager Zeroed + ThickLazyZeroed = Thick Lazy Zeroed + DiskType = Disk Type + PhysicalRDM = Physical RDM + VirtualRDM = Virtual RDM + VMDK = VMDK + DiskMode = Disk Mode + IndependentPersistent = Independent - Persistent + IndependentNonpersistent = Independent - Nonpersistent + Dependent = Dependent + DiskPath = Disk Path + DiskShares = Disk Shares + DiskLimitIOPs = Disk Limit IOPs + Unlimited = Unlimited + SCSIController = SCSI Controller + SCSIAddress = SCSI Address + Path = Path + FreeSpace = Free Space + DaysOld = Days Old + TableVMSummary = VM Summary - {0} + TableVMAdvancedSummary = VM Advanced Summary - {0} + TableVMSnapshotSummary = VM Snapshot Summary - {0} + TableVMConfig = VM Configuration - {0} + TableVMNetworkAdapters = Network Adapters - {0} + TableVMSCSIControllers = SCSI Controllers - {0} + TableVMHardDiskConfig = Hard Disk Configuration - {0} + TableVMHardDisk = {0} - {1} + TableVMGuestVolumes = Guest Volumes - {0} + TableVMSnapshots = VM Snapshots - {0} + VUMCompliance = VM Update Manager Compliance + VUMBaselineName = Baseline + VUMStatus = Status + NotCompliant = Not Compliant + Incompatible = Incompatible + VUMComplianceError = Unable to retrieve VUM compliance information for virtual machines. + InsufficientPrivVUMCompliance = Insufficient privileges to collect VUM compliance information for virtual machines. + TableVUMCompliance = VUM Baseline Compliance - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVUM +GetAbrVSphereVUM = ConvertFrom-StringData @' + InfoLevel = VUM InfoLevel set to {0}. + Collecting = Collecting VMware Update Manager information. + NotAvailable = VUM patch baseline information is not currently available with your version of PowerShell. + PatchNotAvailable = VUM patch information is not currently available with your version of PowerShell. + SectionHeading = VMware Update Manager + ParagraphSummary = The following sections detail the configuration of VMware Update Manager managed by vCenter Server {0}. + Baselines = Baselines + BaselineName = Baseline + Description = Description + Type = Type + TargetType = Target Type + LastUpdate = Last Update Time + NumPatches = # of Patches + Patches = Patches + PatchName = Patch + PatchProduct = Product + PatchDescription = Description + PatchReleaseDate = Release Date + PatchVendorID = Vendor ID + TableVUMBaselines = VMware Update Manager Baseline Summary - {0} + TableVUMPatches = VMware Update Manager Patch Information - {0} + SoftwareDepots = Software Depots + OnlineDepots = Online Depots + OfflineDepots = Offline Depots + DepotUrl = URL + SystemDefined = System Defined + DepotEnabled = Enabled + DepotLocation = Location + DepotError = Unable to retrieve software depot information. {0} + TableOnlineDepots = Online Software Depots - {0} + TableOfflineDepots = Offline Software Depots - {0} +'@ + +# Get-AbrVSphereClusterLCM +GetAbrVSphereClusterLCM = ConvertFrom-StringData @' + Collecting = Collecting Lifecycle Manager information. + ImageComposition = Image Composition + BaseImage = Base Image + VendorAddOn = Vendor Add-On + None = None + Components = Components + ComponentName = Component + ComponentVersion = Version + HardwareSupportManager = Hardware Support Manager + HsmName = Name + HsmVersion = Version + HsmPackages = Hardware Support Packages + ImageCompliance = Image Compliance + Cluster = Cluster + VMHost = VMHost + ComplianceStatus = Compliance Status + LcmError = Unable to retrieve Lifecycle Manager information for cluster {0}. {1} + ComplianceError = Unable to retrieve compliance information for cluster {0}. {1} + TableImageComposition = Image Composition - {0} + TableComponents = Image Components - {0} + TableHardwareSupportManager = Hardware Support Manager - {0} + TableImageCompliance = Image Compliance - {0} + TableHostCompliance = Host Image Compliance - {0} +'@ + +} diff --git a/AsBuiltReport.VMware.vSphere/Language/en-US/VMwarevSphere.psd1 b/AsBuiltReport.VMware.vSphere/Language/en-US/VMwarevSphere.psd1 new file mode 100644 index 0000000..6a63612 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Language/en-US/VMwarevSphere.psd1 @@ -0,0 +1,1625 @@ +# culture = 'en-US' +@{ + +# Module-wide strings +InvokeAsBuiltReportVMwarevSphere = ConvertFrom-StringData @' + Connecting = Connecting to vCenter Server '{0}'. + CheckPrivileges = Checking vCenter user privileges. + UnablePrivileges = Unable to obtain vCenter user privileges. + VMHashtable = Creating VM lookup hashtable. + VMHostHashtable = Creating VMHost lookup hashtable. + DatastoreHashtable = Creating Datastore lookup hashtable. + VDPortGrpHashtable = Creating VDPortGroup lookup hashtable. + EVCHashtable = Creating EVC lookup hashtable. + CheckVUM = Checking for VMware Update Manager Server. + CheckVxRail = Checking for VxRail Manager Server. + CheckSRM = Checking for VMware Site Recovery Manager Server. + CheckNSXT = Checking for VMware NSX-T Manager Server. + CollectingTags = Collecting tag information. + TagError = Error collecting tag information. + CollectingAdvSettings = Collecting {0} advanced settings. +'@ + +# Get-AbrVSpherevCenter +GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = vCenter InfoLevel set to {0}. + Collecting = Collecting vCenter Server information. + SectionHeading = vCenter Server + ParagraphSummaryBrief = The following sections summarise the configuration of vCenter Server {0}. + ParagraphSummary = The following sections detail the configuration of vCenter Server {0}. + InsufficientPrivLicense = Insufficient user privileges to report vCenter Server licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned. + InsufficientPrivStoragePolicy = Insufficient user privileges to report VM storage policies. Please ensure the user account has the 'Storage Profile > View' privilege assigned. + vCenterServer = vCenter Server + IPAddress = IP Address + Version = Version + Build = Build + Product = Product + LicenseKey = License Key + LicenseExpiration = License Expiration + InstanceID = Instance ID + HTTPPort = HTTP Port + HTTPSPort = HTTPS Port + PSC = Platform Services Controller + UpdateManagerServer = Update Manager Server + SRMServer = Site Recovery Manager Server + NSXTServer = NSX-T Manager Server + VxRailServer = VxRail Manager Server + DatabaseSettings = Database Settings + DatabaseType = Database Type + DataSourceName = Data Source Name + MaxDBConnection = Maximum Database Connection + MailSettings = Mail Settings + SMTPServer = SMTP Server + SMTPPort = SMTP Port + MailSender = Mail Sender + HistoricalStatistics = Historical Statistics + IntervalDuration = Interval Duration + IntervalEnabled = Interval Enabled + SaveDuration = Save Duration + StatisticsLevel = Statistics Level + Licensing = Licensing + Total = Total + Used = Used + Available = Available + Expiration = Expiration + Certificate = Certificate + Subject = Subject + Issuer = Issuer + ValidFrom = Valid From + ValidTo = Valid To + Thumbprint = Thumbprint + CertStatus = Status + InsufficientPrivCertificate = Unable to retrieve vCenter Server certificate. {0} + Mode = Mode + SoftThreshold = Soft Threshold + HardThreshold = Hard Threshold + MinutesBefore = Minutes Before + PollInterval = Poll Interval + Roles = Roles + Role = Role + SystemRole = System Role + PrivilegeList = Privilege List + Tags = Tags + TagName = Name + TagCategory = Category + TagDescription = Description + TagCategories = Tag Categories + TagCardinality = Cardinality + TagAssignments = Tag Assignments + TagEntity = Entity + TagEntityType = Entity Type + VMStoragePolicies = VM Storage Policies + StoragePolicy = Storage Policy + Description = Description + ReplicationEnabled = Replication Enabled + CommonRulesName = Common Rules Name + CommonRulesDescription = Common Rules Description + Alarms = Alarms + Alarm = Alarm + AlarmDescription = Description + AlarmEnabled = Enabled + AlarmTriggered = Triggered + AlarmAction = Action + AdvancedSystemSettings = Advanced System Settings + Key = Key + Value = Value + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + None = None + TablevCenterSummary = vCenter Server Summary - {0} + TablevCenterConfig = vCenter Server Configuration - {0} + TableDatabaseSettings = Database Settings - {0} + TableMailSettings = Mail Settings - {0} + TableHistoricalStatistics = Historical Statistics - {0} + TableLicensing = Licensing - {0} + TableCertificate = Certificate - {0} + TableRole = Role {0} - {1} + TableRoles = Roles - {0} + TableTags = Tags - {0} + TableTagCategories = Tag Categories - {0} + TableTagAssignments = Tag Assignments - {0} + TableVMStoragePolicies = VM Storage Policies - {0} + TableAlarm = {0} - {1} + TableAlarms = Alarms - {0} + TableAdvancedSystemSettings = vCenter Advanced System Settings - {0} + RestApiSessionError = Unable to establish vCenter REST API session. {0} + BackupSettings = Backup Settings + BackupSchedule = Backup Schedule + BackupJobHistory = Backup Job History + BackupNotConfigured = No backup schedule is configured. + BackupNoJobs = No backup jobs found. + BackupApiNotAvailable = vCenter backup status requires vSphere 7.0 or later. + BackupApiError = Unable to retrieve backup information. {0} + BackupScheduleID = Schedule ID + BackupLocation = Location + BackupLocationUser = Location User + BackupEnabled = Status + BackupActivated = Activated + BackupDeactivated = Deactivated + BackupParts = Backup Data + BackupPartSeat = Supervisors Control Plane + BackupPartCommon = Inventory and Configuration + BackupPartStats = Stats, Events, and Tasks + BackupRecurrence = Schedule + BackupRetentionCount = Number of Backups to Retain + BackupDaily = Daily + BackupSendEmail = Email Notification + BackupJobLocation = Backup Location + BackupJobType = Type + BackupJobStatus = Status + BackupJobComplete = Complete + BackupJobScheduled = Scheduled + BackupJobDataTransferred = Data Transferred + BackupJobDuration = Duration + BackupJobEndTime = End Time + TableBackupSchedule = Backup Schedule - {0} + TableBackupJobHistory = Backup Job History - {0} + ResourceSummary = Resources + SummaryResource = Resource + Free = Free + CPU = CPU + Memory = Memory + Storage = Storage + VirtualMachines = Virtual Machines + Hosts = Hosts + PoweredOn = Powered On + PoweredOff = Powered Off + Suspended = Suspended + Connected = Connected + Disconnected = Disconnected + Maintenance = Maintenance + ContentLibraries = Content Libraries + ContentLibrary = Content Library + LibraryType = Type + Datastore = Datastore + LibraryLocal = Local + LibrarySubscribed = Subscribed + ItemCount = Items + SubscriptionUrl = Subscription URL + AutomaticSync = Automatic Synchronisation + OnDemandSync = On-Demand Synchronisation + LibraryItems = Library Items + ItemName = Item + ContentType = Content Type + ItemSize = Size + CreationTime = Creation Time + LastModified = Last Modified + ContentLibraryNoItems = No items found in this content library. + ContentLibraryNone = No content libraries found. + CollectingContentLibrary = Collecting Content Library information. + ContentLibraryError = Unable to retrieve Content Library information. {0} + ContentLibraryItemError = Unable to retrieve items for Content Library '{0}'. {1} + TableContentLibraries = Content Libraries - {0} + TableContentLibrary = Content Library {0} - {1} + TableLibraryItems = Library Items - {0} + TableLibraryItem = {0} - {1} + TablevCenterResourceSummary = Resource Summary - {0} + TablevCenterVMSummary = Virtual Machine Summary - {0} + TablevCenterHostSummary = Host Summary - {0} +'@ + +# Get-AbrVSphereCluster +GetAbrVSphereCluster = ConvertFrom-StringData @' + InfoLevel = Cluster InfoLevel set to {0}. + Collecting = Collecting Cluster information. + Processing = Processing Cluster '{0}' ({1}/{2}). + SectionHeading = Clusters + ParagraphSummary = The following sections detail the configuration of vSphere HA/DRS clusters managed by vCenter Server {0}. + ParagraphDetail = The following table details the configuration for cluster {0}. + Cluster = Cluster + ID = ID + Datacenter = Datacenter + NumHosts = # of Hosts + NumVMs = # of VMs + HAEnabled = vSphere HA + DRSEnabled = vSphere DRS + VSANEnabled = Virtual SAN + EVCMode = EVC Mode + VMSwapFilePolicy = VM Swap File Policy + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + Hosts = Hosts + VirtualMachines = Virtual Machines + Permissions = Permissions + Principal = Principal + Role = Role + Propagate = Propagate + IsGroup = Is Group + Enabled = Enabled + Disabled = Disabled + SwapWithVM = With VM + SwapInHostDatastore = In Host Datastore + SwapVMDirectory = Virtual machine directory + SwapHostDatastore = Datastore specified by host + TableClusterSummary = Cluster Summary - {0} + TableClusterConfig = Cluster Configuration - {0} +'@ + +# Get-AbrVSphereClusterHA +GetAbrVSphereClusterHA = ConvertFrom-StringData @' + Collecting = Collecting Cluster HA information. + SectionHeading = vSphere HA Configuration + ParagraphSummary = The following section details the vSphere HA configuration for {0} cluster. + FailuresAndResponses = Failures and Responses + HostMonitoring = Host Monitoring + HostFailureResponse = Host Failure Response + HostIsolationResponse = Host Isolation Response + VMRestartPriority = VM Restart Priority + PDLProtection = Datastore with Permanent Device Loss + APDProtection = Datastore with All Paths Down + VMMonitoring = VM Monitoring + VMMonitoringSensitivity = VM Monitoring Sensitivity + AdmissionControl = Admission Control + FailoverLevel = Host Failures Cluster Tolerates + ACPolicy = Policy + ACHostPercentage = CPU % + ACMemPercentage = Memory % + PerformanceDegradation = VM Performance Degradation + HeartbeatDatastores = Heartbeat Datastores + Datastore = Datastore + HAAdvancedOptions = vSphere HA Advanced Options + Key = Key + Value = Value + APDRecovery = APD recovery after APD timeout + Disabled = Disabled + Enabled = Enabled + RestartVMs = Restart VMs + ShutdownAndRestart = Shutdown and restart VMs + PowerOffAndRestart = Power off and restart VMs + IssueEvents = Issue events + PowerOffRestartConservative = Power off and restart VMs (conservative) + PowerOffRestartAggressive = Power off and restart VMs (aggressive) + ResetVMs = Reset VMs + VMMonitoringOnly = VM monitoring only + VMAndAppMonitoring = VM and application monitoring + DedicatedFailoverHosts = Dedicated failover hosts + ClusterResourcePercentage = Cluster resource percentage + SlotPolicy = Slot policy + Yes = Yes + No = No + FixedSlotSize = Fixed slot size + CoverAllPoweredOnVMs = Cover all powered-on virtual machines + NoneSpecified = None specified + OverrideFailoverCapacity = Override Calculated Failover Capacity + CPUSlotSize = CPU Slot Size (MHz) + MemorySlotSize = Memory Slot Size (MB) + PerfDegradationTolerate = Performance Degradation VMs Tolerate + HeartbeatSelectionPolicy = Heartbeat Selection Policy + HBPolicyAllFeasibleDsWithUserPreference = Use datastores from the specified list and complement automatically if needed + HBPolicyAllFeasibleDs = Automatically select datastores accessible from the host + HBPolicyUserSelectedDs = Use datastores only from the specified list + TableHAFailures = vSphere HA Failures and Responses - {0} + TableHAAdmissionControl = vSphere HA Admission Control - {0} + TableHAHeartbeat = vSphere HA Heartbeat Datastores - {0} + TableHAAdvanced = vSphere HA Advanced Options - {0} +'@ + +# Get-AbrVSphereClusterProactiveHA +GetAbrVSphereClusterProactiveHA = ConvertFrom-StringData @' + Collecting = Collecting Cluster Proactive HA information. + SectionHeading = Proactive HA + ParagraphSummary = The following section details the Proactive HA configuration for {0} cluster. + FailuresAndResponses = Failures and Responses + Provider = Provider + Remediation = Remediation + HealthUpdates = Health Updates + ProactiveHA = Proactive HA + AutomationLevel = Automation Level + ModerateRemediation = Moderate Remediation + SevereRemediation = Severe Remediation + Enabled = Enabled + Disabled = Disabled + MaintenanceMode = Maintenance Mode + QuarantineMode = Quarantine Mode + MixedMode = Mixed Mode + TableProactiveHA = Proactive HA - {0} + Providers = Providers + HealthUpdateCount = Health Updates + TableProactiveHAProviders = Proactive HA Providers - {0} +'@ + +# Get-AbrVSphereClusterDRS +GetAbrVSphereClusterDRS = ConvertFrom-StringData @' + Collecting = Collecting Cluster DRS information. + SectionHeading = vSphere DRS Configuration + ParagraphSummary = The following table details the vSphere DRS configuration for {0} cluster. + AutomationLevel = Automation Level + MigrationThreshold = Migration Threshold + PredictiveDRS = Predictive DRS + VirtualMachineAutomation = Individual Machine Automation + AdditionalOptions = Additional Options + VMDistribution = VM Distribution + MemoryMetricForLB = Memory Metric for Load Balancing + CPUOverCommitment = CPU Over-Commitment + PowerManagement = Power Management + DPMAutomationLevel = DPM Automation Level + DPMThreshold = DPM Threshold + AdvancedOptions = Advanced Options + Key = Key + Value = Value + DRSClusterGroups = DRS Cluster Groups + GroupName = Group Name + GroupType = Group Type + GroupMembers = Members + DRSVMHostRules = DRS VM/Host Rules + RuleName = Rule Name + RuleType = Rule Type + RuleEnabled = Enabled + VMGroup = VM Group + HostGroup = Host Group + DRSRules = DRS Rules + RuleVMs = Virtual Machines + VMOverrides = VM Overrides + VirtualMachine = Virtual Machine + DRSAutomationLevel = DRS Automation Level + DRSBehavior = DRS Behavior + HARestartPriority = HA Restart Priority + HAIsolationResponse = HA Isolation Response + PDLProtection = Datastore with PDL + APDProtection = Datastore with APD + VMMonitoring = VM Monitoring + VMMonitoringFailureInterval = Failure Interval + VMMonitoringMinUpTime = Minimum Uptime + VMMonitoringMaxFailures = Maximum Failures + VMMonitoringMaxFailureWindow = Maximum Failure Window + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + FullyAutomated = Fully Automated + PartiallyAutomated = Partially Automated + Manual = Manual + Off = Off + DRS = vSphere DRS + DPM = DPM + Automated = Automated + None = None + VMGroupType = VM Group + VMHostGroupType = Host Group + MustRunOn = Must run on hosts in group + ShouldRunOn = Should run on hosts in group + MustNotRunOn = Must not run on hosts in group + ShouldNotRunOn = Should not run on hosts in group + VMAffinity = Keep Virtual Machines Together + VMAntiAffinity = Separate Virtual Machines + Mandatory = Mandatory + OverCommitmentRatio = Over-Commitment Ratio + OverCommitmentRatioCluster = Over-Commitment Ratio (% of cluster capacity) + Lowest = Lowest + Low = Low + Medium = Medium + High = High + Highest = Highest + ClusterDefault = Cluster default + VMDependencyTimeout = VM Dependency Restart Condition Timeout + Seconds = {0} seconds + SectionVSphereHA = vSphere HA + IssueEvents = Issue events + PowerOffAndRestart = Power off and restart VMs + ShutdownAndRestartVMs = Shutdown and restart VMs + PowerOffRestartConservative = Power off and restart VMs - Conservative restart policy + PowerOffRestartAggressive = Power off and restart VMs - Aggressive restart policy + PDLFailureResponse = PDL Failure Response + APDFailureResponse = APD Failure Response + VMFailoverDelay = VM Failover Delay + Minutes = {0} minutes + ResponseRecovery = Response Recovery + ResetVMs = Reset VMs + SectionPDLAPD = PDL/APD Protection Settings + NoWindow = No window + WithinHours = Within {0} hrs + VMMonitoringOnly = VM Monitoring Only + VMAndAppMonitoring = VM and Application Monitoring + UserGroup = User/Group + IsGroup = Is Group? + Role = Role + DefinedIn = Defined In + Propagate = Propagate + Permissions = Permissions + ParagraphPermissions = The following table details the permissions for {0}. + TableDRSConfig = vSphere DRS Configuration - {0} + TableDRSAdditional = DRS Additional Options - {0} + TableDPM = vSphere DPM - {0} + TableDRSAdvanced = vSphere DRS Advanced Options - {0} + TableDRSGroups = DRS Cluster Groups - {0} + TableDRSVMHostRules = DRS VM/Host Rules - {0} + TableDRSRules = DRS Rules - {0} + TableDRSVMOverrides = DRS VM Overrides - {0} + TableHAVMOverrides = HA VM Overrides - {0} + TableHAPDLAPD = HA VM Overrides PDL/APD Settings - {0} + TableHAVMMonitoring = HA VM Overrides VM Monitoring - {0} + TablePermissions = Permissions - {0} +'@ + +# Get-AbrVSphereClusterVUM +GetAbrVSphereClusterVUM = ConvertFrom-StringData @' + UpdateManagerBaselines = Update Manager Baselines + Baseline = Baseline + Description = Description + Type = Type + TargetType = Target Type + LastUpdate = Last Update Time + NumPatches = # of Patches + UpdateManagerCompliance = Update Manager Compliance + Entity = Entity + Status = Compliance Status + BaselineInfo = Baseline + VUMPrivilegeMsgBaselines = Insufficient user privileges to report Cluster baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + VUMPrivilegeMsgCompliance = Insufficient user privileges to report Cluster compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + VUMBaselineNotAvailable = Cluster VUM baseline information is not currently available with your version of PowerShell. + VUMComplianceNotAvailable = Cluster VUM compliance information is not currently available with your version of PowerShell. + NotCompliant = Not Compliant + Unknown = Unknown + Incompatible = Incompatible + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} +'@ + +# Get-AbrVSphereResourcePool +GetAbrVSphereResourcePool = ConvertFrom-StringData @' + InfoLevel = ResourcePool InfoLevel set to {0}. + Collecting = Collecting Resource Pool information. + Processing = Processing Resource Pool '{0}' ({1}/{2}). + SectionHeading = Resource Pools + ParagraphSummary = The following sections detail the configuration of resource pools managed by vCenter Server {0}. + ResourcePool = Resource Pool + Parent = Parent + CPUSharesLevel = CPU Shares Level + CPUReservationMHz = CPU Reservation MHz + CPULimitMHz = CPU Limit MHz + MemSharesLevel = Memory Shares Level + MemReservation = Memory Reservation + MemLimit = Memory Limit + ID = ID + NumCPUShares = Number of CPU Shares + CPUReservation = CPU Reservation + CPUExpandable = CPU Expandable Reservation + NumMemShares = Number of Memory Shares + MemExpandable = Memory Expandable Reservation + NumVMs = Number of VMs + VirtualMachines = Virtual Machines + Enabled = Enabled + Disabled = Disabled + Unlimited = Unlimited + TableResourcePoolSummary = Resource Pool Summary - {0} + TableResourcePoolConfig = Resource Pool Configuration - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVMHost +GetAbrVSphereVMHost = ConvertFrom-StringData @' + InfoLevel = VMHost InfoLevel set to {0}. + Collecting = Collecting VMHost information. + Processing = Processing VMHost '{0}' ({1}/{2}). + SectionHeading = Hosts + ParagraphSummary = The following sections detail the configuration of VMware ESXi hosts managed by vCenter Server {0}. + VMHost = Host + Manufacturer = Manufacturer + Model = Model + ProcessorType = Processor Type + NumCPUSockets = CPU Sockets + NumCPUCores = CPU Cores + NumCPUThreads = CPU Threads + MemoryGB = Memory GB + NumNICs = # NICs + NumHBAs = # HBAs + NumDatastores = # Datastores + NumVMs = # VMs + ConnectionState = Connection State + PowerState = Power State + ErrorCollecting = Error collecting VMHost information using VMHost InfoLevel {0}. + NotResponding = Not Responding + Maintenance = Maintenance + Disconnected = Disconnected + Version = Version + Build = Build + Parent = Parent + TableHostSummary = Host Summary - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVMHostHardware +GetAbrVSphereVMHostHardware = ConvertFrom-StringData @' + Collecting = Collecting VMHost Hardware information. + SectionHeading = Hardware + ParagraphSummary = The following section details the host hardware configuration for {0}. + InsufficientPrivLicense = Insufficient user privileges to report ESXi host licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned. + LicenseError = Unable to retrieve license information for VMHost '{0}'. Error: {1} + Specifications = Specifications + Manufacturer = Manufacturer + Model = Model + SerialNumber = Serial Number + AssetTag = Asset Tag + ProcessorType = Processor Type + CPUSockets = CPU Sockets + CPUCores = CPU Cores + CPUThreads = CPU Threads + HyperthreadingActive = Hyperthreading Active + MemoryGB = Memory GB + NUMANodes = NUMA Nodes + NICs = NICs + HBAs = HBAs + Version = Version + Build = Build + LicenseKey = License Key + Product = Product + LicenseExpiration = License Expiration + IPMIBMC = IPMI / BMC + IPMIBMCError = Error collecting IPMI/BMC information for {0}. {1} + IPMIBMCManufacturer = Manufacturer + IPMIBMCType = Type + IPMIBMCIPAddress = IP Address + IPMIBMCMACAddress = MAC Address + BootDevice = Boot Device + BootDeviceError = Error collecting boot device information for {0}. {1} + BootDeviceDescription = Description + BootDeviceType = Type + BootDeviceSize = Size (GB) + BootDeviceIsSAS = Is SAS + BootDeviceIsUSB = Is USB + BootDeviceIsSSD = Is SSD + BootDeviceFromSAN = From SAN + PCIDevices = PCI Devices + PCIDeviceId = PCI ID + PCIVendorName = Vendor Name + PCIDeviceName = Device Name + PCIDriverName = Driver Name + PCIDriverVersion = Driver Version + PCIFirmware = Firmware Version + PCIDriversFirmware = PCI Devices Drivers & Firmware + Enabled = Enabled + Disabled = Disabled + NotApplicable = Not applicable + Unknown = Unknown + Maintenance = Maintenance + NotResponding = Not Responding + Host = Host + ConnectionState = Connection State + ID = ID + Parent = Parent + HyperThreading = HyperThreading + NumberOfCPUSockets = Number of CPU Sockets + NumberOfCPUCores = Number of CPU Cores + NumberOfCPUThreads = Number of CPU Threads + CPUTotalUsedFree = CPU Total / Used / Free + MemoryTotalUsedFree = Memory Total / Used / Free + NumberOfNICs = Number of NICs + NumberOfHBAs = Number of HBAs + NumberOfDatastores = Number of Datastores + NumberOfVMs = Number of VMs + MaximumEVCMode = Maximum EVC Mode + EVCGraphicsMode = EVC Graphics Mode + PowerManagementPolicy = Power Management Policy + ScratchLocation = Scratch Location + BiosVersion = BIOS Version + BiosReleaseDate = BIOS Release Date + BootTime = Boot Time + UptimeDays = Uptime Days + MACAddress = MAC Address + SubnetMask = Subnet Mask + Gateway = Gateway + FirmwareVersion = Firmware Version + Device = Device + BootType = Boot Type + Vendor = Vendor + Size = Size + PCIAddress = PCI Address + DeviceClass = Device Class + TableHardwareConfig = Hardware Configuration - {0} + TableIPMIBMC = IPMI / BMC - {0} + TableBootDevice = Boot Device - {0} + TablePCIDevices = PCI Devices - {0} + TablePCIDriversFirmware = PCI Devices Drivers & Firmware - {0} + PCIDeviceError = Error collecting PCI device information for {0}. {1} + PCIDriversFirmwareError = Error collecting PCI device driver & firmware information for {0}. {1} + HardwareError = Error collecting host hardware information for {0}. {1} + IODeviceIdentifiers = I/O Device Identifiers + VendorID = VID + DeviceID = DID + SubVendorID = SVID + SubDeviceID = SSID + TableIODeviceIdentifiers = I/O Device Identifiers - {0} + IODeviceIdentifiersError = Error collecting I/O device identifier information for {0}. {1} +'@ + +# Get-AbrVSphereVMHostSystem +GetAbrVSphereVMHostSystem = ConvertFrom-StringData @' + Collecting = Collecting VMHost System information. + HostProfile = Host Profile + ProfileName = Host Profile + ProfileCompliance = Compliance + ProfileRemediating = Remediating + ImageProfile = Image Profile + ImageProfileName = Name + ImageProfileVendor = Vendor + ImageProfileAcceptance = Acceptance Level + TimeConfiguration = Time Configuration + NTPServer = NTP Server + TimeZone = Time Zone + Syslog = Syslog + SyslogHost = Syslog Host + VUMBaseline = Update Manager Baselines + VUMBaselineNotAvailable = VMHost VUM baseline information is not currently available with your version of PowerShell. + VUMBaselineName = Baseline + VUMBaselineType = Type + VUMBaselinePatches = # of Patches + VUMCompliance = Update Manager Compliance + VUMComplianceNotAvailable = VMHost VUM compliance information is not currently available with your version of PowerShell. + VUMStatus = Status + AdvancedSettings = Advanced System Settings + Key = Key + Value = Value + VIBs = VMware Installation Bundles (VIBs) + VIBName = Name + VIBVersion = Version + VIBVendor = Vendor + VIBInstallDate = Install Date + VIBAcceptanceLevel = Acceptance Level + SectionHeading = System + ParagraphSummary = The following section details the host system configuration for {0}. + NTPService = NTP Service + NTPServers = NTP Server(s) + SyslogPort = Port + VUMDescription = Description + VUMTargetType = Target Type + VUMLastUpdate = Last Update Time + InstallDate = Installation Date + ImageName = Image Profile + ImageVendor = Vendor + Running = Running + Stopped = Stopped + NotCompliant = Not Compliant + Unknown = Unknown + Incompatible = Incompatible + ProfileDescription = Description + VIBID = ID + VIBCreationDate = Creation Date + TableHostProfile = Host Profile - {0} + TableImageProfile = Image Profile - {0} + TableTimeConfig = Time Configuration - {0} + TableSyslog = Syslog Configuration - {0} + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} + TableAdvancedSettings = Advanced System Settings - {0} + TableVIBs = Software VIBs - {0} + HostProfileError = Error collecting host profile information for {0}. {1} + ImageProfileError = Error collecting image profile information for {0}. {1} + TimeConfigError = Error collecting time configuration for {0}. {1} + SyslogError = Error collecting syslog configuration for {0}. {1} + VUMBaselineError = Error collecting Update Manager baseline information for {0}. {1} + VUMComplianceError = Error collecting Update Manager compliance information for {0}. {1} + AdvancedSettingsError = Error collecting host advanced settings information for {0}. {1} + VIBsError = Error collecting software VIB information for {0}. {1} + InsufficientPrivImageProfile = Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned. + InsufficientPrivVUMBaseline = Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + InsufficientPrivVUMCompliance = Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + SwapFileLocation = VM Swap File Location + SwapFilePlacement = VM Swap File Placement + SwapDatastore = Swap Datastore + WithVM = With VM (Default) + HostLocal = Host Local + TableSwapFileLocation = VM Swap File Location - {0} + SwapFileLocationError = Error collecting VM swap file location for {0}. {1} + HostCertificate = Host Certificate + CertSubject = Subject + CertIssuer = Issuer + CertValidFrom = Valid From + CertValidTo = Valid To + CertThumbprint = SHA-256 Thumbprint + TableHostCertificate = Host Certificate - {0} + HostCertificateError = Error collecting host certificate information for {0}. {1} + LogDir = Log Directory + LogRotations = Log Rotations + LogSize = Log Size (KB) +'@ + +# Get-AbrVSphereVMHostStorage +GetAbrVSphereVMHostStorage = ConvertFrom-StringData @' + Collecting = Collecting VMHost Storage information. + SectionHeading = Storage + DatastoreSpecs = Datastore Specifications + Datastore = Datastore + DatastoreType = Type + DatastoreCapacity = Capacity (GB) + DatastoreFreeSpace = Free Space (GB) + DatastoreState = State + DatastoreShared = Shared + StorageAdapters = Storage Adapters + AdapterName = Adapter + AdapterType = Type + AdapterDriver = Driver + AdapterUID = UID + AdapterModel = Model + AdapterStatus = Status + AdapterSASAddress = SAS Address + AdapterWWN = WWN + AdapterDevices = Devices + AdapterTargets = Targets + ParagraphSummary = The following section details the host storage configuration for {0}. + FC = Fibre Channel + iSCSI = iSCSI + ParallelSCSI = Parallel SCSI + ChapNone = None + ChapUniPreferred = Use unidirectional CHAP unless prohibited by target + ChapUniRequired = Use unidirectional CHAP if required by target + ChapUnidirectional = Use unidirectional CHAP + ChapBidirectional = Use bidirectional CHAP + Online = Online + Offline = Offline + Type = Type + Version = Version + NumberOfVMs = # of VMs + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + TableDatastores = Datastores - {0} + ParagraphStorageAdapters = The following section details the storage adapter configuration for {0}. + AdapterPaths = Paths + iSCSIName = iSCSI Name + iSCSIAlias = iSCSI Alias + AdapterSpeed = Speed + DynamicDiscovery = Dynamic Discovery + StaticDiscovery = Static Discovery + AuthMethod = Authentication Method + CHAPOutgoing = Outgoing CHAP Name + CHAPIncoming = Incoming CHAP Name + AdvancedOptions = Advanced Options + NodeWWN = Node WWN + PortWWN = Port WWN + TableStorageAdapter = Storage Adapter {0} - {1} +'@ + +# Get-AbrVSphereVMHostNetwork +GetAbrVSphereVMHostNetwork = ConvertFrom-StringData @' + Collecting = Collecting VMHost Network information. + SectionHeading = Network + NetworkConfig = Network Configuration + VMKernelAdapters = VMkernel Adapters + PhysicalAdapters = Physical Adapters + CDP = Cisco Discovery Protocol + LLDP = Link Layer Discovery Protocol + StandardvSwitches = Standard Virtual Switches + AdapterName = Adapter + AdapterMAC = MAC Address + AdapterLinkSpeed = Link Speed + AdapterDriver = Driver + AdapterPCIID = PCI Device + AdapterStatus = Status + VMKName = VMkernel Adapter + VMKIP = IP Address + VMKSubnet = Subnet Mask + VMKGateway = Default Gateway + VMKMTU = MTU + VMKPortGroup = Port Group + VMKVirtualSwitch = Virtual Switch + VMKDHCPEnabled = DHCP Enabled + VMKServicesEnabled = Enabled Services + vSwitch = Virtual Switch + vSwitchPorts = Total Ports + vSwitchUsedPorts = Used Ports + vSwitchAvailablePorts = Available Ports + vSwitchMTU = MTU + vSwitchCDPStatus = CDP Status + vSwitchSecurity = Security Policy + vSwitchFailover = Failover Policy + vSwitchLoadBalancing = Load Balancing + vSwitchPortGroups = Port Groups + PortGroup = Port Group + VLAN = VLAN ID + ActiveAdapters = Active Adapters + StandbyAdapters = Standby Adapters + UnusedAdapters = Unused Adapters + ParagraphSummary = The following section details the host network configuration for {0}. + Enabled = Enabled + Disabled = Disabled + Connected = Connected + Disconnected = Disconnected + Yes = Yes + No = No + Accept = Accept + Reject = Reject + Supported = Supported + NotSupported = Not Supported + Inherited = Inherited + TCPDefault = Default + TCPProvisioning = Provisioning + TCPvMotion = vMotion + TCPNsxOverlay = nsx-overlay + TCPNsxHyperbus = nsx-hyperbus + TCPNotApplicable = Not Applicable + LBSrcId = Route based on the originating port ID + LBSrcMac = Route based on source MAC hash + LBIP = Route based on IP hash + LBExplicitFailover = Explicit Failover + NFDLinkStatus = Link status only + NFDBeaconProbing = Beacon probing + FullDuplex = Full Duplex + AutoNegotiate = Auto negotiate + Down = Down + Host = Host + VirtualSwitches = Virtual Switches + VMkernelGateway = VMkernel Gateway + IPv6 = IPv6 + VMkernelIPv6Gateway = VMkernel IPv6 Gateway + DNSServers = DNS Servers + HostName = Host Name + DomainName = Domain Name + SearchDomain = Search Domain + TableNetworkConfig = Network Configuration - {0} + ParagraphPhysicalAdapters = The following section details the physical network adapter configuration for {0}. + VirtualSwitch = Virtual Switch + ActualSpeedDuplex = Actual Speed, Duplex + ConfiguredSpeedDuplex = Configured Speed, Duplex + WakeOnLAN = Wake on LAN + TablePhysicalAdapter = Physical Adapter {0} - {1} + TablePhysicalAdapters = Physical Adapters - {0} + ParagraphCDP = The following section details the CDP information for {0}. + Status = Status + SystemName = System Name + HardwarePlatform = Hardware Platform + SwitchID = Switch ID + SoftwareVersion = Software Version + ManagementAddress = Management Address + Address = Address + PortID = Port ID + MTU = MTU + TableAdapterCDP = Network Adapter {0} CDP Information - {1} + TableAdaptersCDP = Network Adapter CDP Information - {0} + ParagraphLLDP = The following section details the LLDP information for {0}. + ChassisID = Chassis ID + TimeToLive = Time to live + TimeOut = TimeOut + Samples = Samples + PortDescription = Port Description + SystemDescription = System Description + TableAdapterLLDP = Network Adapter {0} LLDP Information - {1} + TableAdaptersLLDP = Network Adapter LLDP Information - {0} + ParagraphVMKernelAdapters = The following section details the VMkernel adapter configuration for {0}. + NetworkLabel = Network Label + TCPIPStack = TCP/IP Stack + DHCP = DHCP + IPAddress = IP Address + SubnetMask = Subnet Mask + DefaultGateway = Default Gateway + vMotion = vMotion + Provisioning = Provisioning + FTLogging = FT Logging + Management = Management + vSphereReplication = vSphere Replication + vSphereReplicationNFC = vSphere Replication NFC + vSAN = vSAN + vSANWitness = vSAN Witness + vSphereBackupNFC = vSphere Backup NFC + TableVMKernelAdapter = VMkernel Adapter {0} - {1} + ParagraphStandardvSwitches = The following section details the standard virtual switch configuration for {0}. + NumberOfPorts = Number of Ports + NumberOfPortsAvailable = Number of Ports Available + TableStandardvSwitches = Standard Virtual Switches - {0} + VSSecurity = Virtual Switch Security + PromiscuousMode = Promiscuous Mode + MACAddressChanges = MAC Address Changes + ForgedTransmits = Forged Transmits + TableVSSecurity = Virtual Switch Security Policy - {0} + VSTrafficShaping = Virtual Switch Traffic Shaping + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + TableVSTrafficShaping = Virtual Switch Traffic Shaping Policy - {0} + VSTeamingFailover = Virtual Switch Teaming & Failover + LoadBalancing = Load Balancing + NetworkFailureDetection = Network Failure Detection + NotifySwitches = Notify Switches + Failback = Failback + ActiveNICs = Active NICs + StandbyNICs = Standby NICs + UnusedNICs = Unused NICs + TableVSTeamingFailover = Virtual Switch Teaming & Failover - {0} + VSPortGroups = Virtual Switch Port Groups + NumberOfVMs = # of VMs + TableVSPortGroups = Virtual Switch Port Groups - {0} + VSPGSecurity = Virtual Switch Port Group Security + MACChanges = MAC Changes + TableVSPGSecurity = Virtual Switch Port Group Security Policy - {0} + VSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping + TableVSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping Policy - {0} + VSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover + TableVSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover - {0} +'@ + +# Get-AbrVSphereVMHostSecurity +GetAbrVSphereVMHostSecurity = ConvertFrom-StringData @' + Collecting = Collecting VMHost Security information. + SectionHeading = Security + LockdownMode = Lockdown Mode + Services = Services + ServiceName = Service + ServiceRunning = Running + ServicePolicy = Startup Policy + ServiceRequired = Required + Firewall = Firewall + FirewallRule = Rule + FirewallAllowed = Allowed Hosts + Authentication = Authentication + Domain = Domain + Trust = Trusted Domains + Membership = Domain Membership + VMInfoSection = Virtual Machines + VMName = Virtual Machine + VMPowerState = Power State + VMIPAddress = IP Address + VMOS = OS + VMGuestID = Guest ID + VMCPUs = CPUs + VMMemoryGB = Memory GB + VMDisks = Disks (GB) + VMNICs = NICs + StartupShutdown = VM Startup/Shutdown + StartupEnabled = Startup Enabled + StartupOrder = Startup Order + StartupDelay = Startup Delay + StopAction = Stop Action + StopDelay = Stop Delay + WaitForHeartbeat = Wait For Heartbeat + ParagraphSummary = The following section details the host security configuration for {0}. + LockdownDisabled = Disabled + LockdownNormal = Enabled (Normal) + LockdownStrict = Enabled (Strict) + Running = Running + Stopped = Stopped + SvcPortUsage = Start and stop with port usage + SvcWithHost = Start and stop with host + SvcManually = Start and stop manually + On = On + Off = Off + Enabled = Enabled + Disabled = Disabled + WaitHeartbeat = Continue if VMware Tools is started + WaitDelay = Wait for startup delay + PowerOff = Power Off + GuestShutdown = Guest Shutdown + ToolsOld = Old + ToolsOK = OK + ToolsNotRunning = Not Running + ToolsNotInstalled = Not Installed + TableLockdownMode = Lockdown Mode - {0} + TableServices = Services - {0} + FirewallService = Service + Status = Status + IncomingPorts = Incoming Ports + OutgoingPorts = Outgoing Ports + Protocols = Protocols + Daemon = Daemon + TableFirewall = Firewall Configuration - {0} + DomainMembership = Domain Membership + TrustedDomains = Trusted Domains + TableAuthentication = Authentication Services - {0} + ParagraphVMInfo = The following section details the virtual machine configuration for {0}. + VMProvisioned = Provisioned + VMUsed = Used + VMHWVersion = HW Version + VMToolsStatus = VM Tools Status + TableVMs = Virtual Machines - {0} + TableStartupShutdown = VM Startup/Shutdown Policy - {0} + TpmEncryption = TPM & Encryption + TpmPresent = TPM Present + TpmStatus = TPM Attestation Status + EncryptionMode = Encryption Mode + RequireSecureBoot = Require Secure Boot + RequireSignedVIBs = Require Executables From Installed VIBs Only + RecoveryKeys = Encryption Recovery Keys + RecoveryID = Recovery ID + RecoveryKey = Recovery Key + TpmEncryptionError = Unable to retrieve TPM & Encryption information for host {0}. {1} + TableTpmEncryption = TPM & Encryption - {0} + TableRecoveryKeys = Encryption Recovery Keys - {0} + Yes = Yes + No = No +'@ + +# Get-AbrVSphereNetwork +GetAbrVSphereNetwork = ConvertFrom-StringData @' + InfoLevel = Network InfoLevel set to {0}. + Collecting = Collecting Distributed Switch information. + Processing = Processing Distributed Switch '{0}' ({1}/{2}). + SectionHeading = Distributed Switches + ParagraphSummary = The following sections detail the configuration of distributed switches managed by vCenter Server {0}. + VDSwitch = Distributed Switch + Datacenter = Datacenter + Manufacturer = Manufacturer + NumUplinks = # Uplinks + NumPorts = # Ports + NumHosts = # Hosts + NumVMs = # VMs + Version = Version + MTU = MTU + ID = ID + NumberOfUplinks = Number of Uplinks + NumberOfPorts = Number of Ports + NumberOfPortGroups = Number of Port Groups + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + Hosts = Hosts + VirtualMachines = Virtual Machines + NIOC = Network I/O Control + DiscoveryProtocol = Discovery Protocol + DiscoveryOperation = Discovery Operation + NumPortGroups = # Port Groups + MaxPorts = Max Ports + Contact = Contact + Location = Location + VDPortGroups = Distributed Port Groups + PortGroup = Port Group + PortGroupType = Port Group Type + VLANID = VLAN ID + VLANConfiguration = VLAN Configuration + PortBinding = Port Binding + Host = Host + UplinkName = Uplink Name + UplinkPortGroup = Uplink Port Group + PhysicalNetworkAdapter = Physical Network Adapter + ActiveUplinks = Active Uplinks + StandbyUplinks = Standby Uplinks + UnusedUplinks = Unused Uplinks + AllowPromiscuous = Allow Promiscuous + ForgedTransmits = Forged Transmits + MACAddressChanges = MAC Address Changes + Accept = Accept + Reject = Reject + Direction = Direction + Status = Status + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + LoadBalancing = Load Balancing + LoadBalanceSrcId = Route based on the originating port ID + LoadBalanceSrcMac = Route based on source MAC hash + LoadBalanceIP = Route based on IP hash + ExplicitFailover = Explicit Failover + NetworkFailureDetection = Network Failure Detection + LinkStatus = Link status only + BeaconProbing = Beacon probing + NotifySwitches = Notify Switches + FailbackEnabled = Failback Enabled + Yes = Yes + No = No + PrimaryVLANID = Primary VLAN ID + PrivateVLANType = Private VLAN Type + SecondaryVLANID = Secondary VLAN ID + UplinkPorts = Distributed Switch Uplink Ports + VDSSecurity = Distributed Switch Security + VDSTrafficShaping = Distributed Switch Traffic Shaping + VDSPortGroups = Distributed Switch Port Groups + VDSPortGroupSecurity = Distributed Switch Port Group Security + VDSPortGroupTrafficShaping = Distributed Switch Port Group Traffic Shaping + VDSPortGroupTeaming = Distributed Switch Port Group Teaming & Failover + VDSPrivateVLANs = Distributed Switch Private VLANs + Enabled = Enabled + Disabled = Disabled + Listen = Listen + Advertise = Advertise + Both = Both + TableVDSSummary = Distributed Switch Summary - {0} + TableVDSGeneral = Distributed Switch General Properties - {0} + TableVDSUplinkPorts = Distributed Switch Uplink Ports - {0} + TableVDSSecurity = Distributed Switch Security - {0} + TableVDSTrafficShaping = Distributed Switch Traffic Shaping - {0} + TableVDSPortGroups = Distributed Switch Port Groups - {0} + TableVDSPortGroupSecurity = Distributed Switch Port Group Security - {0} + TableVDSPortGroupTrafficShaping = Distributed Switch Port Group Traffic Shaping - {0} + TableVDSPortGroupTeaming = Distributed Switch Port Group Teaming & Failover - {0} + TableVDSPrivateVLANs = Distributed Switch Private VLANs - {0} + VDSLACP = Distributed Switch LACP + LACPEnabled = LACP Enabled + LACPMode = LACP Mode + LACPActive = Active + LACPPassive = Passive + VDSNetFlow = Distributed Switch NetFlow + CollectorIP = Collector IP Address + CollectorPort = Collector Port + ActiveFlowTimeout = Active Flow Timeout (s) + IdleFlowTimeout = Idle Flow Timeout (s) + SamplingRate = Sampling Rate + InternalFlowsOnly = Internal Flows Only + NIOCResourcePools = Network I/O Control Resource Pools + NIOCResourcePool = Resource Pool + NIOCSharesLevel = Shares Level + NIOCSharesValue = Shares + NIOCLimitMbps = Limit (Mbps) + Unlimited = Unlimited + TableVDSLACP = Distributed Switch LACP - {0} + TableVDSNetFlow = Distributed Switch NetFlow - {0} + TableNIOCResourcePools = Network I/O Control Resource Pools - {0} + Tags = Tags +'@ + +# Get-AbrVSpherevSAN +GetAbrVSpherevSAN = ConvertFrom-StringData @' + InfoLevel = vSAN InfoLevel set to {0}. + Collecting = Collecting vSAN information. + CollectingESA = Collecting vSAN ESA information for '{0}'. + CollectingOSA = Collecting vSAN OSA information for '{0}'. + CollectingDisks = Collecting vSAN disk information for '{0}'. + CollectingDiskGroups = Collecting vSAN disk group information for '{0}'. + CollectingiSCSITargets = Collecting vSAN iSCSI target information for '{0}'. + CollectingiSCSILUNs = Collecting vSAN iSCSI LUN information for '{0}'. + Processing = Processing vSAN Cluster '{0}' ({1}/{2}). + SectionHeading = vSAN + ParagraphSummary = The following sections detail the configuration of VMware vSAN managed by vCenter Server {0}. + ParagraphDetail = The following table details the vSAN configuration for cluster {0}. + DisksSection = Disks + DiskGroupsSection = Disk Groups + iSCSITargetsSection = iSCSI Targets + iSCSILUNsSection = iSCSI LUNs + Cluster = Cluster + StorageType = Storage Type + ClusterType = Cluster Type + NumHosts = # of Hosts + ID = ID + NumberOfHosts = Number of Hosts + NumberOfDisks = Number of Disks + NumberOfDiskGroups = Number of Disk Groups + DiskClaimMode = Disk Claim Mode + PerformanceService = Performance Service + FileService = File Service + iSCSITargetService = iSCSI Target Service + HistoricalHealthService = Historical Health Service + HealthCheck = Health Check + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + HCLLastUpdated = HCL Last Updated + Hosts = Hosts + Version = Version + Stretched = Stretched Cluster + VSANEnabled = vSAN Enabled + VSANESAEnabled = vSAN ESA Enabled + DisksFormat = Disk Format Version + Deduplication = Deduplication and Compression + AllFlash = All Flash + FaultDomains = Fault Domains + PFTT = Primary Failures to Tolerate + SFTT = Secondary Failures to Tolerate + NetworkDiagnosticMode = Network Diagnostic Mode + HybridMode = Hybrid Mode + AutoRebalance = Automatic Rebalance + ProactiveDisk = Proactive Disk Rebalance + ResyncThrottle = Resync Throttle + SpaceEfficiency = Space Efficiency + Encryption = Encryption + FileServiceEnabled = File Service Enabled + iSCSITargetEnabled = iSCSI Target Enabled + VMHostSpecs = VMHost vSAN Specifications + VMHost = VMHost + DiskGroup = Disk Group + CacheDisks = Cache Disks + DataDisks = Data Disks + DiskGroups = Disk Groups + CacheTier = Cache Tier + DataTier = Data Tier + Status = Status + FaultDomainName = Fault Domain + VSANAdvancedOptions = vSAN Advanced Configuration Options + Key = Key + Value = Value + IDs = Identifiers + VSAN_UUID = vSAN UUID + CapacityTier = Capacity Tier (GB) + BufferTier = Buffer Tier (GB) + DiskName = Disk + Name = Name + DriveType = Drive Type + Host = Host + State = State + Encrypted = Encrypted + Capacity = Capacity + SerialNumber = Serial Number + Vendor = Vendor + Model = Model + DiskType = Disk Type + DiskFormatVersion = Disk Format Version + ClaimedAs = Claimed As + NumDisks = # of Disks + Type = Type + IQN = IQN + Alias = Alias + LUNsCount = LUNs + NetworkInterface = Network Interface + IOOwnerHost = I/O Owner Host + TCPPort = TCP Port + Health = Health + StoragePolicy = Storage Policy + ComplianceStatus = Compliance Status + Authentication = Authentication + LUNName = LUN + LUNID = LUN ID + Yes = Yes + No = No + Enabled = Enabled + Disabled = Disabled + Online = Online + Offline = Offline + Mounted = Mounted + Unmounted = Unmounted + Flash = Flash + HDD = HDD + Cache = Cache + TableVSANClusterSummary = vSAN Cluster Summary - {0} + TableVSANConfiguration = vSAN Configuration - {0} + TableDisk = Disk {0} - {1} + TableVSANDisks = vSAN Disks - {0} + TableVSANDiskGroups = vSAN Disk Groups - {0} + TableVSANiSCSITargets = vSAN iSCSI Targets - {0} + TableVSANiSCSILUNs = vSAN iSCSI LUNs - {0} + ESAError = Error collecting vSAN ESA information for '{0}'. {1} + OSAError = Error collecting vSAN OSA information for '{0}'. {1} + DiskError = Error collecting vSAN disk information for '{0}'. {1} + DiskGroupError = Error collecting vSAN disk group information for '{0}'. {1} + iSCSITargetError = Error collecting vSAN iSCSI target information for '{0}'. {1} + iSCSILUNError = Error collecting vSAN iSCSI LUN information for '{0}'. {1} + ServicesSection = vSAN Services + Service = Service + TableVSANServices = vSAN Services - {0} + ServicesError = Error collecting vSAN services information for '{0}'. {1} +'@ + +# Get-AbrVSphereDatastore +GetAbrVSphereDatastore = ConvertFrom-StringData @' + InfoLevel = Datastore InfoLevel set to {0}. + Collecting = Collecting Datastore information. + Processing = Processing Datastore '{0}' ({1}/{2}). + SectionHeading = Datastores + ParagraphSummary = The following sections detail the configuration of datastores managed by vCenter Server {0}. + Datastore = Datastore + Type = Type + DatastoreURL = URL + FileSystem = File System Version + CapacityGB = Total Capacity (GB) + FreeSpaceGB = Free Space (GB) + UsedSpaceGB = Used Space (GB) + State = State + Accessible = Accessible + NumHosts = # Hosts + NumVMs = # VMs + SIOC = Storage I/O Control + IOLatencyThreshold = I/O Latency Threshold (ms) + IOLoadBalancing = I/O Load Balancing + Enabled = Enabled + Disabled = Disabled + Normal = Normal + Maintenance = Maintenance + Unmounted = Unmounted + ID = ID + Datacenter = Datacenter + Version = Version + NumberOfHosts = Number of Hosts + NumberOfVMs = Number of VMs + CongestionThreshold = Congestion Threshold + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + Hosts = Hosts + VirtualMachines = Virtual Machines + SCSILUNInfo = SCSI LUN Information + Host = Host + CanonicalName = Canonical Name + Capacity = Capacity + Vendor = Vendor + Model = Model + IsSSD = Is SSD + MultipathPolicy = Multipath Policy + Paths = Paths + TableDatastoreSummary = Datastore Summary - {0} + TableDatastoreConfig = Datastore Configuration - {0} + TableSCSILUN = SCSI LUN Information - {0} + Tags = Tags +'@ + +# Get-AbrVSphereDSCluster +GetAbrVSphereDSCluster = ConvertFrom-StringData @' + InfoLevel = DSCluster InfoLevel set to {0}. + Collecting = Collecting Datastore Cluster information. + Processing = Processing Datastore Cluster '{0}' ({1}/{2}). + SectionHeading = Datastore Clusters + ParagraphSummary = The following sections detail the configuration of datastore clusters managed by vCenter Server {0}. + DSCluster = Datastore Cluster + Datacenter = Datacenter + CapacityGB = Total Capacity (GB) + FreeSpaceGB = Free Space (GB) + SDRSEnabled = SDRS + SDRSAutomationLevel = SDRS Automation Level + IOLoadBalancing = I/O Load Balancing + SpaceThreshold = Space Threshold (%) + IOLatencyThreshold = I/O Latency Threshold (ms) + SDRSRules = SDRS Rules + RuleName = Rule + RuleEnabled = Enabled + RuleVMs = Virtual Machines + FullyAutomated = Fully Automated + NoAutomation = No Automation (Manual Mode) + Manual = Manual + Enabled = Enabled + Disabled = Disabled + Yes = Yes + No = No + ID = ID + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + ParagraphDSClusterDetail = The following table details the configuration for datastore cluster {0}. + TableDSClusterConfig = Datastore Cluster Configuration - {0} + TableSDRSVMOverrides = SDRS VM Overrides - {0} + SDRSVMOverrides = SDRS VM Overrides + VirtualMachine = Virtual Machine + KeepVMDKsTogether = Keep VMDKs Together + DefaultBehavior = Default ({0}) + RuleType = Type + RuleAffinity = Affinity + RuleAntiAffinity = Anti-Affinity + TableSDRSRules = SDRS Rules - {0} + SpaceLoadBalanceConfig = Space Load Balance Configuration + SpaceMinDiff = Min Space Utilization Difference (%) + SpaceThresholdMode = Space Threshold Mode + UtilizationMode = Utilization Threshold + FreeSpaceMode = Free Space Threshold + UtilizationThreshold = Space Utilization Threshold (%) + FreeSpaceThreshold = Free Space Threshold (GB) + IOLoadBalanceConfig = I/O Load Balance Configuration + IOCongestionThreshold = I/O Congestion Threshold (ms) + IOReservationMode = Reservation Threshold Mode + IOPSThresholdMode = I/O Operations Count + ReservationMbpsMode = Reservation in Mbps + ReservationIopsMode = Reservation in IOPS + TableSpaceLoadBalance = Space Load Balance Configuration - {0} + TableIOLoadBalance = I/O Load Balance Configuration - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVM +GetAbrVSphereVM = ConvertFrom-StringData @' + InfoLevel = VM InfoLevel set to {0}. + Collecting = Collecting Virtual Machine information. + Processing = Processing Virtual Machine '{0}' ({1}/{2}). + SectionHeading = Virtual Machines + ParagraphSummary = The following sections detail the configuration of virtual machines managed by vCenter Server {0}. + VirtualMachine = Virtual Machine + PowerState = Power State + Template = Template + OS = OS + Version = VM Hardware Version + GuestID = Guest ID + Cluster = Cluster + ResourcePool = Resource Pool + VMHost = Host + Folder = Folder + IPAddress = IP Address + CPUs = CPUs + MemoryGB = Memory GB + ProvisionedGB = Provisioned (GB) + UsedGB = Used (GB) + NumDisks = # Disks + NumNICs = # NICs + NumSnapshots = # Snapshots + VMwareTools = VMware Tools + ToolsVersion = Tools Version + ToolsStatus = Tools Status + ToolsRunningStatus = Tools Running Status + VMAdvancedDetail = Advanced Configuration + BootOptions = Boot Options + BootDelay = Boot Delay (ms) + BootRetryEnabled = Boot Retry Enabled + BootRetryDelay = Boot Retry Delay (ms) + EFISecureBoot = EFI Secure Boot + EnterBIOSSetup = Enter BIOS Setup on Next Boot + HardDisks = Hard Disks + DiskName = Disk + DiskCapacityGB = Capacity (GB) + DiskFormat = Format + DiskStoragePolicy = Storage Policy + DiskDatastore = Datastore + DiskController = Controller + NetworkAdapters = Network Adapters + NICName = Network Adapter + NICType = Adapter Type + NICPortGroup = Port Group + NICMAC = MAC Address + NICConnected = Connected + NICConnectionPolicy = Connect at Power On + SnapshotHeading = Snapshots + SnapshotName = Snapshot + SnapshotDescription = Description + SnapshotSize = Size (GB) + SnapshotDate = Created + SnapshotParent = Parent + On = On + Off = Off + ToolsOld = Old + ToolsOK = OK + ToolsNotRunning = Not Running + ToolsNotInstalled = Not Installed + Yes = Yes + No = No + Connected = Connected + NotConnected = Not Connected + Thin = Thin + Thick = Thick + Enabled = Enabled + Disabled = Disabled + TotalVMs = Total VMs + TotalvCPUs = Total vCPUs + TotalMemory = Total Memory + TotalProvisionedSpace = Total Provisioned Space + TotalUsedSpace = Total Used Space + VMsPoweredOn = VMs Powered On + VMsPoweredOff = VMs Powered Off + VMsOrphaned = VMs Orphaned + VMsInaccessible = VMs Inaccessible + VMsSuspended = VMs Suspended + VMsWithSnapshots = VMs with Snapshots + GuestOSTypes = Guest Operating System Types + VMToolsOKCount = VM Tools OK + VMToolsOldCount = VM Tools Old + VMToolsNotRunningCount = VM Tools Not Running + VMToolsNotInstalledCount = VM Tools Not Installed + vCPUs = vCPUs + Memory = Memory + Provisioned = Provisioned + Used = Used + HWVersion = HW Version + VMToolsStatus = VM Tools Status + ID = ID + OperatingSystem = Operating System + HardwareVersion = Hardware Version + ConnectionState = Connection State + FaultToleranceState = Fault Tolerance State + FTNotConfigured = Not Configured + FTNeedsSecondary = Needs Secondary + FTRunning = Running + FTDisabled = Disabled + FTStarting = Starting + FTEnabled = Enabled + Parent = Parent + ParentFolder = Parent Folder + ParentResourcePool = Parent Resource Pool + CoresPerSocket = Cores per Socket + CPUShares = CPU Shares + CPUReservation = CPU Reservation + CPULimit = CPU Limit + CPUHotAdd = CPU Hot Add + CPUHotRemove = CPU Hot Remove + MemoryAllocation = Memory Allocation + MemoryShares = Memory Shares + MemoryHotAdd = Memory Hot Add + vNICs = vNICs + DNSName = DNS Name + Networks = Networks + MACAddress = MAC Address + vDisks = vDisks + ProvisionedSpace = Provisioned Space + UsedSpace = Used Space + ChangedBlockTracking = Changed Block Tracking + StorageBasedPolicy = Storage Based Policy + StorageBasedPolicyCompliance = Storage Based Policy Compliance + Compliant = Compliant + NonCompliant = Non Compliant + Unknown = Unknown + Notes = Notes + BootTime = Boot Time + UptimeDays = Uptime Days + NetworkName = Network Name + SCSIControllers = SCSI Controllers + Device = Device + ControllerType = Controller Type + BusSharing = Bus Sharing + None = None + GuestVolumes = Guest Volumes + Capacity = Capacity + DiskProvisioning = Disk Provisioning + ThickEagerZeroed = Thick Eager Zeroed + ThickLazyZeroed = Thick Lazy Zeroed + DiskType = Disk Type + PhysicalRDM = Physical RDM + VirtualRDM = Virtual RDM + VMDK = VMDK + DiskMode = Disk Mode + IndependentPersistent = Independent - Persistent + IndependentNonpersistent = Independent - Nonpersistent + Dependent = Dependent + DiskPath = Disk Path + DiskShares = Disk Shares + DiskLimitIOPs = Disk Limit IOPs + Unlimited = Unlimited + SCSIController = SCSI Controller + SCSIAddress = SCSI Address + Path = Path + FreeSpace = Free Space + DaysOld = Days Old + TableVMSummary = VM Summary - {0} + TableVMAdvancedSummary = VM Advanced Summary - {0} + TableVMSnapshotSummary = VM Snapshot Summary - {0} + TableVMConfig = VM Configuration - {0} + TableVMNetworkAdapters = Network Adapters - {0} + TableVMSCSIControllers = SCSI Controllers - {0} + TableVMHardDiskConfig = Hard Disk Configuration - {0} + TableVMHardDisk = {0} - {1} + TableVMGuestVolumes = Guest Volumes - {0} + TableVMSnapshots = VM Snapshots - {0} + VUMCompliance = VM Update Manager Compliance + VUMBaselineName = Baseline + VUMStatus = Status + NotCompliant = Not Compliant + Incompatible = Incompatible + VUMComplianceError = Unable to retrieve VUM compliance information for virtual machines. + InsufficientPrivVUMCompliance = Insufficient privileges to collect VUM compliance information for virtual machines. + TableVUMCompliance = VUM Baseline Compliance - {0} + Tags = Tags +'@ + +# Get-AbrVSphereVUM +GetAbrVSphereVUM = ConvertFrom-StringData @' + InfoLevel = VUM InfoLevel set to {0}. + Collecting = Collecting VMware Update Manager information. + NotAvailable = VUM patch baseline information is not currently available with your version of PowerShell. + PatchNotAvailable = VUM patch information is not currently available with your version of PowerShell. + SectionHeading = VMware Update Manager + ParagraphSummary = The following sections detail the configuration of VMware Update Manager managed by vCenter Server {0}. + Baselines = Baselines + BaselineName = Baseline + Description = Description + Type = Type + TargetType = Target Type + LastUpdate = Last Update Time + NumPatches = # of Patches + Patches = Patches + PatchName = Patch + PatchProduct = Product + PatchDescription = Description + PatchReleaseDate = Release Date + PatchVendorID = Vendor ID + TableVUMBaselines = VMware Update Manager Baseline Summary - {0} + TableVUMPatches = VMware Update Manager Patch Information - {0} + SoftwareDepots = Software Depots + OnlineDepots = Online Depots + OfflineDepots = Offline Depots + DepotUrl = URL + SystemDefined = System Defined + DepotEnabled = Enabled + DepotLocation = Location + DepotError = Unable to retrieve software depot information. {0} + TableOnlineDepots = Online Software Depots - {0} + TableOfflineDepots = Offline Software Depots - {0} +'@ + +# Get-AbrVSphereClusterLCM +GetAbrVSphereClusterLCM = ConvertFrom-StringData @' + Collecting = Collecting Lifecycle Manager information. + ImageComposition = Image Composition + BaseImage = Base Image + VendorAddOn = Vendor Add-On + None = None + Components = Components + ComponentName = Component + ComponentVersion = Version + HardwareSupportManager = Hardware Support Manager + HsmName = Name + HsmVersion = Version + HsmPackages = Hardware Support Packages + ImageCompliance = Image Compliance + Cluster = Cluster + VMHost = VMHost + ComplianceStatus = Compliance Status + LcmError = Unable to retrieve Lifecycle Manager information for cluster {0}. {1} + ComplianceError = Unable to retrieve compliance information for cluster {0}. {1} + TableImageComposition = Image Composition - {0} + TableComponents = Image Components - {0} + TableHardwareSupportManager = Hardware Support Manager - {0} + TableImageCompliance = Image Compliance - {0} + TableHostCompliance = Host Image Compliance - {0} +'@ + +} diff --git a/AsBuiltReport.VMware.vSphere/Language/es-ES/VMwarevSphere.psd1 b/AsBuiltReport.VMware.vSphere/Language/es-ES/VMwarevSphere.psd1 new file mode 100644 index 0000000..7ab172f --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Language/es-ES/VMwarevSphere.psd1 @@ -0,0 +1,1625 @@ +# culture = 'es-ES' +@{ + +# Module-wide strings +InvokeAsBuiltReportVMwarevSphere = ConvertFrom-StringData @' + Connecting = Conectando al servidor vCenter '{0}'. + CheckPrivileges = Comprobando los privilegios del usuario de vCenter. + UnablePrivileges = No se han podido obtener los privilegios del usuario de vCenter. + VMHashtable = Creando tabla de búsqueda de máquinas virtuales. + VMHostHashtable = Creando tabla de búsqueda de hosts VMware. + DatastoreHashtable = Creando tabla de búsqueda de almacenes de datos. + VDPortGrpHashtable = Creando tabla de búsqueda de grupos de puertos distribuidos. + EVCHashtable = Creando tabla de búsqueda de modos EVC. + CheckVUM = Comprobando el servidor VMware Update Manager. + CheckVxRail = Comprobando el servidor VxRail Manager. + CheckSRM = Comprobando el servidor VMware Site Recovery Manager. + CheckNSXT = Comprobando el servidor VMware NSX-T Manager. + CollectingTags = Recopilando información de etiquetas. + TagError = Error al recopilar información de etiquetas. + CollectingAdvSettings = Recopilando configuración avanzada de {0}. +'@ + +# Get-AbrVSpherevCenter +GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = Nivel de información de vCenter establecido en {0}. + Collecting = Recopilando información del servidor vCenter. + SectionHeading = Servidor vCenter + ParagraphSummaryBrief = Las siguientes secciones resumen la configuración del servidor vCenter {0}. + ParagraphSummary = Las siguientes secciones detallan la configuración del servidor vCenter {0}. + InsufficientPrivLicense = Privilegios de usuario insuficientes para informar sobre las licencias del servidor vCenter. Asegúrese de que la cuenta de usuario tenga asignado el privilegio 'Global > Licencias'. + InsufficientPrivStoragePolicy = Privilegios de usuario insuficientes para informar sobre las políticas de almacenamiento de máquinas virtuales. Asegúrese de que la cuenta de usuario tenga asignado el privilegio 'Perfil de almacenamiento > Ver'. + vCenterServer = Servidor vCenter + IPAddress = Dirección IP + Version = Versión + Build = Compilación + Product = Producto + LicenseKey = Clave de licencia + LicenseExpiration = Vencimiento de licencia + InstanceID = ID de instancia + HTTPPort = Puerto HTTP + HTTPSPort = Puerto HTTPS + PSC = Platform Services Controller + UpdateManagerServer = Servidor Update Manager + SRMServer = Servidor Site Recovery Manager + NSXTServer = Servidor NSX-T Manager + VxRailServer = Servidor VxRail Manager + DatabaseSettings = Configuración de base de datos + DatabaseType = Tipo de base de datos + DataSourceName = Nombre del origen de datos + MaxDBConnection = Conexiones máximas a la base de datos + MailSettings = Configuración de correo + SMTPServer = Servidor SMTP + SMTPPort = Puerto SMTP + MailSender = Remitente de correo + HistoricalStatistics = Estadísticas históricas + IntervalDuration = Duración del intervalo + IntervalEnabled = Intervalo habilitado + SaveDuration = Duración de retención + StatisticsLevel = Nivel de estadísticas + Licensing = Licencias + Total = Total + Used = Usado + Available = Disponible + Expiration = Vencimiento + Certificate = Certificado + Subject = Asunto + Issuer = Emisor + ValidFrom = Válido desde + ValidTo = Válido hasta + Thumbprint = Huella digital + CertStatus = Estado + InsufficientPrivCertificate = No se puede recuperar el certificado del servidor vCenter. {0} + Mode = Modo + SoftThreshold = Umbral suave + HardThreshold = Umbral estricto + MinutesBefore = Minutos antes + PollInterval = Intervalo de sondeo + Roles = Roles + Role = Rol + SystemRole = Rol del sistema + PrivilegeList = Lista de privilegios + Tags = Etiquetas + TagName = Nombre + TagCategory = Categoría + TagDescription = Descripción + TagCategories = Categorías de etiquetas + TagCardinality = Cardinalidad + TagAssignments = Asignaciones de etiquetas + TagEntity = Entidad + TagEntityType = Tipo de entidad + VMStoragePolicies = Políticas de almacenamiento de máquinas virtuales + StoragePolicy = Política de almacenamiento + Description = Descripción + ReplicationEnabled = Replicación habilitada + CommonRulesName = Nombre de reglas comunes + CommonRulesDescription = Descripción de reglas comunes + Alarms = Alarmas + Alarm = Alarma + AlarmDescription = Descripción + AlarmEnabled = Habilitado + AlarmTriggered = Disparado + AlarmAction = Acción + AdvancedSystemSettings = Configuración avanzada del sistema + Key = Clave + Value = Valor + Enabled = Habilitado + Disabled = Deshabilitado + Yes = Sí + No = No + None = Ninguno + TablevCenterSummary = vCenter Server Summary - {0} + TablevCenterConfig = vCenter Server Configuration - {0} + TableDatabaseSettings = Database Settings - {0} + TableMailSettings = Mail Settings - {0} + TableHistoricalStatistics = Historical Statistics - {0} + TableLicensing = Licensing - {0} + TableCertificate = Certificate - {0} + TableRole = Role {0} - {1} + TableRoles = Roles - {0} + TableTags = Tags - {0} + TableTagCategories = Tag Categories - {0} + TableTagAssignments = Tag Assignments - {0} + TableVMStoragePolicies = VM Storage Policies - {0} + TableAlarm = {0} - {1} + TableAlarms = Alarms - {0} + TableAdvancedSystemSettings = vCenter Advanced System Settings - {0} + RestApiSessionError = Unable to establish vCenter REST API session. {0} + BackupSettings = Configuración de copia de seguridad + BackupSchedule = Programación de copia de seguridad + BackupJobHistory = Historial de trabajos de copia de seguridad + BackupNotConfigured = No hay ninguna programación de copia de seguridad configurada. + BackupNoJobs = No se encontraron trabajos de copia de seguridad. + BackupApiNotAvailable = El estado de copia de seguridad de vCenter requiere vSphere 7.0 o posterior. + BackupApiError = No se puede recuperar la información de copia de seguridad. {0} + BackupScheduleID = ID de programación + BackupLocation = Ubicación + BackupLocationUser = Usuario de ubicación + BackupEnabled = Estado + BackupActivated = Activado + BackupDeactivated = Desactivado + BackupParts = Datos de copia de seguridad + BackupPartSeat = Plano de control de supervisores + BackupPartCommon = Inventario y configuración + BackupPartStats = Estadísticas, eventos y tareas + BackupRecurrence = Programación + BackupRetentionCount = Número de copias de seguridad a conservar + BackupDaily = Diario + BackupSendEmail = Notificación por correo electrónico + BackupJobLocation = Ubicación de copia de seguridad + BackupJobType = Tipo + BackupJobStatus = Estado + BackupJobComplete = Completado + BackupJobScheduled = Programado + BackupJobDataTransferred = Datos transferidos + BackupJobDuration = Duración + BackupJobEndTime = Hora de finalización + TableBackupSchedule = Programación de copia de seguridad - {0} + TableBackupJobHistory = Historial de trabajos de copia de seguridad - {0} + ResourceSummary = Recursos + SummaryResource = Recurso + Free = Libre + CPU = CPU + Memory = Memoria + Storage = Almacenamiento + VirtualMachines = Máquinas Virtuales + Hosts = Hosts + PoweredOn = Encendido + PoweredOff = Apagado + Suspended = Suspendido + Connected = Conectado + Disconnected = Desconectado + Maintenance = Mantenimiento + ContentLibraries = Bibliotecas de Contenido + ContentLibrary = Biblioteca de Contenido + LibraryType = Tipo + Datastore = Almacén de Datos + LibraryLocal = Local + LibrarySubscribed = Suscrita + ItemCount = Elementos + SubscriptionUrl = URL de Suscripción + AutomaticSync = Sincronización Automática + OnDemandSync = Sincronización bajo Demanda + LibraryItems = Elementos de Biblioteca + ItemName = Elemento + ContentType = Tipo de Contenido + ItemSize = Tamaño + CreationTime = Fecha de Creación + LastModified = Última Modificación + ContentLibraryNoItems = No se encontraron elementos en esta biblioteca de contenido. + ContentLibraryNone = No se encontraron bibliotecas de contenido. + CollectingContentLibrary = Recopilando información de la biblioteca de contenido. + ContentLibraryError = No se puede recuperar la información de la biblioteca de contenido. {0} + ContentLibraryItemError = No se pueden recuperar los elementos de la biblioteca de contenido '{0}'. {1} + TableContentLibraries = Content Libraries - {0} + TableContentLibrary = Content Library {0} - {1} + TableLibraryItems = Library Items - {0} + TableLibraryItem = {0} - {1} + TablevCenterResourceSummary = Resumen de Recursos - {0} + TablevCenterVMSummary = Resumen de Máquinas Virtuales - {0} + TablevCenterHostSummary = Resumen de Hosts - {0} +'@ + +# Get-AbrVSphereCluster +GetAbrVSphereCluster = ConvertFrom-StringData @' + InfoLevel = Nivel de información de Cluster establecido en {0}. + Collecting = Recopilando información de clústeres. + Processing = Procesando clúster '{0}' ({1}/{2}). + SectionHeading = Clústeres + ParagraphSummary = Las siguientes secciones detallan la configuración de los clústeres HA/DRS de vSphere administrados por el servidor vCenter {0}. + ParagraphDetail = La siguiente tabla detalla la configuración del clúster {0}. + Cluster = Clúster + ID = ID + Datacenter = Centro de datos + NumHosts = N.º de hosts + NumVMs = N.º de máquinas virtuales + HAEnabled = vSphere HA + DRSEnabled = vSphere DRS + VSANEnabled = SAN virtual + EVCMode = Modo EVC + VMSwapFilePolicy = Política de archivo de intercambio de máquina virtual + NumberOfHosts = Número de hosts + NumberOfVMs = Número de máquinas virtuales + Hosts = Hosts + VirtualMachines = Máquinas virtuales + Permissions = Permisos + Principal = Principal + Role = Rol + Propagate = Propagar + IsGroup = Es grupo + Enabled = Habilitado + Disabled = Deshabilitado + SwapWithVM = Con VM + SwapInHostDatastore = En el almacén de datos del host + SwapVMDirectory = Directorio de la máquina virtual + SwapHostDatastore = Almacén de datos especificado por el host + TableClusterSummary = Cluster Summary - {0} + TableClusterConfig = Cluster Configuration - {0} +'@ + +# Get-AbrVSphereClusterHA +GetAbrVSphereClusterHA = ConvertFrom-StringData @' + Collecting = Recopilando información de HA del clúster. + SectionHeading = Configuración de vSphere HA + ParagraphSummary = La siguiente sección detalla la configuración de vSphere HA para el clúster {0}. + FailuresAndResponses = Errores y respuestas + HostMonitoring = Supervisión de hosts + HostFailureResponse = Respuesta a fallos de host + HostIsolationResponse = Respuesta al aislamiento de host + VMRestartPriority = Prioridad de reinicio de máquina virtual + PDLProtection = Almacén de datos con pérdida permanente de dispositivo + APDProtection = Almacén de datos con todas las rutas inactivas + VMMonitoring = Supervisión de máquinas virtuales + VMMonitoringSensitivity = Sensibilidad de supervisión de máquinas virtuales + AdmissionControl = Control de admisión + FailoverLevel = Fallos de host tolerados por el clúster + ACPolicy = Política + ACHostPercentage = CPU % + ACMemPercentage = Memoria % + PerformanceDegradation = Degradación del rendimiento de máquinas virtuales + HeartbeatDatastores = Almacenes de datos de latido + Datastore = Almacén de datos + HAAdvancedOptions = Opciones avanzadas de vSphere HA + Key = Clave + Value = Valor + APDRecovery = Recuperación de APD tras tiempo de espera de APD + Disabled = Deshabilitado + Enabled = Habilitado + RestartVMs = Reiniciar VM + ShutdownAndRestart = Apagar y reiniciar VM + PowerOffAndRestart = Apagar y reiniciar VM + IssueEvents = Emitir eventos + PowerOffRestartConservative = Apagar y reiniciar VM (conservador) + PowerOffRestartAggressive = Apagar y reiniciar VM (agresivo) + ResetVMs = Restablecer VM + VMMonitoringOnly = Solo supervisión de VM + VMAndAppMonitoring = Supervisión de VM y aplicaciones + DedicatedFailoverHosts = Hosts de conmutación por error dedicados + ClusterResourcePercentage = Porcentaje de recursos de clúster + SlotPolicy = Política de ranuras + Yes = Sí + No = No + FixedSlotSize = Tamaño de ranura fijo + CoverAllPoweredOnVMs = Cubrir todas las VM encendidas + NoneSpecified = Ninguno especificado + OverrideFailoverCapacity = Override Calculated Failover Capacity + CPUSlotSize = CPU Slot Size (MHz) + MemorySlotSize = Memory Slot Size (MB) + PerfDegradationTolerate = Performance Degradation VMs Tolerate + HeartbeatSelectionPolicy = Heartbeat Selection Policy + HBPolicyAllFeasibleDsWithUserPreference = Use datastores from the specified list and complement automatically if needed + HBPolicyAllFeasibleDs = Automatically select datastores accessible from the host + HBPolicyUserSelectedDs = Use datastores only from the specified list + TableHAFailures = vSphere HA Failures and Responses - {0} + TableHAAdmissionControl = vSphere HA Admission Control - {0} + TableHAHeartbeat = vSphere HA Heartbeat Datastores - {0} + TableHAAdvanced = vSphere HA Advanced Options - {0} +'@ + +# Get-AbrVSphereClusterProactiveHA +GetAbrVSphereClusterProactiveHA = ConvertFrom-StringData @' + Collecting = Recopilando información de HA proactivo del clúster. + SectionHeading = HA proactivo + ParagraphSummary = La siguiente sección detalla la configuración de HA proactivo para el clúster {0}. + FailuresAndResponses = Errores y respuestas + Provider = Proveedor + Remediation = Corrección + HealthUpdates = Actualizaciones de estado + ProactiveHA = HA proactivo + AutomationLevel = Nivel de automatización + ModerateRemediation = Corrección moderada + SevereRemediation = Corrección grave + Enabled = Habilitado + Disabled = Deshabilitado + MaintenanceMode = Modo de Mantenimiento + QuarantineMode = Modo de Cuarentena + MixedMode = Modo Mixto + TableProactiveHA = Proactive HA - {0} + Providers = Proveedores + HealthUpdateCount = Actualizaciones de estado + TableProactiveHAProviders = Proveedores de HA proactiva - {0} +'@ + +# Get-AbrVSphereClusterDRS +GetAbrVSphereClusterDRS = ConvertFrom-StringData @' + Collecting = Recopilando información de DRS del clúster. + SectionHeading = Configuración de vSphere DRS + ParagraphSummary = La siguiente tabla detalla la configuración de vSphere DRS para el clúster {0}. + AutomationLevel = Nivel de automatización de DRS + MigrationThreshold = Umbral de migración + PredictiveDRS = DRS predictivo + VirtualMachineAutomation = Automatización de máquinas individuales + AdditionalOptions = Opciones adicionales + VMDistribution = Distribución de máquinas virtuales + MemoryMetricForLB = Métrica de memoria para equilibrio de carga + CPUOverCommitment = Sobrecompromiso de CPU + PowerManagement = Gestión de energía + DPMAutomationLevel = Nivel de automatización de DPM + DPMThreshold = Umbral de DPM + AdvancedOptions = Opciones avanzadas + Key = Clave + Value = Valor + DRSClusterGroups = Grupos del clúster DRS + GroupName = Nombre del grupo + GroupType = Tipo de grupo + GroupMembers = Miembros + DRSVMHostRules = Reglas de máquina virtual/host de DRS + RuleName = Nombre de regla + RuleType = Tipo de regla + RuleEnabled = Habilitado + VMGroup = Grupo de máquinas virtuales + HostGroup = Grupo de hosts + DRSRules = Reglas de DRS + RuleVMs = Máquinas virtuales + VMOverrides = Reemplazos de máquinas virtuales + VirtualMachine = Máquina virtual + DRSAutomationLevel = Nivel de automatización de DRS + DRSBehavior = Comportamiento de DRS + HARestartPriority = Prioridad de reinicio de HA + HAIsolationResponse = Respuesta al aislamiento de HA + PDLProtection = Almacén de datos con PDL + APDProtection = Almacén de datos con APD + VMMonitoring = Supervisión de máquinas virtuales + VMMonitoringFailureInterval = Intervalo de fallos + VMMonitoringMinUpTime = Tiempo mínimo de actividad + VMMonitoringMaxFailures = Número máximo de fallos + VMMonitoringMaxFailureWindow = Ventana máxima de fallos + Enabled = Habilitado + Disabled = Deshabilitado + Yes = Sí + No = No + FullyAutomated = Totalmente automatizado + PartiallyAutomated = Parcialmente automatizado + Manual = Manual + Off = Desactivado + DRS = vSphere DRS + DPM = DPM + Automated = Automated + None = None + VMGroupType = VM Group + VMHostGroupType = Host Group + MustRunOn = Must run on hosts in group + ShouldRunOn = Should run on hosts in group + MustNotRunOn = Must not run on hosts in group + ShouldNotRunOn = Should not run on hosts in group + VMAffinity = Keep Virtual Machines Together + VMAntiAffinity = Separate Virtual Machines + Mandatory = Mandatory + OverCommitmentRatio = Over-Commitment Ratio + OverCommitmentRatioCluster = Over-Commitment Ratio (% of cluster capacity) + Lowest = Lowest + Low = Low + Medium = Medium + High = High + Highest = Highest + ClusterDefault = Cluster default + VMDependencyTimeout = VM Dependency Restart Condition Timeout + Seconds = {0} seconds + SectionVSphereHA = vSphere HA + IssueEvents = Issue events + PowerOffAndRestart = Power off and restart VMs + ShutdownAndRestartVMs = Shutdown and restart VMs + PowerOffRestartConservative = Power off and restart VMs - Conservative restart policy + PowerOffRestartAggressive = Power off and restart VMs - Aggressive restart policy + PDLFailureResponse = PDL Failure Response + APDFailureResponse = APD Failure Response + VMFailoverDelay = VM Failover Delay + Minutes = {0} minutes + ResponseRecovery = Response Recovery + ResetVMs = Reset VMs + SectionPDLAPD = PDL/APD Protection Settings + NoWindow = No window + WithinHours = Within {0} hrs + VMMonitoringOnly = VM Monitoring Only + VMAndAppMonitoring = VM and Application Monitoring + UserGroup = User/Group + IsGroup = Is Group? + Role = Role + DefinedIn = Defined In + Propagate = Propagate + Permissions = Permissions + ParagraphPermissions = The following table details the permissions for {0}. + TableDRSConfig = vSphere DRS Configuration - {0} + TableDRSAdditional = DRS Additional Options - {0} + TableDPM = vSphere DPM - {0} + TableDRSAdvanced = vSphere DRS Advanced Options - {0} + TableDRSGroups = DRS Cluster Groups - {0} + TableDRSVMHostRules = DRS VM/Host Rules - {0} + TableDRSRules = DRS Rules - {0} + TableDRSVMOverrides = DRS VM Overrides - {0} + TableHAVMOverrides = HA VM Overrides - {0} + TableHAPDLAPD = HA VM Overrides PDL/APD Settings - {0} + TableHAVMMonitoring = HA VM Overrides VM Monitoring - {0} + TablePermissions = Permissions - {0} +'@ + +# Get-AbrVSphereClusterVUM +GetAbrVSphereClusterVUM = ConvertFrom-StringData @' + UpdateManagerBaselines = Líneas base de Update Manager + Baseline = Línea base + Description = Descripción + Type = Tipo + TargetType = Tipo de destino + LastUpdate = Última actualización + NumPatches = N.º de parches + UpdateManagerCompliance = Cumplimiento de Update Manager + Entity = Entidad + Status = Estado de cumplimiento + BaselineInfo = Línea base + VUMPrivilegeMsgBaselines = Privilegios de usuario insuficientes para informar sobre las líneas base del clúster. Asegúrese de que la cuenta de usuario tenga asignado el privilegio 'VMware Update Manager / VMware vSphere Lifecycle Manager > Gestionar parches y actualizaciones > Ver estado de cumplimiento'. + VUMPrivilegeMsgCompliance = Privilegios de usuario insuficientes para informar sobre el cumplimiento del clúster. Asegúrese de que la cuenta de usuario tenga asignado el privilegio 'VMware Update Manager / VMware vSphere Lifecycle Manager > Gestionar parches y actualizaciones > Ver estado de cumplimiento'. + VUMBaselineNotAvailable = La información de líneas base de VUM del clúster no está disponible actualmente con su versión de PowerShell. + VUMComplianceNotAvailable = La información de cumplimiento de VUM del clúster no está disponible actualmente con su versión de PowerShell. + NotCompliant = No conforme + Unknown = Desconocido + Incompatible = Incompatible + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} +'@ + +# Get-AbrVSphereResourcePool +GetAbrVSphereResourcePool = ConvertFrom-StringData @' + InfoLevel = Nivel de información de grupo de recursos establecido en {0}. + Collecting = Recopilando información de grupos de recursos. + Processing = Procesando grupo de recursos '{0}' ({1}/{2}). + SectionHeading = Grupos de recursos + ParagraphSummary = Las siguientes secciones detallan la configuración de los grupos de recursos administrados por el servidor vCenter {0}. + ResourcePool = Grupo de recursos + Parent = Principal + CPUSharesLevel = Nivel de recursos compartidos de CPU + CPUReservationMHz = Reserva de CPU (MHz) + CPULimitMHz = Límite de CPU (MHz) + MemSharesLevel = Nivel de recursos compartidos de memoria + MemReservation = Reserva de memoria + MemLimit = Límite de memoria + ID = ID + NumCPUShares = Número de recursos compartidos de CPU + CPUReservation = Reserva de CPU + CPUExpandable = Reserva ampliable de CPU + NumMemShares = Número de recursos compartidos de memoria + MemExpandable = Reserva ampliable de memoria + NumVMs = Número de máquinas virtuales + VirtualMachines = Máquinas virtuales + Enabled = Habilitado + Disabled = Deshabilitado + Unlimited = Ilimitado + TableResourcePoolSummary = Resource Pool Summary - {0} + TableResourcePoolConfig = Resource Pool Configuration - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSphereVMHost +GetAbrVSphereVMHost = ConvertFrom-StringData @' + InfoLevel = Nivel de información de host VMware establecido en {0}. + Collecting = Recopilando información de hosts VMware. + Processing = Procesando host VMware '{0}' ({1}/{2}). + SectionHeading = Hosts + ParagraphSummary = Las siguientes secciones detallan la configuración de los hosts VMware ESXi administrados por el servidor vCenter {0}. + VMHost = Host + Manufacturer = Fabricante + Model = Modelo + ProcessorType = Tipo de procesador + NumCPUSockets = Zócalos de CPU + NumCPUCores = Núcleos de CPU + NumCPUThreads = Hilos de CPU + MemoryGB = Memoria (GB) + NumNICs = N.º de NIC + NumHBAs = N.º de HBA + NumDatastores = N.º de almacenes de datos + NumVMs = N.º de máquinas virtuales + ConnectionState = Estado de conexión + PowerState = Estado de energía + ErrorCollecting = Error al recopilar información del host VMware con el nivel de información {0}. + NotResponding = No responde + Maintenance = Mantenimiento + Disconnected = Desconectado + Version = Version + Build = Build + Parent = Parent + TableHostSummary = Host Summary - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSphereVMHostHardware +GetAbrVSphereVMHostHardware = ConvertFrom-StringData @' + Collecting = Recopilando información de hardware del host VMware. + SectionHeading = Hardware + ParagraphSummary = La siguiente sección detalla la configuración de hardware del host {0}. + InsufficientPrivLicense = Privilegios de usuario insuficientes para informar sobre las licencias del host ESXi. Asegúrese de que la cuenta de usuario tenga asignado el privilegio 'Global > Licencias'. + LicenseError = No se puede recuperar la información de licencia para VMHost '{0}'. Error: {1} + Specifications = Especificaciones + Manufacturer = Fabricante + Model = Modelo + SerialNumber = Número de serie + AssetTag = Etiqueta de activo + ProcessorType = Tipo de procesador + CPUSockets = Zócalos de CPU + CPUCores = Núcleos de CPU + CPUThreads = Hilos de CPU + HyperthreadingActive = Hyperthreading activo + MemoryGB = Memoria (GB) + NUMANodes = Nodos NUMA + NICs = NIC + HBAs = HBA + Version = Versión + Build = Compilación + LicenseKey = Clave de licencia + Product = Producto + LicenseExpiration = Vencimiento de licencia + IPMIBMC = IPMI / BMC + IPMIBMCError = Error al recopilar información de IPMI/BMC para {0}. + IPMIBMCManufacturer = Fabricante + IPMIBMCType = Tipo + IPMIBMCIPAddress = Dirección IP + IPMIBMCMACAddress = Dirección MAC + BootDevice = Dispositivo de arranque + BootDeviceError = Error al recopilar información del dispositivo de arranque para {0}. + BootDeviceDescription = Descripción + BootDeviceType = Tipo + BootDeviceSize = Tamaño (GB) + BootDeviceIsSAS = Es SAS + BootDeviceIsUSB = Es USB + BootDeviceIsSSD = Es SSD + BootDeviceFromSAN = Desde SAN + PCIDevices = Dispositivos PCI + PCIDeviceId = ID de PCI + PCIVendorName = Nombre del fabricante + PCIDeviceName = Nombre del dispositivo + PCIDriverName = Nombre del controlador + PCIDriverVersion = Versión del controlador + PCIFirmware = Versión de firmware + PCIDriversFirmware = Controladores y firmware de dispositivos PCI + Enabled = Habilitado + Disabled = Deshabilitado + NotApplicable = No aplicable + Unknown = Desconocido + Maintenance = Mantenimiento + NotResponding = Not Responding + Host = Host + ConnectionState = Connection State + ID = ID + Parent = Parent + HyperThreading = HyperThreading + NumberOfCPUSockets = Number of CPU Sockets + NumberOfCPUCores = Number of CPU Cores + NumberOfCPUThreads = Number of CPU Threads + CPUTotalUsedFree = CPU Total / Used / Free + MemoryTotalUsedFree = Memory Total / Used / Free + NumberOfNICs = Number of NICs + NumberOfHBAs = Number of HBAs + NumberOfDatastores = Number of Datastores + NumberOfVMs = Number of VMs + MaximumEVCMode = Maximum EVC Mode + EVCGraphicsMode = EVC Graphics Mode + PowerManagementPolicy = Power Management Policy + ScratchLocation = Scratch Location + BiosVersion = BIOS Version + BiosReleaseDate = BIOS Release Date + BootTime = Boot Time + UptimeDays = Uptime Days + MACAddress = MAC Address + SubnetMask = Subnet Mask + Gateway = Gateway + FirmwareVersion = Firmware Version + Device = Device + BootType = Boot Type + Vendor = Vendor + Size = Size + PCIAddress = PCI Address + DeviceClass = Device Class + TableHardwareConfig = Hardware Configuration - {0} + TableIPMIBMC = IPMI / BMC - {0} + TableBootDevice = Boot Device - {0} + TablePCIDevices = PCI Devices - {0} + TablePCIDriversFirmware = PCI Devices Drivers & Firmware - {0} + PCIDeviceError = Error collecting PCI device information for {0}. {1} + PCIDriversFirmwareError = Error collecting PCI device driver & firmware information for {0}. {1} + HardwareError = Error collecting host hardware information for {0}. {1} + IODeviceIdentifiers = Identificadores de dispositivos de E/S + VendorID = VID + DeviceID = DID + SubVendorID = SVID + SubDeviceID = SSID + TableIODeviceIdentifiers = Identificadores de E/S - {0} + IODeviceIdentifiersError = Error al recopilar identificadores de E/S para {0}. {1} +'@ + +# Get-AbrVSphereVMHostSystem +GetAbrVSphereVMHostSystem = ConvertFrom-StringData @' + Collecting = Recopilando información del sistema del host VMware. + HostProfile = Perfil de host + ProfileName = Perfil de host + ProfileCompliance = Cumplimiento + ProfileRemediating = Corrigiendo + ImageProfile = Perfil de imagen + ImageProfileName = Nombre + ImageProfileVendor = Fabricante + ImageProfileAcceptance = Nivel de aceptación + TimeConfiguration = Configuración de hora + NTPServer = Servidor NTP + TimeZone = Zona horaria + Syslog = Syslog + SyslogHost = Host de Syslog + VUMBaseline = Líneas base de Update Manager + VUMBaselineNotAvailable = La información de líneas base de VUM del host VMware no está disponible actualmente con su versión de PowerShell. + VUMBaselineName = Línea base + VUMBaselineType = Tipo + VUMBaselinePatches = N.º de parches + VUMCompliance = Cumplimiento de Update Manager + VUMComplianceNotAvailable = La información de cumplimiento de VUM del host VMware no está disponible actualmente con su versión de PowerShell. + VUMStatus = Estado + AdvancedSettings = Configuración avanzada del sistema + Key = Clave + Value = Valor + VIBs = Paquetes de instalación de VMware (VIB) + VIBName = Nombre + VIBVersion = Versión + VIBVendor = Fabricante + VIBInstallDate = Fecha de instalación + VIBAcceptanceLevel = Nivel de aceptación + SectionHeading = Sistema + ParagraphSummary = La siguiente sección detalla la configuración del sistema del host {0}. + NTPService = Servicio NTP + NTPServers = Servidor(es) NTP + SyslogPort = Puerto + VUMDescription = Descripción + VUMTargetType = Tipo de destino + VUMLastUpdate = Hora de la última actualización + InstallDate = Fecha de instalación + ImageName = Perfil de imagen + ImageVendor = Proveedor + Running = En ejecución + Stopped = Detenido + NotCompliant = No conforme + Unknown = Desconocido + Incompatible = Incompatible + ProfileDescription = Description + VIBID = ID + VIBCreationDate = Creation Date + TableHostProfile = Host Profile - {0} + TableImageProfile = Image Profile - {0} + TableTimeConfig = Time Configuration - {0} + TableSyslog = Syslog Configuration - {0} + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} + TableAdvancedSettings = Advanced System Settings - {0} + TableVIBs = Software VIBs - {0} + HostProfileError = Error collecting host profile information for {0}. {1} + ImageProfileError = Error collecting image profile information for {0}. {1} + TimeConfigError = Error collecting time configuration for {0}. {1} + SyslogError = Error collecting syslog configuration for {0}. {1} + VUMBaselineError = Error collecting Update Manager baseline information for {0}. {1} + VUMComplianceError = Error collecting Update Manager compliance information for {0}. {1} + AdvancedSettingsError = Error collecting host advanced settings information for {0}. {1} + VIBsError = Error collecting software VIB information for {0}. {1} + InsufficientPrivImageProfile = Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned. + InsufficientPrivVUMBaseline = Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + InsufficientPrivVUMCompliance = Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + SwapFileLocation = Ubicación del archivo de intercambio de VM + SwapFilePlacement = Ubicación del archivo de intercambio de VM + SwapDatastore = Almacén de datos de intercambio + WithVM = Con VM (Predeterminado) + HostLocal = Local del host + TableSwapFileLocation = Ubicación del archivo de intercambio de VM - {0} + SwapFileLocationError = Error al recopilar la ubicación del archivo de intercambio de VM para {0}. {1} + HostCertificate = Certificado del host + CertSubject = Asunto + CertIssuer = Emisor + CertValidFrom = Válido desde + CertValidTo = Válido hasta + CertThumbprint = Huella digital SHA-256 + TableHostCertificate = Certificado del host - {0} + HostCertificateError = Error al recopilar la información del certificado del host para {0}. {1} + LogDir = Directorio de registro + LogRotations = Rotaciones de registro + LogSize = Tamaño de registro (KB) +'@ + +# Get-AbrVSphereVMHostStorage +GetAbrVSphereVMHostStorage = ConvertFrom-StringData @' + Collecting = Recopilando información de almacenamiento del host VMware. + SectionHeading = Almacenamiento + DatastoreSpecs = Especificaciones del almacén de datos + Datastore = Almacén de datos + DatastoreType = Tipo + DatastoreCapacity = Capacidad (GB) + DatastoreFreeSpace = Espacio libre (GB) + DatastoreState = Estado + DatastoreShared = Compartido + StorageAdapters = Adaptadores de almacenamiento + AdapterName = Adaptador + AdapterType = Tipo + AdapterDriver = Controlador + AdapterUID = UID + AdapterModel = Modelo + AdapterStatus = Estado + AdapterSASAddress = Dirección SAS + AdapterWWN = WWN + AdapterDevices = Dispositivos + AdapterTargets = Destinos + ParagraphSummary = La siguiente sección detalla la configuración de almacenamiento del host {0}. + FC = Fibre Channel + iSCSI = iSCSI + ParallelSCSI = SCSI paralelo + ChapNone = Ninguno + ChapUniPreferred = Usar CHAP unidireccional a menos que el destino lo prohíba + ChapUniRequired = Usar CHAP unidireccional si lo requiere el destino + ChapUnidirectional = Usar CHAP unidireccional + ChapBidirectional = Usar CHAP bidireccional + Online = En línea + Offline = Sin conexión + Type = Type + Version = Version + NumberOfVMs = # of VMs + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + TableDatastores = Datastores - {0} + ParagraphStorageAdapters = The following section details the storage adapter configuration for {0}. + AdapterPaths = Paths + iSCSIName = iSCSI Name + iSCSIAlias = iSCSI Alias + AdapterSpeed = Speed + DynamicDiscovery = Dynamic Discovery + StaticDiscovery = Static Discovery + AuthMethod = Authentication Method + CHAPOutgoing = Outgoing CHAP Name + CHAPIncoming = Incoming CHAP Name + AdvancedOptions = Advanced Options + NodeWWN = Node WWN + PortWWN = Port WWN + TableStorageAdapter = Storage Adapter {0} - {1} +'@ + +# Get-AbrVSphereVMHostNetwork +GetAbrVSphereVMHostNetwork = ConvertFrom-StringData @' + Collecting = Recopilando información de red del host VMware. + SectionHeading = Red + NetworkConfig = Configuración de red + VMKernelAdapters = Adaptadores VMkernel + PhysicalAdapters = Adaptadores físicos + CDP = Protocolo de descubrimiento de Cisco + LLDP = Protocolo de descubrimiento de capa de enlace + StandardvSwitches = Conmutadores virtuales estándar + AdapterName = Adaptador + AdapterMAC = Dirección MAC + AdapterLinkSpeed = Velocidad de enlace + AdapterDriver = Controlador + AdapterPCIID = Dispositivo PCI + AdapterStatus = Estado + VMKName = Adaptador VMkernel + VMKIP = Dirección IP + VMKSubnet = Máscara de subred + VMKGateway = Puerta de enlace predeterminada + VMKMTU = MTU + VMKPortGroup = Grupo de puertos + VMKVirtualSwitch = Conmutador virtual + VMKDHCPEnabled = DHCP habilitado + VMKServicesEnabled = Servicios habilitados + vSwitch = Conmutador virtual + vSwitchPorts = Puertos totales + vSwitchUsedPorts = Puertos usados + vSwitchAvailablePorts = Puertos disponibles + vSwitchMTU = MTU + vSwitchCDPStatus = Estado de CDP + vSwitchSecurity = Política de seguridad + vSwitchFailover = Política de conmutación por error + vSwitchLoadBalancing = Equilibrio de carga + vSwitchPortGroups = Grupos de puertos + PortGroup = Grupo de puertos + VLAN = ID de VLAN + ActiveAdapters = Adaptadores activos + StandbyAdapters = Adaptadores en espera + UnusedAdapters = Adaptadores sin usar + ParagraphSummary = La siguiente sección detalla la configuración de red del host {0}. + Enabled = Habilitado + Disabled = Deshabilitado + Connected = Conectado + Disconnected = Desconectado + Yes = Sí + No = No + Accept = Aceptar + Reject = Rechazar + Supported = Compatible + NotSupported = No compatible + Inherited = Heredado + TCPDefault = Predeterminado + TCPProvisioning = Aprovisionamiento + TCPvMotion = vMotion + TCPNsxOverlay = nsx-overlay + TCPNsxHyperbus = nsx-hyperbus + TCPNotApplicable = No aplicable + LBSrcId = Enrutar basado en el ID del puerto de origen + LBSrcMac = Enrutar basado en el hash MAC de origen + LBIP = Enrutar basado en el hash IP + LBExplicitFailover = Conmutación por error explícita + NFDLinkStatus = Solo estado del enlace + NFDBeaconProbing = Sondeo de baliza + FullDuplex = Dúplex completo + AutoNegotiate = Negociación automática + Down = Inactivo + Host = Host + VirtualSwitches = Virtual Switches + VMkernelGateway = VMkernel Gateway + IPv6 = IPv6 + VMkernelIPv6Gateway = VMkernel IPv6 Gateway + DNSServers = DNS Servers + HostName = Host Name + DomainName = Domain Name + SearchDomain = Search Domain + TableNetworkConfig = Network Configuration - {0} + ParagraphPhysicalAdapters = The following section details the physical network adapter configuration for {0}. + VirtualSwitch = Virtual Switch + ActualSpeedDuplex = Actual Speed, Duplex + ConfiguredSpeedDuplex = Configured Speed, Duplex + WakeOnLAN = Wake on LAN + TablePhysicalAdapter = Physical Adapter {0} - {1} + TablePhysicalAdapters = Physical Adapters - {0} + ParagraphCDP = The following section details the CDP information for {0}. + Status = Status + SystemName = System Name + HardwarePlatform = Hardware Platform + SwitchID = Switch ID + SoftwareVersion = Software Version + ManagementAddress = Management Address + Address = Address + PortID = Port ID + MTU = MTU + TableAdapterCDP = Network Adapter {0} CDP Information - {1} + TableAdaptersCDP = Network Adapter CDP Information - {0} + ParagraphLLDP = The following section details the LLDP information for {0}. + ChassisID = Chassis ID + TimeToLive = Time to live + TimeOut = TimeOut + Samples = Samples + PortDescription = Port Description + SystemDescription = System Description + TableAdapterLLDP = Network Adapter {0} LLDP Information - {1} + TableAdaptersLLDP = Network Adapter LLDP Information - {0} + ParagraphVMKernelAdapters = The following section details the VMkernel adapter configuration for {0}. + NetworkLabel = Network Label + TCPIPStack = TCP/IP Stack + DHCP = DHCP + IPAddress = IP Address + SubnetMask = Subnet Mask + DefaultGateway = Default Gateway + vMotion = vMotion + Provisioning = Provisioning + FTLogging = FT Logging + Management = Management + vSphereReplication = vSphere Replication + vSphereReplicationNFC = vSphere Replication NFC + vSAN = vSAN + vSANWitness = vSAN Witness + vSphereBackupNFC = vSphere Backup NFC + TableVMKernelAdapter = VMkernel Adapter {0} - {1} + ParagraphStandardvSwitches = The following section details the standard virtual switch configuration for {0}. + NumberOfPorts = Number of Ports + NumberOfPortsAvailable = Number of Ports Available + TableStandardvSwitches = Standard Virtual Switches - {0} + VSSecurity = Virtual Switch Security + PromiscuousMode = Promiscuous Mode + MACAddressChanges = MAC Address Changes + ForgedTransmits = Forged Transmits + TableVSSecurity = Virtual Switch Security Policy - {0} + VSTrafficShaping = Virtual Switch Traffic Shaping + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + TableVSTrafficShaping = Virtual Switch Traffic Shaping Policy - {0} + VSTeamingFailover = Virtual Switch Teaming & Failover + LoadBalancing = Load Balancing + NetworkFailureDetection = Network Failure Detection + NotifySwitches = Notify Switches + Failback = Failback + ActiveNICs = Active NICs + StandbyNICs = Standby NICs + UnusedNICs = Unused NICs + TableVSTeamingFailover = Virtual Switch Teaming & Failover - {0} + VSPortGroups = Virtual Switch Port Groups + NumberOfVMs = # of VMs + TableVSPortGroups = Virtual Switch Port Groups - {0} + VSPGSecurity = Virtual Switch Port Group Security + MACChanges = MAC Changes + TableVSPGSecurity = Virtual Switch Port Group Security Policy - {0} + VSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping + TableVSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping Policy - {0} + VSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover + TableVSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover - {0} +'@ + +# Get-AbrVSphereVMHostSecurity +GetAbrVSphereVMHostSecurity = ConvertFrom-StringData @' + Collecting = Recopilando información de seguridad del host VMware. + SectionHeading = Seguridad + LockdownMode = Modo de bloqueo + Services = Servicios + ServiceName = Servicio + ServiceRunning = En ejecución + ServicePolicy = Política de inicio + ServiceRequired = Obligatorio + Firewall = Cortafuegos + FirewallRule = Regla + FirewallAllowed = Hosts permitidos + Authentication = Autenticación + Domain = Dominio + Trust = Dominios de confianza + Membership = Pertenencia al dominio + VMInfoSection = Máquinas virtuales + VMName = Máquina virtual + VMPowerState = Estado de energía + VMIPAddress = Dirección IP + VMOS = Sistema operativo + VMGuestID = ID de invitado + VMCPUs = CPU + VMMemoryGB = Memoria (GB) + VMDisks = Discos (GB) + VMNICs = NIC + StartupShutdown = Inicio/apagado de máquina virtual + StartupEnabled = Inicio habilitado + StartupOrder = Orden de inicio + StartupDelay = Retraso de inicio + StopAction = Acción de detención + StopDelay = Retraso de detención + WaitForHeartbeat = Esperar latido + ParagraphSummary = La siguiente sección detalla la configuración de seguridad del host {0}. + LockdownDisabled = Deshabilitado + LockdownNormal = Habilitado (Normal) + LockdownStrict = Habilitado (Estricto) + Running = En ejecución + Stopped = Detenido + SvcPortUsage = Iniciar y detener con el uso del puerto + SvcWithHost = Iniciar y detener con el host + SvcManually = Iniciar y detener manualmente + On = Encendido + Off = Apagado + Enabled = Habilitado + Disabled = Deshabilitado + WaitHeartbeat = Continuar si VMware Tools está iniciado + WaitDelay = Esperar el retraso de inicio + PowerOff = Apagar + GuestShutdown = Apagado del SO + ToolsOld = Antiguo + ToolsOK = Correcto + ToolsNotRunning = No está en ejecución + ToolsNotInstalled = No instalado + TableLockdownMode = Lockdown Mode - {0} + TableServices = Services - {0} + FirewallService = Service + Status = Status + IncomingPorts = Incoming Ports + OutgoingPorts = Outgoing Ports + Protocols = Protocols + Daemon = Daemon + TableFirewall = Firewall Configuration - {0} + DomainMembership = Domain Membership + TrustedDomains = Trusted Domains + TableAuthentication = Authentication Services - {0} + ParagraphVMInfo = The following section details the virtual machine configuration for {0}. + VMProvisioned = Provisioned + VMUsed = Used + VMHWVersion = HW Version + VMToolsStatus = VM Tools Status + TableVMs = Virtual Machines - {0} + TableStartupShutdown = VM Startup/Shutdown Policy - {0} + TpmEncryption = TPM y cifrado + TpmPresent = TPM presente + TpmStatus = Estado de atestación TPM + EncryptionMode = Modo de cifrado + RequireSecureBoot = Requerir arranque seguro + RequireSignedVIBs = Requerir ejecutables solo de VIBs instalados + RecoveryKeys = Claves de recuperación de cifrado + RecoveryID = ID de recuperación + RecoveryKey = Clave de recuperación + TpmEncryptionError = No se puede recuperar información de TPM y cifrado para el host {0}. {1} + TableTpmEncryption = TPM y cifrado - {0} + TableRecoveryKeys = Claves de recuperación de cifrado - {0} + Yes = Sí + No = No +'@ + +# Get-AbrVSphereNetwork +GetAbrVSphereNetwork = ConvertFrom-StringData @' + InfoLevel = Nivel de información de red establecido en {0}. + Collecting = Recopilando información de conmutadores distribuidos. + Processing = Procesando conmutador distribuido '{0}' ({1}/{2}). + SectionHeading = Conmutadores distribuidos + ParagraphSummary = Las siguientes secciones detallan la configuración de los conmutadores distribuidos administrados por el servidor vCenter {0}. + VDSwitch = Conmutador distribuido + Datacenter = Centro de datos + Manufacturer = Fabricante + NumUplinks = N.º de uplinks + NumPorts = N.º de puertos + NumHosts = N.º de hosts + NumVMs = N.º de máquinas virtuales + Version = Versión + MTU = MTU + ID = ID + NumberOfUplinks = Número de uplinks + NumberOfPorts = Número de puertos + NumberOfPortGroups = Número de grupos de puertos + NumberOfHosts = Número de hosts + NumberOfVMs = Número de máquinas virtuales + Hosts = Hosts + VirtualMachines = Máquinas virtuales + NIOC = Control de E/S de red + DiscoveryProtocol = Protocolo de descubrimiento + DiscoveryOperation = Operación de descubrimiento + NumPortGroups = N.º de grupos de puertos + MaxPorts = Puertos máximos + Contact = Contacto + Location = Ubicación + VDPortGroups = Grupos de puertos distribuidos + PortGroup = Grupo de puertos + PortGroupType = Tipo de grupo de puertos + VLANID = ID de VLAN + VLANConfiguration = Configuración de VLAN + PortBinding = Vinculación de puertos + Host = Host + UplinkName = Nombre del uplink + UplinkPortGroup = Grupo de puertos de uplink + PhysicalNetworkAdapter = Adaptador de red físico + ActiveUplinks = Uplinks activos + StandbyUplinks = Uplinks en espera + UnusedUplinks = Uplinks sin usar + AllowPromiscuous = Permitir modo promiscuo + ForgedTransmits = Transmisiones falsificadas + MACAddressChanges = Cambios de dirección MAC + Accept = Aceptar + Reject = Rechazar + Direction = Dirección + Status = Estado + AverageBandwidth = Ancho de banda promedio (kbit/s) + PeakBandwidth = Ancho de banda pico (kbit/s) + BurstSize = Tamaño de ráfaga (KB) + LoadBalancing = Equilibrio de carga + LoadBalanceSrcId = Enrutar basado en el ID del puerto de origen + LoadBalanceSrcMac = Enrutar basado en el hash MAC de origen + LoadBalanceIP = Enrutar basado en el hash IP + ExplicitFailover = Conmutación por error explícita + NetworkFailureDetection = Detección de fallo de red + LinkStatus = Solo estado del enlace + BeaconProbing = Sondeo de baliza + NotifySwitches = Notificar conmutadores + FailbackEnabled = Conmutación de retorno habilitada + Yes = Sí + No = No + PrimaryVLANID = ID de VLAN primaria + PrivateVLANType = Tipo de VLAN privada + SecondaryVLANID = ID de VLAN secundaria + UplinkPorts = Puertos de uplink del conmutador distribuido + VDSSecurity = Seguridad del conmutador distribuido + VDSTrafficShaping = Modelado de tráfico del conmutador distribuido + VDSPortGroups = Grupos de puertos del conmutador distribuido + VDSPortGroupSecurity = Seguridad del grupo de puertos del conmutador distribuido + VDSPortGroupTrafficShaping = Modelado de tráfico del grupo de puertos del conmutador distribuido + VDSPortGroupTeaming = Equipos y conmutación por error del grupo de puertos del conmutador distribuido + VDSPrivateVLANs = VLAN privadas del conmutador distribuido + Enabled = Habilitado + Disabled = Deshabilitado + Listen = Escuchar + Advertise = Anunciar + Both = Ambos + TableVDSSummary = Resumen del conmutador distribuido - {0} + TableVDSGeneral = Propiedades generales del conmutador distribuido - {0} + TableVDSUplinkPorts = Puertos de uplink del conmutador distribuido - {0} + TableVDSSecurity = Seguridad del conmutador distribuido - {0} + TableVDSTrafficShaping = Modelado de tráfico del conmutador distribuido - {0} + TableVDSPortGroups = Grupos de puertos del conmutador distribuido - {0} + TableVDSPortGroupSecurity = Seguridad del grupo de puertos del conmutador distribuido - {0} + TableVDSPortGroupTrafficShaping = Modelado de tráfico del grupo de puertos del conmutador distribuido - {0} + TableVDSPortGroupTeaming = Equipos y conmutación por error del grupo de puertos del conmutador distribuido - {0} + TableVDSPrivateVLANs = VLAN privadas del conmutador distribuido - {0} + VDSLACP = LACP del conmutador distribuido + LACPEnabled = LACP habilitado + LACPMode = Modo LACP + LACPActive = Activo + LACPPassive = Pasivo + VDSNetFlow = NetFlow del conmutador distribuido + CollectorIP = Dirección IP del colector + CollectorPort = Puerto del colector + ActiveFlowTimeout = Tiempo de espera de flujo activo (s) + IdleFlowTimeout = Tiempo de espera de flujo inactivo (s) + SamplingRate = Tasa de muestreo + InternalFlowsOnly = Solo flujos internos + NIOCResourcePools = Grupos de recursos de control de E/S de red + NIOCResourcePool = Grupo de recursos + NIOCSharesLevel = Nivel de participaciones + NIOCSharesValue = Participaciones + NIOCLimitMbps = Límite (Mbps) + Unlimited = Ilimitado + TableVDSLACP = LACP del conmutador distribuido - {0} + TableVDSNetFlow = NetFlow del conmutador distribuido - {0} + TableNIOCResourcePools = Grupos de recursos de control de E/S de red - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSpherevSAN +GetAbrVSpherevSAN = ConvertFrom-StringData @' + InfoLevel = Nivel de información de vSAN establecido en {0}. + Collecting = Recopilando información de vSAN. + CollectingESA = Recopilando información vSAN ESA para '{0}'. + CollectingOSA = Recopilando información vSAN OSA para '{0}'. + CollectingDisks = Recopilando información de discos vSAN para '{0}'. + CollectingDiskGroups = Recopilando información de grupos de discos vSAN para '{0}'. + CollectingiSCSITargets = Recopilando información de destinos iSCSI vSAN para '{0}'. + CollectingiSCSILUNs = Recopilando información de LUN iSCSI vSAN para '{0}'. + Processing = Procesando clúster vSAN '{0}' ({1}/{2}). + SectionHeading = vSAN + ParagraphSummary = Las siguientes secciones detallan la configuración de VMware vSAN administrado por el servidor vCenter {0}. + ParagraphDetail = La siguiente tabla detalla la configuración de vSAN para el clúster {0}. + DisksSection = Discos + DiskGroupsSection = Grupos de discos + iSCSITargetsSection = Destinos iSCSI + iSCSILUNsSection = LUN iSCSI + Cluster = Clúster + StorageType = Tipo de almacenamiento + ClusterType = Tipo de clúster + NumHosts = N.º de hosts + ID = ID + NumberOfHosts = Número de hosts + NumberOfDisks = Número de discos + NumberOfDiskGroups = Número de grupos de discos + DiskClaimMode = Modo de reclamación de disco + PerformanceService = Servicio de rendimiento + FileService = Servicio de archivos + iSCSITargetService = Servicio de destino iSCSI + HistoricalHealthService = Servicio de historial de salud + HealthCheck = Comprobación de estado + TotalCapacity = Capacidad total + UsedCapacity = Capacidad usada + FreeCapacity = Capacidad libre + PercentUsed = % usado + HCLLastUpdated = Última actualización de HCL + Hosts = Hosts + Version = Versión + Stretched = Clúster extendido + VSANEnabled = vSAN habilitado + VSANESAEnabled = vSAN ESA habilitado + DisksFormat = Versión del formato de disco + Deduplication = Deduplicación y compresión + AllFlash = All Flash + FaultDomains = Dominios de fallo + PFTT = Fallos primarios a tolerar + SFTT = Fallos secundarios a tolerar + NetworkDiagnosticMode = Modo de diagnóstico de red + HybridMode = Modo híbrido + AutoRebalance = Reequilibrio automático + ProactiveDisk = Reequilibrio proactivo de disco + ResyncThrottle = Limitación de resincronización + SpaceEfficiency = Eficiencia de espacio + Encryption = Cifrado + FileServiceEnabled = Servicio de archivos habilitado + iSCSITargetEnabled = Destino iSCSI habilitado + VMHostSpecs = Especificaciones de vSAN del host VMware + VMHost = Host VMware + DiskGroup = Grupo de discos + CacheDisks = Discos de caché + DataDisks = Discos de datos + DiskGroups = Grupos de discos + CacheTier = Nivel de caché + DataTier = Nivel de datos + Status = Estado + FaultDomainName = Dominio de fallo + VSANAdvancedOptions = Opciones de configuración avanzada de vSAN + Key = Clave + Value = Valor + IDs = Identificadores + VSAN_UUID = UUID de vSAN + CapacityTier = Nivel de capacidad (GB) + BufferTier = Nivel de búfer (GB) + DiskName = Disco + Name = Nombre + DriveType = Tipo de unidad + Host = Host + State = Estado + Encrypted = Cifrado + Capacity = Capacidad + SerialNumber = Número de serie + Vendor = Fabricante + Model = Modelo + DiskType = Tipo de disco + DiskFormatVersion = Versión del formato de disco + ClaimedAs = Reclamado como + NumDisks = N.º de discos + Type = Tipo + IQN = IQN + Alias = Alias + LUNsCount = LUN + NetworkInterface = Interfaz de red + IOOwnerHost = Host propietario de E/S + TCPPort = Puerto TCP + Health = Estado de salud + StoragePolicy = Política de almacenamiento + ComplianceStatus = Estado de cumplimiento + Authentication = Autenticación + LUNName = LUN + LUNID = ID de LUN + Yes = Sí + No = No + Enabled = Habilitado + Disabled = Deshabilitado + Online = En línea + Offline = Sin conexión + Mounted = Montado + Unmounted = Desmontado + Flash = Flash + HDD = HDD + Cache = Caché + TableVSANClusterSummary = Resumen del clúster vSAN - {0} + TableVSANConfiguration = Configuración de vSAN - {0} + TableDisk = Disco {0} - {1} + TableVSANDisks = Discos vSAN - {0} + TableVSANDiskGroups = Grupos de discos vSAN - {0} + TableVSANiSCSITargets = Destinos iSCSI vSAN - {0} + TableVSANiSCSILUNs = LUN iSCSI vSAN - {0} + ESAError = Error al recopilar información vSAN ESA para '{0}'. {1} + OSAError = Error al recopilar información vSAN OSA para '{0}'. {1} + DiskError = Error al recopilar información de discos vSAN para '{0}'. {1} + DiskGroupError = Error al recopilar información de grupos de discos vSAN para '{0}'. {1} + iSCSITargetError = Error al recopilar información de destinos iSCSI vSAN para '{0}'. {1} + iSCSILUNError = Error al recopilar información de LUN iSCSI vSAN para '{0}'. {1} + ServicesSection = Servicios de vSAN + Service = Servicio + TableVSANServices = Servicios de vSAN - {0} + ServicesError = Error al recopilar información de servicios vSAN para '{0}'. {1} +'@ + +# Get-AbrVSphereDatastore +GetAbrVSphereDatastore = ConvertFrom-StringData @' + InfoLevel = Nivel de información de almacén de datos establecido en {0}. + Collecting = Recopilando información de almacenes de datos. + Processing = Procesando almacén de datos '{0}' ({1}/{2}). + SectionHeading = Almacenes de datos + ParagraphSummary = Las siguientes secciones detallan la configuración de los almacenes de datos administrados por el servidor vCenter {0}. + Datastore = Almacén de datos + Type = Tipo + DatastoreURL = URL + FileSystem = Versión del sistema de archivos + CapacityGB = Capacidad total (GB) + FreeSpaceGB = Espacio libre (GB) + UsedSpaceGB = Espacio usado (GB) + State = Estado + Accessible = Accesible + NumHosts = N.º de hosts + NumVMs = N.º de máquinas virtuales + SIOC = Control de E/S de almacenamiento + IOLatencyThreshold = Umbral de latencia de E/S (ms) + IOLoadBalancing = Equilibrio de carga de E/S + Enabled = Habilitado + Disabled = Deshabilitado + Normal = Normal + Maintenance = Mantenimiento + Unmounted = Desmontado + ID = ID + Datacenter = Centro de datos + Version = Versión + NumberOfHosts = Número de hosts + NumberOfVMs = Número de máquinas virtuales + CongestionThreshold = Umbral de congestión + TotalCapacity = Capacidad total + UsedCapacity = Capacidad usada + FreeCapacity = Capacidad libre + PercentUsed = % usado + Hosts = Hosts + VirtualMachines = Máquinas virtuales + SCSILUNInfo = Información de LUN SCSI + Host = Host + CanonicalName = Nombre canónico + Capacity = Capacidad + Vendor = Fabricante + Model = Modelo + IsSSD = Es SSD + MultipathPolicy = Política multiruta + Paths = Rutas + TableDatastoreSummary = Resumen del almacén de datos - {0} + TableDatastoreConfig = Configuración del almacén de datos - {0} + TableSCSILUN = Información de LUN SCSI - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSphereDSCluster +GetAbrVSphereDSCluster = ConvertFrom-StringData @' + InfoLevel = Nivel de información de clúster de almacenes de datos establecido en {0}. + Collecting = Recopilando información de clústeres de almacenes de datos. + Processing = Procesando clúster de almacenes de datos '{0}' ({1}/{2}). + SectionHeading = Clústeres de almacenes de datos + ParagraphSummary = Las siguientes secciones detallan la configuración de los clústeres de almacenes de datos administrados por el servidor vCenter {0}. + DSCluster = Clúster de almacenes de datos + Datacenter = Centro de datos + CapacityGB = Capacidad total (GB) + FreeSpaceGB = Espacio libre (GB) + SDRSEnabled = SDRS + SDRSAutomationLevel = Nivel de automatización de SDRS + IOLoadBalancing = Equilibrio de carga de E/S + SpaceThreshold = Umbral de espacio (%) + IOLatencyThreshold = Umbral de latencia de E/S (ms) + SDRSRules = Reglas de SDRS + RuleName = Regla + RuleEnabled = Habilitado + RuleVMs = Máquinas virtuales + FullyAutomated = Totalmente automatizado + NoAutomation = Sin automatización (Modo manual) + Manual = Manual + Enabled = Habilitado + Disabled = Deshabilitado + Yes = Sí + No = No + ID = ID + TotalCapacity = Capacidad total + UsedCapacity = Capacidad usada + FreeCapacity = Capacidad libre + PercentUsed = % usado + ParagraphDSClusterDetail = La siguiente tabla detalla la configuración del clúster de almacenes de datos {0}. + TableDSClusterConfig = Configuración del clúster de almacenes de datos - {0} + TableSDRSVMOverrides = Excepciones de máquinas virtuales de SDRS - {0} + SDRSVMOverrides = Excepciones de máquinas virtuales de SDRS + VirtualMachine = Máquina virtual + KeepVMDKsTogether = Mantener VMDK juntos + DefaultBehavior = Predeterminado ({0}) + RuleType = Tipo + RuleAffinity = Afinidad + RuleAntiAffinity = Antiafinidad + TableSDRSRules = Reglas SDRS - {0} + SpaceLoadBalanceConfig = Configuración de equilibrio de carga de espacio + SpaceMinDiff = Diferencia mínima de utilización de espacio (%) + SpaceThresholdMode = Modo de umbral de espacio + UtilizationMode = Umbral de utilización + FreeSpaceMode = Umbral de espacio libre + UtilizationThreshold = Umbral de utilización de espacio (%) + FreeSpaceThreshold = Umbral de espacio libre (GB) + IOLoadBalanceConfig = Configuración de equilibrio de carga de E/S + IOCongestionThreshold = Umbral de congestión de E/S (ms) + IOReservationMode = Modo de umbral de reserva + IOPSThresholdMode = Recuento de operaciones de E/S + ReservationMbpsMode = Reserva en Mbps + ReservationIopsMode = Reserva en IOPS + TableSpaceLoadBalance = Configuración de equilibrio de carga de espacio - {0} + TableIOLoadBalance = Configuración de equilibrio de carga de E/S - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSphereVM +GetAbrVSphereVM = ConvertFrom-StringData @' + InfoLevel = Nivel de información de máquina virtual establecido en {0}. + Collecting = Recopilando información de máquinas virtuales. + Processing = Procesando máquina virtual '{0}' ({1}/{2}). + SectionHeading = Máquinas virtuales + ParagraphSummary = Las siguientes secciones detallan la configuración de las máquinas virtuales administradas por el servidor vCenter {0}. + VirtualMachine = Máquina virtual + PowerState = Estado de energía + Template = Plantilla + OS = Sistema operativo + Version = Versión de hardware de máquina virtual + GuestID = ID de invitado + Cluster = Clúster + ResourcePool = Grupo de recursos + VMHost = Host + Folder = Carpeta + IPAddress = Dirección IP + CPUs = CPU + MemoryGB = Memoria (GB) + ProvisionedGB = Aprovisionado (GB) + UsedGB = Usado (GB) + NumDisks = N.º de discos + NumNICs = N.º de NIC + NumSnapshots = N.º de instantáneas + VMwareTools = VMware Tools + ToolsVersion = Versión de Tools + ToolsStatus = Estado de Tools + ToolsRunningStatus = Estado de ejecución de Tools + VMAdvancedDetail = Configuración avanzada + BootOptions = Opciones de arranque + BootDelay = Retraso de arranque (ms) + BootRetryEnabled = Reintento de arranque habilitado + BootRetryDelay = Retraso de reintento de arranque (ms) + EFISecureBoot = Arranque seguro EFI + EnterBIOSSetup = Acceder a la configuración del BIOS en el próximo arranque + HardDisks = Discos duros + DiskName = Disco + DiskCapacityGB = Capacidad (GB) + DiskFormat = Formato + DiskStoragePolicy = Política de almacenamiento + DiskDatastore = Almacén de datos + DiskController = Controlador + NetworkAdapters = Adaptadores de red + NICName = Adaptador de red + NICType = Tipo de adaptador + NICPortGroup = Grupo de puertos + NICMAC = Dirección MAC + NICConnected = Conectado + NICConnectionPolicy = Conectar al encender + SnapshotHeading = Instantáneas + SnapshotName = Instantánea + SnapshotDescription = Descripción + SnapshotSize = Tamaño (GB) + SnapshotDate = Creado + SnapshotParent = Principal + On = Encendido + Off = Apagado + ToolsOld = Antiguo + ToolsOK = Correcto + ToolsNotRunning = No está en ejecución + ToolsNotInstalled = No instalado + Yes = Sí + No = No + Connected = Conectado + NotConnected = No conectado + Thin = Aprovisionamiento ligero + Thick = Aprovisionamiento grueso + Enabled = Habilitado + Disabled = Deshabilitado + TotalVMs = Total de máquinas virtuales + TotalvCPUs = Total de vCPU + TotalMemory = Memoria total + TotalProvisionedSpace = Espacio total aprovisionado + TotalUsedSpace = Espacio total usado + VMsPoweredOn = Máquinas virtuales encendidas + VMsPoweredOff = Máquinas virtuales apagadas + VMsOrphaned = Máquinas virtuales huérfanas + VMsInaccessible = Máquinas virtuales inaccesibles + VMsSuspended = Máquinas virtuales suspendidas + VMsWithSnapshots = Máquinas virtuales con instantáneas + GuestOSTypes = Tipos de sistema operativo invitado + VMToolsOKCount = Herramientas de VM correctas + VMToolsOldCount = Herramientas de VM antiguas + VMToolsNotRunningCount = Herramientas de VM no en ejecución + VMToolsNotInstalledCount = Herramientas de VM no instaladas + vCPUs = vCPU + Memory = Memoria + Provisioned = Aprovisionado + Used = Usado + HWVersion = Versión de hardware + VMToolsStatus = Estado de herramientas de VM + ID = ID + OperatingSystem = Sistema operativo + HardwareVersion = Versión de hardware + ConnectionState = Estado de conexión + FaultToleranceState = Estado de tolerancia a fallos + FTNotConfigured = No configurado + FTNeedsSecondary = Necesita secundario + FTRunning = En ejecución + FTDisabled = Deshabilitado + FTStarting = Iniciando + FTEnabled = Habilitado + Parent = Principal + ParentFolder = Carpeta principal + ParentResourcePool = Grupo de recursos principal + CoresPerSocket = Núcleos por socket + CPUShares = Recursos de CPU + CPUReservation = Reserva de CPU + CPULimit = Límite de CPU + CPUHotAdd = Adición en caliente de CPU + CPUHotRemove = Eliminación en caliente de CPU + MemoryAllocation = Asignación de memoria + MemoryShares = Recursos de memoria + MemoryHotAdd = Adición en caliente de memoria + vNICs = vNIC + DNSName = Nombre DNS + Networks = Redes + MACAddress = Dirección MAC + vDisks = Discos virtuales + ProvisionedSpace = Espacio aprovisionado + UsedSpace = Espacio usado + ChangedBlockTracking = Seguimiento de bloques modificados + StorageBasedPolicy = Política basada en almacenamiento + StorageBasedPolicyCompliance = Cumplimiento de política basada en almacenamiento + Compliant = Conforme + NonCompliant = No conforme + Unknown = Desconocido + Notes = Notas + BootTime = Hora de arranque + UptimeDays = Días de actividad + NetworkName = Nombre de red + SCSIControllers = Controladores SCSI + Device = Dispositivo + ControllerType = Tipo de controlador + BusSharing = Uso compartido del bus + None = Ninguno + GuestVolumes = Volúmenes del invitado + Capacity = Capacidad + DiskProvisioning = Aprovisionamiento de disco + ThickEagerZeroed = Grosor con cero por adelantado + ThickLazyZeroed = Grosor con cero por demanda + DiskType = Tipo de disco + PhysicalRDM = RDM físico + VirtualRDM = RDM virtual + VMDK = VMDK + DiskMode = Modo de disco + IndependentPersistent = Independiente - Persistente + IndependentNonpersistent = Independiente - No persistente + Dependent = Dependiente + DiskPath = Ruta de disco + DiskShares = Recursos de disco + DiskLimitIOPs = Límite de IOPS de disco + Unlimited = Ilimitado + SCSIController = Controlador SCSI + SCSIAddress = Dirección SCSI + Path = Ruta + FreeSpace = Espacio libre + DaysOld = Días de antigüedad + TableVMSummary = Resumen de máquinas virtuales - {0} + TableVMAdvancedSummary = Resumen avanzado de máquinas virtuales - {0} + TableVMSnapshotSummary = Resumen de instantáneas de máquinas virtuales - {0} + TableVMConfig = Configuración de máquinas virtuales - {0} + TableVMNetworkAdapters = Adaptadores de red - {0} + TableVMSCSIControllers = Controladores SCSI - {0} + TableVMHardDiskConfig = Configuración de disco duro - {0} + TableVMHardDisk = {0} - {1} + TableVMGuestVolumes = Volúmenes del invitado - {0} + TableVMSnapshots = Instantáneas de máquinas virtuales - {0} + VUMCompliance = Cumplimiento de Update Manager de VM + VUMBaselineName = Línea base + VUMStatus = Estado + NotCompliant = No conforme + Incompatible = Incompatible + VUMComplianceError = Unable to retrieve VUM compliance information for virtual machines. + InsufficientPrivVUMCompliance = Insufficient privileges to collect VUM compliance information for virtual machines. + TableVUMCompliance = Cumplimiento de línea base VUM - {0} + Tags = Etiquetas +'@ + +# Get-AbrVSphereVUM +GetAbrVSphereVUM = ConvertFrom-StringData @' + InfoLevel = Nivel de información de VUM establecido en {0}. + Collecting = Recopilando información de VMware Update Manager. + NotAvailable = La información de líneas base de parches de VUM no está disponible actualmente con su versión de PowerShell. + PatchNotAvailable = La información de parches de VUM no está disponible actualmente con su versión de PowerShell. + SectionHeading = VMware Update Manager + ParagraphSummary = Las siguientes secciones detallan la configuración de VMware Update Manager administrado por el servidor vCenter {0}. + Baselines = Líneas base + BaselineName = Línea base + Description = Descripción + Type = Tipo + TargetType = Tipo de destino + LastUpdate = Última actualización + NumPatches = N.º de parches + Patches = Parches + PatchName = Parche + PatchProduct = Producto + PatchDescription = Descripción + PatchReleaseDate = Fecha de lanzamiento + PatchVendorID = ID de fabricante + TableVUMBaselines = Resumen de líneas base de VMware Update Manager - {0} + TableVUMPatches = Información de parches de VMware Update Manager - {0} + SoftwareDepots = Depósitos de software + OnlineDepots = Depósitos en línea + OfflineDepots = Depósitos sin conexión + DepotUrl = URL + SystemDefined = Definido por el sistema + DepotEnabled = Habilitado + DepotLocation = Ubicación + DepotError = No se puede recuperar información de depósitos de software. {0} + TableOnlineDepots = Depósitos de software en línea - {0} + TableOfflineDepots = Depósitos de software sin conexión - {0} +'@ + +# Get-AbrVSphereClusterLCM +GetAbrVSphereClusterLCM = ConvertFrom-StringData @' + Collecting = Recopilando información del Lifecycle Manager. + ImageComposition = Composición de imagen + BaseImage = Imagen base + VendorAddOn = Complemento del proveedor + None = Ninguno + Components = Componentes + ComponentName = Componente + ComponentVersion = Versión + HardwareSupportManager = Administrador de soporte de hardware + HsmName = Nombre + HsmVersion = Versión + HsmPackages = Paquetes de soporte de hardware + ImageCompliance = Conformidad de imagen + Cluster = Clúster + VMHost = VMHost + ComplianceStatus = Estado de conformidad + LcmError = No se puede recuperar información del Lifecycle Manager para el clúster {0}. {1} + ComplianceError = No se puede recuperar información de conformidad para el clúster {0}. {1} + TableImageComposition = Composición de imagen - {0} + TableComponents = Componentes de imagen - {0} + TableHardwareSupportManager = Administrador de soporte de hardware - {0} + TableImageCompliance = Conformidad de imagen - {0} + TableHostCompliance = Conformidad de imagen del host - {0} +'@ + +} diff --git a/AsBuiltReport.VMware.vSphere/Language/fr-FR/VMwarevSphere.psd1 b/AsBuiltReport.VMware.vSphere/Language/fr-FR/VMwarevSphere.psd1 new file mode 100644 index 0000000..f520d96 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Language/fr-FR/VMwarevSphere.psd1 @@ -0,0 +1,1625 @@ +# culture = 'fr-FR' +@{ + +# Module-wide strings +InvokeAsBuiltReportVMwarevSphere = ConvertFrom-StringData @' + Connecting = Connexion au serveur vCenter '{0}'. + CheckPrivileges = Vérification des privilèges de l'utilisateur vCenter. + UnablePrivileges = Impossible d'obtenir les privilèges de l'utilisateur vCenter. + VMHashtable = Création de la table de correspondance des machines virtuelles. + VMHostHashtable = Création de la table de correspondance des hôtes VMHost. + DatastoreHashtable = Création de la table de correspondance des magasins de données. + VDPortGrpHashtable = Création de la table de correspondance des groupes de ports distribués. + EVCHashtable = Création de la table de correspondance EVC. + CheckVUM = Vérification de la présence du serveur VMware Update Manager. + CheckVxRail = Vérification de la présence du serveur VxRail Manager. + CheckSRM = Vérification de la présence du serveur VMware Site Recovery Manager. + CheckNSXT = Vérification de la présence du serveur VMware NSX-T Manager. + CollectingTags = Collecte des informations sur les étiquettes. + TagError = Erreur lors de la collecte des informations sur les étiquettes. + CollectingAdvSettings = Collecte des paramètres avancés de {0}. +'@ + +# Get-AbrVSpherevCenter +GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = Niveau d'information vCenter défini sur {0}. + Collecting = Collecte des informations du serveur vCenter. + SectionHeading = Serveur vCenter + ParagraphSummaryBrief = Les sections suivantes résument la configuration du serveur vCenter {0}. + ParagraphSummary = Les sections suivantes détaillent la configuration du serveur vCenter {0}. + InsufficientPrivLicense = Privilèges utilisateur insuffisants pour rapporter les licences du serveur vCenter. Veuillez vous assurer que le compte utilisateur dispose du privilège 'Global > Licences'. + InsufficientPrivStoragePolicy = Privilèges utilisateur insuffisants pour rapporter les stratégies de stockage des machines virtuelles. Veuillez vous assurer que le compte utilisateur dispose du privilège 'Profil de stockage > Afficher'. + vCenterServer = Serveur vCenter + IPAddress = Adresse IP + Version = Version + Build = Build + Product = Produit + LicenseKey = Clé de licence + LicenseExpiration = Expiration de la licence + InstanceID = ID d'instance + HTTPPort = Port HTTP + HTTPSPort = Port HTTPS + PSC = Contrôleur de services de plateforme + UpdateManagerServer = Serveur Update Manager + SRMServer = Serveur Site Recovery Manager + NSXTServer = Serveur NSX-T Manager + VxRailServer = Serveur VxRail Manager + DatabaseSettings = Paramètres de base de données + DatabaseType = Type de base de données + DataSourceName = Nom de la source de données + MaxDBConnection = Connexions maximales à la base de données + MailSettings = Paramètres de messagerie + SMTPServer = Serveur SMTP + SMTPPort = Port SMTP + MailSender = Expéditeur + HistoricalStatistics = Statistiques historiques + IntervalDuration = Durée de l'intervalle + IntervalEnabled = Intervalle activé + SaveDuration = Durée de conservation + StatisticsLevel = Niveau des statistiques + Licensing = Licences + Total = Total + Used = Utilisé + Available = Disponible + Expiration = Expiration + Certificate = Certificat + Subject = Sujet + Issuer = Émetteur + ValidFrom = Valide à partir de + ValidTo = Valide jusqu'au + Thumbprint = Empreinte numérique + CertStatus = Statut + InsufficientPrivCertificate = Impossible de récupérer le certificat du serveur vCenter. {0} + Mode = Mode + SoftThreshold = Seuil souple + HardThreshold = Seuil strict + MinutesBefore = Minutes avant + PollInterval = Intervalle d'interrogation + Roles = Rôles + Role = Rôle + SystemRole = Rôle système + PrivilegeList = Liste des privilèges + Tags = Étiquettes + TagName = Nom + TagCategory = Catégorie + TagDescription = Description + TagCategories = Catégories d'étiquettes + TagCardinality = Cardinalité + TagAssignments = Affectations d'étiquettes + TagEntity = Entité + TagEntityType = Type d'entité + VMStoragePolicies = Stratégies de stockage des machines virtuelles + StoragePolicy = Stratégie de stockage + Description = Description + ReplicationEnabled = Réplication activée + CommonRulesName = Nom des règles communes + CommonRulesDescription = Description des règles communes + Alarms = Alarmes + Alarm = Alarme + AlarmDescription = Description + AlarmEnabled = Activée + AlarmTriggered = Déclenchée + AlarmAction = Action + AdvancedSystemSettings = Paramètres système avancés + Key = Clé + Value = Valeur + Enabled = Activé + Disabled = Désactivé + Yes = Oui + No = Non + None = Aucun + TablevCenterSummary = vCenter Server Summary - {0} + TablevCenterConfig = vCenter Server Configuration - {0} + TableDatabaseSettings = Database Settings - {0} + TableMailSettings = Mail Settings - {0} + TableHistoricalStatistics = Historical Statistics - {0} + TableLicensing = Licensing - {0} + TableCertificate = Certificate - {0} + TableRole = Role {0} - {1} + TableRoles = Roles - {0} + TableTags = Tags - {0} + TableTagCategories = Tag Categories - {0} + TableTagAssignments = Tag Assignments - {0} + TableVMStoragePolicies = VM Storage Policies - {0} + TableAlarm = {0} - {1} + TableAlarms = Alarms - {0} + TableAdvancedSystemSettings = vCenter Advanced System Settings - {0} + RestApiSessionError = Unable to establish vCenter REST API session. {0} + BackupSettings = Paramètres de sauvegarde + BackupSchedule = Calendrier de sauvegarde + BackupJobHistory = Historique des tâches de sauvegarde + BackupNotConfigured = Aucun calendrier de sauvegarde n'est configuré. + BackupNoJobs = Aucune tâche de sauvegarde trouvée. + BackupApiNotAvailable = L'état de sauvegarde vCenter nécessite vSphere 7.0 ou version ultérieure. + BackupApiError = Impossible de récupérer les informations de sauvegarde. {0} + BackupScheduleID = ID de calendrier + BackupLocation = Emplacement + BackupLocationUser = Utilisateur de l'emplacement + BackupEnabled = État + BackupActivated = Activé + BackupDeactivated = Désactivé + BackupParts = Données de sauvegarde + BackupPartSeat = Plan de contrôle des superviseurs + BackupPartCommon = Inventaire et configuration + BackupPartStats = Statistiques, événements et tâches + BackupRecurrence = Planification + BackupRetentionCount = Nombre de sauvegardes à conserver + BackupDaily = Quotidien + BackupSendEmail = Notification par e-mail + BackupJobLocation = Emplacement de sauvegarde + BackupJobType = Type + BackupJobStatus = État + BackupJobComplete = Terminé + BackupJobScheduled = Planifié + BackupJobDataTransferred = Données transférées + BackupJobDuration = Durée + BackupJobEndTime = Heure de fin + TableBackupSchedule = Calendrier de sauvegarde - {0} + TableBackupJobHistory = Historique des tâches de sauvegarde - {0} + ResourceSummary = Ressources + SummaryResource = Ressource + Free = Libre + CPU = CPU + Memory = Mémoire + Storage = Stockage + VirtualMachines = Machines Virtuelles + Hosts = Hôtes + PoweredOn = Allumé + PoweredOff = Éteint + Suspended = Suspendu + Connected = Connecté + Disconnected = Déconnecté + Maintenance = Maintenance + ContentLibraries = Bibliothèques de Contenu + ContentLibrary = Bibliothèque de Contenu + LibraryType = Type + Datastore = Banque de Données + LibraryLocal = Locale + LibrarySubscribed = Abonnée + ItemCount = Éléments + SubscriptionUrl = URL d'Abonnement + AutomaticSync = Synchronisation Automatique + OnDemandSync = Synchronisation à la Demande + LibraryItems = Éléments de Bibliothèque + ItemName = Élément + ContentType = Type de Contenu + ItemSize = Taille + CreationTime = Date de Création + LastModified = Dernière Modification + ContentLibraryNoItems = Aucun élément trouvé dans cette bibliothèque de contenu. + ContentLibraryNone = Aucune bibliothèque de contenu trouvée. + CollectingContentLibrary = Collecte des informations de la bibliothèque de contenu. + ContentLibraryError = Impossible de récupérer les informations de la bibliothèque de contenu. {0} + ContentLibraryItemError = Impossible de récupérer les éléments de la bibliothèque de contenu '{0}'. {1} + TableContentLibraries = Content Libraries - {0} + TableContentLibrary = Content Library {0} - {1} + TableLibraryItems = Library Items - {0} + TableLibraryItem = {0} - {1} + TablevCenterResourceSummary = Résumé des Ressources - {0} + TablevCenterVMSummary = Résumé des Machines Virtuelles - {0} + TablevCenterHostSummary = Résumé des Hôtes - {0} +'@ + +# Get-AbrVSphereCluster +GetAbrVSphereCluster = ConvertFrom-StringData @' + InfoLevel = Niveau d'information Cluster défini sur {0}. + Collecting = Collecte des informations sur les clusters. + Processing = Traitement du cluster '{0}' ({1}/{2}). + SectionHeading = Clusters + ParagraphSummary = Les sections suivantes détaillent la configuration des clusters vSphere HA/DRS gérés par le serveur vCenter {0}. + ParagraphDetail = Le tableau suivant détaille la configuration du cluster {0}. + Cluster = Cluster + ID = ID + Datacenter = Centre de données + NumHosts = Nb d'hôtes + NumVMs = Nb de machines virtuelles + HAEnabled = vSphere HA + DRSEnabled = vSphere DRS + VSANEnabled = SAN virtuel + EVCMode = Mode EVC + VMSwapFilePolicy = Stratégie de fichier d'échange des MV + NumberOfHosts = Nombre d'hôtes + NumberOfVMs = Nombre de machines virtuelles + Hosts = Hôtes + VirtualMachines = Machines virtuelles + Permissions = Autorisations + Principal = Principal + Role = Rôle + Propagate = Propager + IsGroup = Est un groupe + Enabled = Activé + Disabled = Désactivé + SwapWithVM = Avec la VM + SwapInHostDatastore = Dans la banque de données de l'hôte + SwapVMDirectory = Répertoire de la machine virtuelle + SwapHostDatastore = Banque de données spécifiée par l'hôte + TableClusterSummary = Cluster Summary - {0} + TableClusterConfig = Cluster Configuration - {0} +'@ + +# Get-AbrVSphereClusterHA +GetAbrVSphereClusterHA = ConvertFrom-StringData @' + Collecting = Collecte des informations sur le Cluster HA. + SectionHeading = Configuration de vSphere HA + ParagraphSummary = La section suivante détaille la configuration de vSphere HA pour le cluster {0}. + FailuresAndResponses = Pannes et réponses + HostMonitoring = Surveillance des hôtes + HostFailureResponse = Réponse aux pannes d'hôtes + HostIsolationResponse = Réponse à l'isolation des hôtes + VMRestartPriority = Priorité de redémarrage des MV + PDLProtection = Magasin de données avec perte permanente de périphérique + APDProtection = Magasin de données avec tous les chemins inactifs + VMMonitoring = Surveillance des MV + VMMonitoringSensitivity = Sensibilité de la surveillance des MV + AdmissionControl = Contrôle d'admission + FailoverLevel = Pannes d'hôtes tolérées par le cluster + ACPolicy = Stratégie + ACHostPercentage = % CPU + ACMemPercentage = % Mémoire + PerformanceDegradation = Dégradation des performances des MV + HeartbeatDatastores = Magasins de données de pulsation + Datastore = Magasin de données + HAAdvancedOptions = Options avancées de vSphere HA + Key = Clé + Value = Valeur + APDRecovery = Récupération APD après expiration du délai APD + Disabled = Désactivé + Enabled = Activé + RestartVMs = Redémarrer les VM + ShutdownAndRestart = Arrêter et redémarrer les VM + PowerOffAndRestart = Éteindre et redémarrer les VM + IssueEvents = Générer des événements + PowerOffRestartConservative = Éteindre et redémarrer les VM (conservateur) + PowerOffRestartAggressive = Éteindre et redémarrer les VM (agressif) + ResetVMs = Réinitialiser les VM + VMMonitoringOnly = Surveillance VM uniquement + VMAndAppMonitoring = Surveillance VM et applications + DedicatedFailoverHosts = Hôtes de basculement dédiés + ClusterResourcePercentage = Pourcentage des ressources du cluster + SlotPolicy = Politique d'emplacement + Yes = Oui + No = Non + FixedSlotSize = Taille d'emplacement fixe + CoverAllPoweredOnVMs = Couvrir toutes les machines virtuelles sous tension + NoneSpecified = Aucun spécifié + OverrideFailoverCapacity = Override Calculated Failover Capacity + CPUSlotSize = CPU Slot Size (MHz) + MemorySlotSize = Memory Slot Size (MB) + PerfDegradationTolerate = Performance Degradation VMs Tolerate + HeartbeatSelectionPolicy = Heartbeat Selection Policy + HBPolicyAllFeasibleDsWithUserPreference = Use datastores from the specified list and complement automatically if needed + HBPolicyAllFeasibleDs = Automatically select datastores accessible from the host + HBPolicyUserSelectedDs = Use datastores only from the specified list + TableHAFailures = vSphere HA Failures and Responses - {0} + TableHAAdmissionControl = vSphere HA Admission Control - {0} + TableHAHeartbeat = vSphere HA Heartbeat Datastores - {0} + TableHAAdvanced = vSphere HA Advanced Options - {0} +'@ + +# Get-AbrVSphereClusterProactiveHA +GetAbrVSphereClusterProactiveHA = ConvertFrom-StringData @' + Collecting = Collecte des informations sur le Cluster HA proactif. + SectionHeading = HA proactif + ParagraphSummary = La section suivante détaille la configuration du HA proactif pour le cluster {0}. + FailuresAndResponses = Pannes et réponses + Provider = Fournisseur + Remediation = Remédiation + HealthUpdates = Mises à jour de l'état de santé + ProactiveHA = HA proactive + AutomationLevel = Niveau d'automatisation + ModerateRemediation = Correction modérée + SevereRemediation = Correction grave + Enabled = Activé + Disabled = Désactivé + MaintenanceMode = Mode Maintenance + QuarantineMode = Mode Quarantaine + MixedMode = Mode Mixte + TableProactiveHA = Proactive HA - {0} + Providers = Fournisseurs + HealthUpdateCount = Mises à jour de santé + TableProactiveHAProviders = Fournisseurs de HA proactive - {0} +'@ + +# Get-AbrVSphereClusterDRS +GetAbrVSphereClusterDRS = ConvertFrom-StringData @' + Collecting = Collecte des informations sur le Cluster DRS. + SectionHeading = Configuration de vSphere DRS + ParagraphSummary = Le tableau suivant détaille la configuration de vSphere DRS pour le cluster {0}. + AutomationLevel = Niveau d'automatisation DRS + MigrationThreshold = Seuil de migration + PredictiveDRS = DRS prédictif + VirtualMachineAutomation = Automatisation individuelle des machines + AdditionalOptions = Options supplémentaires + VMDistribution = Distribution des MV + MemoryMetricForLB = Métrique mémoire pour l'équilibrage de charge + CPUOverCommitment = Sur-engagement CPU + PowerManagement = Gestion de l'alimentation + DPMAutomationLevel = Niveau d'automatisation DPM + DPMThreshold = Seuil DPM + AdvancedOptions = Options avancées + Key = Clé + Value = Valeur + DRSClusterGroups = Groupes de clusters DRS + GroupName = Nom du groupe + GroupType = Type de groupe + GroupMembers = Membres + DRSVMHostRules = Règles MV/Hôte DRS + RuleName = Nom de la règle + RuleType = Type de règle + RuleEnabled = Activée + VMGroup = Groupe de MV + HostGroup = Groupe d'hôtes + DRSRules = Règles DRS + RuleVMs = Machines virtuelles + VMOverrides = Remplacements de MV + VirtualMachine = Machine virtuelle + DRSAutomationLevel = Niveau d'automatisation DRS + DRSBehavior = Comportement DRS + HARestartPriority = Priorité de redémarrage HA + HAIsolationResponse = Réponse à l'isolation HA + PDLProtection = Magasin de données avec PDL + APDProtection = Magasin de données avec APD + VMMonitoring = Surveillance des MV + VMMonitoringFailureInterval = Intervalle d'échec + VMMonitoringMinUpTime = Temps de fonctionnement minimum + VMMonitoringMaxFailures = Nombre maximum d'échecs + VMMonitoringMaxFailureWindow = Fenêtre d'échec maximale + Enabled = Activé + Disabled = Désactivé + Yes = Oui + No = Non + FullyAutomated = Entièrement automatisé + PartiallyAutomated = Partiellement automatisé + Manual = Manuel + Off = Désactivé + DRS = vSphere DRS + DPM = DPM + Automated = Automated + None = None + VMGroupType = VM Group + VMHostGroupType = Host Group + MustRunOn = Must run on hosts in group + ShouldRunOn = Should run on hosts in group + MustNotRunOn = Must not run on hosts in group + ShouldNotRunOn = Should not run on hosts in group + VMAffinity = Keep Virtual Machines Together + VMAntiAffinity = Separate Virtual Machines + Mandatory = Mandatory + OverCommitmentRatio = Over-Commitment Ratio + OverCommitmentRatioCluster = Over-Commitment Ratio (% of cluster capacity) + Lowest = Lowest + Low = Low + Medium = Medium + High = High + Highest = Highest + ClusterDefault = Cluster default + VMDependencyTimeout = VM Dependency Restart Condition Timeout + Seconds = {0} seconds + SectionVSphereHA = vSphere HA + IssueEvents = Issue events + PowerOffAndRestart = Power off and restart VMs + ShutdownAndRestartVMs = Shutdown and restart VMs + PowerOffRestartConservative = Power off and restart VMs - Conservative restart policy + PowerOffRestartAggressive = Power off and restart VMs - Aggressive restart policy + PDLFailureResponse = PDL Failure Response + APDFailureResponse = APD Failure Response + VMFailoverDelay = VM Failover Delay + Minutes = {0} minutes + ResponseRecovery = Response Recovery + ResetVMs = Reset VMs + SectionPDLAPD = PDL/APD Protection Settings + NoWindow = No window + WithinHours = Within {0} hrs + VMMonitoringOnly = VM Monitoring Only + VMAndAppMonitoring = VM and Application Monitoring + UserGroup = User/Group + IsGroup = Is Group? + Role = Role + DefinedIn = Defined In + Propagate = Propagate + Permissions = Permissions + ParagraphPermissions = The following table details the permissions for {0}. + TableDRSConfig = vSphere DRS Configuration - {0} + TableDRSAdditional = DRS Additional Options - {0} + TableDPM = vSphere DPM - {0} + TableDRSAdvanced = vSphere DRS Advanced Options - {0} + TableDRSGroups = DRS Cluster Groups - {0} + TableDRSVMHostRules = DRS VM/Host Rules - {0} + TableDRSRules = DRS Rules - {0} + TableDRSVMOverrides = DRS VM Overrides - {0} + TableHAVMOverrides = HA VM Overrides - {0} + TableHAPDLAPD = HA VM Overrides PDL/APD Settings - {0} + TableHAVMMonitoring = HA VM Overrides VM Monitoring - {0} + TablePermissions = Permissions - {0} +'@ + +# Get-AbrVSphereClusterVUM +GetAbrVSphereClusterVUM = ConvertFrom-StringData @' + UpdateManagerBaselines = Lignes de base Update Manager + Baseline = Ligne de base + Description = Description + Type = Type + TargetType = Type de cible + LastUpdate = Heure de la dernière mise à jour + NumPatches = Nb de correctifs + UpdateManagerCompliance = Conformité Update Manager + Entity = Entité + Status = État de conformité + BaselineInfo = Ligne de base + VUMPrivilegeMsgBaselines = Privilèges utilisateur insuffisants pour rapporter les lignes de base du cluster. Veuillez vous assurer que le compte utilisateur dispose du privilège 'VMware Update Manager / VMware vSphere Lifecycle Manager > Gérer les correctifs et les mises à niveau > Afficher l'état de conformité'. + VUMPrivilegeMsgCompliance = Privilèges utilisateur insuffisants pour rapporter la conformité du cluster. Veuillez vous assurer que le compte utilisateur dispose du privilège 'VMware Update Manager / VMware vSphere Lifecycle Manager > Gérer les correctifs et les mises à niveau > Afficher l'état de conformité'. + VUMBaselineNotAvailable = Les informations de ligne de base VUM du cluster ne sont pas disponibles avec votre version de PowerShell. + VUMComplianceNotAvailable = Les informations de conformité VUM du cluster ne sont pas disponibles avec votre version de PowerShell. + NotCompliant = Non conforme + Unknown = Inconnu + Incompatible = Incompatible + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} +'@ + +# Get-AbrVSphereResourcePool +GetAbrVSphereResourcePool = ConvertFrom-StringData @' + InfoLevel = Niveau d'information Pool de ressources défini sur {0}. + Collecting = Collecte des informations sur les pools de ressources. + Processing = Traitement du pool de ressources '{0}' ({1}/{2}). + SectionHeading = Pools de ressources + ParagraphSummary = Les sections suivantes détaillent la configuration des pools de ressources gérés par le serveur vCenter {0}. + ResourcePool = Pool de ressources + Parent = Parent + CPUSharesLevel = Niveau de partage CPU + CPUReservationMHz = Réservation CPU (MHz) + CPULimitMHz = Limite CPU (MHz) + MemSharesLevel = Niveau de partage mémoire + MemReservation = Réservation mémoire + MemLimit = Limite mémoire + ID = ID + NumCPUShares = Nombre de partages CPU + CPUReservation = Réservation CPU + CPUExpandable = Réservation CPU extensible + NumMemShares = Nombre de partages mémoire + MemExpandable = Réservation mémoire extensible + NumVMs = Nombre de MV + VirtualMachines = Machines virtuelles + Enabled = Activé + Disabled = Désactivé + Unlimited = Illimité + TableResourcePoolSummary = Resource Pool Summary - {0} + TableResourcePoolConfig = Resource Pool Configuration - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSphereVMHost +GetAbrVSphereVMHost = ConvertFrom-StringData @' + InfoLevel = Niveau d'information VMHost défini sur {0}. + Collecting = Collecte des informations sur les hôtes VMHost. + Processing = Traitement de l'hôte VMHost '{0}' ({1}/{2}). + SectionHeading = Hôtes + ParagraphSummary = Les sections suivantes détaillent la configuration des hôtes VMware ESXi gérés par le serveur vCenter {0}. + VMHost = Hôte + Manufacturer = Fabricant + Model = Modèle + ProcessorType = Type de processeur + NumCPUSockets = Sockets CPU + NumCPUCores = Cœurs CPU + NumCPUThreads = Threads CPU + MemoryGB = Mémoire (Go) + NumNICs = Nb de cartes réseau + NumHBAs = Nb de HBA + NumDatastores = Nb de magasins de données + NumVMs = Nb de MV + ConnectionState = État de connexion + PowerState = État d'alimentation + ErrorCollecting = Erreur lors de la collecte des informations VMHost avec le niveau d'information VMHost {0}. + NotResponding = Ne répond pas + Maintenance = Maintenance + Disconnected = Déconnecté + Version = Version + Build = Build + Parent = Parent + TableHostSummary = Host Summary - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSphereVMHostHardware +GetAbrVSphereVMHostHardware = ConvertFrom-StringData @' + Collecting = Collecte des informations matérielles de l'hôte VMHost. + SectionHeading = Matériel + ParagraphSummary = La section suivante détaille la configuration matérielle de l'hôte {0}. + InsufficientPrivLicense = Privilèges utilisateur insuffisants pour rapporter les licences de l'hôte ESXi. Veuillez vous assurer que le compte utilisateur dispose du privilège 'Global > Licences'. + LicenseError = Impossible de récupérer les informations de licence pour VMHost '{0}'. Erreur : {1} + Specifications = Spécifications + Manufacturer = Fabricant + Model = Modèle + SerialNumber = Numéro de série + AssetTag = Étiquette d'inventaire + ProcessorType = Type de processeur + CPUSockets = Sockets CPU + CPUCores = Cœurs CPU + CPUThreads = Threads CPU + HyperthreadingActive = Hyperthreading actif + MemoryGB = Mémoire (Go) + NUMANodes = Nœuds NUMA + NICs = Cartes réseau + HBAs = HBA + Version = Version + Build = Build + LicenseKey = Clé de licence + Product = Produit + LicenseExpiration = Expiration de la licence + IPMIBMC = IPMI / BMC + IPMIBMCError = Erreur lors de la collecte des informations IPMI/BMC pour {0}. + IPMIBMCManufacturer = Fabricant + IPMIBMCType = Type + IPMIBMCIPAddress = Adresse IP + IPMIBMCMACAddress = Adresse MAC + BootDevice = Périphérique de démarrage + BootDeviceError = Erreur lors de la collecte des informations sur le périphérique de démarrage pour {0}. + BootDeviceDescription = Description + BootDeviceType = Type + BootDeviceSize = Taille (Go) + BootDeviceIsSAS = Est SAS + BootDeviceIsUSB = Est USB + BootDeviceIsSSD = Est SSD + BootDeviceFromSAN = Depuis SAN + PCIDevices = Périphériques PCI + PCIDeviceId = ID PCI + PCIVendorName = Nom du fabricant + PCIDeviceName = Nom du périphérique + PCIDriverName = Nom du pilote + PCIDriverVersion = Version du pilote + PCIFirmware = Version du micrologiciel + PCIDriversFirmware = Pilotes et micrologiciels des périphériques PCI + Enabled = Activé + Disabled = Désactivé + NotApplicable = Non applicable + Unknown = Inconnu + Maintenance = Maintenance + NotResponding = Not Responding + Host = Host + ConnectionState = Connection State + ID = ID + Parent = Parent + HyperThreading = HyperThreading + NumberOfCPUSockets = Number of CPU Sockets + NumberOfCPUCores = Number of CPU Cores + NumberOfCPUThreads = Number of CPU Threads + CPUTotalUsedFree = CPU Total / Used / Free + MemoryTotalUsedFree = Memory Total / Used / Free + NumberOfNICs = Number of NICs + NumberOfHBAs = Number of HBAs + NumberOfDatastores = Number of Datastores + NumberOfVMs = Number of VMs + MaximumEVCMode = Maximum EVC Mode + EVCGraphicsMode = EVC Graphics Mode + PowerManagementPolicy = Power Management Policy + ScratchLocation = Scratch Location + BiosVersion = BIOS Version + BiosReleaseDate = BIOS Release Date + BootTime = Boot Time + UptimeDays = Uptime Days + MACAddress = MAC Address + SubnetMask = Subnet Mask + Gateway = Gateway + FirmwareVersion = Firmware Version + Device = Device + BootType = Boot Type + Vendor = Vendor + Size = Size + PCIAddress = PCI Address + DeviceClass = Device Class + TableHardwareConfig = Hardware Configuration - {0} + TableIPMIBMC = IPMI / BMC - {0} + TableBootDevice = Boot Device - {0} + TablePCIDevices = PCI Devices - {0} + TablePCIDriversFirmware = PCI Devices Drivers & Firmware - {0} + PCIDeviceError = Error collecting PCI device information for {0}. {1} + PCIDriversFirmwareError = Error collecting PCI device driver & firmware information for {0}. {1} + HardwareError = Error collecting host hardware information for {0}. {1} + IODeviceIdentifiers = Identifiants des périphériques d'E/S + VendorID = VID + DeviceID = DID + SubVendorID = SVID + SubDeviceID = SSID + TableIODeviceIdentifiers = Identifiants E/S - {0} + IODeviceIdentifiersError = Erreur lors de la collecte des identifiants E/S pour {0}. {1} +'@ + +# Get-AbrVSphereVMHostSystem +GetAbrVSphereVMHostSystem = ConvertFrom-StringData @' + Collecting = Collecte des informations système de l'hôte VMHost. + HostProfile = Profil d'hôte + ProfileName = Profil d'hôte + ProfileCompliance = Conformité + ProfileRemediating = Remédiation + ImageProfile = Profil d'image + ImageProfileName = Nom + ImageProfileVendor = Fabricant + ImageProfileAcceptance = Niveau d'acceptation + TimeConfiguration = Configuration de l'heure + NTPServer = Serveur NTP + TimeZone = Fuseau horaire + Syslog = Syslog + SyslogHost = Hôte Syslog + VUMBaseline = Lignes de base Update Manager + VUMBaselineNotAvailable = Les informations de ligne de base VUM de l'hôte VMHost ne sont pas disponibles avec votre version de PowerShell. + VUMBaselineName = Ligne de base + VUMBaselineType = Type + VUMBaselinePatches = Nb de correctifs + VUMCompliance = Conformité Update Manager + VUMComplianceNotAvailable = Les informations de conformité VUM de l'hôte VMHost ne sont pas disponibles avec votre version de PowerShell. + VUMStatus = État + AdvancedSettings = Paramètres système avancés + Key = Clé + Value = Valeur + VIBs = Bundles d'installation VMware (VIB) + VIBName = Nom + VIBVersion = Version + VIBVendor = Fabricant + VIBInstallDate = Date d'installation + VIBAcceptanceLevel = Niveau d'acceptation + SectionHeading = Système + ParagraphSummary = La section suivante détaille la configuration du système de l'hôte {0}. + NTPService = Service NTP + NTPServers = Serveur(s) NTP + SyslogPort = Port + VUMDescription = Description + VUMTargetType = Type de cible + VUMLastUpdate = Heure de la dernière mise à jour + InstallDate = Date d'installation + ImageName = Profil d'image + ImageVendor = Fournisseur + Running = En cours d'exécution + Stopped = Arrêté + NotCompliant = Non conforme + Unknown = Inconnu + Incompatible = Incompatible + ProfileDescription = Description + VIBID = ID + VIBCreationDate = Creation Date + TableHostProfile = Host Profile - {0} + TableImageProfile = Image Profile - {0} + TableTimeConfig = Time Configuration - {0} + TableSyslog = Syslog Configuration - {0} + TableVUMBaselines = Update Manager Baselines - {0} + TableVUMCompliance = Update Manager Compliance - {0} + TableAdvancedSettings = Advanced System Settings - {0} + TableVIBs = Software VIBs - {0} + HostProfileError = Error collecting host profile information for {0}. {1} + ImageProfileError = Error collecting image profile information for {0}. {1} + TimeConfigError = Error collecting time configuration for {0}. {1} + SyslogError = Error collecting syslog configuration for {0}. {1} + VUMBaselineError = Error collecting Update Manager baseline information for {0}. {1} + VUMComplianceError = Error collecting Update Manager compliance information for {0}. {1} + AdvancedSettingsError = Error collecting host advanced settings information for {0}. {1} + VIBsError = Error collecting software VIB information for {0}. {1} + InsufficientPrivImageProfile = Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned. + InsufficientPrivVUMBaseline = Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + InsufficientPrivVUMCompliance = Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned. + SwapFileLocation = Emplacement du fichier d'échange de VM + SwapFilePlacement = Emplacement du fichier d'échange de VM + SwapDatastore = Banque de données d'échange + WithVM = Avec la VM (Par défaut) + HostLocal = Local de l'hôte + TableSwapFileLocation = Emplacement du fichier d'échange de VM - {0} + SwapFileLocationError = Erreur lors de la collecte de l'emplacement du fichier d'échange pour {0}. {1} + HostCertificate = Certificat de l'hôte + CertSubject = Sujet + CertIssuer = Émetteur + CertValidFrom = Valide à partir du + CertValidTo = Valide jusqu'au + CertThumbprint = Empreinte SHA-256 + TableHostCertificate = Certificat de l'hôte - {0} + HostCertificateError = Erreur lors de la collecte des informations de certificat de l'hôte pour {0}. {1} + LogDir = Répertoire des journaux + LogRotations = Rotations des journaux + LogSize = Taille des journaux (Ko) +'@ + +# Get-AbrVSphereVMHostStorage +GetAbrVSphereVMHostStorage = ConvertFrom-StringData @' + Collecting = Collecte des informations de stockage de l'hôte VMHost. + SectionHeading = Stockage + DatastoreSpecs = Spécifications des magasins de données + Datastore = Magasin de données + DatastoreType = Type + DatastoreCapacity = Capacité (Go) + DatastoreFreeSpace = Espace libre (Go) + DatastoreState = État + DatastoreShared = Partagé + StorageAdapters = Adaptateurs de stockage + AdapterName = Adaptateur + AdapterType = Type + AdapterDriver = Pilote + AdapterUID = UID + AdapterModel = Modèle + AdapterStatus = État + AdapterSASAddress = Adresse SAS + AdapterWWN = WWN + AdapterDevices = Périphériques + AdapterTargets = Cibles + ParagraphSummary = La section suivante détaille la configuration de stockage de l'hôte {0}. + FC = Fibre Channel + iSCSI = iSCSI + ParallelSCSI = SCSI parallèle + ChapNone = Aucun + ChapUniPreferred = Utiliser CHAP unidirectionnel sauf si interdit par la cible + ChapUniRequired = Utiliser CHAP unidirectionnel si requis par la cible + ChapUnidirectional = Utiliser CHAP unidirectionnel + ChapBidirectional = Utiliser CHAP bidirectionnel + Online = En ligne + Offline = Hors ligne + Type = Type + Version = Version + NumberOfVMs = # of VMs + TotalCapacity = Total Capacity + UsedCapacity = Used Capacity + FreeCapacity = Free Capacity + PercentUsed = % Used + TableDatastores = Datastores - {0} + ParagraphStorageAdapters = The following section details the storage adapter configuration for {0}. + AdapterPaths = Paths + iSCSIName = iSCSI Name + iSCSIAlias = iSCSI Alias + AdapterSpeed = Speed + DynamicDiscovery = Dynamic Discovery + StaticDiscovery = Static Discovery + AuthMethod = Authentication Method + CHAPOutgoing = Outgoing CHAP Name + CHAPIncoming = Incoming CHAP Name + AdvancedOptions = Advanced Options + NodeWWN = Node WWN + PortWWN = Port WWN + TableStorageAdapter = Storage Adapter {0} - {1} +'@ + +# Get-AbrVSphereVMHostNetwork +GetAbrVSphereVMHostNetwork = ConvertFrom-StringData @' + Collecting = Collecte des informations réseau de l'hôte VMHost. + SectionHeading = Réseau + NetworkConfig = Configuration réseau + VMKernelAdapters = Adaptateurs VMkernel + PhysicalAdapters = Adaptateurs physiques + CDP = Protocole de découverte Cisco + LLDP = Protocole de découverte de la couche liaison + StandardvSwitches = Commutateurs virtuels standard + AdapterName = Adaptateur + AdapterMAC = Adresse MAC + AdapterLinkSpeed = Vitesse de liaison + AdapterDriver = Pilote + AdapterPCIID = Périphérique PCI + AdapterStatus = État + VMKName = Adaptateur VMkernel + VMKIP = Adresse IP + VMKSubnet = Masque de sous-réseau + VMKGateway = Passerelle par défaut + VMKMTU = MTU + VMKPortGroup = Groupe de ports + VMKVirtualSwitch = Commutateur virtuel + VMKDHCPEnabled = DHCP activé + VMKServicesEnabled = Services activés + vSwitch = Commutateur virtuel + vSwitchPorts = Ports totaux + vSwitchUsedPorts = Ports utilisés + vSwitchAvailablePorts = Ports disponibles + vSwitchMTU = MTU + vSwitchCDPStatus = État CDP + vSwitchSecurity = Stratégie de sécurité + vSwitchFailover = Stratégie de basculement + vSwitchLoadBalancing = Équilibrage de charge + vSwitchPortGroups = Groupes de ports + PortGroup = Groupe de ports + VLAN = ID VLAN + ActiveAdapters = Adaptateurs actifs + StandbyAdapters = Adaptateurs en attente + UnusedAdapters = Adaptateurs inutilisés + ParagraphSummary = La section suivante détaille la configuration réseau de l'hôte {0}. + Enabled = Activé + Disabled = Désactivé + Connected = Connecté + Disconnected = Déconnecté + Yes = Oui + No = Non + Accept = Accepter + Reject = Rejeter + Supported = Pris en charge + NotSupported = Non pris en charge + Inherited = Hérité + TCPDefault = Défaut + TCPProvisioning = Provisionnement + TCPvMotion = vMotion + TCPNsxOverlay = nsx-overlay + TCPNsxHyperbus = nsx-hyperbus + TCPNotApplicable = Non applicable + LBSrcId = Route basée sur l'ID du port d'origine + LBSrcMac = Route basée sur le hachage MAC source + LBIP = Route basée sur le hachage IP + LBExplicitFailover = Basculement explicite + NFDLinkStatus = Statut du lien uniquement + NFDBeaconProbing = Sondage de balise + FullDuplex = Full Duplex + AutoNegotiate = Négociation automatique + Down = Indisponible + Host = Host + VirtualSwitches = Virtual Switches + VMkernelGateway = VMkernel Gateway + IPv6 = IPv6 + VMkernelIPv6Gateway = VMkernel IPv6 Gateway + DNSServers = DNS Servers + HostName = Host Name + DomainName = Domain Name + SearchDomain = Search Domain + TableNetworkConfig = Network Configuration - {0} + ParagraphPhysicalAdapters = The following section details the physical network adapter configuration for {0}. + VirtualSwitch = Virtual Switch + ActualSpeedDuplex = Actual Speed, Duplex + ConfiguredSpeedDuplex = Configured Speed, Duplex + WakeOnLAN = Wake on LAN + TablePhysicalAdapter = Physical Adapter {0} - {1} + TablePhysicalAdapters = Physical Adapters - {0} + ParagraphCDP = The following section details the CDP information for {0}. + Status = Status + SystemName = System Name + HardwarePlatform = Hardware Platform + SwitchID = Switch ID + SoftwareVersion = Software Version + ManagementAddress = Management Address + Address = Address + PortID = Port ID + MTU = MTU + TableAdapterCDP = Network Adapter {0} CDP Information - {1} + TableAdaptersCDP = Network Adapter CDP Information - {0} + ParagraphLLDP = The following section details the LLDP information for {0}. + ChassisID = Chassis ID + TimeToLive = Time to live + TimeOut = TimeOut + Samples = Samples + PortDescription = Port Description + SystemDescription = System Description + TableAdapterLLDP = Network Adapter {0} LLDP Information - {1} + TableAdaptersLLDP = Network Adapter LLDP Information - {0} + ParagraphVMKernelAdapters = The following section details the VMkernel adapter configuration for {0}. + NetworkLabel = Network Label + TCPIPStack = TCP/IP Stack + DHCP = DHCP + IPAddress = IP Address + SubnetMask = Subnet Mask + DefaultGateway = Default Gateway + vMotion = vMotion + Provisioning = Provisioning + FTLogging = FT Logging + Management = Management + vSphereReplication = vSphere Replication + vSphereReplicationNFC = vSphere Replication NFC + vSAN = vSAN + vSANWitness = vSAN Witness + vSphereBackupNFC = vSphere Backup NFC + TableVMKernelAdapter = VMkernel Adapter {0} - {1} + ParagraphStandardvSwitches = The following section details the standard virtual switch configuration for {0}. + NumberOfPorts = Number of Ports + NumberOfPortsAvailable = Number of Ports Available + TableStandardvSwitches = Standard Virtual Switches - {0} + VSSecurity = Virtual Switch Security + PromiscuousMode = Promiscuous Mode + MACAddressChanges = MAC Address Changes + ForgedTransmits = Forged Transmits + TableVSSecurity = Virtual Switch Security Policy - {0} + VSTrafficShaping = Virtual Switch Traffic Shaping + AverageBandwidth = Average Bandwidth (kbit/s) + PeakBandwidth = Peak Bandwidth (kbit/s) + BurstSize = Burst Size (KB) + TableVSTrafficShaping = Virtual Switch Traffic Shaping Policy - {0} + VSTeamingFailover = Virtual Switch Teaming & Failover + LoadBalancing = Load Balancing + NetworkFailureDetection = Network Failure Detection + NotifySwitches = Notify Switches + Failback = Failback + ActiveNICs = Active NICs + StandbyNICs = Standby NICs + UnusedNICs = Unused NICs + TableVSTeamingFailover = Virtual Switch Teaming & Failover - {0} + VSPortGroups = Virtual Switch Port Groups + NumberOfVMs = # of VMs + TableVSPortGroups = Virtual Switch Port Groups - {0} + VSPGSecurity = Virtual Switch Port Group Security + MACChanges = MAC Changes + TableVSPGSecurity = Virtual Switch Port Group Security Policy - {0} + VSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping + TableVSPGTrafficShaping = Virtual Switch Port Group Traffic Shaping Policy - {0} + VSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover + TableVSPGTeamingFailover = Virtual Switch Port Group Teaming & Failover - {0} +'@ + +# Get-AbrVSphereVMHostSecurity +GetAbrVSphereVMHostSecurity = ConvertFrom-StringData @' + Collecting = Collecte des informations de sécurité de l'hôte VMHost. + SectionHeading = Sécurité + LockdownMode = Mode de verrouillage + Services = Services + ServiceName = Service + ServiceRunning = En cours d'exécution + ServicePolicy = Stratégie de démarrage + ServiceRequired = Requis + Firewall = Pare-feu + FirewallRule = Règle + FirewallAllowed = Hôtes autorisés + Authentication = Authentification + Domain = Domaine + Trust = Domaines approuvés + Membership = Appartenance au domaine + VMInfoSection = Machines virtuelles + VMName = Machine virtuelle + VMPowerState = État d'alimentation + VMIPAddress = Adresse IP + VMOS = Système d'exploitation + VMGuestID = ID invité + VMCPUs = CPU + VMMemoryGB = Mémoire (Go) + VMDisks = Disques (Go) + VMNICs = Cartes réseau + StartupShutdown = Démarrage/Arrêt des MV + StartupEnabled = Démarrage activé + StartupOrder = Ordre de démarrage + StartupDelay = Délai de démarrage + StopAction = Action d'arrêt + StopDelay = Délai d'arrêt + WaitForHeartbeat = Attendre la pulsation + ParagraphSummary = La section suivante détaille la configuration de sécurité de l'hôte {0}. + LockdownDisabled = Désactivé + LockdownNormal = Activé (Normal) + LockdownStrict = Activé (Strict) + Running = En cours d'exécution + Stopped = Arrêté + SvcPortUsage = Démarrer et arrêter avec l'utilisation du port + SvcWithHost = Démarrer et arrêter avec l'hôte + SvcManually = Démarrer et arrêter manuellement + On = Activé + Off = Désactivé + Enabled = Activé + Disabled = Désactivé + WaitHeartbeat = Continuer si VMware Tools est démarré + WaitDelay = Attendre le délai de démarrage + PowerOff = Éteindre + GuestShutdown = Arrêt du système d'exploitation + ToolsOld = Obsolète + ToolsOK = OK + ToolsNotRunning = Pas en cours d'exécution + ToolsNotInstalled = Pas installé + TableLockdownMode = Lockdown Mode - {0} + TableServices = Services - {0} + FirewallService = Service + Status = Status + IncomingPorts = Incoming Ports + OutgoingPorts = Outgoing Ports + Protocols = Protocols + Daemon = Daemon + TableFirewall = Firewall Configuration - {0} + DomainMembership = Domain Membership + TrustedDomains = Trusted Domains + TableAuthentication = Authentication Services - {0} + ParagraphVMInfo = The following section details the virtual machine configuration for {0}. + VMProvisioned = Provisioned + VMUsed = Used + VMHWVersion = HW Version + VMToolsStatus = VM Tools Status + TableVMs = Virtual Machines - {0} + TableStartupShutdown = VM Startup/Shutdown Policy - {0} + TpmEncryption = TPM et chiffrement + TpmPresent = TPM présent + TpmStatus = Statut d'attestation TPM + EncryptionMode = Mode de chiffrement + RequireSecureBoot = Exiger le démarrage sécurisé + RequireSignedVIBs = Exiger les exécutables uniquement depuis les VIBs installés + RecoveryKeys = Clés de récupération de chiffrement + RecoveryID = ID de récupération + RecoveryKey = Clé de récupération + TpmEncryptionError = Impossible de récupérer les informations TPM et chiffrement pour l'hôte {0}. {1} + TableTpmEncryption = TPM et chiffrement - {0} + TableRecoveryKeys = Clés de récupération de chiffrement - {0} + Yes = Oui + No = Non +'@ + +# Get-AbrVSphereNetwork +GetAbrVSphereNetwork = ConvertFrom-StringData @' + InfoLevel = Niveau d'information Réseau défini sur {0}. + Collecting = Collecte des informations sur les commutateurs distribués. + Processing = Traitement du commutateur distribué '{0}' ({1}/{2}). + SectionHeading = Commutateurs distribués + ParagraphSummary = Les sections suivantes détaillent la configuration des commutateurs distribués gérés par le serveur vCenter {0}. + VDSwitch = Commutateur distribué + Datacenter = Centre de données + Manufacturer = Fabricant + NumUplinks = Nb de liaisons montantes + NumPorts = Nb de ports + NumHosts = Nb d'hôtes + NumVMs = Nb de MV + Version = Version + MTU = MTU + ID = ID + NumberOfUplinks = Nombre de liaisons montantes + NumberOfPorts = Nombre de ports + NumberOfPortGroups = Nombre de groupes de ports + NumberOfHosts = Nombre d'hôtes + NumberOfVMs = Nombre de MV + Hosts = Hôtes + VirtualMachines = Machines virtuelles + NIOC = Contrôle des E/S réseau + DiscoveryProtocol = Protocole de découverte + DiscoveryOperation = Opération de découverte + NumPortGroups = Nb de groupes de ports + MaxPorts = Ports maximum + Contact = Contact + Location = Emplacement + VDPortGroups = Groupes de ports distribués + PortGroup = Groupe de ports + PortGroupType = Type de groupe de ports + VLANID = ID VLAN + VLANConfiguration = Configuration VLAN + PortBinding = Liaison de port + Host = Hôte + UplinkName = Nom de la liaison montante + UplinkPortGroup = Groupe de ports de liaison montante + PhysicalNetworkAdapter = Adaptateur réseau physique + ActiveUplinks = Liaisons montantes actives + StandbyUplinks = Liaisons montantes en attente + UnusedUplinks = Liaisons montantes inutilisées + AllowPromiscuous = Autoriser le mode promiscuité + ForgedTransmits = Transmissions forgées + MACAddressChanges = Modifications d'adresse MAC + Accept = Accepter + Reject = Rejeter + Direction = Direction + Status = Statut + AverageBandwidth = Bande passante moyenne (kbit/s) + PeakBandwidth = Bande passante de pointe (kbit/s) + BurstSize = Taille de rafale (Ko) + LoadBalancing = Équilibrage de charge + LoadBalanceSrcId = Route basée sur l'ID du port d'origine + LoadBalanceSrcMac = Route basée sur le hachage MAC source + LoadBalanceIP = Route basée sur le hachage IP + ExplicitFailover = Basculement explicite + NetworkFailureDetection = Détection d'échec réseau + LinkStatus = Statut du lien uniquement + BeaconProbing = Sondage de balise + NotifySwitches = Notifier les commutateurs + FailbackEnabled = Retour arrière activé + Yes = Oui + No = Non + PrimaryVLANID = ID VLAN primaire + PrivateVLANType = Type de VLAN privé + SecondaryVLANID = ID VLAN secondaire + UplinkPorts = Ports de liaison montante du commutateur distribué + VDSSecurity = Sécurité du commutateur distribué + VDSTrafficShaping = Régulation du trafic du commutateur distribué + VDSPortGroups = Groupes de ports du commutateur distribué + VDSPortGroupSecurity = Sécurité du groupe de ports du commutateur distribué + VDSPortGroupTrafficShaping = Régulation du trafic du groupe de ports du commutateur distribué + VDSPortGroupTeaming = Équipe et basculement du groupe de ports du commutateur distribué + VDSPrivateVLANs = VLAN privés du commutateur distribué + Enabled = Activé + Disabled = Désactivé + Listen = Écouter + Advertise = Annonce + Both = Les deux + TableVDSSummary = Récapitulatif du commutateur distribué - {0} + TableVDSGeneral = Propriétés générales du commutateur distribué - {0} + TableVDSUplinkPorts = Ports de liaison montante du commutateur distribué - {0} + TableVDSSecurity = Sécurité du commutateur distribué - {0} + TableVDSTrafficShaping = Régulation du trafic du commutateur distribué - {0} + TableVDSPortGroups = Groupes de ports du commutateur distribué - {0} + TableVDSPortGroupSecurity = Sécurité du groupe de ports du commutateur distribué - {0} + TableVDSPortGroupTrafficShaping = Régulation du trafic du groupe de ports du commutateur distribué - {0} + TableVDSPortGroupTeaming = Équipe et basculement du groupe de ports du commutateur distribué - {0} + TableVDSPrivateVLANs = VLAN privés du commutateur distribué - {0} + VDSLACP = LACP du commutateur distribué + LACPEnabled = LACP activé + LACPMode = Mode LACP + LACPActive = Actif + LACPPassive = Passif + VDSNetFlow = NetFlow du commutateur distribué + CollectorIP = Adresse IP du collecteur + CollectorPort = Port du collecteur + ActiveFlowTimeout = Délai d'expiration des flux actifs (s) + IdleFlowTimeout = Délai d'expiration des flux inactifs (s) + SamplingRate = Taux d'échantillonnage + InternalFlowsOnly = Flux internes uniquement + NIOCResourcePools = Pools de ressources de contrôle d'E/S réseau + NIOCResourcePool = Pool de ressources + NIOCSharesLevel = Niveau de partages + NIOCSharesValue = Partages + NIOCLimitMbps = Limite (Mbps) + Unlimited = Illimité + TableVDSLACP = LACP du commutateur distribué - {0} + TableVDSNetFlow = NetFlow du commutateur distribué - {0} + TableNIOCResourcePools = Pools de ressources de contrôle d'E/S réseau - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSpherevSAN +GetAbrVSpherevSAN = ConvertFrom-StringData @' + InfoLevel = Niveau d'information vSAN défini sur {0}. + Collecting = Collecte des informations vSAN. + CollectingESA = Collecte des informations vSAN ESA pour '{0}'. + CollectingOSA = Collecte des informations vSAN OSA pour '{0}'. + CollectingDisks = Collecte des informations sur les disques vSAN pour '{0}'. + CollectingDiskGroups = Collecte des informations sur les groupes de disques vSAN pour '{0}'. + CollectingiSCSITargets = Collecte des informations sur les cibles iSCSI vSAN pour '{0}'. + CollectingiSCSILUNs = Collecte des informations sur les LUN iSCSI vSAN pour '{0}'. + Processing = Traitement du cluster vSAN '{0}' ({1}/{2}). + SectionHeading = vSAN + ParagraphSummary = Les sections suivantes détaillent la configuration de VMware vSAN géré par le serveur vCenter {0}. + ParagraphDetail = Le tableau suivant détaille la configuration vSAN pour le cluster {0}. + DisksSection = Disques + DiskGroupsSection = Groupes de disques + iSCSITargetsSection = Cibles iSCSI + iSCSILUNsSection = LUN iSCSI + Cluster = Cluster + StorageType = Type de stockage + ClusterType = Type de cluster + NumHosts = Nb d'hôtes + ID = ID + NumberOfHosts = Nombre d'hôtes + NumberOfDisks = Nombre de disques + NumberOfDiskGroups = Nombre de groupes de disques + DiskClaimMode = Mode de revendication de disque + PerformanceService = Service de performances + FileService = Service de fichiers + iSCSITargetService = Service de cible iSCSI + HistoricalHealthService = Service d'historique de santé + HealthCheck = Vérification de l'état + TotalCapacity = Capacité totale + UsedCapacity = Capacité utilisée + FreeCapacity = Capacité libre + PercentUsed = % utilisé + HCLLastUpdated = Dernière mise à jour de la LCM + Hosts = Hôtes + Version = Version + Stretched = Cluster étendu + VSANEnabled = vSAN activé + VSANESAEnabled = vSAN ESA activé + DisksFormat = Version du format de disque + Deduplication = Déduplication et compression + AllFlash = Tout flash + FaultDomains = Domaines de panne + PFTT = Pannes primaires à tolérer + SFTT = Pannes secondaires à tolérer + NetworkDiagnosticMode = Mode de diagnostic réseau + HybridMode = Mode hybride + AutoRebalance = Rééquilibrage automatique + ProactiveDisk = Rééquilibrage proactif des disques + ResyncThrottle = Limitation de resynchronisation + SpaceEfficiency = Efficacité d'espace + Encryption = Chiffrement + FileServiceEnabled = Service de fichiers activé + iSCSITargetEnabled = Cible iSCSI activée + VMHostSpecs = Spécifications vSAN des hôtes VMHost + VMHost = Hôte VMHost + DiskGroup = Groupe de disques + CacheDisks = Disques de cache + DataDisks = Disques de données + DiskGroups = Groupes de disques + CacheTier = Niveau cache + DataTier = Niveau données + Status = État + FaultDomainName = Domaine de panne + VSANAdvancedOptions = Options de configuration avancées vSAN + Key = Clé + Value = Valeur + IDs = Identifiants + VSAN_UUID = UUID vSAN + CapacityTier = Niveau capacité (Go) + BufferTier = Niveau tampon (Go) + DiskName = Disque + Name = Nom + DriveType = Type de lecteur + Host = Hôte + State = État + Encrypted = Chiffré + Capacity = Capacité + SerialNumber = Numéro de série + Vendor = Fournisseur + Model = Modèle + DiskType = Type de disque + DiskFormatVersion = Version du format de disque + ClaimedAs = Revendiqué comme + NumDisks = Nb de disques + Type = Type + IQN = IQN + Alias = Alias + LUNsCount = LUN + NetworkInterface = Interface réseau + IOOwnerHost = Hôte propriétaire des E/S + TCPPort = Port TCP + Health = État de santé + StoragePolicy = Stratégie de stockage + ComplianceStatus = État de conformité + Authentication = Authentification + LUNName = LUN + LUNID = ID LUN + Yes = Oui + No = Non + Enabled = Activé + Disabled = Désactivé + Online = En ligne + Offline = Hors ligne + Mounted = Monté + Unmounted = Démonté + Flash = Flash + HDD = HDD + Cache = Cache + TableVSANClusterSummary = Résumé du cluster vSAN - {0} + TableVSANConfiguration = Configuration vSAN - {0} + TableDisk = Disque {0} - {1} + TableVSANDisks = Disques vSAN - {0} + TableVSANDiskGroups = Groupes de disques vSAN - {0} + TableVSANiSCSITargets = Cibles iSCSI vSAN - {0} + TableVSANiSCSILUNs = LUN iSCSI vSAN - {0} + ESAError = Erreur lors de la collecte des informations vSAN ESA pour '{0}'. {1} + OSAError = Erreur lors de la collecte des informations vSAN OSA pour '{0}'. {1} + DiskError = Erreur lors de la collecte des informations sur les disques vSAN pour '{0}'. {1} + DiskGroupError = Erreur lors de la collecte des informations sur les groupes de disques vSAN pour '{0}'. {1} + iSCSITargetError = Erreur lors de la collecte des informations sur les cibles iSCSI vSAN pour '{0}'. {1} + iSCSILUNError = Erreur lors de la collecte des informations sur les LUN iSCSI vSAN pour '{0}'. {1} + ServicesSection = Services vSAN + Service = Service + TableVSANServices = Services vSAN - {0} + ServicesError = Erreur lors de la collecte des informations sur les services vSAN pour '{0}'. {1} +'@ + +# Get-AbrVSphereDatastore +GetAbrVSphereDatastore = ConvertFrom-StringData @' + InfoLevel = Niveau d'information Magasin de données défini sur {0}. + Collecting = Collecte des informations sur les magasins de données. + Processing = Traitement du magasin de données '{0}' ({1}/{2}). + SectionHeading = Magasins de données + ParagraphSummary = Les sections suivantes détaillent la configuration des magasins de données gérés par le serveur vCenter {0}. + Datastore = Magasin de données + Type = Type + DatastoreURL = URL + FileSystem = Version du système de fichiers + CapacityGB = Capacité totale (Go) + FreeSpaceGB = Espace libre (Go) + UsedSpaceGB = Espace utilisé (Go) + State = État + Accessible = Accessible + NumHosts = Nb d'hôtes + NumVMs = Nb de MV + SIOC = Contrôle des E/S de stockage + IOLatencyThreshold = Seuil de latence E/S (ms) + IOLoadBalancing = Équilibrage de charge E/S + Enabled = Activé + Disabled = Désactivé + Normal = Normal + Maintenance = Maintenance + Unmounted = Démonté + ID = ID + Datacenter = Centre de données + Version = Version + NumberOfHosts = Nombre d'hôtes + NumberOfVMs = Nombre de MV + CongestionThreshold = Seuil de congestion + TotalCapacity = Capacité totale + UsedCapacity = Capacité utilisée + FreeCapacity = Capacité libre + PercentUsed = % utilisé + Hosts = Hôtes + VirtualMachines = Machines virtuelles + SCSILUNInfo = Informations LUN SCSI + Host = Hôte + CanonicalName = Nom canonique + Capacity = Capacité + Vendor = Fabricant + Model = Modèle + IsSSD = Est SSD + MultipathPolicy = Politique de chemins multiples + Paths = Chemins + TableDatastoreSummary = Récapitulatif du magasin de données - {0} + TableDatastoreConfig = Configuration du magasin de données - {0} + TableSCSILUN = Informations LUN SCSI - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSphereDSCluster +GetAbrVSphereDSCluster = ConvertFrom-StringData @' + InfoLevel = Niveau d'information Cluster de magasins de données défini sur {0}. + Collecting = Collecte des informations sur les clusters de magasins de données. + Processing = Traitement du cluster de magasins de données '{0}' ({1}/{2}). + SectionHeading = Clusters de magasins de données + ParagraphSummary = Les sections suivantes détaillent la configuration des clusters de magasins de données gérés par le serveur vCenter {0}. + DSCluster = Cluster de magasins de données + Datacenter = Centre de données + CapacityGB = Capacité totale (Go) + FreeSpaceGB = Espace libre (Go) + SDRSEnabled = SDRS + SDRSAutomationLevel = Niveau d'automatisation SDRS + IOLoadBalancing = Équilibrage de charge E/S + SpaceThreshold = Seuil d'espace (%) + IOLatencyThreshold = Seuil de latence E/S (ms) + SDRSRules = Règles SDRS + RuleName = Règle + RuleEnabled = Activée + RuleVMs = Machines virtuelles + FullyAutomated = Entièrement automatisé + NoAutomation = Aucune automatisation (Mode Manuel) + Manual = Manuel + Enabled = Activé + Disabled = Désactivé + Yes = Oui + No = Non + ID = ID + TotalCapacity = Capacité totale + UsedCapacity = Capacité utilisée + FreeCapacity = Capacité libre + PercentUsed = % utilisé + ParagraphDSClusterDetail = Le tableau suivant détaille la configuration du cluster de magasins de données {0}. + TableDSClusterConfig = Configuration du cluster de magasins de données - {0} + TableSDRSVMOverrides = Remplacements de MV SDRS - {0} + SDRSVMOverrides = Remplacements de MV SDRS + VirtualMachine = Machine virtuelle + KeepVMDKsTogether = Garder les VMDK ensemble + DefaultBehavior = Défaut ({0}) + RuleType = Type + RuleAffinity = Affinité + RuleAntiAffinity = Anti-Affinité + TableSDRSRules = Règles SDRS - {0} + SpaceLoadBalanceConfig = Configuration de l'équilibrage de charge d'espace + SpaceMinDiff = Différence minimale d'utilisation de l'espace (%) + SpaceThresholdMode = Mode de seuil d'espace + UtilizationMode = Seuil d'utilisation + FreeSpaceMode = Seuil d'espace libre + UtilizationThreshold = Seuil d'utilisation de l'espace (%) + FreeSpaceThreshold = Seuil d'espace libre (Go) + IOLoadBalanceConfig = Configuration de l'équilibrage de charge d'E/S + IOCongestionThreshold = Seuil de congestion d'E/S (ms) + IOReservationMode = Mode de seuil de réservation + IOPSThresholdMode = Nombre d'opérations d'E/S + ReservationMbpsMode = Réservation en Mbps + ReservationIopsMode = Réservation en IOPS + TableSpaceLoadBalance = Configuration de l'équilibrage de charge d'espace - {0} + TableIOLoadBalance = Configuration de l'équilibrage de charge d'E/S - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSphereVM +GetAbrVSphereVM = ConvertFrom-StringData @' + InfoLevel = Niveau d'information MV défini sur {0}. + Collecting = Collecte des informations sur les machines virtuelles. + Processing = Traitement de la machine virtuelle '{0}' ({1}/{2}). + SectionHeading = Machines virtuelles + ParagraphSummary = Les sections suivantes détaillent la configuration des machines virtuelles gérées par le serveur vCenter {0}. + VirtualMachine = Machine virtuelle + PowerState = État d'alimentation + Template = Modèle + OS = Système d'exploitation + Version = Version du matériel MV + GuestID = ID invité + Cluster = Cluster + ResourcePool = Pool de ressources + VMHost = Hôte + Folder = Dossier + IPAddress = Adresse IP + CPUs = CPU + MemoryGB = Mémoire (Go) + ProvisionedGB = Provisionné (Go) + UsedGB = Utilisé (Go) + NumDisks = Nb de disques + NumNICs = Nb de cartes réseau + NumSnapshots = Nb de snapshots + VMwareTools = VMware Tools + ToolsVersion = Version des outils + ToolsStatus = État des outils + ToolsRunningStatus = État d'exécution des outils + VMAdvancedDetail = Configuration avancée + BootOptions = Options de démarrage + BootDelay = Délai de démarrage (ms) + BootRetryEnabled = Nouvelle tentative de démarrage activée + BootRetryDelay = Délai de nouvelle tentative (ms) + EFISecureBoot = Démarrage sécurisé EFI + EnterBIOSSetup = Accéder à la configuration du BIOS au prochain démarrage + HardDisks = Disques durs + DiskName = Disque + DiskCapacityGB = Capacité (Go) + DiskFormat = Format + DiskStoragePolicy = Stratégie de stockage + DiskDatastore = Magasin de données + DiskController = Contrôleur + NetworkAdapters = Adaptateurs réseau + NICName = Adaptateur réseau + NICType = Type d'adaptateur + NICPortGroup = Groupe de ports + NICMAC = Adresse MAC + NICConnected = Connecté + NICConnectionPolicy = Se connecter à la mise sous tension + SnapshotHeading = Snapshots + SnapshotName = Snapshot + SnapshotDescription = Description + SnapshotSize = Taille (Go) + SnapshotDate = Créé + SnapshotParent = Parent + On = Activé + Off = Désactivé + ToolsOld = Obsolète + ToolsOK = OK + ToolsNotRunning = Pas en cours d'exécution + ToolsNotInstalled = Pas installé + Yes = Oui + No = Non + Connected = Connecté + NotConnected = Non connecté + Thin = Fin + Thick = Épais + Enabled = Activé + Disabled = Désactivé + TotalVMs = Total des MV + TotalvCPUs = Total des vCPU + TotalMemory = Mémoire totale + TotalProvisionedSpace = Espace total provisionné + TotalUsedSpace = Espace total utilisé + VMsPoweredOn = MV sous tension + VMsPoweredOff = MV hors tension + VMsOrphaned = MV orphelines + VMsInaccessible = MV inaccessibles + VMsSuspended = MV suspendues + VMsWithSnapshots = MV avec des snapshots + GuestOSTypes = Types de systèmes d'exploitation invités + VMToolsOKCount = Outils VM corrects + VMToolsOldCount = Outils VM obsolètes + VMToolsNotRunningCount = Outils VM non en cours d'exécution + VMToolsNotInstalledCount = Outils VM non installés + vCPUs = vCPU + Memory = Mémoire + Provisioned = Provisionné + Used = Utilisé + HWVersion = Version matérielle + VMToolsStatus = Statut des outils VM + ID = ID + OperatingSystem = Système d'exploitation + HardwareVersion = Version matérielle + ConnectionState = État de la connexion + FaultToleranceState = État de tolérance aux pannes + FTNotConfigured = Non configuré + FTNeedsSecondary = Nécessite un secondaire + FTRunning = En cours d'exécution + FTDisabled = Désactivé + FTStarting = Démarrage + FTEnabled = Activé + Parent = Parent + ParentFolder = Dossier parent + ParentResourcePool = Pool de ressources parent + CoresPerSocket = Cœurs par socket + CPUShares = Parts CPU + CPUReservation = Réservation CPU + CPULimit = Limite CPU + CPUHotAdd = Ajout à chaud CPU + CPUHotRemove = Suppression à chaud CPU + MemoryAllocation = Allocation mémoire + MemoryShares = Parts mémoire + MemoryHotAdd = Ajout à chaud mémoire + vNICs = vNIC + DNSName = Nom DNS + Networks = Réseaux + MACAddress = Adresse MAC + vDisks = Disques virtuels + ProvisionedSpace = Espace provisionné + UsedSpace = Espace utilisé + ChangedBlockTracking = Suivi des blocs modifiés + StorageBasedPolicy = Stratégie basée sur le stockage + StorageBasedPolicyCompliance = Conformité de la stratégie basée sur le stockage + Compliant = Conforme + NonCompliant = Non conforme + Unknown = Inconnu + Notes = Notes + BootTime = Heure de démarrage + UptimeDays = Jours de fonctionnement + NetworkName = Nom du réseau + SCSIControllers = Contrôleurs SCSI + Device = Périphérique + ControllerType = Type de contrôleur + BusSharing = Partage de bus + None = Aucun + GuestVolumes = Volumes invités + Capacity = Capacité + DiskProvisioning = Provisionnement de disque + ThickEagerZeroed = Épais avec zéro d'avance + ThickLazyZeroed = Épais avec zéro à la demande + DiskType = Type de disque + PhysicalRDM = RDM physique + VirtualRDM = RDM virtuel + VMDK = VMDK + DiskMode = Mode de disque + IndependentPersistent = Indépendant - Persistant + IndependentNonpersistent = Indépendant - Non persistant + Dependent = Dépendant + DiskPath = Chemin du disque + DiskShares = Parts de disque + DiskLimitIOPs = Limite IOPS du disque + Unlimited = Illimité + SCSIController = Contrôleur SCSI + SCSIAddress = Adresse SCSI + Path = Chemin + FreeSpace = Espace libre + DaysOld = Jours d'ancienneté + TableVMSummary = Récapitulatif des MV - {0} + TableVMAdvancedSummary = Récapitulatif avancé des MV - {0} + TableVMSnapshotSummary = Récapitulatif des snapshots des MV - {0} + TableVMConfig = Configuration des MV - {0} + TableVMNetworkAdapters = Adaptateurs réseau - {0} + TableVMSCSIControllers = Contrôleurs SCSI - {0} + TableVMHardDiskConfig = Configuration du disque dur - {0} + TableVMHardDisk = {0} - {1} + TableVMGuestVolumes = Volumes invités - {0} + TableVMSnapshots = Snapshots des MV - {0} + VUMCompliance = Conformité Update Manager de la VM + VUMBaselineName = Ligne de base + VUMStatus = État + NotCompliant = Non conforme + Incompatible = Incompatible + VUMComplianceError = Unable to retrieve VUM compliance information for virtual machines. + InsufficientPrivVUMCompliance = Insufficient privileges to collect VUM compliance information for virtual machines. + TableVUMCompliance = Conformité de la ligne de base VUM - {0} + Tags = Étiquettes +'@ + +# Get-AbrVSphereVUM +GetAbrVSphereVUM = ConvertFrom-StringData @' + InfoLevel = Niveau d'information VUM défini sur {0}. + Collecting = Collecte des informations sur VMware Update Manager. + NotAvailable = Les informations de ligne de base des correctifs VUM ne sont pas disponibles avec votre version de PowerShell. + PatchNotAvailable = Les informations sur les correctifs VUM ne sont pas disponibles avec votre version de PowerShell. + SectionHeading = VMware Update Manager + ParagraphSummary = Les sections suivantes détaillent la configuration de VMware Update Manager géré par le serveur vCenter {0}. + Baselines = Lignes de base + BaselineName = Ligne de base + Description = Description + Type = Type + TargetType = Type de cible + LastUpdate = Heure de la dernière mise à jour + NumPatches = Nb de correctifs + Patches = Correctifs + PatchName = Correctif + PatchProduct = Produit + PatchDescription = Description + PatchReleaseDate = Date de publication + PatchVendorID = ID fournisseur + TableVUMBaselines = Résumé des lignes de base VMware Update Manager - {0} + TableVUMPatches = Informations sur les correctifs VMware Update Manager - {0} + SoftwareDepots = Dépôts de logiciels + OnlineDepots = Dépôts en ligne + OfflineDepots = Dépôts hors ligne + DepotUrl = URL + SystemDefined = Défini par le système + DepotEnabled = Activé + DepotLocation = Emplacement + DepotError = Impossible de récupérer les informations des dépôts de logiciels. {0} + TableOnlineDepots = Dépôts de logiciels en ligne - {0} + TableOfflineDepots = Dépôts de logiciels hors ligne - {0} +'@ + +# Get-AbrVSphereClusterLCM +GetAbrVSphereClusterLCM = ConvertFrom-StringData @' + Collecting = Collecte des informations du Lifecycle Manager. + ImageComposition = Composition de l'image + BaseImage = Image de base + VendorAddOn = Module complémentaire du fournisseur + None = Aucun + Components = Composants + ComponentName = Composant + ComponentVersion = Version + HardwareSupportManager = Gestionnaire de support matériel + HsmName = Nom + HsmVersion = Version + HsmPackages = Packages de support matériel + ImageCompliance = Conformité de l'image + Cluster = Cluster + VMHost = VMHost + ComplianceStatus = Statut de conformité + LcmError = Impossible de récupérer les informations du Lifecycle Manager pour le cluster {0}. {1} + ComplianceError = Impossible de récupérer les informations de conformité pour le cluster {0}. {1} + TableImageComposition = Composition de l'image - {0} + TableComponents = Composants de l'image - {0} + TableHardwareSupportManager = Gestionnaire de support matériel - {0} + TableImageCompliance = Conformité de l'image - {0} + TableHostCompliance = Conformité de l'image de l'hôte - {0} +'@ + +} diff --git a/Src/Private/Convert-DataSize.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Convert-DataSize.ps1 similarity index 100% rename from Src/Private/Convert-DataSize.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Convert-DataSize.ps1 diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereCluster.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereCluster.ps1 new file mode 100644 index 0000000..bd92292 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereCluster.ps1 @@ -0,0 +1,155 @@ +function Get-AbrVSphereCluster { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Cluster information. + .DESCRIPTION + Documents the configuration of VMware vSphere Clusters in Word/HTML/Text formats using PScribo. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereCluster + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.Cluster) + } + + process { + try { + if ($InfoLevel.Cluster -ge 1) { + $Clusters = Get-Cluster -Server $vCenter | Sort-Object Name + if ($Clusters) { + Write-PScriboMessage -Message $LocalizedData.Collecting + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Cluster Summary + if ($InfoLevel.Cluster -le 2) { + BlankLine + $ClusterInfo = foreach ($Cluster in $Clusters) { + [PSCustomObject]@{ + $LocalizedData.Cluster = $Cluster.Name + $LocalizedData.Datacenter = ($Cluster | Get-Datacenter).Name + $LocalizedData.NumHosts = $Cluster.ExtensionData.Host.Count + $LocalizedData.NumVMs = $Cluster.ExtensionData.VM.Count + $LocalizedData.HAEnabled = if ($Cluster.HAEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.DRSEnabled = if ($Cluster.DRSEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.VSANEnabled = if ($Cluster.VsanEnabled -or $VsanCluster.VsanEsaEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.EVCMode = if ($Cluster.EVCMode) { $EvcModeLookup."$($Cluster.EVCMode)" } else { $LocalizedData.Disabled } + $LocalizedData.VMSwapFilePolicy = switch ($Cluster.VMSwapfilePolicy) { + 'WithVM' { $LocalizedData.SwapWithVM } + 'InHostDatastore' { $LocalizedData.SwapInHostDatastore } + default { $Cluster.VMSwapfilePolicy } + } + } + } + if ($Healthcheck.Cluster.HAEnabled) { + $ClusterInfo | Where-Object { $_.$($LocalizedData.HAEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.HAEnabled + } + if ($Healthcheck.Cluster.DRSEnabled) { + $ClusterInfo | Where-Object { $_.$($LocalizedData.DRSEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.DRSEnabled + } + if ($Healthcheck.Cluster.VsanEnabled) { + $ClusterInfo | Where-Object { $_.$($LocalizedData.VSANEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.VSANEnabled + } + if ($Healthcheck.Cluster.EvcEnabled) { + $ClusterInfo | Where-Object { $_.$($LocalizedData.EVCMode) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.EVCMode + } + $TableParams = @{ + Name = ($LocalizedData.TableClusterSummary -f $vCenterServerName) + ColumnWidths = 15, 15, 7, 7, 11, 11, 11, 15, 8 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterInfo | Table @TableParams + } + #endregion Cluster Summary + + #region Cluster Detailed Information + if ($InfoLevel.Cluster -ge 3) { + $Count = 1 + foreach ($Cluster in $Clusters) { + Write-PScriboMessage -Message ($LocalizedData.Processing -f $Cluster.Name, $Count, $Clusters.Count) + $Count++ + $ClusterDasConfig = $Cluster.ExtensionData.Configuration.DasConfig + $ClusterDrsConfig = $Cluster.ExtensionData.Configuration.DrsConfig + $ClusterConfigEx = $Cluster.ExtensionData.ConfigurationEx + Section -Style Heading3 $Cluster { + Paragraph ($LocalizedData.ParagraphDetail -f $Cluster) + BlankLine + #region Cluster Configuration + $ClusterDetail = [PSCustomObject]@{ + $LocalizedData.Cluster = $Cluster.Name + $LocalizedData.ID = $Cluster.Id + $LocalizedData.Datacenter = ($Cluster | Get-Datacenter).Name + $LocalizedData.NumberOfHosts = $Cluster.ExtensionData.Host.Count + $LocalizedData.NumberOfVMs = ($Cluster | Get-VM).Count + $LocalizedData.HAEnabled = if ($Cluster.HAEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.DRSEnabled = if ($Cluster.DRSEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.VSANEnabled = if ($Cluster.VsanEnabled -or $Cluster.VsanEsaEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } + $LocalizedData.EVCMode = if ($Cluster.EVCMode) { $EvcModeLookup."$($Cluster.EVCMode)" } else { $LocalizedData.Disabled } + $LocalizedData.VMSwapFilePolicy = switch ($Cluster.VMSwapfilePolicy) { + 'WithVM' { $LocalizedData.SwapVMDirectory } + 'InHostDatastore' { $LocalizedData.SwapHostDatastore } + default { $Cluster.VMSwapfilePolicy } + } + } + if ($Healthcheck.Cluster.HAEnabled) { + $ClusterDetail | Where-Object { $_.$($LocalizedData.HAEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.HAEnabled + } + if ($Healthcheck.Cluster.DRSEnabled) { + $ClusterDetail | Where-Object { $_.$($LocalizedData.DRSEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.DRSEnabled + } + if ($Healthcheck.Cluster.VsanEnabled) { + $ClusterDetail | Where-Object { $_.$($LocalizedData.VSANEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.VSANEnabled + } + if ($Healthcheck.Cluster.EvcEnabled) { + $ClusterDetail | Where-Object { $_.$($LocalizedData.EVCMode) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.EVCMode + } + if ($InfoLevel.Cluster -ge 4) { + $ClusterDetail | ForEach-Object { + $ClusterHosts = $Cluster | Get-VMHost | Sort-Object Name + Add-Member -InputObject $_ -MemberType NoteProperty -Name $LocalizedData.Hosts -Value ($ClusterHosts.Name -join ', ') + $ClusterVMs = $Cluster | Get-VM | Sort-Object Name + Add-Member -InputObject $_ -MemberType NoteProperty -Name $LocalizedData.VirtualMachines -Value ($ClusterVMs.Name -join ', ') + } + } + $TableParams = @{ + Name = ($LocalizedData.TableClusterConfig -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterDetail | Table @TableParams + #endregion Cluster Configuration + + # Call sub-functions for HA, Proactive HA, DRS, VUM, and LCM + Get-AbrVSphereClusterHA + Get-AbrVSphereClusterProactiveHA + Get-AbrVSphereClusterDRS + Get-AbrVSphereClusterVUM + Get-AbrVSphereClusterLCM + } + } + } + #endregion Cluster Detailed Information + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterDRS.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterDRS.ps1 new file mode 100644 index 0000000..5fc31c6 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterDRS.ps1 @@ -0,0 +1,530 @@ +<# +.SYNOPSIS + Private function to report vSphere DRS cluster configuration. +.DESCRIPTION + Generates a PScriboDocument section detailing the vSphere DRS configuration + for a given cluster, including DRS settings, Additional Options, Power Management, + Advanced Options, DRS Cluster Groups, DRS VM/Host Rules, DRS Rules, VM Overrides, + and Permissions subsections. +.NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman +.INPUTS + None. Uses variables from the parent scope: + $Cluster, $ClusterDrsConfig, $ClusterConfigEx, $VMLookup, $InfoLevel, $Report, + $Healthcheck, $vCenter, $reportTranslate +.OUTPUTS + None. Writes PScriboDocument content directly. +#> +function Get-AbrVSphereClusterDRS { + [CmdletBinding()] + param () + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereClusterDRS + } + process { + Try { + if ($Cluster.DrsEnabled) { + Write-PScriboMessage -Message $LocalizedData.Collecting + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $Cluster) + BlankLine + + #region vSphere DRS Cluster Specifications + $DrsCluster = [PSCustomObject]@{ + $LocalizedData.DRS = if ($Cluster.DrsEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + $MemberProps = @{ + 'InputObject' = $DrsCluster + 'MemberType' = 'NoteProperty' + } + Switch ($Cluster.DrsAutomationLevel) { + 'Manual' { + Add-Member @MemberProps -Name $LocalizedData.AutomationLevel -Value $LocalizedData.Manual + } + 'PartiallyAutomated' { + Add-Member @MemberProps -Name $LocalizedData.AutomationLevel -Value $LocalizedData.PartiallyAutomated + } + 'FullyAutomated' { + Add-Member @MemberProps -Name $LocalizedData.AutomationLevel -Value $LocalizedData.FullyAutomated + } + } + Add-Member @MemberProps -Name $LocalizedData.MigrationThreshold -Value $ClusterDrsConfig.VmotionRate + if ($ClusterConfigEx.ProactiveDrsConfig.Enabled) { + Add-Member @MemberProps -Name $LocalizedData.PredictiveDRS -Value $LocalizedData.Enabled + } else { + Add-Member @MemberProps -Name $LocalizedData.PredictiveDRS -Value $LocalizedData.Disabled + } + if ($ClusterDrsConfig.EnableVmBehaviorOverrides) { + Add-Member @MemberProps -Name $LocalizedData.VirtualMachineAutomation -Value $LocalizedData.Enabled + } else { + Add-Member @MemberProps -Name $LocalizedData.VirtualMachineAutomation -Value $LocalizedData.Disabled + } + if ($Healthcheck.Cluster.DrsEnabled) { + $DrsCluster | Where-Object { $_.$($LocalizedData.DRS) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.DRS + } + if ($Healthcheck.Cluster.DrsAutomationLevelFullyAuto) { + $DrsCluster | Where-Object { $_.$($LocalizedData.AutomationLevel) -ne $LocalizedData.FullyAutomated } | Set-Style -Style Warning -Property $LocalizedData.AutomationLevel + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSConfig -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsCluster | Table @TableParams + #endregion vSphere DRS Cluster Specifications + + #region DRS Cluster Additional Options + $DrsAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterDRS' } + if ($DrsAdvancedSettings) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.AdditionalOptions { + $DrsAdditionalOptions = [PSCustomObject] @{ + $LocalizedData.VMDistribution = Switch (($DrsAdvancedSettings | Where-Object { $_.name -eq 'TryBalanceVmsPerHost' }).Value) { + '1' { $LocalizedData.Enabled } + $null { $LocalizedData.Disabled } + } + $LocalizedData.MemoryMetricForLB = Switch (($DrsAdvancedSettings | Where-Object { $_.name -eq 'PercentIdleMBInMemDemand' }).Value) { + '100' { $LocalizedData.Enabled } + $null { $LocalizedData.Disabled } + } + $LocalizedData.CPUOverCommitment = if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerCore' }).Value) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + $MemberProps = @{ + 'InputObject' = $DrsAdditionalOptions + 'MemberType' = 'NoteProperty' + } + if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerCore' }).Value) { + Add-Member @MemberProps -Name $LocalizedData.OverCommitmentRatio -Value "$(($DrsAdvancedSettings | Where-Object {$_.name -eq 'MaxVcpusPerCore'}).Value):1 (vCPU:pCPU)" + } + if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerClusterPct' }).Value) { + Add-Member @MemberProps -Name $LocalizedData.OverCommitmentRatioCluster -Value "$(($DrsAdvancedSettings | Where-Object {$_.name -eq 'MaxVcpusPerClusterPct'}).Value) %" + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSAdditional -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsAdditionalOptions | Table @TableParams + } + } + #endregion DRS Cluster Additional Options + + #region vSphere DPM Configuration + if ($ClusterConfigEx.DpmConfigInfo.Enabled) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.PowerManagement { + $DpmConfig = [PSCustomObject]@{ + $LocalizedData.DPM = if ($ClusterConfigEx.DpmConfigInfo.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + $MemberProps = @{ + 'InputObject' = $DpmConfig + 'MemberType' = 'NoteProperty' + } + Switch ($ClusterConfigEx.DpmConfigInfo.DefaultDpmBehavior) { + 'manual' { + Add-Member @MemberProps -Name $LocalizedData.DPMAutomationLevel -Value $LocalizedData.Manual + } + 'automated' { + Add-Member @MemberProps -Name $LocalizedData.DPMAutomationLevel -Value $LocalizedData.Automated + } + } + if ($ClusterConfigEx.DpmConfigInfo.DefaultDpmBehavior -eq 'automated') { + Add-Member @MemberProps -Name $LocalizedData.DPMThreshold -Value $ClusterConfigEx.DpmConfigInfo.HostPowerActionRate + } + $TableParams = @{ + Name = ($LocalizedData.TableDPM -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DpmConfig | Table @TableParams + } + } + #endregion vSphere DPM Configuration + + #region vSphere DRS Cluster Advanced Options + $DrsAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterDRS' } + if ($DrsAdvancedSettings) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.AdvancedOptions { + $DrsAdvancedOptions = @() + foreach ($DrsAdvancedSetting in $DrsAdvancedSettings) { + $DrsAdvancedOption = [PSCustomObject]@{ + $LocalizedData.Key = $DrsAdvancedSetting.Name + $LocalizedData.Value = $DrsAdvancedSetting.Value + } + $DrsAdvancedOptions += $DrsAdvancedOption + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSAdvanced -f $Cluster) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsAdvancedOptions | Sort-Object $LocalizedData.Key | Table @TableParams + } + } + #endregion vSphere DRS Cluster Advanced Options + + #region vSphere DRS Cluster Group + $DrsClusterGroups = $Cluster | Get-DrsClusterGroup + if ($DrsClusterGroups) { + #region vSphere DRS Cluster Group Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.DRSClusterGroups { + $DrsGroups = foreach ($DrsClusterGroup in $DrsClusterGroups) { + [PSCustomObject]@{ + $LocalizedData.GroupName = $DrsClusterGroup.Name + $LocalizedData.GroupType = Switch ($DrsClusterGroup.GroupType) { + 'VMGroup' { $LocalizedData.VMGroupType } + 'VMHostGroup' { $LocalizedData.VMHostGroupType } + default { $DrsClusterGroup.GroupType } + } + $LocalizedData.GroupMembers = if (($DrsClusterGroup.Member).Count -gt 0) { + ($DrsClusterGroup.Member | Sort-Object) -join ', ' + } else { + $LocalizedData.None + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSGroups -f $Cluster) + ColumnWidths = 42, 16, 42 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsGroups | Sort-Object $LocalizedData.GroupName, $LocalizedData.GroupType | Table @TableParams + } + #endregion vSphere DRS Cluster Group Section + + #region vSphere DRS Cluster VM/Host Rules + $DrsVMHostRules = $Cluster | Get-DrsVMHostRule + if ($DrsVMHostRules) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.DRSVMHostRules { + $DrsVMHostRuleDetail = foreach ($DrsVMHostRule in $DrsVMHostRules) { + [PSCustomObject]@{ + $LocalizedData.RuleName = $DrsVMHostRule.Name + $LocalizedData.RuleType = Switch ($DrsVMHostRule.Type) { + 'MustRunOn' { $LocalizedData.MustRunOn } + 'ShouldRunOn' { $LocalizedData.ShouldRunOn } + 'MustNotRunOn' { $LocalizedData.MustNotRunOn } + 'ShouldNotRunOn' { $LocalizedData.ShouldNotRunOn } + default { $DrsVMHostRule.Type } + } + $LocalizedData.RuleEnabled = if ($DrsVMHostRule.Enabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.VMGroup = $DrsVMHostRule.VMGroup.Name + $LocalizedData.HostGroup = $DrsVMHostRule.VMHostGroup.Name + } + } + if ($Healthcheck.Cluster.DrsVMHostRules) { + $DrsVMHostRuleDetail | Where-Object { $_.$($LocalizedData.RuleEnabled) -eq $LocalizedData.No } | Set-Style -Style Warning -Property $LocalizedData.RuleEnabled + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSVMHostRules -f $Cluster) + ColumnWidths = 22, 22, 12, 22, 22 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsVMHostRuleDetail | Sort-Object $LocalizedData.RuleName | Table @TableParams + } + } + #endregion vSphere DRS Cluster VM/Host Rules + + #region vSphere DRS Cluster Rules + $DrsRules = $Cluster | Get-DrsRule + if ($DrsRules) { + #region vSphere DRS Cluster Rules Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.DRSRules { + $DrsRuleDetail = foreach ($DrsRule in $DrsRules) { + [PSCustomObject]@{ + $LocalizedData.RuleName = $DrsRule.Name + $LocalizedData.RuleType = Switch ($DrsRule.Type) { + 'VMAffinity' { $LocalizedData.VMAffinity } + 'VMAntiAffinity' { $LocalizedData.VMAntiAffinity } + } + $LocalizedData.RuleEnabled = if ($DrsRule.Enabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Mandatory = $DrsRule.Mandatory + $LocalizedData.RuleVMs = ($DrsRule.VMIds | ForEach-Object { (Get-View -Id $_).name }) -join ', ' + } + if ($Healthcheck.Cluster.DrsRules) { + $DrsRuleDetail | Where-Object { $_.$($LocalizedData.RuleEnabled) -eq $LocalizedData.No } | Set-Style -Style Warning -Property $LocalizedData.RuleEnabled + } + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSRules -f $Cluster) + ColumnWidths = 26, 25, 12, 12, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsRuleDetail | Sort-Object $LocalizedData.RuleType | Table @TableParams + } + #endregion vSphere DRS Cluster Rules Section + } + #endregion vSphere DRS Cluster Rules + } + #endregion vSphere DRS Cluster Group + + #region Cluster VM Overrides + $DrsVmOverrides = $Cluster.ExtensionData.Configuration.DrsVmConfig + $DasVmOverrides = $Cluster.ExtensionData.Configuration.DasVmConfig + if ($DrsVmOverrides -or $DasVmOverrides) { + #region VM Overrides Section + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.VMOverrides { + #region vSphere DRS VM Overrides + if ($DrsVmOverrides) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.DRS { + $DrsVmOverrideDetails = foreach ($DrsVmOverride in $DrsVmOverrides) { + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($DrsVmOverride.Key.Type)-$($DrsVmOverride.Key.Value)" + $LocalizedData.DRSAutomationLevel = if ($DrsVmOverride.Enabled -eq $false) { + $LocalizedData.Disabled + } else { + Switch ($DrsVmOverride.Behavior) { + 'manual' { $LocalizedData.Manual } + 'partiallyAutomated' { $LocalizedData.PartiallyAutomated } + 'fullyAutomated' { $LocalizedData.FullyAutomated } + default { $DrsVmOverride.Behavior } + } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableDRSVMOverrides -f $Cluster) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DrsVmOverrideDetails | Sort-Object $LocalizedData.VirtualMachine | Table @TableParams + } + } + #endregion vSphere DRS VM Overrides + + #region vSphere HA VM Overrides + if ($DasVmOverrides) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.SectionVSphereHA { + $DasVmOverrideDetails = foreach ($DasVmOverride in $DasVmOverrides) { + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" + $LocalizedData.HARestartPriority = Switch ($DasVmOverride.DasSettings.RestartPriority) { + $null { '--' } + 'lowest' { $LocalizedData.Lowest } + 'low' { $LocalizedData.Low } + 'medium' { $LocalizedData.Medium } + 'high' { $LocalizedData.High } + 'highest' { $LocalizedData.Highest } + 'disabled' { $LocalizedData.Disabled } + 'clusterRestartPriority' { $LocalizedData.ClusterDefault } + } + $LocalizedData.VMDependencyTimeout = Switch ($DasVmOverride.DasSettings.RestartPriorityTimeout) { + $null { '--' } + '-1' { $LocalizedData.Disabled } + default { $LocalizedData.Seconds -f $DasVmOverride.DasSettings.RestartPriorityTimeout } + } + $LocalizedData.HAIsolationResponse = Switch ($DasVmOverride.DasSettings.IsolationResponse) { + $null { '--' } + 'none' { $LocalizedData.Disabled } + 'powerOff' { $LocalizedData.PowerOffAndRestart } + 'shutdown' { $LocalizedData.ShutdownAndRestartVMs } + 'clusterIsolationResponse' { $LocalizedData.ClusterDefault } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableHAVMOverrides -f $Cluster) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DasVmOverrideDetails | Sort-Object $LocalizedData.VirtualMachine | Table @TableParams + + #region PDL/APD Protection Settings Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.SectionPDLAPD { + $DasVmOverridePdlApd = foreach ($DasVmOverride in $DasVmOverrides) { + $DasVmComponentProtection = $DasVmOverride.DasSettings.VmComponentProtectionSettings + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" + $LocalizedData.PDLFailureResponse = Switch ($DasVmComponentProtection.VmStorageProtectionForPDL) { + $null { '--' } + 'clusterDefault' { $LocalizedData.ClusterDefault } + 'warning' { $LocalizedData.IssueEvents } + 'restartAggressive' { $LocalizedData.PowerOffAndRestart } + 'disabled' { $LocalizedData.Disabled } + } + $LocalizedData.APDFailureResponse = Switch ($DasVmComponentProtection.VmStorageProtectionForAPD) { + $null { '--' } + 'clusterDefault' { $LocalizedData.ClusterDefault } + 'warning' { $LocalizedData.IssueEvents } + 'restartConservative' { $LocalizedData.PowerOffRestartConservative } + 'restartAggressive' { $LocalizedData.PowerOffRestartAggressive } + 'disabled' { $LocalizedData.Disabled } + } + $LocalizedData.VMFailoverDelay = Switch ($DasVmComponentProtection.VmTerminateDelayForAPDSec) { + $null { '--' } + '-1' { $LocalizedData.Disabled } + default { $LocalizedData.Minutes -f (($DasVmComponentProtection.VmTerminateDelayForAPDSec)/60) } + } + $LocalizedData.ResponseRecovery = Switch ($DasVmComponentProtection.VmReactionOnAPDCleared) { + $null { '--' } + 'reset' { $LocalizedData.ResetVMs } + 'disabled' { $LocalizedData.Disabled } + 'useClusterDefault' { $LocalizedData.ClusterDefault } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableHAPDLAPD -f $Cluster) + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DasVmOverridePdlApd | Sort-Object $LocalizedData.VirtualMachine | Table @TableParams + } + #endregion PDL/APD Protection Settings Section + + #region VM Monitoring Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VMMonitoring { + $DasVmOverrideVmMonitoring = foreach ($DasVmOverride in $DasVmOverrides) { + $DasVmMonitoring = $DasVmOverride.DasSettings.VmToolsMonitoringSettings + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" + $LocalizedData.VMMonitoring = Switch ($DasVmMonitoring.VmMonitoring) { + $null { '--' } + 'vmMonitoringDisabled' { $LocalizedData.Disabled } + 'vmMonitoringOnly' { $LocalizedData.VMMonitoringOnly } + 'vmAndAppMonitoring' { $LocalizedData.VMAndAppMonitoring } + } + $LocalizedData.VMMonitoringFailureInterval = Switch ($DasVmMonitoring.FailureInterval) { + $null { '--' } + default { + if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { + '--' + } else { + $LocalizedData.Seconds -f $DasVmMonitoring.FailureInterval + } + } + } + $LocalizedData.VMMonitoringMinUpTime = Switch ($DasVmMonitoring.MinUptime) { + $null { '--' } + default { + if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { + '--' + } else { + $LocalizedData.Seconds -f $DasVmMonitoring.MinUptime + } + } + } + $LocalizedData.VMMonitoringMaxFailures = Switch ($DasVmMonitoring.MaxFailures) { + $null { '--' } + default { + if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { + '--' + } else { + $DasVmMonitoring.MaxFailures + } + } + } + $LocalizedData.VMMonitoringMaxFailureWindow = Switch ($DasVmMonitoring.MaxFailureWindow) { + $null { '--' } + '-1' { $LocalizedData.NoWindow } + default { + if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { + '--' + } else { + $LocalizedData.WithinHours -f (($DasVmMonitoring.MaxFailureWindow)/3600) + } + } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableHAVMMonitoring -f $Cluster) + ColumnWidths = 40, 12, 12, 12, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DasVmOverrideVmMonitoring | Sort-Object $LocalizedData.VirtualMachine | Table @TableParams + } + #endregion VM Monitoring Section + } + } + #endregion vSphere HA VM Overrides + } + #endregion VM Overrides Section + } + #endregion Cluster VM Overrides + + #region Cluster Permissions + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.Permissions { + Paragraph ($LocalizedData.ParagraphPermissions -f $Cluster) + BlankLine + $VIPermissions = $Cluster | Get-VIPermission + $ClusterVIPermissions = foreach ($VIPermission in $VIPermissions) { + [PSCustomObject]@{ + $LocalizedData.UserGroup = $VIPermission.Principal + $LocalizedData.IsGroup = if ($VIPermission.IsGroup) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Role = $VIPermission.Role + $LocalizedData.DefinedIn = $VIPermission.Entity.Name + $LocalizedData.Propagate = if ($VIPermission.Propagate) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TablePermissions -f $Cluster) + ColumnWidths = 42, 12, 20, 14, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterVIPermissions | Sort-Object $LocalizedData.UserGroup | Table @TableParams + } + #endregion Cluster Permissions + } + } + } Catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterHA.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterHA.ps1 new file mode 100644 index 0000000..69eddcc --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterHA.ps1 @@ -0,0 +1,249 @@ +<# +.SYNOPSIS + Private function to report vSphere HA cluster configuration. +.DESCRIPTION + Generates a PScriboDocument section detailing the vSphere HA configuration + for a given cluster, including Failures and Responses, Admission Control, + Heartbeat Datastores, and Advanced Options subsections. +.NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman +.INPUTS + None. Uses variables from the parent scope: + $Cluster, $ClusterDasConfig, $InfoLevel, $Report, $Healthcheck, $TextInfo, $reportTranslate +.OUTPUTS + None. Writes PScriboDocument content directly. +#> +function Get-AbrVSphereClusterHA { + [CmdletBinding()] + param () + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereClusterHA + } + process { + try { + if ($Cluster.HAEnabled) { + Write-PScriboMessage -Message $LocalizedData.Collecting + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $Cluster) + #region vSphere HA Cluster Failures and Responses + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.FailuresAndResponses { + $HAClusterResponses = [PSCustomObject]@{ + $LocalizedData.HostMonitoring = $TextInfo.ToTitleCase($ClusterDasConfig.HostMonitoring) + } + if ($ClusterDasConfig.HostMonitoring -eq 'Enabled') { + $MemberProps = @{ + 'InputObject' = $HAClusterResponses + 'MemberType' = 'NoteProperty' + } + if ($ClusterDasConfig.DefaultVmSettings.RestartPriority -eq 'Disabled') { + Add-Member @MemberProps -Name $LocalizedData.HostFailureResponse -Value $LocalizedData.Disabled + } else { + Add-Member @MemberProps -Name $LocalizedData.HostFailureResponse -Value $LocalizedData.RestartVMs + switch ($Cluster.HAIsolationResponse) { + 'DoNothing' { + Add-Member @MemberProps -Name $LocalizedData.HostIsolationResponse -Value $LocalizedData.Disabled + } + 'Shutdown' { + Add-Member @MemberProps -Name $LocalizedData.HostIsolationResponse -Value $LocalizedData.ShutdownAndRestart + } + 'PowerOff' { + Add-Member @MemberProps -Name $LocalizedData.HostIsolationResponse -Value $LocalizedData.PowerOffAndRestart + } + } + Add-Member @MemberProps -Name $LocalizedData.VMRestartPriority -Value $Cluster.HARestartPriority + switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL) { + 'disabled' { + Add-Member @MemberProps -Name $LocalizedData.PDLProtection -Value $LocalizedData.Disabled + } + 'warning' { + Add-Member @MemberProps -Name $LocalizedData.PDLProtection -Value $LocalizedData.IssueEvents + } + 'restartAggressive' { + Add-Member @MemberProps -Name $LocalizedData.PDLProtection -Value $LocalizedData.PowerOffAndRestart + } + } + switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD) { + 'disabled' { + Add-Member @MemberProps -Name $LocalizedData.APDProtection -Value $LocalizedData.Disabled + } + 'warning' { + Add-Member @MemberProps -Name $LocalizedData.APDProtection -Value $LocalizedData.IssueEvents + } + 'restartConservative' { + Add-Member @MemberProps -Name $LocalizedData.APDProtection -Value $LocalizedData.PowerOffRestartConservative + } + 'restartAggressive' { + Add-Member @MemberProps -Name $LocalizedData.APDProtection -Value $LocalizedData.PowerOffRestartAggressive + } + } + switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared) { + 'none' { + Add-Member @MemberProps -Name $LocalizedData.APDRecovery -Value $LocalizedData.Disabled + } + 'reset' { + Add-Member @MemberProps -Name $LocalizedData.APDRecovery -Value $LocalizedData.ResetVMs + } + } + } + switch ($ClusterDasConfig.VmMonitoring) { + 'vmMonitoringDisabled' { + Add-Member @MemberProps -Name $LocalizedData.VMMonitoring -Value $LocalizedData.Disabled + } + 'vmMonitoringOnly' { + Add-Member @MemberProps -Name $LocalizedData.VMMonitoring -Value $LocalizedData.VMMonitoringOnly + } + 'vmAndAppMonitoring' { + Add-Member @MemberProps -Name $LocalizedData.VMMonitoring -Value $LocalizedData.VMAndAppMonitoring + } + } + } + if ($Healthcheck.Cluster.HostFailureResponse) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.HostFailureResponse) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.HostFailureResponse + } + if ($Healthcheck.Cluster.HostMonitoring) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.HostMonitoring) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.HostMonitoring + } + if ($Healthcheck.Cluster.DatastoreOnPDL) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.PDLProtection) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.PDLProtection + } + if ($Healthcheck.Cluster.DatastoreOnAPD) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.APDProtection) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.APDProtection + } + if ($Healthcheck.Cluster.APDTimeout) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.APDRecovery) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.APDRecovery + } + if ($Healthcheck.Cluster.vmMonitoring) { + $HAClusterResponses | Where-Object { $_.$($LocalizedData.VMMonitoring) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.VMMonitoring + } + $TableParams = @{ + Name = ($LocalizedData.TableHAFailures -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HAClusterResponses | Table @TableParams + } + #endregion vSphere HA Cluster Failures and Responses + + #region vSphere HA Cluster Admission Control + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.AdmissionControl { + $HAAdmissionControl = [PSCustomObject]@{ + $LocalizedData.AdmissionControl = if ($Cluster.HAAdmissionControlEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + if ($Cluster.HAAdmissionControlEnabled) { + $MemberProps = @{ + 'InputObject' = $HAAdmissionControl + 'MemberType' = 'NoteProperty' + } + Add-Member @MemberProps -Name $LocalizedData.FailoverLevel -Value $Cluster.HAFailoverLevel + switch ($ClusterDasConfig.AdmissionControlPolicy.GetType().Name) { + 'ClusterFailoverHostAdmissionControlPolicy' { + Add-Member @MemberProps -Name $LocalizedData.ACPolicy -Value $LocalizedData.DedicatedFailoverHosts + } + 'ClusterFailoverResourcesAdmissionControlPolicy' { + Add-Member @MemberProps -Name $LocalizedData.ACPolicy -Value $LocalizedData.ClusterResourcePercentage + } + 'ClusterFailoverLevelAdmissionControlPolicy' { + Add-Member @MemberProps -Name $LocalizedData.ACPolicy -Value $LocalizedData.SlotPolicy + } + } + if ($ClusterDasConfig.AdmissionControlPolicy.AutoComputePercentages) { + Add-Member @MemberProps -Name $LocalizedData.OverrideFailoverCapacity -Value $LocalizedData.No + } else { + Add-Member @MemberProps -Name $LocalizedData.OverrideFailoverCapacity -Value $LocalizedData.Yes + Add-Member @MemberProps -Name $LocalizedData.ACHostPercentage -Value $ClusterDasConfig.AdmissionControlPolicy.CpuFailoverResourcesPercent + Add-Member @MemberProps -Name $LocalizedData.ACMemPercentage -Value $ClusterDasConfig.AdmissionControlPolicy.MemoryFailoverResourcesPercent + } + if ($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy) { + Add-Member @MemberProps -Name $LocalizedData.SlotPolicy -Value $LocalizedData.FixedSlotSize + Add-Member @MemberProps -Name $LocalizedData.CPUSlotSize -Value "$($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy.Cpu) MHz" + Add-Member @MemberProps -Name $LocalizedData.MemorySlotSize -Value "$($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy.Memory) MB" + } else { + Add-Member @MemberProps -Name $LocalizedData.SlotPolicy -Value $LocalizedData.CoverAllPoweredOnVMs + } + if ($ClusterDasConfig.AdmissionControlPolicy.ResourceReductionToToleratePercent) { + Add-Member @MemberProps -Name $LocalizedData.PerfDegradationTolerate -Value "$($ClusterDasConfig.AdmissionControlPolicy.ResourceReductionToToleratePercent)%" + } + } + if ($Healthcheck.Cluster.HAAdmissionControl) { + $HAAdmissionControl | Where-Object { $_.$($LocalizedData.AdmissionControl) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.AdmissionControl + } + $TableParams = @{ + Name = ($LocalizedData.TableHAAdmissionControl -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HAAdmissionControl | Table @TableParams + } + #endregion vSphere HA Cluster Admission Control + + #region vSphere HA Cluster Heartbeat Datastores + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.HeartbeatDatastores { + $HeartbeatDatastores = [PSCustomObject]@{ + $LocalizedData.HeartbeatSelectionPolicy = switch ($ClusterDasConfig.HBDatastoreCandidatePolicy) { + 'allFeasibleDsWithUserPreference' { $LocalizedData.HBPolicyAllFeasibleDsWithUserPreference } + 'allFeasibleDs' { $LocalizedData.HBPolicyAllFeasibleDs } + 'userSelectedDs' { $LocalizedData.HBPolicyUserSelectedDs } + default { $ClusterDasConfig.HBDatastoreCandidatePolicy } + } + $LocalizedData.HeartbeatDatastores = try { + (((Get-View -Id $ClusterDasConfig.HeartbeatDatastore -Property Name).Name | Sort-Object) -join ', ') + } catch { + $LocalizedData.NoneSpecified + } + } + $TableParams = @{ + Name = ($LocalizedData.TableHAHeartbeat -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HeartbeatDatastores | Table @TableParams + } + #endregion vSphere HA Cluster Heartbeat Datastores + + #region vSphere HA Cluster Advanced Options + $HAAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterHA' } + if ($HAAdvancedSettings) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.HAAdvancedOptions { + $HAAdvancedOptions = @() + foreach ($HAAdvancedSetting in $HAAdvancedSettings) { + $HAAdvancedOption = [PSCustomObject]@{ + $LocalizedData.Key = $HAAdvancedSetting.Name + $LocalizedData.Value = $HAAdvancedSetting.Value + } + $HAAdvancedOptions += $HAAdvancedOption + } + $TableParams = @{ + Name = ($LocalizedData.TableHAAdvanced -f $Cluster) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HAAdvancedOptions | Sort-Object $LocalizedData.Key | Table @TableParams + } + } + #endregion vSphere HA Cluster Advanced Options + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterLCM.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterLCM.ps1 new file mode 100644 index 0000000..f275658 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterLCM.ps1 @@ -0,0 +1,183 @@ +function Get-AbrVSphereClusterLCM { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Lifecycle Manager information for a cluster. + .NOTES + Version: 2.0.0 + Author: Tim Carman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereClusterLCM + } + + process { + try { + # $vcApiUri is only set for vSphere 7.0+; silently skip on older versions + if (-not $vcApiUri) { return } + + $clusterId = $Cluster.Id -replace 'ClusterComputeResource-', '' + $softwareUri = "$vcApiUri/esx/settings/clusters/$clusterId/software" + + try { + $lcmSoftware = Invoke-RestMethod -Uri $softwareUri -Method Get ` + -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch [Microsoft.PowerShell.Commands.HttpResponseException] { + # 404 = cluster is in VUM baseline mode — silently skip + if ($_.Exception.Response.StatusCode -eq 404) { return } + Write-PScriboMessage -IsWarning ($LocalizedData.LcmError -f $Cluster, $_.Exception.Message) + return + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.LcmError -f $Cluster, $_.Exception.Message) + return + } + + #region vLCM Image Composition + BlankLine + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.ImageComposition { + $ImageInfo = [PSCustomObject]@{ + $LocalizedData.BaseImage = $lcmSoftware.base_image.version + $LocalizedData.VendorAddOn = if ($lcmSoftware.add_on) { + "$($lcmSoftware.add_on.name) $($lcmSoftware.add_on.version)" + } else { + $LocalizedData.None + } + } + $TableParams = @{ + Name = ($LocalizedData.TableImageComposition -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ImageInfo | Table @TableParams + + # Components sub-table — InfoLevel >= 4 + if ($InfoLevel.Cluster -ge 4 -and $lcmSoftware.components) { + BlankLine + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Components { + $ComponentInfo = foreach ($name in ($lcmSoftware.components.PSObject.Properties.Name | Sort-Object)) { + [PSCustomObject]@{ + $LocalizedData.ComponentName = $name + $LocalizedData.ComponentVersion = $lcmSoftware.components.$name.version + } + } + $TableParams = @{ + Name = ($LocalizedData.TableComponents -f $Cluster) + ColumnWidths = 60, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ComponentInfo | Table @TableParams + } + } + } + #endregion vLCM Image Composition + + #region Hardware Support Manager + if ($lcmSoftware.hardware_support -and $lcmSoftware.hardware_support.managers) { + BlankLine + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.HardwareSupportManager { + $HsmInfo = foreach ($mgrId in $lcmSoftware.hardware_support.managers.PSObject.Properties.Name) { + $mgr = $lcmSoftware.hardware_support.managers.$mgrId + $packages = if ($mgr.packages) { + ($mgr.packages.PSObject.Properties | ForEach-Object { + "$($_.Name) $($_.Value.version)" + }) -join '; ' + } else { + $LocalizedData.None + } + [PSCustomObject]@{ + $LocalizedData.HsmName = $mgr.name + $LocalizedData.HsmVersion = $mgr.version + $LocalizedData.HsmPackages = $packages + } + } + $TableParams = @{ + Name = ($LocalizedData.TableHardwareSupportManager -f $Cluster) + ColumnWidths = 35, 20, 45 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HsmInfo | Table @TableParams + } + } + #endregion Hardware Support Manager + + #region Image Compliance + $lcmCompliance = $null + try { + $complianceUri = "$vcApiUri/esx/settings/clusters/$clusterId/software/compliance" + $lcmCompliance = Invoke-RestMethod -Uri $complianceUri -Method Get ` + -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.ComplianceError -f $Cluster, $_.Exception.Message) + } + if ($lcmCompliance) { + BlankLine + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.ImageCompliance { + $clusterStatus = $TextInfo.ToTitleCase( + $lcmCompliance.status.ToString().ToLower().Replace('_', ' ') + ) + $ClusterComplianceInfo = [PSCustomObject]@{ + $LocalizedData.Cluster = $Cluster.Name + $LocalizedData.ComplianceStatus = $clusterStatus + } + if ($Healthcheck.Cluster.LCMCompliance) { + $ClusterComplianceInfo | Where-Object { + $_.$($LocalizedData.ComplianceStatus) -ne 'Compliant' + } | Set-Style -Style Warning -Property $LocalizedData.ComplianceStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableImageCompliance -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterComplianceInfo | Table @TableParams + + # Per-host compliance — InfoLevel >= 4 + if ($InfoLevel.Cluster -ge 4 -and $lcmCompliance.hosts) { + BlankLine + $HostComplianceInfo = foreach ($hostId in $lcmCompliance.hosts.PSObject.Properties.Name) { + $hostData = $lcmCompliance.hosts.$hostId + $hostStatus = $TextInfo.ToTitleCase( + $hostData.status.ToString().ToLower().Replace('_', ' ') + ) + [PSCustomObject]@{ + $LocalizedData.VMHost = $hostData.host_info.name + $LocalizedData.ComplianceStatus = $hostStatus + } + } + if ($Healthcheck.Cluster.LCMCompliance) { + $HostComplianceInfo | Where-Object { + $_.$($LocalizedData.ComplianceStatus) -ne 'Compliant' + } | Set-Style -Style Warning -Property $LocalizedData.ComplianceStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableHostCompliance -f $Cluster) + ColumnWidths = 60, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HostComplianceInfo | Table @TableParams + } + } + } + #endregion Image Compliance + + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterProactiveHA.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterProactiveHA.ps1 new file mode 100644 index 0000000..3af9b71 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterProactiveHA.ps1 @@ -0,0 +1,116 @@ +<# +.SYNOPSIS + Private function to report vSphere Proactive HA cluster configuration. +.DESCRIPTION + Generates a PScriboDocument section detailing the Proactive HA configuration + for a given cluster, including Failures and Responses subsection. + Proactive HA is only available in vSphere 6.5 and above. +.NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman +.INPUTS + None. Uses variables from the parent scope: + $ClusterConfigEx, $Cluster, $vCenter, $InfoLevel, $Report, $Healthcheck, $reportTranslate +.OUTPUTS + None. Writes PScriboDocument content directly. +#> +function Get-AbrVSphereClusterProactiveHA { + [CmdletBinding()] + param () + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereClusterProactiveHA + } + process { + try { + # Proactive HA is only available in vSphere 6.5 and above + if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled -and $vCenter.Version -ge 6.5) { + Write-PScriboMessage -Message $LocalizedData.Collecting + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $Cluster) + #region Proactive HA Failures and Responses Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.FailuresAndResponses { + $ProactiveHa = [PSCustomObject]@{ + $LocalizedData.ProactiveHA = if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled) { + $ProactiveHaModerateRemediation = switch ($ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation) { + 'MaintenanceMode' { $LocalizedData.MaintenanceMode } + 'QuarantineMode' { $LocalizedData.QuarantineMode } + default { $ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation } + } + $ProactiveHaSevereRemediation = switch ($ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation) { + 'MaintenanceMode' { $LocalizedData.MaintenanceMode } + 'QuarantineMode' { $LocalizedData.QuarantineMode } + default { $ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation } + } + $MemberProps = @{ + 'InputObject' = $ProactiveHa + 'MemberType' = 'NoteProperty' + } + Add-Member @MemberProps -Name $LocalizedData.AutomationLevel -Value $ClusterConfigEx.InfraUpdateHaConfig.Behavior + if ($ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation -eq $ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation) { + Add-Member @MemberProps -Name $LocalizedData.Remediation -Value $ProactiveHaModerateRemediation + } else { + Add-Member @MemberProps -Name $LocalizedData.Remediation -Value $LocalizedData.MixedMode + Add-Member @MemberProps -Name $LocalizedData.ModerateRemediation -Value $ProactiveHaModerateRemediation + Add-Member @MemberProps -Name $LocalizedData.SevereRemediation -Value $ProactiveHaSevereRemediation + } + } + if ($Healthcheck.Cluster.ProactiveHA) { + $ProactiveHa | Where-Object { $_.$($LocalizedData.ProactiveHA) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.ProactiveHA + } + $TableParams = @{ + Name = ($LocalizedData.TableProactiveHA -f $Cluster) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ProactiveHa | Table @TableParams + } + #endregion Proactive HA Failures and Responses Section + + #region Proactive HA Providers Section + $ClusterProviderIds = $ClusterConfigEx.InfraUpdateHaConfig.Providers + if ($ClusterProviderIds) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Providers { + $ProviderDetails = foreach ($ProviderId in $ClusterProviderIds) { + $HealthUpdateCount = 0 + try { + $SvcContent = (Get-View -Id ServiceInstance -Server $vCenter -ErrorAction Stop).Content + if ($SvcContent.HealthUpdateManager) { + $HealthUpdateMgr = Get-View -Id $SvcContent.HealthUpdateManager -Server $vCenter -ErrorAction Stop + $HealthUpdateCount = ($HealthUpdateMgr.QueryHealthUpdateInfos($ProviderId)).Count + } + } catch {} + [PSCustomObject]@{ + $LocalizedData.Provider = $ProviderId + $LocalizedData.HealthUpdateCount = $HealthUpdateCount + } + } + $TableParams = @{ + Name = ($LocalizedData.TableProactiveHAProviders -f $Cluster) + ColumnWidths = 70, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ProviderDetails | Sort-Object $LocalizedData.Provider | Table @TableParams + } + } + #endregion Proactive HA Providers Section + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterVUM.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterVUM.ps1 new file mode 100644 index 0000000..ec4fc86 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereClusterVUM.ps1 @@ -0,0 +1,120 @@ +<# +.SYNOPSIS + Private function to report vSphere cluster Update Manager baselines and compliance. +.DESCRIPTION + Generates a PScriboDocument section detailing the VMware Update Manager baselines + and compliance status for a given cluster. +.NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman +.INPUTS + None. Uses variables from the parent scope: + $Cluster, $InfoLevel, $Report, $Healthcheck, $UserPrivileges, $VumServer, + $vCenter, $VUMConnection, $reportTranslate +.OUTPUTS + None. Writes PScriboDocument content directly. +#> +function Get-AbrVSphereClusterVUM { + [CmdletBinding()] + param () + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereClusterVUM + } + process { + Try { + #region Cluster VUM Baselines + if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { + if ($VUMConnection) { + Try { + $ClusterPatchBaselines = $Cluster | Get-PatchBaseline -ErrorAction Stop + } Catch { + Write-PScriboMessage -Message $LocalizedData.VUMBaselineNotAvailable + } + if ($ClusterPatchBaselines) { + Section -Style Heading3 $LocalizedData.UpdateManagerBaselines { + $ClusterBaselines = foreach ($ClusterBaseline in $ClusterPatchBaselines) { + [PSCustomObject]@{ + $LocalizedData.Baseline = $ClusterBaseline.Name + $LocalizedData.Description = $ClusterBaseline.Description + $LocalizedData.Type = $ClusterBaseline.BaselineType + $LocalizedData.TargetType = $ClusterBaseline.TargetType + $LocalizedData.LastUpdate = ($ClusterBaseline.LastUpdateTime).ToLocalTime().ToString() + $LocalizedData.NumPatches = $ClusterBaseline.CurrentPatches.Count + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMBaselines -f $Cluster) + ColumnWidths = 25, 25, 10, 10, 20, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterBaselines | Sort-Object $LocalizedData.Baseline | Table @TableParams + } + } + if ($Healthcheck.Cluster.VUMCompliance) { + $ClusterComplianceInfo | Where-Object { $_.$($LocalizedData.Status) -eq $LocalizedData.Unknown } | Set-Style -Style Warning + $ClusterComplianceInfo | Where-Object { $_.$($LocalizedData.Status) -eq $LocalizedData.NotCompliant -or $_.$($LocalizedData.Status) -eq $LocalizedData.Incompatible } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMCompliance -f $Cluster) + ColumnWidths = 25, 50, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterComplianceInfo | Sort-Object $LocalizedData.Entity, $LocalizedData.BaselineInfo | Table @TableParams + } + } else { + Write-PScriboMessage -Message $LocalizedData.VUMPrivilegeMsgBaselines + } + #endregion Cluster VUM Baselines + + #region Cluster VUM Compliance (Advanced Detail Information) + if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { + if ($InfoLevel.Cluster -ge 4 -and $VumServer.Name) { + Try { + $ClusterCompliances = $Cluster | Get-Compliance -ErrorAction SilentlyContinue + } Catch { + Write-PScriboMessage -Message $LocalizedData.VUMComplianceNotAvailable + } + if ($ClusterCompliances) { + Section -Style Heading4 $LocalizedData.UpdateManagerCompliance { + $ClusterComplianceInfo = foreach ($ClusterCompliance in $ClusterCompliances) { + [PSCustomObject]@{ + $LocalizedData.Entity = $ClusterCompliance.Entity.Name + $LocalizedData.BaselineInfo = $ClusterCompliance.Baseline.Name + $LocalizedData.Status = Switch ($ClusterCompliance.Status) { + 'NotCompliant' { $LocalizedData.NotCompliant } + default { $ClusterCompliance.Status } + } + } + } + if ($Healthcheck.Cluster.VUMCompliance) { + $ClusterComplianceInfo | Where-Object { $_.$($LocalizedData.Status) -eq $LocalizedData.Unknown } | Set-Style -Style Warning + $ClusterComplianceInfo | Where-Object { $_.$($LocalizedData.Status) -eq $LocalizedData.NotCompliant -or $_.$($LocalizedData.Status) -eq $LocalizedData.Incompatible } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMCompliance -f $Cluster) + ColumnWidths = 25, 50, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ClusterComplianceInfo | Sort-Object $LocalizedData.Entity, $LocalizedData.BaselineInfo | Table @TableParams + } + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.VUMPrivilegeMsgCompliance + } + #endregion Cluster VUM Compliance (Advanced Detail Information) + + } Catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDSCluster.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDSCluster.ps1 new file mode 100644 index 0000000..534d3b1 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDSCluster.ps1 @@ -0,0 +1,262 @@ +function Get-AbrVSphereDSCluster { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Datastore Cluster information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereDSCluster + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.DSCluster) + } + + process { + try { + if ($InfoLevel.DSCluster -ge 1) { + Write-PScriboMessage -Message $LocalizedData.Collecting + $DSClusters = Get-DatastoreCluster -Server $vCenter + if ($DSClusters) { + #region Datastore Clusters Section + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Datastore Cluster Advanced Summary + if ($InfoLevel.DSCluster -le 2) { + BlankLine + $DSClusterInfo = foreach ($DSCluster in $DSClusters) { + [PSCustomObject]@{ + $LocalizedData.DSCluster = $DSCluster.Name + $LocalizedData.SDRSAutomationLevel = switch ($DSCluster.SdrsAutomationLevel) { + 'FullyAutomated' { $LocalizedData.FullyAutomated } + 'Manual' { $LocalizedData.Manual } + default { $DSCluster.SdrsAutomationLevel } + } + $LocalizedData.SpaceThreshold = "$($DSCluster.SpaceUtilizationThresholdPercent)%" + $LocalizedData.IOLoadBalancing = if ($DSCluster.IOLoadBalanceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.IOLatencyThreshold = "$($DSCluster.IOLatencyThresholdMillisecond) ms" + } + } + if ($Healthcheck.DSCluster.SDRSAutomationLevelFullyAuto) { + $DSClusterInfo | Where-Object { $_.$($LocalizedData.SDRSAutomationLevel) -ne $LocalizedData.FullyAutomated } | Set-Style -Style Warning -Property $LocalizedData.SDRSAutomationLevel + } + $TableParams = @{ + Name = ($LocalizedData.TableDSClusterConfig -f $DSCluster.Name) + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DSClusterInfo | Sort-Object $LocalizedData.DSCluster | Table @TableParams + } + #endregion Datastore Cluster Advanced Summary + + #region Datastore Cluster Detailed Information + if ($InfoLevel.DSCluster -ge 3) { + foreach ($DSCluster in $DSClusters) { + $DSCUsedPercent = if (0 -in @($DSCluster.FreeSpaceGB, $DSCluster.CapacityGB)) { 0 } else { [math]::Round((100 - (($DSCluster.FreeSpaceGB) / ($DSCluster.CapacityGB) * 100)), 2) } + $DSCFreePercent = if (0 -in @($DSCluster.FreeSpaceGB, $DSCluster.CapacityGB)) { 0 } else { [math]::Round(($DSCluster.FreeSpaceGB / $DSCluster.CapacityGB) * 100, 2) } + $DSCUsedCapacityGB = ($DSCluster.CapacityGB - $DSCluster.FreeSpaceGB) + + Section -Style Heading3 $DSCluster.Name { + Paragraph ($LocalizedData.ParagraphDSClusterDetail -f $DSCluster) + BlankLine + + $DSClusterDetail = [PSCustomObject]@{ + $LocalizedData.DSCluster = $DSCluster.Name + $LocalizedData.ID = $DSCluster.Id + $LocalizedData.SDRSAutomationLevel = switch ($DSCluster.SdrsAutomationLevel) { + 'FullyAutomated' { $LocalizedData.FullyAutomated } + 'Manual' { $LocalizedData.Manual } + default { $DSCluster.SdrsAutomationLevel } + } + $LocalizedData.SpaceThreshold = "$($DSCluster.SpaceUtilizationThresholdPercent)%" + $LocalizedData.IOLoadBalancing = if ($DSCluster.IOLoadBalanceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.IOLatencyThreshold = "$($DSCluster.IOLatencyThresholdMillisecond) ms" + $LocalizedData.TotalCapacity = Convert-DataSize $DSCluster.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $DSCUsedCapacityGB), $DSCUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $DSCluster.FreeSpaceGB), $DSCFreePercent + $LocalizedData.PercentUsed = $DSCUsedPercent + } + $MemberProps = @{ + 'InputObject' = $DSClusterDetail + 'MemberType' = 'NoteProperty' + } + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $DSCluster })) { + Add-Member @MemberProps -Name $LocalizedData.Tags -Value $(($TagAssignments | Where-Object { $_.entity -eq $DSCluster }).Tag -join ', ') + } + if ($Healthcheck.DSCluster.CapacityUtilization) { + $DSClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $DSClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + if ($Healthcheck.DSCluster.SDRSAutomationLevel) { + $DSClusterDetail | Where-Object { $_.$($LocalizedData.SDRSAutomationLevel) -ne $LocalizedData.FullyAutomated } | Set-Style -Style Warning -Property $LocalizedData.SDRSAutomationLevel + } + $TableParams = @{ + Name = ($LocalizedData.TableDSClusterConfig -f $DSCluster.Name) + List = $true + Columns = $LocalizedData.DSCluster, $LocalizedData.ID, $LocalizedData.SDRSAutomationLevel, $LocalizedData.SpaceThreshold, $LocalizedData.IOLoadBalancing, $LocalizedData.IOLatencyThreshold, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DSClusterDetail | Table @TableParams + + #region SDRS VM Overrides + $StoragePodProps = @{ + 'ViewType' = 'StoragePod' + 'Filter' = @{'Name' = $DSCluster.Name } + } + $StoragePod = Get-View @StoragePodProps + if ($StoragePod) { + $PodConfig = $StoragePod.PodStorageDrsEntry.StorageDrsConfig.PodConfig + # Set default automation value variables + switch ($PodConfig.DefaultVmBehavior) { + "automated" { $DefaultVmBehavior = ($LocalizedData.DefaultBehavior -f $LocalizedData.FullyAutomated) } + "manual" { $DefaultVmBehavior = ($LocalizedData.DefaultBehavior -f $LocalizedData.NoAutomation) } + } + if ($PodConfig.DefaultIntraVmAffinity) { + $DefaultIntraVmAffinity = ($LocalizedData.DefaultBehavior -f $LocalizedData.Yes) + } else { + $DefaultIntraVmAffinity = ($LocalizedData.DefaultBehavior -f $LocalizedData.No) + } + $VMOverrides = $StoragePod.PodStorageDrsEntry.StorageDrsConfig.VmConfig | Where-Object { + -not ( + ($null -eq $_.Enabled) -and + ($null -eq $_.IntraVmAffinity) + ) + } + $SDRSRules = $PodConfig.Rule + $SpaceConfig = $PodConfig.SpaceLoadBalanceConfig + if ($SpaceConfig) { + Section -Style Heading4 $LocalizedData.SpaceLoadBalanceConfig { + $SpaceLoadBalanceDetail = [PSCustomObject]@{ + $LocalizedData.SpaceMinDiff = "$($SpaceConfig.MinSpaceUtilizationDifference)%" + $LocalizedData.SpaceThresholdMode = switch ($SpaceConfig.SpaceThresholdMode) { + 'utilization' { $LocalizedData.UtilizationMode } + 'freeSpace' { $LocalizedData.FreeSpaceMode } + default { $SpaceConfig.SpaceThresholdMode } + } + $LocalizedData.UtilizationThreshold = "$($SpaceConfig.SpaceUtilizationThreshold)%" + $LocalizedData.FreeSpaceThreshold = "$($SpaceConfig.FreeSpaceThresholdGB) GB" + } + $TableParams = @{ + Name = ($LocalizedData.TableSpaceLoadBalance -f $DSCluster.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SpaceLoadBalanceDetail | Table @TableParams + } + } + $IOConfig = $PodConfig.IoLoadBalanceConfig + if ($IOConfig) { + Section -Style Heading4 $LocalizedData.IOLoadBalanceConfig { + $IOLoadBalanceDetail = [PSCustomObject]@{ + $LocalizedData.IOCongestionThreshold = "$($IOConfig.CongestionThreshold) ms" + $LocalizedData.IOLatencyThreshold = "$($IOConfig.IoLatencyThreshold) ms" + $LocalizedData.IOReservationMode = switch ($IOConfig.ReservationThresholdMode) { + 'ioOperationsCountThreshold' { $LocalizedData.IOPSThresholdMode } + 'reservationInMbps' { $LocalizedData.ReservationMbpsMode } + 'reservationInIops' { $LocalizedData.ReservationIopsMode } + default { $IOConfig.ReservationThresholdMode } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableIOLoadBalance -f $DSCluster.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $IOLoadBalanceDetail | Table @TableParams + } + } + } + + if ($VMOverrides) { + $VMOverrideDetails = foreach ($Override in $VMOverrides) { + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($Override.Vm.Type)-$($Override.Vm.Value)" + $LocalizedData.SDRSAutomationLevel = switch ($Override.Enabled) { + $true { $LocalizedData.FullyAutomated } + $false { $LocalizedData.Disabled } + $null { $DefaultVmBehavior } + } + $LocalizedData.KeepVMDKsTogether = switch ($Override.IntraVmAffinity) { + $true { $LocalizedData.Yes } + $false { $LocalizedData.No } + $null { $DefaultIntraVmAffinity } + } + } + } + Section -Style Heading4 $LocalizedData.SDRSVMOverrides { + $TableParams = @{ + Name = ($LocalizedData.TableSDRSVMOverrides -f $DSCluster.Name) + ColumnWidths = 50, 30, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMOverrideDetails | Sort-Object $LocalizedData.VirtualMachine | Table @TableParams + } + } + if ($SDRSRules) { + $SDRSRuleDetails = foreach ($Rule in $SDRSRules) { + [PSCustomObject]@{ + $LocalizedData.RuleName = $Rule.Name + $LocalizedData.RuleEnabled = if ($Rule.Enabled) { $LocalizedData.Yes } else { $LocalizedData.No } + $LocalizedData.RuleType = if ($Rule.GetType().Name -like '*AntiAffinity*') { $LocalizedData.RuleAntiAffinity } else { $LocalizedData.RuleAffinity } + $LocalizedData.RuleVMs = if ($Rule.Vm) { + $RuleVMs = foreach ($Vm in $Rule.Vm) { + $VMLookup."$($Vm.Type)-$($Vm.Value)" + } + ($RuleVMs | Sort-Object) -join ', ' + } else { + '--' + } + } + } + Section -Style Heading4 $LocalizedData.SDRSRules { + $TableParams = @{ + Name = ($LocalizedData.TableSDRSRules -f $DSCluster.Name) + ColumnWidths = 25, 15, 20, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SDRSRuleDetails | Sort-Object $LocalizedData.RuleName | Table @TableParams + } + } + #endregion SDRS VM Overrides + } + } + } + #endregion Datastore Cluster Detailed Information + } + #endregion Datastore Clusters Section + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDatastore.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDatastore.ps1 new file mode 100644 index 0000000..80e3243 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereDatastore.ps1 @@ -0,0 +1,198 @@ +function Get-AbrVSphereDatastore { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Datastore information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereDatastore + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.Datastore) + } + + process { + try { + if ($InfoLevel.Datastore -ge 1) { + Write-PScriboMessage -Message $LocalizedData.Collecting + if ($Datastores) { + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Datastore Infomative Information + if ($InfoLevel.Datastore -le 2) { + BlankLine + $DatastoreInfo = foreach ($Datastore in $Datastores) { + + $DsUsedPercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) { 0 } else { [math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2) } + $DsFreePercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) { 0 } else { [math]::Round(($Datastore.FreeSpaceGB / $Datastore.CapacityGB) * 100, 2) } + $DsUsedCapacityGB = ($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB) + + [PSCustomObject]@{ + $LocalizedData.Datastore = $Datastore.Name + $LocalizedData.Type = $Datastore.Type + $LocalizedData.Version = if ($Datastore.FileSystemVersion) { + $Datastore.FileSystemVersion + } else { + '--' + } + $LocalizedData.NumHosts = $Datastore.ExtensionData.Host.Count + $LocalizedData.NumVMs = $Datastore.ExtensionData.VM.Count + $LocalizedData.TotalCapacity = Convert-DataSize $Datastore.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $DsUsedCapacityGB), $DsUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $DsFreePercent + $LocalizedData.PercentUsed = $DsUsedPercent + } + } + if ($Healthcheck.Datastore.CapacityUtilization) { + $DatastoreInfo | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $DatastoreInfo | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and + $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + $TableParams = @{ + Name = ($LocalizedData.TableDatastoreSummary -f $vCenterServerName) + Columns = $LocalizedData.Datastore, $LocalizedData.Type, $LocalizedData.Version, $LocalizedData.NumHosts, $LocalizedData.NumVMs, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + ColumnWidths = 21, 10, 9, 9, 9, 14, 14, 14 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DatastoreInfo | Sort-Object $LocalizedData.Datastore | Table @TableParams + } + #endregion Datastore Advanced Summary + + #region Datastore Detailed Information + if ($InfoLevel.Datastore -ge 3) { + foreach ($Datastore in $Datastores) { + $DsUsedPercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) { 0 } else { [math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2) } + $DSFreePercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) { 0 } else { [math]::Round(($Datastore.FreeSpaceGB / $Datastore.CapacityGB) * 100, 2) } + $UsedCapacityGB = ($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB) + + #region Datastore Section + Section -Style Heading3 $Datastore.Name { + $DatastoreDetail = [PSCustomObject]@{ + $LocalizedData.Datastore = $Datastore.Name + $LocalizedData.ID = $Datastore.Id + $LocalizedData.Datacenter = $Datastore.Datacenter.Name + $LocalizedData.Type = $Datastore.Type + $LocalizedData.Version = if ($Datastore.FileSystemVersion) { + $Datastore.FileSystemVersion + } else { + '--' + } + $LocalizedData.State = switch ($Datastore.State) { + 'Normal' { $LocalizedData.Normal } + 'Maintenance' { $LocalizedData.Maintenance } + 'Unmounted' { $LocalizedData.Unmounted } + default { $Datastore.State } + } + $LocalizedData.NumberOfHosts = $Datastore.ExtensionData.Host.Count + $LocalizedData.NumberOfVMs = $Datastore.ExtensionData.VM.Count + $LocalizedData.SIOC = if ($Datastore.StorageIOControlEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.CongestionThreshold = if ($Datastore.CongestionThresholdMillisecond) { + "$($Datastore.CongestionThresholdMillisecond) ms" + } else { + '--' + } + $LocalizedData.TotalCapacity = Convert-DataSize $Datastore.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $UsedCapacityGB), $DsUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $DSFreePercent + $LocalizedData.PercentUsed = $DsUsedPercent + } + if ($Healthcheck.Datastore.CapacityUtilization) { + $DatastoreDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $DatastoreDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and + $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + $MemberProps = @{ + 'InputObject' = $DatastoreDetail + 'MemberType' = 'NoteProperty' + } + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $Datastore })) { + Add-Member @MemberProps -Name $LocalizedData.Tags -Value $(($TagAssignments | Where-Object { $_.entity -eq $Datastore }).Tag -join ', ') + } + + #region Datastore Advanced Detailed Information + if ($InfoLevel.Datastore -ge 4) { + $DatastoreHosts = foreach ($DatastoreHost in $Datastore.ExtensionData.Host.Key) { + $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" + } + Add-Member @MemberProps -Name $LocalizedData.Hosts -Value (($DatastoreHosts | Sort-Object) -join ', ') + $DatastoreVMs = foreach ($DatastoreVM in $Datastore.ExtensionData.VM) { + $VMLookup."$($DatastoreVM.Type)-$($DatastoreVM.Value)" + } + Add-Member @MemberProps -Name $LocalizedData.VirtualMachines -Value (($DatastoreVMs | Sort-Object) -join ', ') + } + #endregion Datastore Advanced Detailed Information + $TableParams = @{ + Name = ($LocalizedData.TableDatastoreConfig -f $Datastore.Name) + List = $true + Columns = $LocalizedData.Datastore, $LocalizedData.ID, $LocalizedData.Datacenter, $LocalizedData.Type, $LocalizedData.Version, $LocalizedData.State, $LocalizedData.NumberOfHosts, $LocalizedData.NumberOfVMs, $LocalizedData.SIOC, $LocalizedData.CongestionThreshold, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + ColumnWidths = 40, 60 + } + if ($InfoLevel.Datastore -ge 4) { + $TableParams['Columns'] += $LocalizedData.Hosts, $LocalizedData.VirtualMachines + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $DatastoreDetail | Sort-Object $LocalizedData.Datacenter, $LocalizedData.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 $LocalizedData.SCSILUNInfo { + $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 + + [PSCustomObject]@{ + $LocalizedData.Host = $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" + $LocalizedData.CanonicalName = $DiskName + $LocalizedData.Capacity = Convert-DataSize $ScsiDeviceDetail.CapacityGB + $LocalizedData.Vendor = $ScsiDeviceDetail.Vendor + $LocalizedData.Model = $ScsiDeviceDetail.Model + $LocalizedData.IsSSD = $ScsiDeviceDetail.Ssd + $LocalizedData.MultipathPolicy = $ScsiDeviceDetail.MultipathPolicy + $LocalizedData.Paths = $ScsiDeviceDetail.Paths + } + } + $TableParams = @{ + Name = ($LocalizedData.TableSCSILUN -f $vCenterServerName) + ColumnWidths = 19, 19, 10, 10, 10, 10, 14, 8 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ScsiLuns | Sort-Object $LocalizedData.Host | Table @TableParams + } + #endregion SCSI LUN Information Section + } + } + #endregion Datastore Section + } + } + #endregion Datastore Detailed Information + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereNetwork.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereNetwork.ps1 new file mode 100644 index 0000000..12bf4b2 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereNetwork.ps1 @@ -0,0 +1,481 @@ +function Get-AbrVSphereNetwork { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Network information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereNetwork + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.Network) + } + + process { + try { + if ($InfoLevel.Network -ge 1) { + Write-PScriboMessage -Message $LocalizedData.Collecting + # Create Distributed Switch Section if they exist + $VDSwitches = Get-VDSwitch -Server $vCenter | Sort-Object Name + if ($VDSwitches) { + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Distributed Switch Advanced Summary + if ($InfoLevel.Network -le 2) { + BlankLine + $VDSInfo = foreach ($VDS in $VDSwitches) { + [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.Datacenter = $VDS.Datacenter.Name + $LocalizedData.Manufacturer = $VDS.Vendor + $LocalizedData.Version = $VDS.Version + $LocalizedData.NumUplinks = $VDS.NumUplinkPorts + $LocalizedData.NumPorts = $VDS.NumPorts + $LocalizedData.NumHosts = $VDS.ExtensionData.Summary.HostMember.Count + $LocalizedData.NumVMs = $VDS.ExtensionData.Summary.VM.Count + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSSummary -f $vCenterServerName) + ColumnWidths = 20, 18, 18, 10, 10, 8, 8, 8 + } + 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) { + foreach ($VDS in ($VDSwitches)) { + #region VDS Section + Section -Style Heading3 $VDS { + #region Distributed Switch General Properties + $VDSwitchDetail = [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.ID = $VDS.Id + $LocalizedData.Datacenter = $VDS.Datacenter.Name + $LocalizedData.Manufacturer = $VDS.Vendor + $LocalizedData.Version = $VDS.Version + $LocalizedData.NumberOfUplinks = $VDS.NumUplinkPorts + $LocalizedData.NumberOfPorts = $VDS.NumPorts + $LocalizedData.NumberOfPortGroups = $VDS.ExtensionData.Summary.PortGroupName.Count + $LocalizedData.NumberOfHosts = $VDS.ExtensionData.Summary.HostMember.Count + $LocalizedData.NumberOfVMs = $VDS.ExtensionData.Summary.VM.Count + $LocalizedData.MTU = $VDS.Mtu + $LocalizedData.NIOC = if ($VDS.ExtensionData.Config.NetworkResourceManagementEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.DiscoveryProtocol = $VDS.LinkDiscoveryProtocol + $LocalizedData.DiscoveryOperation = switch ($VDS.LinkDiscoveryProtocolOperation) { + 'listen' { $LocalizedData.Listen } + 'advertise' { $LocalizedData.Advertise } + 'both' { $LocalizedData.Both } + 'none' { $LocalizedData.Disabled } + default { $VDS.LinkDiscoveryProtocolOperation } + } + } + $MemberProps = @{ + 'InputObject' = $VDSwitchDetail + 'MemberType' = 'NoteProperty' + } + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $VDS })) { + Add-Member @MemberProps -Name $LocalizedData.Tags -Value $(($TagAssignments | Where-Object { $_.entity -eq $VDS }).Tag -join ', ') + } + #region Network Advanced Detail Information + if ($InfoLevel.Network -ge 4) { + $VDSwitchDetail | ForEach-Object { + $VDSwitchHosts = $VDS | Get-VMHost | Sort-Object Name + Add-Member -InputObject $_ -MemberType NoteProperty -Name $LocalizedData.Hosts -Value ($VDSwitchHosts.Name -join ', ') + $VDSwitchVMs = $VDS | Get-VM | Sort-Object + Add-Member -InputObject $_ -MemberType NoteProperty -Name $LocalizedData.VirtualMachines -Value ($VDSwitchVMs.Name -join ', ') + } + } + #endregion Network Advanced Detail Information + $TableParams = @{ + Name = ($LocalizedData.TableVDSGeneral -f $VDS) + List = $true + ColumnWidths = 40, 60 + } + 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 $LocalizedData.UplinkPorts { + $VdsUplinkDetail = foreach ($VdsUplink in $VdsUplinks) { + [PSCustomObject]@{ + $LocalizedData.VDSwitch = [string]$VdsUplink.Switch + $LocalizedData.Host = [string]$VdsUplink.ProxyHost + $LocalizedData.UplinkName = $VdsUplink.Name + $LocalizedData.PhysicalNetworkAdapter = [string]$VdsUplink.ConnectedEntity + $LocalizedData.UplinkPortGroup = [string]$VdsUplink.Portgroup + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSUplinkPorts -f $VDS) + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VdsUplinkDetail | Sort-Object $LocalizedData.VDSwitch, $LocalizedData.Host, $LocalizedData.UplinkName | Table @TableParams + } + } + #endregion Distributed Switch Uplink Ports + + #region Distributed Switch Security + $VDSecurityPolicy = $VDS | Get-VDSecurityPolicy + if ($VDSecurityPolicy) { + Section -Style Heading4 $LocalizedData.VDSSecurity { + $VDSecurityPolicyDetail = [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDSecurityPolicy.VDSwitch.Name + $LocalizedData.AllowPromiscuous = if ($VDSecurityPolicy.AllowPromiscuous) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.ForgedTransmits = if ($VDSecurityPolicy.ForgedTransmits) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.MACAddressChanges = if ($VDSecurityPolicy.MacChanges) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSSecurity -f $VDS) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSecurityPolicyDetail | Table @TableParams + } + } + #endregion Distributed Switch Security + + #region Distributed Switch Traffic Shaping + $VDSTrafficShaping = @() + $VDSTrafficShapingIn = $VDS | Get-VDTrafficShapingPolicy -Direction In + $VDSTrafficShapingOut = $VDS | Get-VDTrafficShapingPolicy -Direction Out + $VDSTrafficShaping += $VDSTrafficShapingIn + $VDSTrafficShaping += $VDSTrafficShapingOut + if ($VDSTrafficShapingIn -or $VDSTrafficShapingOut) { + Section -Style Heading4 $LocalizedData.VDSTrafficShaping { + $VDSTrafficShapingDetail = foreach ($VDSTrafficShape in $VDSTrafficShaping) { + [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDSTrafficShape.VDSwitch.Name + $LocalizedData.Direction = $VDSTrafficShape.Direction + $LocalizedData.Status = if ($VDSTrafficShape.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.AverageBandwidth = $VDSTrafficShape.AverageBandwidth + $LocalizedData.PeakBandwidth = $VDSTrafficShape.PeakBandwidth + $LocalizedData.BurstSize = $VDSTrafficShape.BurstSize + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSTrafficShaping -f $VDS) + ColumnWidths = 25, 13, 11, 17, 17, 17 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSTrafficShapingDetail | Sort-Object $LocalizedData.Direction | Table @TableParams + } + } + #endregion Distributed Switch Traffic Shaping + + #region Distributed Switch LACP + $VDSLacpGroups = $VDS.ExtensionData.Config.LacpGroupConfig + if ($VDSLacpGroups) { + Section -Style Heading4 $LocalizedData.VDSLACP { + $LACPDetail = foreach ($LacpGroup in $VDSLacpGroups) { + [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.LACPEnabled = $LocalizedData.Yes + $LocalizedData.LACPMode = switch ($LacpGroup.Mode) { + 'active' { $LocalizedData.LACPActive } + 'passive' { $LocalizedData.LACPPassive } + default { $LacpGroup.Mode } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSLACP -f $VDS) + ColumnWidths = 34, 33, 33 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $LACPDetail | Table @TableParams + } + } + #endregion Distributed Switch LACP + + #region Distributed Switch NetFlow + $VDSNetFlow = $VDS.ExtensionData.Config.IpfixConfig + if ($VDSNetFlow -and $VDSNetFlow.CollectorIpAddress) { + Section -Style Heading4 $LocalizedData.VDSNetFlow { + $NetFlowDetail = [PSCustomObject]@{ + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.CollectorIP = $VDSNetFlow.CollectorIpAddress + $LocalizedData.CollectorPort = $VDSNetFlow.CollectorPort + $LocalizedData.ActiveFlowTimeout = "$($VDSNetFlow.ActiveFlowTimeout) s" + $LocalizedData.IdleFlowTimeout = "$($VDSNetFlow.IdleFlowTimeout) s" + $LocalizedData.SamplingRate = $VDSNetFlow.SamplingRate + $LocalizedData.InternalFlowsOnly = if ($VDSNetFlow.InternalFlowsOnly) { $LocalizedData.Yes } else { $LocalizedData.No } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSNetFlow -f $VDS) + ColumnWidths = 22, 13, 13, 13, 13, 13, 13 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $NetFlowDetail | Table @TableParams + } + } + #endregion Distributed Switch NetFlow + + #region Distributed Switch NIOC Resource Pools + if ($InfoLevel.Network -ge 4 -and $VDS.ExtensionData.Config.NetworkResourceManagementEnabled) { + $VDSNIOCPools = $VDS | Get-VDNetworkResourcePool | Sort-Object Name + if ($VDSNIOCPools) { + Section -Style Heading4 $LocalizedData.NIOCResourcePools { + $NIOCPoolDetails = foreach ($Pool in $VDSNIOCPools) { + [PSCustomObject]@{ + $LocalizedData.NIOCResourcePool = $Pool.Name + $LocalizedData.NIOCSharesLevel = $Pool.SharesLevel + $LocalizedData.NIOCSharesValue = $Pool.NumShares + $LocalizedData.NIOCLimitMbps = if ($Pool.Limit -eq -1) { $LocalizedData.Unlimited } else { $Pool.Limit } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableNIOCResourcePools -f $VDS) + ColumnWidths = 35, 20, 20, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $NIOCPoolDetails | Table @TableParams + } + } + } + #endregion Distributed Switch NIOC Resource Pools + + #region Distributed Switch Port Groups + $VDSPortgroups = $VDS | Get-VDPortgroup + if ($VDSPortgroups) { + Section -Style Heading4 $LocalizedData.VDSPortGroups { + $VDSPortgroupDetail = foreach ($VDSPortgroup in $VDSPortgroups) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = $VDSPortgroup.Name + $LocalizedData.VDSwitch = $VDSPortgroup.VDSwitch.Name + $LocalizedData.Datacenter = $VDSPortgroup.Datacenter.Name + $LocalizedData.VLANConfiguration = if ($VDSPortgroup.VlanConfiguration) { + $VDSPortgroup.VlanConfiguration + } else { + '--' + } + $LocalizedData.PortBinding = $VDSPortgroup.PortBinding + $LocalizedData.NumPorts = $VDSPortgroup.NumPorts + <# + # Tags on portgroups cause Get-TagAssignments to error + 'Tags' = & { + if ($TagAssignments | Where-Object {$_.entity -eq $VDSPortgroup}) { + ($TagAssignments | Where-Object {$_.entity -eq $VDSPortgroup}).Tag -join ',' + } else { + '--' + } + } + #> + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSPortGroups -f $VDS) + ColumnWidths = 20, 20, 20, 15, 15, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSPortgroupDetail | Sort-Object $LocalizedData.PortGroup | Table @TableParams + } + } + #endregion Distributed Switch Port Groups + + #region Distributed Switch Port Group Security + $VDSPortgroupSecurity = $VDS | Get-VDPortgroup | Get-VDSecurityPolicy + if ($VDSPortgroupSecurity) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VDSPortGroupSecurity { + $VDSSecurityPolicies = foreach ($VDSSecurityPolicy in $VDSPortgroupSecurity) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = [string]$VDSSecurityPolicy.VDPortgroup + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.AllowPromiscuous = if ($VDSSecurityPolicy.AllowPromiscuous) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.ForgedTransmits = if ($VDSSecurityPolicy.ForgedTransmits) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.MACAddressChanges = if ($VDSSecurityPolicy.MacChanges) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSPortGroupSecurity -f $VDS) + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSSecurityPolicies | Sort-Object $LocalizedData.PortGroup | Table @TableParams + } + } + #endregion Distributed Switch Port Group Security + + #region Distributed Switch Port Group Traffic Shaping + $VDSPortgroupTrafficShaping = @() + $VDSPortgroupTrafficShapingIn = $VDS | Get-VDPortgroup | Get-VDTrafficShapingPolicy -Direction In + $VDSPortgroupTrafficShapingOut = $VDS | Get-VDPortgroup | Get-VDTrafficShapingPolicy -Direction Out + $VDSPortgroupTrafficShaping += $VDSPortgroupTrafficShapingIn + $VDSPortgroupTrafficShaping += $VDSPortgroupTrafficShapingOut + if ($VDSPortgroupTrafficShaping) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VDSPortGroupTrafficShaping { + $VDSPortgroupTrafficShapingDetail = foreach ($VDSPortgroupTrafficShape in $VDSPortgroupTrafficShaping) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = [string]$VDSPortgroupTrafficShape.VDPortgroup + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.Direction = $VDSPortgroupTrafficShape.Direction + $LocalizedData.Status = if ($VDSPortgroupTrafficShape.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.AverageBandwidth = $VDSPortgroupTrafficShape.AverageBandwidth + $LocalizedData.PeakBandwidth = $VDSPortgroupTrafficShape.PeakBandwidth + $LocalizedData.BurstSize = $VDSPortgroupTrafficShape.BurstSize + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSPortGroupTrafficShaping -f $VDS) + ColumnWidths = 16, 16, 10, 10, 16, 16, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSPortgroupTrafficShapingDetail | Sort-Object $LocalizedData.PortGroup, $LocalizedData.Direction | Table @TableParams + + } + } + #endregion Distributed Switch Port Group Traffic Shaping + + #region Distributed Switch Port Group Teaming & Failover + $VDUplinkTeamingPolicy = $VDS | Get-VDPortgroup | Get-VDUplinkTeamingPolicy + if ($VDUplinkTeamingPolicy) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VDSPortGroupTeaming { + $VDSPortgroupNICTeaming = foreach ($VDUplink in $VDUplinkTeamingPolicy) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = [string]$VDUplink.VDPortgroup + $LocalizedData.VDSwitch = $VDS.Name + $LocalizedData.LoadBalancing = switch ($VDUplink.LoadBalancingPolicy) { + 'LoadbalanceSrcId' { $LocalizedData.LoadBalanceSrcId } + 'LoadbalanceSrcMac' { $LocalizedData.LoadBalanceSrcMac } + 'LoadbalanceIP' { $LocalizedData.LoadBalanceIP } + 'ExplicitFailover' { $LocalizedData.ExplicitFailover } + default { $VDUplink.LoadBalancingPolicy } + } + $LocalizedData.NetworkFailureDetection = switch ($VDUplink.FailoverDetectionPolicy) { + 'LinkStatus' { $LocalizedData.LinkStatus } + 'BeaconProbing' { $LocalizedData.BeaconProbing } + default { $VDUplink.FailoverDetectionPolicy } + } + $LocalizedData.NotifySwitches = if ($VDUplink.NotifySwitches) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.FailbackEnabled = if ($VDUplink.EnableFailback) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.ActiveUplinks = $VDUplink.ActiveUplinkPort -join [Environment]::NewLine + $LocalizedData.StandbyUplinks = $VDUplink.StandbyUplinkPort -join [Environment]::NewLine + $LocalizedData.UnusedUplinks = $VDUplink.UnusedUplinkPort -join [Environment]::NewLine + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSPortGroupTeaming -f $VDS) + ColumnWidths = 12, 12, 12, 11, 10, 10, 11, 11, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSPortgroupNICTeaming | Sort-Object $LocalizedData.PortGroup | Table @TableParams + } + } + #endregion Distributed Switch Port Group Teaming & Failover + + #region Distributed Switch Private VLANs + $VDSwitchPrivateVLANs = $VDS | Get-VDSwitchPrivateVlan + if ($VDSwitchPrivateVLANs) { + Section -Style Heading4 $LocalizedData.VDSPrivateVLANs { + $VDSPvlan = foreach ($VDSwitchPrivateVLAN in $VDSwitchPrivateVLANs) { + [PSCustomObject]@{ + $LocalizedData.PrimaryVLANID = $VDSwitchPrivateVLAN.PrimaryVlanId + $LocalizedData.PrivateVLANType = $VDSwitchPrivateVLAN.PrivateVlanType + $LocalizedData.SecondaryVLANID = $VDSwitchPrivateVLAN.SecondaryVlanId + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVDSPrivateVLANs -f $VDS) + ColumnWidths = 33, 34, 33 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VDSPvlan | Sort-Object $LocalizedData.PrimaryVLANID, $LocalizedData.SecondaryVLANID | Table @TableParams + } + } + #endregion Distributed Switch Private VLANs + } + #endregion VDS Section + } + } + #endregion Distributed Switch Detailed Information + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereResourcePool.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereResourcePool.ps1 new file mode 100644 index 0000000..2a0a90e --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereResourcePool.ps1 @@ -0,0 +1,134 @@ +function Get-AbrVSphereResourcePool { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Resource Pool information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereResourcePool + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.ResourcePool) + } + + process { + try { + if ($InfoLevel.ResourcePool -ge 1) { + $ResourcePools = Get-ResourcePool -Server $vCenter | Sort-Object Parent, Name + if ($ResourcePools) { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region Resource Pools Section + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Resource Pool Advanced Summary + if ($InfoLevel.ResourcePool -le 2) { + BlankLine + $ResourcePoolInfo = foreach ($ResourcePool in $ResourcePools) { + [PSCustomObject]@{ + $LocalizedData.ResourcePool = $ResourcePool.Name + $LocalizedData.Parent = $ResourcePool.Parent.Name + $LocalizedData.CPUSharesLevel = $ResourcePool.CpuSharesLevel + $LocalizedData.CPUReservationMHz = $ResourcePool.CpuReservationMHz + $LocalizedData.CPULimitMHz = switch ($ResourcePool.CpuLimitMHz) { + '-1' { $LocalizedData.Unlimited } + default { $ResourcePool.CpuLimitMHz } + } + $LocalizedData.MemSharesLevel = $ResourcePool.MemSharesLevel + $LocalizedData.MemReservation = Convert-DataSize $ResourcePool.MemReservationGB -RoundUnits 0 + $LocalizedData.MemLimit = switch ($ResourcePool.MemLimitGB) { + '-1' { $LocalizedData.Unlimited } + default { Convert-DataSize $ResourcePool.MemLimitGB -RoundUnits 0 } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableResourcePoolSummary -f $vCenterServerName) + ColumnWidths = 20, 20, 10, 10, 10, 10, 10, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ResourcePoolInfo | Sort-Object $LocalizedData.ResourcePool | Table @TableParams + } + #endregion Resource Pool Advanced Summary + + #region Resource Pool Detailed Information + if ($InfoLevel.ResourcePool -ge 3) { + foreach ($ResourcePool in $ResourcePools) { + Section -Style Heading3 $ResourcePool.Name { + $ResourcePoolDetail = [PSCustomObject]@{ + $LocalizedData.ResourcePool = $ResourcePool.Name + $LocalizedData.ID = $ResourcePool.Id + $LocalizedData.Parent = $ResourcePool.Parent.Name + $LocalizedData.CPUSharesLevel = $ResourcePool.CpuSharesLevel + $LocalizedData.NumCPUShares = $ResourcePool.NumCpuShares + $LocalizedData.CPUReservation = "$($ResourcePool.CpuReservationMHz) MHz" + $LocalizedData.CPUExpandable = if ($ResourcePool.CpuExpandableReservation) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.CPULimitMHz = switch ($ResourcePool.CpuLimitMHz) { + '-1' { $LocalizedData.Unlimited } + default { "$($ResourcePool.CpuLimitMHz) MHz" } + } + $LocalizedData.MemSharesLevel = $ResourcePool.MemSharesLevel + $LocalizedData.NumMemShares = $ResourcePool.NumMemShares + $LocalizedData.MemReservation = Convert-DataSize $ResourcePool.MemReservationGB -RoundUnits 0 + $LocalizedData.MemExpandable = if ($ResourcePool.MemExpandableReservation) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.MemLimit = switch ($ResourcePool.MemLimitGB) { + '-1' { $LocalizedData.Unlimited } + default { Convert-DataSize $ResourcePool.MemLimitGB -RoundUnits 0 } + } + $LocalizedData.NumVMs = $ResourcePool.ExtensionData.VM.Count + } + $MemberProps = @{ + 'InputObject' = $ResourcePoolDetail + 'MemberType' = 'NoteProperty' + } + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $ResourcePool })) { + Add-Member @MemberProps -Name $LocalizedData.Tags -Value $(($TagAssignments | Where-Object { $_.entity -eq $ResourcePool }).Tag -join ', ') + } + #region Resource Pool Advanced Detail Information + if ($InfoLevel.ResourcePool -ge 4) { + $ResourcePoolDetail | ForEach-Object { + # Query for VMs by resource pool Id + $ResourcePoolId = $_.Id + $ResourcePoolVMs = $VMs | Where-Object { $_.ResourcePoolId -eq $ResourcePoolId } | Sort-Object Name + Add-Member -InputObject $_ -MemberType NoteProperty -Name $LocalizedData.VirtualMachines -Value ($ResourcePoolVMs.Name -join ', ') + } + } + #endregion Resource Pool Advanced Detail Information + $TableParams = @{ + Name = ($LocalizedData.TableResourcePoolConfig -f $ResourcePool.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $ResourcePoolDetail | Table @TableParams + } + } + } + #endregion Resource Pool Detailed Information + } + #endregion Resource Pools Section + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVM.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVM.ps1 new file mode 100644 index 0000000..7852975 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVM.ps1 @@ -0,0 +1,546 @@ +function Get-AbrVSphereVM { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere Virtual Machine information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVM + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.VM) + } + + process { + try { + if ($InfoLevel.VM -ge 1) { + Write-PScriboMessage -Message $LocalizedData.Collecting + if ($VMs) { + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region Virtual Machine Summary Information + if ($InfoLevel.VM -eq 1) { + BlankLine + $VMSummary = [PSCustomObject]@{ + $LocalizedData.TotalVMs = $VMs.Count + $LocalizedData.TotalvCPUs = ($VMs | Measure-Object -Property NumCpu -Sum).Sum + $LocalizedData.TotalMemory = Convert-DataSize ($VMs | Measure-Object -Property MemoryGB -Sum).Sum + $LocalizedData.TotalProvisionedSpace = Convert-DataSize ($VMs | Measure-Object -Property ProvisionedSpaceGB -Sum).Sum + $LocalizedData.TotalUsedSpace = Convert-DataSize ($VMs | Measure-Object -Property UsedSpaceGB -Sum).Sum + $LocalizedData.VMsPoweredOn = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOn' }).Count + $LocalizedData.VMsPoweredOff = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOff' }).Count + $LocalizedData.VMsOrphaned = ($VMs | Where-Object { $_.ExtensionData.Runtime.ConnectionState -eq 'Orphaned' }).Count + $LocalizedData.VMsInaccessible = ($VMs | Where-Object { $_.ExtensionData.Runtime.ConnectionState -eq 'Inaccessible' }).Count + $LocalizedData.VMsSuspended = ($VMs | Where-Object { $_.PowerState -eq 'Suspended' }).Count + $LocalizedData.VMsWithSnapshots = ($VMs | Where-Object { $_.ExtensionData.Snapshot }).Count + $LocalizedData.GuestOSTypes = (($VMs | Get-View).Summary.Config.GuestFullName | Select-Object -Unique).Count + $LocalizedData.VMToolsOKCount = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOK' }).Count + $LocalizedData.VMToolsOldCount = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsOld' }).Count + $LocalizedData.VMToolsNotRunningCount = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotRunning' }).Count + $LocalizedData.VMToolsNotInstalledCount = ($VMs | Where-Object { $_.ExtensionData.Guest.ToolsStatus -eq 'toolsNotInstalled' }).Count + } + $TableParams = @{ + Name = ($LocalizedData.TableVMSummary -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMSummary | Table @TableParams + } + #endregion Virtual Machine Summary Information + + #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]@{ + $LocalizedData.VirtualMachine = $VM.Name + $LocalizedData.PowerState = switch ($VM.PowerState) { + 'PoweredOn' { $LocalizedData.On } + 'PoweredOff' { $LocalizedData.Off } + default { $VM.PowerState } + } + $LocalizedData.IPAddress = if ($VMView.Guest.IpAddress) { + $VMView.Guest.IpAddress + } else { + '--' + } + $LocalizedData.vCPUs = $VM.NumCpu + $LocalizedData.Memory = Convert-DataSize $VM.MemoryGB -RoundUnits 0 + $LocalizedData.Provisioned = Convert-DataSize $VM.ProvisionedSpaceGB + $LocalizedData.Used = Convert-DataSize $VM.UsedSpaceGB + $LocalizedData.HWVersion = ($VM.HardwareVersion).Replace('vmx-', 'v') + $LocalizedData.VMToolsStatus = switch ($VMView.Guest.ToolsStatus) { + 'toolsOld' { $LocalizedData.ToolsOld } + 'toolsOK' { $LocalizedData.ToolsOK } + 'toolsNotRunning' { $LocalizedData.ToolsNotRunning } + 'toolsNotInstalled' { $LocalizedData.ToolsNotInstalled } + default { $VMView.Guest.ToolsStatus } + } + } + } + if ($Healthcheck.VM.VMToolsStatus) { + $VMInfo | Where-Object { $_.$($LocalizedData.VMToolsStatus) -ne $LocalizedData.ToolsOK } | Set-Style -Style Warning -Property $LocalizedData.VMToolsStatus + } + if ($Healthcheck.VM.PowerState) { + $VMInfo | Where-Object { $_.$($LocalizedData.PowerState) -ne $LocalizedData.On } | Set-Style -Style Warning -Property $LocalizedData.PowerState + } + $TableParams = @{ + Name = ($LocalizedData.TableVMAdvancedSummary -f $vCenterServerName) + ColumnWidths = 21, 8, 16, 9, 9, 9, 9, 9, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMInfo | Table @TableParams + + #region VM Snapshot Information + if ($VMSnapshotList -and $Options.ShowVMSnapshots) { + Section -Style Heading3 $LocalizedData.SnapshotHeading { + $VMSnapshotInfo = foreach ($VMSnapshot in $VMSnapshotList) { + [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VMLookup."$($VMSnapshot.VM)" + $LocalizedData.SnapshotName = $VMSnapshot.Name + $LocalizedData.SnapshotDescription = $VMSnapshot.Description + $LocalizedData.DaysOld = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days + } + } + if ($Healthcheck.VM.VMSnapshots) { + $VMSnapshotInfo | Where-Object { $_.$($LocalizedData.DaysOld) -ge 7 } | Set-Style -Style Warning + $VMSnapshotInfo | Where-Object { $_.$($LocalizedData.DaysOld) -ge 14 } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableVMSnapshotSummary -f $vCenterServerName) + ColumnWidths = 30, 30, 30, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMSnapshotInfo | Table @TableParams + } + } + #endregion VM Snapshot Information + } + #endregion Virtual Machine Advanced Summary + + #region Virtual Machine Detailed Information + if ($InfoLevel.VM -ge 3) { + if ($UserPrivileges -contains 'StorageProfile.View') { + $VMSpbmConfig = Get-SpbmEntityConfiguration -VM ($VMs) | Where-Object { $null -ne $_.StoragePolicy } + } else { + Write-PScriboMessage $LocalizedData.InsufficientPrivStoragePolicy + } + if ($InfoLevel.VM -ge 4) { + $VMHardDisks = Get-HardDisk -VM ($VMs) -Server $vCenter + } + $VMComplianceData = $null + if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { + if ($VUMConnection) { + Try { + $VMComplianceData = $VMs | Get-Compliance -ErrorAction SilentlyContinue + } Catch { + Write-PScriboMessage -Message $LocalizedData.VUMComplianceError + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivVUMCompliance + } + foreach ($VM in $VMs) { + Section -Style Heading3 $VM.name { + $VMUptime = Get-Uptime -VM $VM + $VMSpbmPolicy = $VMSpbmConfig | Where-Object { $_.entity -eq $vm } + $VMView = $VM | Get-View + $VMSnapshotList = $vmview.Snapshot.RootSnapshotList + $VMDetail = [PSCustomObject]@{ + $LocalizedData.VirtualMachine = $VM.Name + $LocalizedData.ID = $VM.Id + $LocalizedData.OperatingSystem = $VMView.Summary.Config.GuestFullName + $LocalizedData.HardwareVersion = ($VM.HardwareVersion).Replace('vmx-', 'v') + $LocalizedData.PowerState = switch ($VM.PowerState) { + 'PoweredOn' { $LocalizedData.On } + 'PoweredOff' { $LocalizedData.Off } + default { $TextInfo.ToTitleCase($VM.PowerState) } + } + $LocalizedData.ConnectionState = $TextInfo.ToTitleCase($VM.ExtensionData.Runtime.ConnectionState) + $LocalizedData.VMToolsStatus = switch ($VMView.Guest.ToolsStatus) { + 'toolsOld' { $LocalizedData.ToolsOld } + 'toolsOK' { $LocalizedData.ToolsOK } + 'toolsNotRunning' { $LocalizedData.ToolsNotRunning } + 'toolsNotInstalled' { $LocalizedData.ToolsNotInstalled } + default { $TextInfo.ToTitleCase($VMView.Guest.ToolsStatus) } + } + $LocalizedData.FaultToleranceState = switch ($VMView.Runtime.FaultToleranceState) { + 'notConfigured' { $LocalizedData.FTNotConfigured } + 'needsSecondary' { $LocalizedData.FTNeedsSecondary } + 'running' { $LocalizedData.FTRunning } + 'disabled' { $LocalizedData.FTDisabled } + 'starting' { $LocalizedData.FTStarting } + 'enabled' { $LocalizedData.FTEnabled } + default { $TextInfo.ToTitleCase($VMview.Runtime.FaultToleranceState) } + } + $LocalizedData.VMHost = $VM.VMHost.Name + $LocalizedData.Parent = $VM.VMHost.Parent.Name + $LocalizedData.ParentFolder = $VM.Folder.Name + $LocalizedData.ParentResourcePool = $VM.ResourcePool.Name + $LocalizedData.vCPUs = $VM.NumCpu + $LocalizedData.CoresPerSocket = $VM.CoresPerSocket + $LocalizedData.CPUShares = "$($VM.VMResourceConfiguration.CpuSharesLevel) / $($VM.VMResourceConfiguration.NumCpuShares)" + $LocalizedData.CPUReservation = $VM.VMResourceConfiguration.CpuReservationMhz + $LocalizedData.CPULimit = "$($VM.VMResourceConfiguration.CpuReservationMhz) MHz" + $LocalizedData.CPUHotAdd = if ($VMView.Config.CpuHotAddEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.CPUHotRemove = if ($VMView.Config.CpuHotRemoveEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.MemoryAllocation = Convert-DataSize $VM.memoryGB -RoundUnits 0 + $LocalizedData.MemoryShares = "$($VM.VMResourceConfiguration.MemSharesLevel) / $($VM.VMResourceConfiguration.NumMemShares)" + $LocalizedData.MemoryHotAdd = if ($VMView.Config.MemoryHotAddEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vNICs = $VMView.Summary.Config.NumEthernetCards + $LocalizedData.DNSName = if ($VMView.Guest.HostName) { + $VMView.Guest.HostName + } else { + '--' + } + $LocalizedData.Networks = if ($VMView.Guest.Net.Network) { + (($VMView.Guest.Net | Where-Object { $null -ne $_.Network } | Select-Object Network | Sort-Object Network).Network -join ', ') + } else { + '--' + } + $LocalizedData.IPAddress = if ($VMView.Guest.Net.IpAddress) { + (($VMView.Guest.Net | Where-Object { ($null -ne $_.Network) -and ($null -ne $_.IpAddress) } | Select-Object IpAddress | Sort-Object IpAddress).IpAddress -join ', ') + } else { + '--' + } + $LocalizedData.MACAddress = if ($VMView.Guest.Net.MacAddress) { + (($VMView.Guest.Net | Where-Object { $null -ne $_.Network } | Select-Object -Property MacAddress).MacAddress -join ', ') + } else { + '--' + } + $LocalizedData.vDisks = $VMView.Summary.Config.NumVirtualDisks + $LocalizedData.ProvisionedSpace = Convert-DataSize $VM.ProvisionedSpaceGB + $LocalizedData.UsedSpace = Convert-DataSize $VM.UsedSpaceGB + $LocalizedData.ChangedBlockTracking = if ($VMView.Config.ChangeTrackingEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.StorageBasedPolicy = if ($VMSpbmPolicy.StoragePolicy.Name) { + $TextInfo.ToTitleCase($VMSpbmPolicy.StoragePolicy.Name) + } else { + '--' + } + $LocalizedData.StorageBasedPolicyCompliance = switch ($VMSpbmPolicy.ComplianceStatus) { + $null { '--' } + 'compliant' { $LocalizedData.Compliant } + 'nonCompliant' { $LocalizedData.NonCompliant } + 'unknown' { $LocalizedData.Unknown } + default { $TextInfo.ToTitleCase($VMSpbmPolicy.ComplianceStatus) } + } + } + $MemberProps = @{ + 'InputObject' = $VMDetail + 'MemberType' = 'NoteProperty' + } + #if ($VMView.Config.CreateDate) { + # Add-Member @MemberProps -Name 'Creation Date' -Value ($VMView.Config.CreateDate).ToLocalTime().ToString() + #} + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $VM })) { + Add-Member @MemberProps -Name $LocalizedData.Tags -Value $(($TagAssignments | Where-Object { $_.entity -eq $VM }).Tag -join ', ') + } + if ($VM.Notes) { + Add-Member @MemberProps -Name $LocalizedData.Notes -Value $VM.Notes + } + if ($VMView.Runtime.BootTime) { + Add-Member @MemberProps -Name $LocalizedData.BootTime -Value ($VMView.Runtime.BootTime).ToLocalTime().ToString() + } + if ($VMUptime.UptimeDays) { + Add-Member @MemberProps -Name $LocalizedData.UptimeDays -Value $VMUptime.UptimeDays + } + + #region VM Health Checks + if ($Healthcheck.VM.VMToolsStatus) { + $VMDetail | Where-Object { $_.$($LocalizedData.VMToolsStatus) -ne $LocalizedData.ToolsOK } | Set-Style -Style Warning -Property $LocalizedData.VMToolsStatus + } + if ($Healthcheck.VM.PowerState) { + $VMDetail | Where-Object { $_.$($LocalizedData.PowerState) -ne $LocalizedData.On } | Set-Style -Style Warning -Property $LocalizedData.PowerState + } + if ($Healthcheck.VM.ConnectionState) { + $VMDetail | Where-Object { $_.$($LocalizedData.ConnectionState) -ne 'Connected' } | Set-Style -Style Critical -Property $LocalizedData.ConnectionState + } + if ($Healthcheck.VM.CpuHotAdd) { + $VMDetail | Where-Object { $_.$($LocalizedData.CPUHotAdd) -eq $LocalizedData.Enabled } | Set-Style -Style Warning -Property $LocalizedData.CPUHotAdd + } + if ($Healthcheck.VM.CpuHotRemove) { + $VMDetail | Where-Object { $_.$($LocalizedData.CPUHotRemove) -eq $LocalizedData.Enabled } | Set-Style -Style Warning -Property $LocalizedData.CPUHotRemove + } + if ($Healthcheck.VM.MemoryHotAdd) { + $VMDetail | Where-Object { $_.$($LocalizedData.MemoryHotAdd) -eq $LocalizedData.Enabled } | Set-Style -Style Warning -Property $LocalizedData.MemoryHotAdd + } + if ($Healthcheck.VM.ChangeBlockTracking) { + $VMDetail | Where-Object { $_.$($LocalizedData.ChangedBlockTracking) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.ChangedBlockTracking + } + if ($Healthcheck.VM.SpbmPolicyCompliance) { + $VMDetail | Where-Object { $_.$($LocalizedData.StorageBasedPolicyCompliance) -eq $LocalizedData.Unknown } | Set-Style -Style Warning -Property $LocalizedData.StorageBasedPolicyCompliance + $VMDetail | Where-Object { $_.$($LocalizedData.StorageBasedPolicyCompliance) -eq $LocalizedData.NonCompliant } | Set-Style -Style Critical -Property $LocalizedData.StorageBasedPolicyCompliance + } + #endregion VM Health Checks + $TableParams = @{ + Name = ($LocalizedData.TableVMConfig -f $VM.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMDetail | Table @TableParams + + if ($InfoLevel.VM -ge 4) { + $VMnics = $VM.Guest.Nics | Where-Object { $null -ne $_.Device } | 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 $LocalizedData.NetworkAdapters { + $VMnicInfo = foreach ($VMnic in $VMnics) { + [PSCustomObject]@{ + $LocalizedData.NICName = $VMnic.Device.DeviceInfo.Label + $LocalizedData.NICConnected = if ($VMnic.Connected) { $LocalizedData.Connected } else { $LocalizedData.NotConnected } + $LocalizedData.NetworkName = switch -wildcard ($VMnic.NetworkName) { + 'dvportgroup*' { $VDPortgroupLookup."$($VMnic.NetworkName)" } + default { $VMnic.NetworkName } + } + $LocalizedData.NICType = $VMnic.Device.Type + $LocalizedData.IPAddress = $VMnic.IpAddress -join [Environment]::NewLine + $LocalizedData.NICMAC = $VMnic.Device.MacAddress + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVMNetworkAdapters -f $VM.Name) + ColumnWidths = 20, 12, 16, 12, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMnicInfo | Table @TableParams + } + } + if ($SCSIControllers) { + Section -Style Heading4 $LocalizedData.SCSIControllers { + $VMScsiControllers = foreach ($VMSCSIController in $SCSIControllers) { + [PSCustomObject]@{ + $LocalizedData.Device = $VMSCSIController.DeviceInfo.Label + $LocalizedData.ControllerType = $VMSCSIController.DeviceInfo.Summary + $LocalizedData.BusSharing = switch ($VMSCSIController.SharedBus) { + 'noSharing' { $LocalizedData.None } + default { $VMSCSIController.SharedBus } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVMSCSIControllers -f $VM.Name) + ColumnWidths = 33, 34, 33 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMScsiControllers | Sort-Object $LocalizedData.Device | Table @TableParams + } + } + if ($VMHdds) { + Section -Style Heading4 $LocalizedData.HardDisks { + 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]@{ + $LocalizedData.DiskName = $VMHdd.Name + $LocalizedData.DiskDatastore = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) + $LocalizedData.Capacity = Convert-DataSize $VMHdd.CapacityGB + $LocalizedData.DiskProvisioning = switch ($VMHdd.StorageFormat) { + 'EagerZeroedThick' { $LocalizedData.ThickEagerZeroed } + 'LazyZeroedThick' { $LocalizedData.ThickLazyZeroed } + $null { '--' } + default { $VMHdd.StorageFormat } + } + $LocalizedData.DiskType = switch ($VMHdd.DiskType) { + 'RawPhysical' { $LocalizedData.PhysicalRDM } + 'RawVirtual' { $LocalizedData.VirtualRDM } + 'Flat' { $LocalizedData.VMDK } + default { $VMHdd.DiskType } + } + $LocalizedData.DiskMode = switch ($VMHdd.Persistence) { + 'IndependentPersistent' { $LocalizedData.IndependentPersistent } + 'IndependentNonPersistent' { $LocalizedData.IndependentNonpersistent } + 'Persistent' { $LocalizedData.Dependent } + default { $VMHdd.Persistence } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVMHardDiskConfig -f $VM.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 NOTOCHeading5 -ExcludeFromTOC "$($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]@{ + $LocalizedData.DiskDatastore = $VMHdd.FileName.Substring($VMHdd.Filename.IndexOf("[") + 1, $VMHdd.Filename.IndexOf("]") - 1) + $LocalizedData.Capacity = Convert-DataSize $VMHdd.CapacityGB + $LocalizedData.DiskPath = $VMHdd.Filename.Substring($VMHdd.Filename.IndexOf("]") + 2) + $LocalizedData.DiskShares = "$($TextInfo.ToTitleCase($VMHdd.ExtensionData.Shares.Level)) / $($VMHdd.ExtensionData.Shares.Shares)" + $LocalizedData.DiskLimitIOPs = switch ($VMHdd.ExtensionData.StorageIOAllocation.Limit) { + '-1' { $LocalizedData.Unlimited } + default { $VMHdd.ExtensionData.StorageIOAllocation.Limit } + } + $LocalizedData.DiskProvisioning = switch ($VMHdd.StorageFormat) { + 'EagerZeroedThick' { $LocalizedData.ThickEagerZeroed } + 'LazyZeroedThick' { $LocalizedData.ThickLazyZeroed } + $null { '--' } + default { $VMHdd.StorageFormat } + } + $LocalizedData.DiskType = switch ($VMHdd.DiskType) { + 'RawPhysical' { $LocalizedData.PhysicalRDM } + 'RawVirtual' { $LocalizedData.VirtualRDM } + 'Flat' { $LocalizedData.VMDK } + default { $VMHdd.DiskType } + } + $LocalizedData.DiskMode = switch ($VMHdd.Persistence) { + 'IndependentPersistent' { $LocalizedData.IndependentPersistent } + 'IndependentNonPersistent' { $LocalizedData.IndependentNonpersistent } + 'Persistent' { $LocalizedData.Dependent } + default { $VMHdd.Persistence } + } + $LocalizedData.SCSIController = $SCSIController.DeviceInfo.Label + $LocalizedData.SCSIAddress = "$($SCSIController.BusNumber):$($VMHdd.ExtensionData.UnitNumber)" + } + $TableParams = @{ + Name = ($LocalizedData.TableVMHardDisk -f $VMHdd.Name, $VM.Name) + List = $true + ColumnWidths = 25, 75 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHardDiskInfo | Table @TableParams + } + } + } + } + } + if ($VMGuestVols) { + Section -Style Heading4 $LocalizedData.GuestVolumes { + $VMGuestDiskInfo = foreach ($VMGuestVol in $VMGuestVols) { + [PSCustomObject]@{ + $LocalizedData.Path = $VMGuestVol.Path + $LocalizedData.Capacity = Convert-DataSize $VMGuestVol.CapacityGB + $LocalizedData.UsedSpace = Convert-DataSize (($VMGuestVol.CapacityGB) - ($VMGuestVol.FreeSpaceGB)) + $LocalizedData.FreeSpace = Convert-DataSize $VMGuestVol.FreeSpaceGB + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVMGuestVolumes -f $VM.Name) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMGuestDiskInfo | Table @TableParams + } + } + } + + + if ($VMSnapshotList -and $Options.ShowVMSnapshots) { + Section -Style Heading4 $LocalizedData.SnapshotHeading { + $VMSnapshots = foreach ($VMSnapshot in $VMSnapshotList) { + [PSCustomObject]@{ + $LocalizedData.SnapshotName = $VMSnapshot.Name + $LocalizedData.SnapshotDescription = $VMSnapshot.Description + $LocalizedData.DaysOld = ((Get-Date).ToUniversalTime() - $VMSnapshot.CreateTime).Days + } + } + if ($Healthcheck.VM.VMSnapshots) { + $VMSnapshots | Where-Object { $_.$($LocalizedData.DaysOld) -ge 7 } | Set-Style -Style Warning + $VMSnapshots | Where-Object { $_.$($LocalizedData.DaysOld) -ge 14 } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableVMSnapshots -f $VM.Name) + ColumnWidths = 45, 45, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMSnapshots | Table @TableParams + } + } + + #region VM VUM Compliance + $VMCompliances = $VMComplianceData | Where-Object { $_.Entity -eq $VM } + if ($VMCompliances) { + BlankLine + Section -Style NOTOCHeading4 -ExcludeFromTOC $LocalizedData.VUMCompliance { + $VMComplianceInfo = foreach ($VMCompliance in $VMCompliances) { + $compStatus = switch ($VMCompliance.Status) { + 'NotCompliant' { $LocalizedData.NotCompliant } + 'Incompatible' { $LocalizedData.Incompatible } + 'Unknown' { $LocalizedData.Unknown } + default { $VMCompliance.Status } + } + [PSCustomObject]@{ + $LocalizedData.VUMBaselineName = $VMCompliance.Baseline.Name + $LocalizedData.VUMStatus = $compStatus + } + } + if ($Healthcheck.VM.VUMCompliance) { + $VMComplianceInfo | Where-Object { $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.Unknown } | Set-Style -Style Warning -Property $LocalizedData.VUMStatus + $VMComplianceInfo | Where-Object { $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.NotCompliant -or $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.Incompatible } | Set-Style -Style Critical -Property $LocalizedData.VUMStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMCompliance -f $VM.Name) + ColumnWidths = 75, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMComplianceInfo | Sort-Object $LocalizedData.VUMBaselineName | Table @TableParams + } + } + #endregion VM VUM Compliance + } + } + } + #endregion Virtual Machine Detailed Information + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHost.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHost.ps1 new file mode 100644 index 0000000..c8f4647 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHost.ps1 @@ -0,0 +1,98 @@ +function Get-AbrVSphereVMHost { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHost + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.VMHost) + } + + process { + try { + if ($InfoLevel.VMHost -ge 1) { + if ($VMHosts) { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region Hosts Section + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region ESXi Host Advanced Summary + if ($InfoLevel.VMHost -le 2) { + BlankLine + try { + $VMHostInfo = foreach ($VMHost in $VMHosts) { + [PSCustomObject]@{ + $LocalizedData.VMHost = $VMHost.Name + $LocalizedData.Version = $VMHost.Version + $LocalizedData.Build = $VMHost.Build + $LocalizedData.Parent = $VMHost.Parent.Name + $LocalizedData.ConnectionState = switch ($VMHost.ConnectionState) { + 'NotResponding' { $LocalizedData.NotResponding } + 'Maintenance' { $LocalizedData.Maintenance } + 'Disconnected' { $LocalizedData.Disconnected } + default { $TextInfo.ToTitleCase($VMHost.ConnectionState) } + } + $LocalizedData.NumCPUSockets = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages + $LocalizedData.NumCPUCores = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores + $LocalizedData.MemoryGB = Convert-DataSize $VMHost.MemoryTotalGB -RoundUnits 0 + $LocalizedData.NumVMs = $VMHost.ExtensionData.Vm.Count + } + } + if ($Healthcheck.VMHost.ConnectionState) { + $VMHostInfo | Where-Object { $_.$($LocalizedData.ConnectionState) -eq $LocalizedData.Maintenance } | Set-Style -Style Warning + $VMHostInfo | Where-Object { $_.$($LocalizedData.ConnectionState) -eq $LocalizedData.NotResponding } | Set-Style -Style Critical + $VMHostInfo | Where-Object { $_.$($LocalizedData.ConnectionState) -eq $LocalizedData.Disconnected } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableHostSummary -f $vCenterServerName) + ColumnWidths = 17, 9, 11, 15, 13, 9, 9, 9, 8 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostInfo | Table @TableParams + } catch { + Write-PScriboMessage -Message ($LocalizedData.ErrorCollecting -f $InfoLevel.VMHost) + } + } + #endregion ESXi Host Advanced Summary + + #region ESXi Host Detailed Information + if ($InfoLevel.VMHost -ge 3) { + #region foreach VMHost Detailed Information loop + foreach ($VMHost in ($VMHosts | Where-Object { $_.ConnectionState -eq 'Connected' -or $_.ConnectionState -eq 'Maintenance' })) { + #region VMHost Section + Section -Style Heading3 $VMHost { + if ($Options.ShowTags -and ($TagAssignments | Where-Object { $_.entity -eq $VMHost })) { + Paragraph ($LocalizedData.Tags + ': ' + (($TagAssignments | Where-Object { $_.entity -eq $VMHost }).Tag -join ', ')) + } + Get-AbrVSphereVMHostHardware + Get-AbrVSphereVMHostSystem + Get-AbrVSphereVMHostStorage + Get-AbrVSphereVMHostNetwork + Get-AbrVSphereVMHostSecurity + } + #endregion VMHost Section + } + #endregion foreach VMHost Detailed Information loop + } + #endregion ESXi Host Detailed Information + } + #endregion Hosts Section + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostHardware.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostHardware.ps1 new file mode 100644 index 0000000..53a4417 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostHardware.ps1 @@ -0,0 +1,334 @@ +function Get-AbrVSphereVMHostHardware { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost Hardware information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHostHardware + } + + process { + try { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region ESXi Host Hardware Section + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $VMHost) + BlankLine + + #region ESXi Host Specifications + $VMHostUptime = Get-Uptime -VMHost $VMHost + $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter + $ScratchLocation = Get-AdvancedSetting -Entity $VMHost | Where-Object { $_.Name -eq 'ScratchConfig.CurrentScratchLocation' } + $VMHostCpuTotal = [math]::Round(($VMHost.CpuTotalMhz) / 1000, 2) + $VMHostCpuUsed = [math]::Round(($VMHost.CpuUsageMhz) / 1000, 2) + $VMHostCpuFree = $VMHostCpuTotal - $VMHostCpuUsed + $VMHostDetail = [PSCustomObject]@{ + $LocalizedData.Host = $VMHost.Name + $LocalizedData.ConnectionState = switch ($VMHost.ConnectionState) { + 'NotResponding' { $LocalizedData.NotResponding } + default { $TextInfo.ToTitleCase($VMHost.ConnectionState) } + } + $LocalizedData.ID = $VMHost.Id + $LocalizedData.Parent = $VMHost.Parent.Name + $LocalizedData.Manufacturer = $VMHost.Manufacturer + $LocalizedData.Model = $VMHost.Model + $LocalizedData.SerialNumber = if ($VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber) { + $VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber + } else { + '--' + } + $LocalizedData.AssetTag = if ($VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue) { + $VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue + } else { + $LocalizedData.Unknown + } + $LocalizedData.ProcessorType = $VMHost.Processortype + $LocalizedData.HyperThreading = if ($VMHost.HyperthreadingActive) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.NumberOfCPUSockets = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages + $LocalizedData.NumberOfCPUCores = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores + $LocalizedData.NumberOfCPUThreads = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuThreads + $LocalizedData.CPUTotalUsedFree = "{0:N2} GHz / {1:N2} GHz / {2:N2} GHz" -f $VMHostCpuTotal, $VMHostCpuUsed, $VMHostCpuFree + $LocalizedData.MemoryTotalUsedFree = "{0} / {1} / {2}" -f (Convert-DataSize $VMHost.MemoryTotalGB), (Convert-DataSize $VMHost.MemoryUsageGB), (Convert-DataSize ($VMHost.MemoryTotalGB - $VMHost.MemoryUsageGB)) + $LocalizedData.NUMANodes = $VMHost.ExtensionData.Hardware.NumaInfo.NumNodes + $LocalizedData.NumberOfNICs = $VMHost.ExtensionData.Summary.Hardware.NumNics + $LocalizedData.NumberOfHBAs = $VMHost.ExtensionData.Summary.Hardware.NumHBAs + $LocalizedData.NumberOfDatastores = ($VMHost.ExtensionData.Datastore).Count + $LocalizedData.NumberOfVMs = $VMHost.ExtensionData.VM.Count + $LocalizedData.MaximumEVCMode = $EvcModeLookup."$($VMHost.MaxEVCMode)" + $LocalizedData.EVCGraphicsMode = if ($VMHost.ExtensionData.Summary.CurrentEVCGraphicsModeKey) { + $VMHost.ExtensionData.Summary.CurrentEVCGraphicsModeKey + } else { + $LocalizedData.NotApplicable + } + $LocalizedData.PowerManagementPolicy = $VMHost.ExtensionData.Hardware.CpuPowerManagementInfo.CurrentPolicy + $LocalizedData.ScratchLocation = $ScratchLocation.Value + $LocalizedData.BiosVersion = $VMHost.ExtensionData.Hardware.BiosInfo.BiosVersion + $LocalizedData.BiosReleaseDate = ($VMHost.ExtensionData.Hardware.BiosInfo.ReleaseDate).ToString() + $LocalizedData.Version = $VMHost.Version + $LocalizedData.Build = $VMHost.build + $LocalizedData.BootTime = ($VMHost.ExtensionData.Runtime.Boottime).ToLocalTime().ToString() + $LocalizedData.UptimeDays = $VMHostUptime.UptimeDays + } + $MemberProps = @{ + 'InputObject' = $VMHostDetail + 'MemberType' = 'NoteProperty' + } + if ($UserPrivileges -contains 'Global.Licenses') { + try { + $VMHostLicense = Get-License -VMHost $VMHost + Add-Member @MemberProps -Name $LocalizedData.Product -Value $VMHostLicense.Product + Add-Member @MemberProps -Name $LocalizedData.LicenseKey -Value $VMHostLicense.LicenseKey + Add-Member @MemberProps -Name $LocalizedData.LicenseExpiration -Value $VMHostLicense.Expiration + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.LicenseError -f $VMHost.Name, $_.Exception.Message) + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivLicense + } + <# + if ($TagAssignments | Where-Object {$_.entity -eq $VMHost}) { + Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $VMHost}).Tag -join ',') + } + #> + if ($Healthcheck.VMHost.ConnectionState) { + $VMHostDetail | Where-Object { $_.$($LocalizedData.ConnectionState) -eq $LocalizedData.Maintenance } | Set-Style -Style Warning -Property $LocalizedData.ConnectionState + } + if ($Healthcheck.VMHost.HyperThreading) { + $VMHostDetail | Where-Object { $_.$($LocalizedData.HyperThreading) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.HyperThreading + } + if ($Healthcheck.VMHost.Licensing) { + $VMHostDetail | Where-Object { $_.$($LocalizedData.Product) -like '*Evaluation*' } | Set-Style -Style Warning -Property $LocalizedData.Product + $VMHostDetail | Where-Object { $_.$($LocalizedData.LicenseKey) -like '*-00000-00000' } | Set-Style -Style Warning -Property $LocalizedData.LicenseKey + $VMHostDetail | Where-Object { $_.$($LocalizedData.LicenseExpiration) -eq 'Expired' } | Set-Style -Style Critical -Property $LocalizedData.LicenseExpiration + } + if ($Healthcheck.VMHost.ScratchLocation) { + $VMHostDetail | Where-Object { $_.$($LocalizedData.ScratchLocation) -eq '/tmp/scratch' } | Set-Style -Style Warning -Property $LocalizedData.ScratchLocation + } + if ($Healthcheck.VMHost.UpTimeDays) { + $VMHostDetail | Where-Object { $_.$($LocalizedData.UptimeDays) -ge 275 -and $_.$($LocalizedData.UptimeDays) -lt 365 } | Set-Style -Style Warning -Property $LocalizedData.UptimeDays + $VMHostDetail | Where-Object { $_.$($LocalizedData.UptimeDays) -ge 365 } | Set-Style -Style Critical -Property $LocalizedData.UptimeDays + } + $TableParams = @{ + Name = ($LocalizedData.TableHardwareConfig -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostDetail | Table @TableParams + #endregion ESXi Host Specifications + + #region ESXi IPMI/BMC Settings + try { + $VMHostIPMI = $esxcli.hardware.ipmi.bmc.get.invoke() + } catch { + Write-PScriboMessage -Message ($LocalizedData.IPMIBMCError -f $VMHost.Name, $_.Exception.Message) + } + if ($VMHostIPMI) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.IPMIBMC { + $VMHostIPMIInfo = [PSCustomObject]@{ + $LocalizedData.Manufacturer = $VMHostIPMI.Manufacturer + $LocalizedData.MACAddress = $VMHostIPMI.MacAddress + $LocalizedData.IPMIBMCIPAddress = $VMHostIPMI.IPv4Address + $LocalizedData.SubnetMask = $VMHostIPMI.IPv4Subnet + $LocalizedData.Gateway = $VMHostIPMI.IPv4Gateway + $LocalizedData.FirmwareVersion = $VMHostIPMI.BMCFirmwareVersion + } + + $TableParams = @{ + Name = ($LocalizedData.TableIPMIBMC -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostIPMIInfo | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.IPMIBMCError -f $VMHost.Name, $_.Exception.Message) + } + } + #endregion ESXi IPMI/BMC Settings + + #region ESXi Host Boot Device + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.BootDevice { + $ESXiBootDevice = Get-ESXiBootDevice -VMHost $VMHost + $VMHostBootDevice = [PSCustomObject]@{ + $LocalizedData.Host = $ESXiBootDevice.Host + $LocalizedData.Device = $ESXiBootDevice.Device + $LocalizedData.BootType = $ESXiBootDevice.BootType + $LocalizedData.Vendor = $ESXiBootDevice.Vendor + $LocalizedData.Model = $ESXiBootDevice.Model + $LocalizedData.Size = switch ($ESXiBootDevice.SizeMB) { + 'N/A' { 'N/A' } + default { Convert-DataSize $ESXiBootDevice.SizeMB -InputUnit MB -RoundUnits 0 } + } + $LocalizedData.BootDeviceIsSAS = $ESXiBootDevice.IsSAS + $LocalizedData.BootDeviceIsSSD = $ESXiBootDevice.IsSSD + $LocalizedData.BootDeviceIsUSB = $ESXiBootDevice.IsUSB + } + $TableParams = @{ + Name = ($LocalizedData.TableBootDevice -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostBootDevice | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.BootDeviceError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Boot Devices + + #region ESXi Host PCI Devices + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.PCIDevices { + <# Move away from esxcli.v2 implementation to be compatible with 8.x branch. + 'Slot Description' information does not seem to be available through the API + Create an array with PCI Address and VMware Devices (vmnic,vmhba,?vmgfx?) + #> + $PciToDeviceMapping = @{} + $NetworkAdapters = Get-VMHostNetworkAdapter -VMHost $VMHost -Physical + foreach ($adapter in $NetworkAdapters) { + $PciToDeviceMapping[$adapter.PciId] = $adapter.DeviceName + } + $hbAdapters = Get-VMHostHba -VMHost $VMHost + foreach ($adapter in $hbAdapters) { + $PciToDeviceMapping[$adapter.Pci] = $adapter.Device + } + <# Data Object - HostGraphicsInfo(vim.host.GraphicsInfo) + This function has been available since version 5.5, but we can't be sure if it is still valid. + I don't have access to a vGPU-enabled system. + #> + $GpuAdapters = (Get-VMHost $VMhost | Get-View -Property Config).Config.GraphicsInfo + foreach ($adapter in $GpuAdapters) { + $PciToDeviceMapping[$adapter.pciId] = $adapter.deviceName + } + + $VMHostPciDevice = @{ + VMHost = $VMHost + DeviceClass = @('MassStorageController', 'NetworkController', 'DisplayController', 'SerialBusController') + } + $PciDevices = Get-VMHostPciDevice @VMHostPciDevice + + # Combine PciDevices and PciToDeviceMapping + + $VMHostPciDevices = $PciDevices | ForEach-Object { + $PciDevice = $_ + $device = $PCIToDeviceMapping[$pciDevice.Id] + + if ($device) { + [PSCustomObject]@{ + $LocalizedData.Device = $device + $LocalizedData.PCIAddress = $PciDevice.Id + $LocalizedData.DeviceClass = $PciDevice.DeviceClass -replace ('Controller', "") + $LocalizedData.PCIDeviceName = $PciDevice.DeviceName + $LocalizedData.PCIVendorName = $PciDevice.VendorName + } + } + } + + $TableParams = @{ + Name = ($LocalizedData.TablePCIDevices -f $VMHost) + ColumnWidths = 17, 18, 15, 30, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPciDevices | Sort-Object $LocalizedData.Device | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.PCIDeviceError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host PCI Devices + + #region ESXi Host PCI Devices Drivers & Firmware + $VMHostPciDevicesDetails = Get-PciDeviceDetail -Server $vCenter -esxcli $esxcli -VMHost $VMHost | Sort-Object 'Device' + if ($VMHostPciDevicesDetails) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.PCIDriversFirmware { + $TableParams = @{ + Name = ($LocalizedData.TablePCIDriversFirmware -f $VMHost) + ColumnWidths = 12, 20, 11, 19, 11, 11, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPciDevicesDetails | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.PCIDriversFirmwareError -f $VMHost.Name, $_.Exception.Message) + } + } + #endregion ESXi Host PCI Devices Drivers & Firmware + + #region ESXi Host I/O Device Identifiers + try { + # Build PCI address -> VMkernel name mapping (VMkernelName is unpopulated on ESXi 8) + # Guard against null keys — software HBAs (iSCSI, software NVMe) have no PCI address + $IOPciToDevice = @{} + Get-VMHostNetworkAdapter -VMHost $VMHost -Physical | ForEach-Object { + if ($_.PciId) { $IOPciToDevice[$_.PciId] = $_.DeviceName } + } + Get-VMHostHba -VMHost $VMHost | ForEach-Object { + if ($_.Pci) { $IOPciToDevice[$_.Pci] = $_.Device } + } + (Get-VMHost $VMHost | Get-View -Property Config).Config.GraphicsInfo | ForEach-Object { + if ($_.pciId) { $IOPciToDevice[$_.pciId] = $_.deviceName } + } + $VMHostIODevices = $esxcli.hardware.pci.list.Invoke() | + Where-Object { $IOPciToDevice.ContainsKey($_.Address) } | + Sort-Object -Property Address + if ($VMHostIODevices) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.IODeviceIdentifiers { + $VMHostIODeviceInfo = $VMHostIODevices | ForEach-Object { + [PSCustomObject]@{ + $LocalizedData.Device = $IOPciToDevice[$_.Address] + $LocalizedData.Model = $_.DeviceName + $LocalizedData.VendorID = [String]::Format("{0:x4}", $_.VendorID) + $LocalizedData.DeviceID = [String]::Format("{0:x4}", $_.DeviceID) + $LocalizedData.SubVendorID = [String]::Format("{0:x4}", $_.SubVendorID) + $LocalizedData.SubDeviceID = [String]::Format("{0:x4}", $_.SubDeviceID) + } + } + $TableParams = @{ + Name = ($LocalizedData.TableIODeviceIdentifiers -f $VMHost) + ColumnWidths = 13, 31, 14, 14, 14, 14 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostIODeviceInfo | Sort-Object $LocalizedData.Device | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.IODeviceIdentifiersError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host I/O Device Identifiers + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.HardwareError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Hardware Section + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostNetwork.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostNetwork.ps1 new file mode 100644 index 0000000..2a43b2b --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostNetwork.ps1 @@ -0,0 +1,682 @@ +function Get-AbrVSphereVMHostNetwork { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost Network information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHostNetwork + } + + process { + try { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region ESXi Host Network Section + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $VMHost) + 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]@{ + $LocalizedData.Host = $VMHost.Name + $LocalizedData.VirtualSwitches = ($VMHostVirtualSwitch | Sort-Object) -join ', ' + $LocalizedData.VMKernelAdapters = ($VMHostNetwork.Vnic.Device | Sort-Object) -join ', ' + $LocalizedData.PhysicalAdapters = ($VMHostNetwork.Pnic.Device | Sort-Object) -join ', ' + $LocalizedData.VMkernelGateway = $VMHostNetwork.IpRouteConfig.DefaultGateway + $LocalizedData.IPv6 = if ($VMHostNetwork.IPv6Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.VMkernelIPv6Gateway = if ($VMHostNetwork.IpRouteConfig.IpV6DefaultGateway) { + $VMHostNetwork.IpRouteConfig.IpV6DefaultGateway + } else { + '--' + } + $LocalizedData.DNSServers = ($VMHostNetwork.DnsConfig.Address | Sort-Object) -join ', ' + $LocalizedData.HostName = $VMHostNetwork.DnsConfig.HostName + $LocalizedData.DomainName = $VMHostNetwork.DnsConfig.DomainName + $LocalizedData.SearchDomain = ($VMHostNetwork.DnsConfig.SearchDomain | Sort-Object) -join ', ' + } + if ($Healthcheck.VMHost.IPv6) { + $VMHostNetworkDetail | Where-Object { $_.$($LocalizedData.IPv6) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.IPv6 + } + $TableParams = @{ + Name = ($LocalizedData.TableNetworkConfig -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostNetworkDetail | Table @TableParams + #endregion ESXi Host Network Configuration + + #region ESXi Host Physical Adapters + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.PhysicalAdapters { + Paragraph ($LocalizedData.ParagraphPhysicalAdapters -f $VMHost) + $PhysicalNetAdapters = $VMHost.ExtensionData.Config.Network.Pnic | Sort-Object Device + $VMHostPhysicalNetAdapters = foreach ($PhysicalNetAdapter in $PhysicalNetAdapters) { + [PSCustomObject]@{ + $LocalizedData.AdapterName = $PhysicalNetAdapter.Device + $LocalizedData.Status = if ($PhysicalNetAdapter.Linkspeed) { + $LocalizedData.Connected + } else { + $LocalizedData.Disconnected + } + $LocalizedData.VirtualSwitch = $( + 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 { + '--' + } + ) + $LocalizedData.AdapterMAC = $PhysicalNetAdapter.Mac + $LocalizedData.ActualSpeedDuplex = if ($PhysicalNetAdapter.LinkSpeed.SpeedMb) { + if ($PhysicalNetAdapter.LinkSpeed.Duplex) { + "$($PhysicalNetAdapter.LinkSpeed.SpeedMb) Mbps, $($LocalizedData.FullDuplex)" + } else { + $LocalizedData.AutoNegotiate + } + } else { + $LocalizedData.Down + } + $LocalizedData.ConfiguredSpeedDuplex = if ($PhysicalNetAdapter.Spec.LinkSpeed) { + if ($PhysicalNetAdapter.Spec.LinkSpeed.Duplex) { + "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps, $($LocalizedData.FullDuplex)" + } else { + "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps" + } + } else { + $LocalizedData.AutoNegotiate + } + $LocalizedData.WakeOnLAN = if ($PhysicalNetAdapter.WakeOnLanSupported) { + $LocalizedData.Supported + } else { + $LocalizedData.NotSupported + } + } + } + if ($Healthcheck.VMHost.NetworkAdapter) { + $VMHostPhysicalNetAdapters | Where-Object { $_.$($LocalizedData.Status) -ne $LocalizedData.Connected } | Set-Style -Style Critical -Property $LocalizedData.Status + $VMHostPhysicalNetAdapters | Where-Object { $_.$($LocalizedData.ActualSpeedDuplex) -eq $LocalizedData.Down } | Set-Style -Style Critical -Property $LocalizedData.ActualSpeedDuplex + } + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostPhysicalNetAdapter in $VMHostPhysicalNetAdapters) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($VMHostPhysicalNetAdapter.$($LocalizedData.AdapterName))" { + $TableParams = @{ + Name = ($LocalizedData.TablePhysicalAdapter -f $VMHostPhysicalNetAdapter.$($LocalizedData.AdapterName), $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostPhysicalNetAdapter | Table @TableParams + } + } + } else { + BlankLine + $TableParams = @{ + Name = ($LocalizedData.TablePhysicalAdapters -f $VMHost) + 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-VMHostNetworkAdapterDP | Where-Object { $_.Status -eq 'Connected' } | Sort-Object Device + if ($VMHostNetworkAdapterCDP) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.CDP { + Paragraph ($LocalizedData.ParagraphCDP -f $VMHost) + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($VMHostNetworkAdapter.Device)" { + $VMHostCDP = [PSCustomObject]@{ + $LocalizedData.Status = $VMHostNetworkAdapter.Status + $LocalizedData.SystemName = $VMHostNetworkAdapter.SystemName + $LocalizedData.HardwarePlatform = $VMHostNetworkAdapter.HardwarePlatform + $LocalizedData.SwitchID = $VMHostNetworkAdapter.SwitchId + $LocalizedData.SoftwareVersion = $VMHostNetworkAdapter.SoftwareVersion + $LocalizedData.ManagementAddress = $VMHostNetworkAdapter.ManagementAddress + $LocalizedData.Address = $VMHostNetworkAdapter.Address + $LocalizedData.PortID = $VMHostNetworkAdapter.PortId + $LocalizedData.VLAN = $VMHostNetworkAdapter.Vlan + $LocalizedData.MTU = $VMHostNetworkAdapter.Mtu + } + $TableParams = @{ + Name = ($LocalizedData.TableAdapterCDP -f $VMHostNetworkAdapter.Device, $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostCDP | Table @TableParams + } + } + } else { + BlankLine + $VMHostCDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { + [PSCustomObject]@{ + $LocalizedData.AdapterName = $VMHostNetworkAdapter.Device + $LocalizedData.Status = $VMHostNetworkAdapter.Status + $LocalizedData.HardwarePlatform = $VMHostNetworkAdapter.HardwarePlatform + $LocalizedData.SwitchID = $VMHostNetworkAdapter.SwitchId + $LocalizedData.Address = $VMHostNetworkAdapter.Address + $LocalizedData.PortID = $VMHostNetworkAdapter.PortId + } + } + $TableParams = @{ + Name = ($LocalizedData.TableAdaptersCDP -f $VMHost) + 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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.LLDP { + Paragraph ($LocalizedData.ParagraphLLDP -f $VMHost) + if ($InfoLevel.VMHost -ge 4) { + foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterLLDP) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($VMHostNetworkAdapter.Device)" { + $VMHostLLDP = [PSCustomObject]@{ + $LocalizedData.ChassisID = $VMHostNetworkAdapter.ChassisId + $LocalizedData.PortID = $VMHostNetworkAdapter.PortId + $LocalizedData.TimeToLive = $VMHostNetworkAdapter.TimeToLive + $LocalizedData.TimeOut = $VMHostNetworkAdapter.TimeOut + $LocalizedData.Samples = $VMHostNetworkAdapter.Samples + $LocalizedData.ManagementAddress = $VMHostNetworkAdapter.ManagementAddress + $LocalizedData.PortDescription = $VMHostNetworkAdapter.PortDescription + $LocalizedData.SystemDescription = $VMHostNetworkAdapter.SystemDescription + $LocalizedData.SystemName = $VMHostNetworkAdapter.SystemName + } + $TableParams = @{ + Name = ($LocalizedData.TableAdapterLLDP -f $VMHostNetworkAdapter.Device, $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostLLDP | Table @TableParams + } + } + } else { + BlankLine + $VMHostLLDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterLLDP) { + [PSCustomObject]@{ + $LocalizedData.AdapterName = $VMHostNetworkAdapter.Device + $LocalizedData.ChassisID = $VMHostNetworkAdapter.ChassisId + $LocalizedData.PortID = $VMHostNetworkAdapter.PortId + $LocalizedData.ManagementAddress = $VMHostNetworkAdapter.ManagementAddress + $LocalizedData.PortDescription = $VMHostNetworkAdapter.PortDescription + $LocalizedData.SystemName = $VMHostNetworkAdapter.SystemName + } + } + $TableParams = @{ + Name = ($LocalizedData.TableAdaptersLLDP -f $VMHost) + 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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VMKernelAdapters { + Paragraph ($LocalizedData.ParagraphVMKernelAdapters -f $VMHost) + $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]@{ + $LocalizedData.AdapterName = $_.Device + $LocalizedData.NetworkLabel = & { + if ($_.Spec.Portgroup) { + $script:pg = $_.Spec.Portgroup + $script:pg + } elseif ($_.Spec.DistributedVirtualPort.Portgroupkey) { + $script:pg = Get-View -ViewType DistributedVirtualPortgroup -Property Name, Key -Filter @{'Key' = "$($_.Spec.DistributedVirtualPort.PortgroupKey)" } | Select-Object -ExpandProperty Name + $script:pg + } else { + '--' + } + } + $LocalizedData.VirtualSwitch = & { + if ($_.Spec.Portgroup) { + (Get-VirtualPortGroup -Standard -Name $script:pg -VMHost $VMHost).VirtualSwitchName + } elseif ($_.Spec.DistributedVirtualPort.Portgroupkey) { + (Get-VDPortgroup -Name $script:pg).VDSwitch.Name | Select-Object -Unique + } else { + # Haven't figured out how to gather this yet! + '--' + } + } + $LocalizedData.TCPIPStack = switch ($_.Spec.NetstackInstanceKey) { + 'defaultTcpipStack' { $LocalizedData.TCPDefault } + 'vSphereProvisioning' { $LocalizedData.TCPProvisioning } + 'vmotion' { $LocalizedData.TCPvMotion } + 'vxlan' { $LocalizedData.TCPNsxOverlay } + 'hyperbus' { $LocalizedData.TCPNsxHyperbus } + $null { $LocalizedData.TCPNotApplicable } + default { $_.Spec.NetstackInstanceKey } + } + $LocalizedData.MTU = $_.Spec.Mtu + $LocalizedData.AdapterMAC = $_.Spec.Mac + $LocalizedData.DHCP = if ($_.Spec.Ip.Dhcp) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.IPAddress = & { + if ($_.Spec.IP.IPAddress) { + $script:ip = $_.Spec.IP.IPAddress + } else { + $script:ip = '--' + } + $script:ip + } + $LocalizedData.SubnetMask = & { + if ($_.Spec.IP.SubnetMask) { + $script:netmask = $_.Spec.IP.SubnetMask + } else { + $script:netmask = '--' + } + $script:netmask + } + $LocalizedData.DefaultGateway = if ($_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway) { + $_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway + } else { + '--' + } + $LocalizedData.vMotion = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vmotion' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Provisioning = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereProvisioning' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.FTLogging = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'faultToleranceLogging' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Management = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'management' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vSphereReplication = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereReplication' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vSphereReplicationNFC = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereReplicationNFC' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vSAN = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vsan' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vSANWitness = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vsanWitness' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.vSphereBackupNFC = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereBackupnNFC' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + } + } + foreach ($VMkernelAdapter in ($VMkernelAdapters | Sort-Object $LocalizedData.AdapterName)) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($VMkernelAdapter.$($LocalizedData.AdapterName))" { + $TableParams = @{ + Name = ($LocalizedData.TableVMKernelAdapter -f $VMkernelAdapter.$($LocalizedData.AdapterName), $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMkernelAdapter | Table @TableParams + } + } + } + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.StandardvSwitches { + Paragraph ($LocalizedData.ParagraphStandardvSwitches -f $VMHost) + BlankLine + $VSSwitchNicTeaming = $VSSwitches | Get-NicTeamingPolicy + #region ESXi Host Standard Virtual Switch Properties + $VSSProperties = foreach ($VSSwitchNicTeam in $VSSwitchNicTeaming) { + [PSCustomObject]@{ + $LocalizedData.VirtualSwitch = $VSSwitchNicTeam.VirtualSwitch.Name + $LocalizedData.MTU = $VSSwitchNicTeam.VirtualSwitch.Mtu + $LocalizedData.NumberOfPorts = $VSSwitchNicTeam.VirtualSwitch.NumPorts + $LocalizedData.NumberOfPortsAvailable = $VSSwitchNicTeam.VirtualSwitch.NumPortsAvailable + } + } + $TableParams = @{ + Name = ($LocalizedData.TableStandardvSwitches -f $VMHost) + 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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSSecurity { + $VssSecurity = foreach ($VssSec in $VssSecurity) { + [PSCustomObject]@{ + $LocalizedData.VirtualSwitch = $VssSec.VirtualSwitch.Name + $LocalizedData.PromiscuousMode = if ($VssSec.AllowPromiscuous) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.MACAddressChanges = if ($VssSec.MacChanges) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.ForgedTransmits = if ($VssSec.ForgedTransmits) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSSecurity -f $VMHost) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssSecurity | Sort-Object $LocalizedData.VirtualSwitch | Table @TableParams + } + #endregion Virtual Switch Security Policy + } + #endregion ESXi Host Virtual Switch Security Policy + + #region ESXi Host Virtual Switch Traffic Shaping Policy + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSTrafficShaping { + $VssTrafficShapingPolicy = foreach ($VSSwitch in $VSSwitches) { + [PSCustomObject]@{ + $LocalizedData.VirtualSwitch = $VSSwitch.Name + $LocalizedData.Status = if ($VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.AverageBandwidth = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth + $LocalizedData.PeakBandwidth = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth + $LocalizedData.BurstSize = $VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSTrafficShaping -f $VMHost) + ColumnWidths = 25, 15, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssTrafficShapingPolicy | Sort-Object $LocalizedData.VirtualSwitch | 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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSTeamingFailover { + $VssNicTeaming = foreach ($VssNicTeam in $VssNicTeamingPolicy) { + [PSCustomObject]@{ + $LocalizedData.VirtualSwitch = $VssNicTeam.VirtualSwitch.Name + $LocalizedData.LoadBalancing = switch ($VssNicTeam.LoadBalancingPolicy) { + 'LoadbalanceSrcId' { $LocalizedData.LBSrcId } + 'LoadbalanceSrcMac' { $LocalizedData.LBSrcMac } + 'LoadbalanceIP' { $LocalizedData.LBIP } + 'ExplicitFailover' { $LocalizedData.LBExplicitFailover } + default { $VssNicTeam.LoadBalancingPolicy } + } + $LocalizedData.NetworkFailureDetection = switch ($VssNicTeam.NetworkFailoverDetectionPolicy) { + 'LinkStatus' { $LocalizedData.NFDLinkStatus } + 'BeaconProbing' { $LocalizedData.NFDBeaconProbing } + default { $VssNicTeam.NetworkFailoverDetectionPolicy } + } + $LocalizedData.NotifySwitches = if ($VssNicTeam.NotifySwitches) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Failback = if ($VssNicTeam.FailbackEnabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.ActiveNICs = ($VssNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine + $LocalizedData.StandbyNICs = ($VssNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine + $LocalizedData.UnusedNICs = ($VssNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSTeamingFailover -f $VMHost) + ColumnWidths = 20, 17, 12, 11, 10, 10, 10, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssNicTeaming | Sort-Object $LocalizedData.VirtualSwitch | Table @TableParams + } + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSPortGroups { + $VssPortgroups = foreach ($VssPortgroup in $VssPortgroups) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = $VssPortgroup.Name + $LocalizedData.VLAN = $VssPortgroup.VLanId + $LocalizedData.VirtualSwitch = $VssPortgroup.VirtualSwitchName + $LocalizedData.NumberOfVMs = ($VssPortgroup | Get-VM).Count + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSPortGroups -f $VMHost) + ColumnWidths = 40, 10, 40, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroups | Sort-Object $LocalizedData.PortGroup, $LocalizedData.VLAN, $LocalizedData.VirtualSwitch | 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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSPGSecurity { + $VssPortgroupSecurity = foreach ($VssPortgroupSec in $VssPortgroupSecurity) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = $VssPortgroupSec.VirtualPortGroup.Name + $LocalizedData.VirtualSwitch = $VssPortgroupSec.virtualportgroup.virtualswitchname + $LocalizedData.PromiscuousMode = if ($VssPortgroupSec.AllowPromiscuous) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.MACChanges = if ($VssPortgroupSec.MacChanges) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + $LocalizedData.ForgedTransmits = if ($VssPortgroupSec.ForgedTransmits) { + $LocalizedData.Accept + } else { + $LocalizedData.Reject + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSPGSecurity -f $VMHost) + ColumnWidths = 27, 25, 16, 16, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupSecurity | Sort-Object $LocalizedData.PortGroup, $LocalizedData.VirtualSwitch | Table @TableParams + } + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSPGTrafficShaping { + $VssPortgroupTrafficShapingPolicy = foreach ($VssPortgroup in $VssPortgroups) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = $VssPortgroup.Name + $LocalizedData.VirtualSwitch = $VssPortgroup.VirtualSwitchName + $LocalizedData.Status = switch ($VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { + $True { $LocalizedData.Enabled } + $False { $LocalizedData.Disabled } + $null { $LocalizedData.Inherited } + } + $LocalizedData.AverageBandwidth = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.AverageBandwidth + $LocalizedData.PeakBandwidth = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.PeakBandwidth + $LocalizedData.BurstSize = $VssPortgroup.ExtensionData.Spec.Policy.ShapingPolicy.BurstSize + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSPGTrafficShaping -f $VMHost) + ColumnWidths = 19, 19, 11, 17, 17, 17 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupTrafficShapingPolicy | Sort-Object $LocalizedData.PortGroup, $LocalizedData.VirtualSwitch | Table @TableParams + } + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VSPGTeamingFailover { + $VssPortgroupNicTeaming = foreach ($VssPortgroupNicTeam in $VssPortgroupNicTeaming) { + [PSCustomObject]@{ + $LocalizedData.PortGroup = $VssPortgroupNicTeam.VirtualPortGroup.Name + $LocalizedData.VirtualSwitch = $VssPortgroupNicTeam.virtualportgroup.virtualswitchname + $LocalizedData.LoadBalancing = switch ($VssPortgroupNicTeam.LoadBalancingPolicy) { + 'LoadbalanceSrcId' { $LocalizedData.LBSrcId } + 'LoadbalanceSrcMac' { $LocalizedData.LBSrcMac } + 'LoadbalanceIP' { $LocalizedData.LBIP } + 'ExplicitFailover' { $LocalizedData.LBExplicitFailover } + default { $VssPortgroupNicTeam.LoadBalancingPolicy } + } + $LocalizedData.NetworkFailureDetection = switch ($VssPortgroupNicTeam.NetworkFailoverDetectionPolicy) { + 'LinkStatus' { $LocalizedData.NFDLinkStatus } + 'BeaconProbing' { $LocalizedData.NFDBeaconProbing } + default { $VssPortgroupNicTeam.NetworkFailoverDetectionPolicy } + } + $LocalizedData.NotifySwitches = if ($VssPortgroupNicTeam.NotifySwitches) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Failback = if ($VssPortgroupNicTeam.FailbackEnabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.ActiveNICs = ($VssPortgroupNicTeam.ActiveNic | Sort-Object) -join [Environment]::NewLine + $LocalizedData.StandbyNICs = ($VssPortgroupNicTeam.StandbyNic | Sort-Object) -join [Environment]::NewLine + $LocalizedData.UnusedNICs = ($VssPortgroupNicTeam.UnusedNic | Sort-Object) -join [Environment]::NewLine + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSPGTeamingFailover -f $VMHost) + ColumnWidths = 12, 11, 11, 11, 11, 11, 11, 11, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VssPortgroupNicTeaming | Sort-Object $LocalizedData.PortGroup, $LocalizedData.VirtualSwitch | Table @TableParams + } + #endregion Virtual Switch Port Group Teaming & Failover Section + } + #endregion ESXi Host Virtual Switch Port Group Teaming & Failover + } + } + #endregion Section Standard Virtual Switches + } + #endregion ESXi Host Standard Virtual Switches + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + #endregion ESXi Host Network Section + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSecurity.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSecurity.ps1 new file mode 100644 index 0000000..42531e2 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSecurity.ps1 @@ -0,0 +1,321 @@ +function Get-AbrVSphereVMHostSecurity { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost Security information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHostSecurity + } + + process { + try { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region ESXi Host Security Section + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $VMHost) + #region ESXi Host Lockdown Mode + if ($null -ne $VMHost.ExtensionData.Config.LockdownMode) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.LockdownMode { + $LockdownMode = [PSCustomObject]@{ + $LocalizedData.LockdownMode = switch ($VMHost.ExtensionData.Config.LockdownMode) { + 'lockdownDisabled' { $LocalizedData.LockdownDisabled } + 'lockdownNormal' { $LocalizedData.LockdownNormal } + 'lockdownStrict' { $LocalizedData.LockdownStrict } + default { $VMHost.ExtensionData.Config.LockdownMode } + } + } + if ($Healthcheck.VMHost.LockdownMode) { + $LockdownMode | Where-Object { $_.$($LocalizedData.LockdownMode) -eq $LocalizedData.LockdownDisabled } | Set-Style -Style Warning -Property $LocalizedData.LockdownMode + } + $TableParams = @{ + Name = ($LocalizedData.TableLockdownMode -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $LockdownMode | Table @TableParams + } + } + #endregion ESXi Host Lockdown Mode + + #region ESXi Host Services + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Services { + $VMHostServices = $VMHost | Get-VMHostService + $Services = foreach ($VMHostService in $VMHostServices) { + [PSCustomObject]@{ + $LocalizedData.ServiceName = $VMHostService.Label + $LocalizedData.ServiceRunning = if ($VMHostService.Running) { + $LocalizedData.Running + } else { + $LocalizedData.Stopped + } + $LocalizedData.ServicePolicy = switch ($VMHostService.Policy) { + 'automatic' { $LocalizedData.SvcPortUsage } + 'on' { $LocalizedData.SvcWithHost } + 'off' { $LocalizedData.SvcManually } + default { $VMHostService.Policy } + } + } + } + if ($Healthcheck.VMHost.NTP) { + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'NTP Daemon') -and ($_.$($LocalizedData.ServiceRunning) -eq $LocalizedData.Stopped) } | Set-Style -Style Critical -Property $LocalizedData.ServiceRunning + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'NTP Daemon') -and ($_.$($LocalizedData.ServicePolicy) -ne $LocalizedData.SvcWithHost) } | Set-Style -Style Critical -Property $LocalizedData.ServicePolicy + } + if ($Healthcheck.VMHost.SSH) { + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'SSH') -and ($_.$($LocalizedData.ServiceRunning) -eq $LocalizedData.Running) } | Set-Style -Style Warning -Property $LocalizedData.ServiceRunning + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'SSH') -and ($_.$($LocalizedData.ServicePolicy) -ne $LocalizedData.SvcManually) } | Set-Style -Style Warning -Property $LocalizedData.ServicePolicy + } + if ($Healthcheck.VMHost.ESXiShell) { + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'ESXi Shell') -and ($_.$($LocalizedData.ServiceRunning) -eq $LocalizedData.Running) } | Set-Style -Style Warning -Property $LocalizedData.ServiceRunning + $Services | Where-Object { ($_.$($LocalizedData.ServiceName) -eq 'ESXi Shell') -and ($_.$($LocalizedData.ServicePolicy) -ne $LocalizedData.SvcManually) } | Set-Style -Style Warning -Property $LocalizedData.ServicePolicy + } + $TableParams = @{ + Name = ($LocalizedData.TableServices -f $VMHost) + ColumnWidths = 40, 20, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $Services | Sort-Object $LocalizedData.ServiceName | Table @TableParams + } + #endregion ESXi Host Services + + #region ESXi Host TPM & Encryption + $TpmAttestation = $VMHost.ExtensionData.Config.TpmAttestation + $EncryptionSettings = $null + try { + $esxcliTpm = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter + $EncryptionSettings = $esxcliTpm.system.settings.encryption.get.Invoke() + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.TpmEncryptionError -f $VMHost, $_.Exception.Message) + } + if ($null -ne $TpmAttestation -or ($null -ne $EncryptionSettings -and $EncryptionSettings.Mode -ne 'None')) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.TpmEncryption { + $TpmEncryptionInfo = [PSCustomObject]@{ + $LocalizedData.TpmPresent = if ($null -ne $TpmAttestation) { $LocalizedData.Yes } else { $LocalizedData.No } + $LocalizedData.TpmStatus = if ($null -ne $TpmAttestation) { $TpmAttestation.Status } else { 'N/A' } + $LocalizedData.EncryptionMode = if ($null -ne $EncryptionSettings) { $EncryptionSettings.Mode } else { 'N/A' } + $LocalizedData.RequireSecureBoot = if ($null -ne $EncryptionSettings) { $EncryptionSettings.RequireSecureBoot } else { 'N/A' } + $LocalizedData.RequireSignedVIBs = if ($null -ne $EncryptionSettings) { $EncryptionSettings.RequireExecutablesOnlyFromInstalledVIBs } else { 'N/A' } + } + if ($Healthcheck.VMHost.TpmAttestation) { + $TpmEncryptionInfo | Where-Object { + $null -ne $TpmAttestation -and $TpmAttestation.Status -ne 'attested' + } | Set-Style -Style Warning -Property $LocalizedData.TpmStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableTpmEncryption -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $TpmEncryptionInfo | Table @TableParams + + # Recovery keys — InfoLevel >= 3 and ShowEncryptionKeys option + if ($InfoLevel.VMHost -ge 3 -and $Options.ShowEncryptionKeys -and $null -ne $esxcliTpm) { + try { + $RecoveryKeys = $esxcliTpm.system.settings.encryption.recovery.list.Invoke() + if ($RecoveryKeys) { + Section -Style NOTOCHeading6 -ExcludeFromTOC $LocalizedData.RecoveryKeys { + $RecoveryKeyInfo = foreach ($RecoveryKey in $RecoveryKeys) { + [PSCustomObject]@{ + $LocalizedData.RecoveryID = $RecoveryKey.RecoveryID + $LocalizedData.RecoveryKey = $RecoveryKey.Key + } + } + $TableParams = @{ + Name = ($LocalizedData.TableRecoveryKeys -f $VMHost) + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $RecoveryKeyInfo | Table @TableParams + } + } + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.TpmEncryptionError -f $VMHost, $_.Exception.Message) + } + } + } + } + #endregion ESXi Host TPM & Encryption + + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Firewall { + $VMHostFirewall = foreach ($VMHostFirewallException in $VMHostFirewallExceptions) { + [PScustomObject]@{ + $LocalizedData.FirewallService = $VMHostFirewallException.Name + $LocalizedData.Status = if ($VMHostFirewallException.Enabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.IncomingPorts = $VMHostFirewallException.IncomingPorts + $LocalizedData.OutgoingPorts = $VMHostFirewallException.OutgoingPorts + $LocalizedData.Protocols = $VMHostFirewallException.Protocols + $LocalizedData.Daemon = switch ($VMHostFirewallException.ServiceRunning) { + $true { $LocalizedData.Running } + $false { $LocalizedData.Stopped } + $null { 'N/A' } + default { $VMHostFirewallException.ServiceRunning } + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableFirewall -f $VMHost) + ColumnWidths = 22, 12, 21, 21, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostFirewall | Sort-Object $LocalizedData.FirewallService | Table @TableParams + } + #endregion Friewall Section + } + #endregion ESXi Host Firewall + + #region ESXi Host Authentication + $AuthServices = $VMHost | Get-VMHostAuthentication + if ($AuthServices.DomainMembershipStatus) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Authentication { + $AuthServices = $AuthServices | Select-Object @{L = $LocalizedData.Domain; E = { $_.Domain } }, @{L = $LocalizedData.DomainMembership; E = { $_.DomainMembershipStatus } }, @{L = $LocalizedData.TrustedDomains; E = { $_.TrustedDomains } } + $TableParams = @{ + Name = ($LocalizedData.TableAuthentication -f $VMHost) + ColumnWidths = 25, 25, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $AuthServices | Table @TableParams + } + } + #endregion ESXi Host Authentication + } + #endregion ESXi Host Advanced Detail Information + } + #endregion ESXi Host Security Section + + #region ESXi Host Virtual Machines Advanced Detail Information + if ($InfoLevel.VMHost -ge 4) { + $VMHostVMs = $VMHost | Get-VM | Sort-Object Name + if ($VMHostVMs) { + #region Virtual Machines Section + Section -Style Heading4 $LocalizedData.VMInfoSection { + Paragraph ($LocalizedData.ParagraphVMInfo -f $VMHost) + BlankLine + #region ESXi Host Virtual Machine Information + $VMHostVMInfo = foreach ($VMHostVM in $VMHostVMs) { + $VMHostVMView = $VMHostVM | Get-View + [PSCustomObject]@{ + $LocalizedData.VMName = $VMHostVM.Name + $LocalizedData.VMPowerState = switch ($VMHostVM.PowerState) { + 'PoweredOn' { $LocalizedData.On } + 'PoweredOff' { $LocalizedData.Off } + default { $VMHostVM.PowerState } + } + $LocalizedData.VMIPAddress = if ($VMHostVMView.Guest.IpAddress) { + $VMHostVMView.Guest.IpAddress + } else { + '--' + } + $LocalizedData.VMCPUs = $VMHostVM.NumCpu + #'Cores per Socket' = $VMHostVM.CoresPerSocket + $LocalizedData.VMMemoryGB = Convert-DataSize $VMHostVM.memoryGB -RoundUnits 0 + $LocalizedData.VMProvisioned = Convert-DataSize $VMHostVM.ProvisionedSpaceGB + $LocalizedData.VMUsed = Convert-DataSize $VMHostVM.UsedSpaceGB + $LocalizedData.VMHWVersion = ($VMHostVM.HardwareVersion).Replace('vmx-', 'v') + $LocalizedData.VMToolsStatus = switch ($VMHostVM.ExtensionData.Guest.ToolsStatus) { + 'toolsOld' { $LocalizedData.ToolsOld } + 'toolsOK' { $LocalizedData.ToolsOK } + 'toolsNotRunning' { $LocalizedData.ToolsNotRunning } + 'toolsNotInstalled' { $LocalizedData.ToolsNotInstalled } + default { $VMHostVM.ExtensionData.Guest.ToolsStatus } + } + } + } + if ($Healthcheck.VM.VMToolsStatus) { + $VMHostVMInfo | Where-Object { $_.$($LocalizedData.VMToolsStatus) -ne $LocalizedData.ToolsOK } | Set-Style -Style Warning -Property $LocalizedData.VMToolsStatus + } + if ($Healthcheck.VM.PowerState) { + $VMHostVMInfo | Where-Object { $_.$($LocalizedData.VMPowerState) -ne $LocalizedData.On } | Set-Style -Style Warning -Property $LocalizedData.VMPowerState + } + $TableParams = @{ + Name = ($LocalizedData.TableVMs -f $VMHost) + ColumnWidths = 21, 8, 16, 9, 9, 9, 9, 9, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostVMInfo | Table @TableParams + #endregion ESXi Host Virtual Machine Information + + #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 NOTOCHeading5 -ExcludeFromTOC $LocalizedData.StartupShutdown { + $VMStartPolicies = foreach ($VMStartPol in $VMStartPolicy) { + [PSCustomObject]@{ + $LocalizedData.StartupOrder = $VMStartPol.StartOrder + $LocalizedData.VMName = $VMStartPol.VirtualMachineName + $LocalizedData.StartupEnabled = switch ($VMStartPol.StartAction) { + 'PowerOn' { $LocalizedData.Enabled } + 'None' { $LocalizedData.Disabled } + default { $VMStartPol.StartAction } + } + $LocalizedData.StartupDelay = "$($VMStartPol.StartDelay) seconds" + $LocalizedData.WaitForHeartbeat = if ($VMStartPol.WaitForHeartbeat) { + $LocalizedData.WaitHeartbeat + } else { + $LocalizedData.WaitDelay + } + $LocalizedData.StopAction = switch ($VMStartPol.StopAction) { + 'PowerOff' { $LocalizedData.PowerOff } + 'GuestShutdown' { $LocalizedData.GuestShutdown } + default { $VMStartPol.StopAction } + } + $LocalizedData.StopDelay = "$($VMStartPol.StopDelay) seconds" + } + } + $TableParams = @{ + Name = ($LocalizedData.TableStartupShutdown -f $VMHost) + ColumnWidths = 11, 34, 11, 11, 11, 11, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMStartPolicies | Table @TableParams + } + #endregion VM Startup/Shutdown Section + } + #endregion ESXi Host VM Startup/Shutdown Information + } + #endregion Virtual Machines Section + } + } + #endregion ESXi Host Virtual Machines Advanced Detail Information + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostStorage.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostStorage.ps1 new file mode 100644 index 0000000..6b31e4a --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostStorage.ps1 @@ -0,0 +1,176 @@ +function Get-AbrVSphereVMHostStorage { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost Storage information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHostStorage + } + + process { + try { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region ESXi Host Storage Section + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $VMHost) + + #region ESXi Host Datastore Specifications + $VMHostDatastores = $VMHost | Get-Datastore | Where-Object { ($_.State -eq 'Available') -and ($_.CapacityGB -gt 0) } | Sort-Object Name + if ($VMHostDatastores) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.DatastoreSpecs { + $VMHostDsSpecs = foreach ($VMHostDatastore in $VMHostDatastores) { + + $VMHostDsUsedPercent = if (0 -in @($VMHostDatastore.FreeSpaceGB, $VMHostDatastore.CapacityGB)) { 0 } else { [math]::Round((100 - (($VMHostDatastore.FreeSpaceGB) / ($VMHostDatastore.CapacityGB) * 100)), 2) } + $VMHostDsFreePercent = if (0 -in @($VMHostDatastore.FreeSpaceGB, $VMHostDatastore.CapacityGB)) { 0 } else { [math]::Round(($VMHostDatastore.FreeSpaceGB / $VMHostDatastore.CapacityGB) * 100, 2) } + $VMHostDsUsedCapacityGB = ($VMHostDatastore.CapacityGB) - ($VMHostDatastore.FreeSpaceGB) + + [PSCustomObject]@{ + $LocalizedData.Datastore = $VMHostDatastore.Name + $LocalizedData.DatastoreType = $VMHostDatastore.Type + $LocalizedData.Version = if ($VMHostDatastore.FileSystemVersion) { + $VMHostDatastore.FileSystemVersion + } else { + '--' + } + $LocalizedData.NumberOfVMs = $VMHostDatastore.ExtensionData.VM.Count + $LocalizedData.TotalCapacity = Convert-DataSize $VMHostDatastore.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $VMHostDsUsedCapacityGB), $VMHostDsUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $VMHostDsFreePercent + $LocalizedData.PercentUsed = $VMHostDsUsedPercent + } + } + if ($Healthcheck.Datastore.CapacityUtilization) { + $VMHostDsSpecs | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $VMHostDsSpecs | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + $TableParams = @{ + Name = ($LocalizedData.TableDatastores -f $VMHost) + Columns = $LocalizedData.Datastore, $LocalizedData.DatastoreType, $LocalizedData.Version, $LocalizedData.NumberOfVMs, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + ColumnWidths = 21, 10, 9, 9, 17, 17, 17 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostDsSpecs | Sort-Object $LocalizedData.Datastore | Table @TableParams + } + } + #endregion ESXi Host Datastore Specifications + + #region ESXi Host Storage Adapter Information + $VMHostHbas = $VMHost | Get-VMHostHba | Sort-Object Device + if ($VMHostHbas) { + #region ESXi Host Storage Adapters Section + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.StorageAdapters { + Paragraph ($LocalizedData.ParagraphStorageAdapters -f $VMHost) + 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 NOTOCHeading5 -ExcludeFromTOC "$($VMHostHba.Device)" { + $VMHostStorageAdapter = [PSCustomObject]@{ + $LocalizedData.AdapterName = $VMHostHba.Device + $LocalizedData.AdapterType = switch ($VMHostHba.Type) { + 'FibreChannel' { $LocalizedData.FC } + 'IScsi' { $LocalizedData.iSCSI } + 'ParallelScsi' { $LocalizedData.ParallelSCSI } + default { $TextInfo.ToTitleCase($VMHostHba.Type) } + } + $LocalizedData.AdapterModel = $VMHostHba.Model + $LocalizedData.AdapterStatus = $TextInfo.ToTitleCase($VMHostHba.Status) + $LocalizedData.AdapterTargets = $Target.Count + $LocalizedData.AdapterDevices = $LUNs.Count + $LocalizedData.AdapterPaths = $Paths.Sum + } + $MemberProps = @{ + 'InputObject' = $VMHostStorageAdapter + 'MemberType' = 'NoteProperty' + } + if ($VMHostStorageAdapter.$($LocalizedData.AdapterType) -eq $LocalizedData.iSCSI) { + $iScsiAuthenticationMethod = switch ($VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType) { + 'chapProhibited' { $LocalizedData.ChapNone } + 'chapPreferred' { $LocalizedData.ChapUniPreferred } + 'chapDiscouraged' { $LocalizedData.ChapUniRequired } + 'chapRequired' { + switch ($VMHostHba.ExtensionData.AuthenticationProperties.MutualChapAuthenticationType) { + 'chapProhibited' { $LocalizedData.ChapUnidirectional } + 'chapRequired' { $LocalizedData.ChapBidirectional } + } + } + default { $VMHostHba.ExtensionData.AuthenticationProperties.ChapAuthenticationType } + } + Add-Member @MemberProps -Name $LocalizedData.iSCSIName -Value $VMHostHba.IScsiName + if ($VMHostHba.IScsiAlias) { + Add-Member @MemberProps -Name $LocalizedData.iSCSIAlias -Value $VMHostHba.IScsiAlias + } else { + Add-Member @MemberProps -Name $LocalizedData.iSCSIAlias -Value '--' + } + if ($VMHostHba.CurrentSpeedMb) { + Add-Member @MemberProps -Name $LocalizedData.AdapterSpeed -Value "$($VMHostHba.CurrentSpeedMb) Mb" + } else { + Add-Member @MemberProps -Name $LocalizedData.AdapterSpeed -Value '--' + } + if ($VMHostHba.ExtensionData.ConfiguredSendTarget) { + Add-Member @MemberProps -Name $LocalizedData.DynamicDiscovery -Value (($VMHostHba.ExtensionData.ConfiguredSendTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" }) -join [Environment]::NewLine) + } else { + Add-Member @MemberProps -Name $LocalizedData.DynamicDiscovery -Value '--' + } + if ($VMHostHba.ExtensionData.ConfiguredStaticTarget) { + Add-Member @MemberProps -Name $LocalizedData.StaticDiscovery -Value (($VMHostHba.ExtensionData.ConfiguredStaticTarget | ForEach-Object { "$($_.Address)" + ":" + "$($_.Port)" + " " + "$($_.IScsiName)" }) -join [Environment]::NewLine) + } else { + Add-Member @MemberProps -Name $LocalizedData.StaticDiscovery -Value '--' + } + if ($iScsiAuthenticationMethod -eq $LocalizedData.ChapNone) { + Add-Member @MemberProps -Name $LocalizedData.AuthMethod -Value $iScsiAuthenticationMethod + } elseif ($iScsiAuthenticationMethod -eq $LocalizedData.ChapBidirectional) { + Add-Member @MemberProps -Name $LocalizedData.AuthMethod -Value $iScsiAuthenticationMethod + Add-Member @MemberProps -Name $LocalizedData.CHAPOutgoing -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName + Add-Member @MemberProps -Name $LocalizedData.CHAPIncoming -Value $VMHostHba.ExtensionData.AuthenticationProperties.MutualChapName + } else { + Add-Member @MemberProps -Name $LocalizedData.AuthMethod -Value $iScsiAuthenticationMethod + Add-Member @MemberProps -Name $LocalizedData.CHAPOutgoing -Value $VMHostHba.ExtensionData.AuthenticationProperties.ChapName + } + if ($InfoLevel.VMHost -ge 4) { + Add-Member @MemberProps -Name $LocalizedData.AdvancedOptions -Value (($VMHostHba.ExtensionData.AdvancedOptions | ForEach-Object { "$($_.Key) = $($_.Value)" }) -join [Environment]::NewLine) + } + } + if ($VMHostStorageAdapter.$($LocalizedData.AdapterType) -eq $LocalizedData.FC) { + Add-Member @MemberProps -Name $LocalizedData.NodeWWN -Value (([String]::Format("{0:X}", $VMHostHba.NodeWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") + Add-Member @MemberProps -Name $LocalizedData.PortWWN -Value (([String]::Format("{0:X}", $VMHostHba.PortWorldWideName) -split "(\w{2})" | Where-Object { $_ -ne "" }) -join ":") + Add-Member @MemberProps -Name $LocalizedData.AdapterSpeed -Value $VMHostHba.Speed + } + if ($Healthcheck.VMHost.StorageAdapter) { + $VMHostStorageAdapter | Where-Object { $_.$($LocalizedData.AdapterStatus) -ne $LocalizedData.Online } | Set-Style -Style Warning -Property $LocalizedData.AdapterStatus + $VMHostStorageAdapter | Where-Object { $_.$($LocalizedData.AdapterStatus) -eq $LocalizedData.Offline } | Set-Style -Style Critical -Property $LocalizedData.AdapterStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableStorageAdapter -f $VMHostStorageAdapter.$($LocalizedData.AdapterName), $VMHost) + List = $true + ColumnWidths = 25, 75 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostStorageAdapter | Table @TableParams + } + } + } + #endregion ESXi Host Storage Adapters Section + } + #endregion ESXi Host Storage Adapter Information + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + #endregion ESXi Host Storage Section + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSystem.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSystem.ps1 new file mode 100644 index 0000000..6c7d039 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVMHostSystem.ps1 @@ -0,0 +1,336 @@ +function Get-AbrVSphereVMHostSystem { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere ESXi VMHost System information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVMHostSystem + } + + process { + try { + Write-PScriboMessage -Message $LocalizedData.Collecting + #region ESXi Host System Section + Section -Style Heading4 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $VMHost) + #region ESXi Host Profile Information + if ($VMHost | Get-VMHostProfile) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.HostProfile { + $VMHostProfile = $VMHost | Get-VMHostProfile | Select-Object @{L = $LocalizedData.ProfileName; E = { $_.Name } }, @{L = $LocalizedData.ProfileDescription; E = { $_.Description } } + $TableParams = @{ + Name = ($LocalizedData.TableHostProfile -f $VMHost) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostProfile | Sort-Object $LocalizedData.ProfileName | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.HostProfileError -f $VMHost.Name, $_.Exception.Message) + } + } + #endregion ESXi Host Profile Information + + #region ESXi Host Image Profile Information + if ($UserPrivileges -contains 'Host.Config.Settings') { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.ImageProfile { + $installdate = Get-InstallDate + $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter + $ImageProfile = $esxcli.software.profile.get.Invoke() + $SecurityProfile = [PSCustomObject]@{ + $LocalizedData.ImageName = $ImageProfile.Name + $LocalizedData.ImageVendor = $ImageProfile.Vendor + $LocalizedData.InstallDate = $InstallDate.InstallDate + } + $TableParams = @{ + Name = ($LocalizedData.TableImageProfile -f $VMHost) + ColumnWidths = 50, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SecurityProfile | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.ImageProfileError -f $VMHost.Name, $_.Exception.Message) + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivImageProfile + } + #endregion ESXi Host Image Profile Information + + #region ESXi Host Time Configuration + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.TimeConfiguration { + $VMHostTimeSettings = [PSCustomObject]@{ + $LocalizedData.TimeZone = $VMHost.timezone + $LocalizedData.NTPService = if ((Get-VMHostService -VMHost $VMHost | Where-Object { $_.key -eq 'ntpd' }).Running) { + $LocalizedData.Running + } else { + $LocalizedData.Stopped + } + $LocalizedData.NTPServers = (Get-VMHostNtpServer -VMHost $VMHost | Sort-Object) -join ', ' + } + if ($Healthcheck.VMHost.NTP) { + $VMHostTimeSettings | Where-Object { $_.$($LocalizedData.NTPService) -eq $LocalizedData.Stopped } | Set-Style -Style Critical -Property $LocalizedData.NTPService + } + $TableParams = @{ + Name = ($LocalizedData.TableTimeConfig -f $VMHost) + ColumnWidths = 30, 30, 40 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostTimeSettings | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.TimeConfigError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Time Configuration + + #region ESXi Host VM Swap File Location + try { + $VMHostSwapView = Get-View $VMHost -Property 'config.vmSwapPlacement', 'config.localSwapDatastore' -ErrorAction SilentlyContinue + $SwapPlacement = $VMHostSwapView.Config.VmSwapPlacement + if ($SwapPlacement) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.SwapFileLocation { + $SwapDatastoreRef = $VMHostSwapView.Config.LocalSwapDatastore + $SwapDatastoreName = if ($SwapDatastoreRef -and $SwapPlacement -eq 'hostLocal') { + ($Datastores | Where-Object { $_.ExtensionData.MoRef.Value -eq $SwapDatastoreRef.Value }).Name + } else { + '--' + } + $SwapFileDetail = [PSCustomObject]@{ + $LocalizedData.SwapFilePlacement = switch ($SwapPlacement) { + 'vmDirectory' { $LocalizedData.WithVM } + 'hostLocal' { $LocalizedData.HostLocal } + default { $SwapPlacement } + } + $LocalizedData.SwapDatastore = $SwapDatastoreName + } + $TableParams = @{ + Name = ($LocalizedData.TableSwapFileLocation -f $VMHost) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SwapFileDetail | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.SwapFileLocationError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host VM Swap File Location + + #region ESXi Host Certificate Information + try { + $CertBytes = $VMHost.ExtensionData.Config.Certificate + if ($CertBytes) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.HostCertificate { + $Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new([byte[]]$CertBytes) + $ThumbprintBytes = $Cert.GetCertHash([System.Security.Cryptography.HashAlgorithmName]::SHA256) + $HostCertDetail = [PSCustomObject]@{ + $LocalizedData.CertSubject = $Cert.Subject + $LocalizedData.CertIssuer = $Cert.Issuer + $LocalizedData.CertValidFrom = $Cert.NotBefore.ToLocalTime().ToString() + $LocalizedData.CertValidTo = $Cert.NotAfter.ToLocalTime().ToString() + $LocalizedData.CertThumbprint = [System.BitConverter]::ToString($ThumbprintBytes) -replace '-', ':' + } + $TableParams = @{ + Name = ($LocalizedData.TableHostCertificate -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $HostCertDetail | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.HostCertificateError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Certificate Information + + #region ESXi Host Syslog Configuration + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.Syslog { + $SyslogConfig = $VMHost | Get-VMHostSysLogServer + $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter + $SyslogGlobalConfig = $esxcli.system.syslog.config.get.Invoke() + $SyslogDetail = [PSCustomObject]@{ + $LocalizedData.SyslogHost = if ($SyslogConfig) { ($SyslogConfig.Host | Sort-Object) -join ', ' } else { '--' } + $LocalizedData.SyslogPort = if ($SyslogConfig) { ($SyslogConfig.Port | Select-Object -Unique) -join ', ' } else { '--' } + $LocalizedData.LogDir = $SyslogGlobalConfig.LogDir + $LocalizedData.LogRotations = $SyslogGlobalConfig.DefaultRotation + $LocalizedData.LogSize = $SyslogGlobalConfig.DefaultSize + } + $TableParams = @{ + Name = ($LocalizedData.TableSyslog -f $VMHost) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $SyslogDetail | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.SyslogError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Syslog Configuration + + #region ESXi Update Manager Baseline Information + if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { + if ($VumServer.Name) { + try { + $VMHostPatchBaselines = $VMHost | Get-PatchBaseline + } catch { + Write-PScriboMessage -Message $LocalizedData.VUMBaselineNotAvailable + } + if ($VMHostPatchBaselines) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VUMBaseline { + $VMHostBaselines = foreach ($VMHostBaseline in $VMHostPatchBaselines) { + [PSCustomObject]@{ + $LocalizedData.VUMBaselineName = $VMHostBaseline.Name + $LocalizedData.VUMDescription = $VMHostBaseline.Description + $LocalizedData.VUMBaselineType = $VMHostBaseline.BaselineType + $LocalizedData.VUMTargetType = $VMHostBaseline.TargetType + $LocalizedData.VUMLastUpdate = ($VMHostBaseline.LastUpdateTime).ToLocalTime().ToString() + $LocalizedData.VUMBaselinePatches = $VMHostBaseline.CurrentPatches.Count + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMBaselines -f $VMHost) + ColumnWidths = 25, 25, 10, 10, 20, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostBaselines | Sort-Object $LocalizedData.VUMBaselineName | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.VUMBaselineError -f $VMHost.Name, $_.Exception.Message) + } + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivVUMBaseline + } + #endregion ESXi Update Manager Baseline Information + + #region ESXi Update Manager Compliance Information + if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { + if ($VumServer.Name) { + try { + $VMHostCompliances = $VMHost | Get-Compliance -ErrorAction SilentlyContinue + } catch { + Write-PScriboMessage -Message $LocalizedData.VUMComplianceNotAvailable + } + if ($VMHostCompliances) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VUMCompliance { + $VMHostComplianceInfo = foreach ($VMHostCompliance in $VMHostCompliances) { + [PSCustomObject]@{ + $LocalizedData.VUMBaselineName = $VMHostCompliance.Baseline.Name + $LocalizedData.VUMStatus = switch ($VMHostCompliance.Status) { + 'NotCompliant' { $LocalizedData.NotCompliant } + default { $VMHostCompliance.Status } + } + } + } + if ($Healthcheck.VMHost.VUMCompliance) { + $VMHostComplianceInfo | Where-Object { $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.Unknown } | Set-Style -Style Warning + $VMHostComplianceInfo | Where-Object { $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.NotCompliant -or $_.$($LocalizedData.VUMStatus) -eq $LocalizedData.Incompatible } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMCompliance -f $VMHost) + ColumnWidths = 75, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostComplianceInfo | Sort-Object $LocalizedData.VUMBaselineName | Table @TableParams + } + } catch { + Write-PScriboMessage -Message -Message ($LocalizedData.VUMComplianceError -f $VMHost.Name, $_.Exception.Message) + } + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivVUMCompliance + } + #endregion ESXi Update Manager Compliance Information + + #region ESXi Host Comprehensive Information Section + if ($InfoLevel.VMHost -ge 5) { + #region ESXi Host Advanced System Settings + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.AdvancedSettings { + $AdvSettings = $VMHost | Get-AdvancedSetting | Select-Object @{L = $LocalizedData.Key; E = { $_.Name } }, @{L = $LocalizedData.Value; E = { $_.Value } } + $TableParams = @{ + Name = ($LocalizedData.TableAdvancedSettings -f $VMHost) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $AdvSettings | Sort-Object $LocalizedData.Key | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.AdvancedSettingsError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Advanced System Settings + + #region ESXi Host Software VIBs + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $LocalizedData.VIBs { + $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter + $VMHostVibs = $esxcli.software.vib.list.Invoke() + $VMHostVibs = foreach ($VMHostVib in $VMHostVibs) { + [PSCustomObject]@{ + $LocalizedData.VIBName = $VMHostVib.Name + $LocalizedData.VIBID = $VMHostVib.Id + $LocalizedData.VIBVersion = $VMHostVib.Version + $LocalizedData.VIBAcceptanceLevel = $VMHostVib.AcceptanceLevel + $LocalizedData.VIBCreationDate = $VMHostVib.CreationDate + $LocalizedData.VIBInstallDate = $VMHostVib.InstallDate + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVIBs -f $VMHost) + ColumnWidths = 15, 25, 15, 15, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VMHostVibs | Sort-Object $LocalizedData.VIBInstallDate -Descending | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.VIBsError -f $VMHost.Name, $_.Exception.Message) + } + #endregion ESXi Host Software VIBs + } + #endregion ESXi Host Comprehensive Information Section + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + #endregion ESXi Host System Section + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVUM.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVUM.ps1 new file mode 100644 index 0000000..4e6f526 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSphereVUM.ps1 @@ -0,0 +1,168 @@ +function Get-AbrVSphereVUM { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere VMware Update Manager information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphereVUM + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.VUM) + } + + process { + try { + if (($InfoLevel.VUM -ge 1) -and ($VumServer.Name)) { + Write-PScriboMessage -Message $LocalizedData.Collecting + try { + $VUMBaselines = Get-PatchBaseline -Server $vCenter + } catch { + Write-PScriboMessage -Message $LocalizedData.NotAvailable + } + + # Query software depots (vSphere 7.0+ REST API) + $OnlineDepots = $null + $OfflineDepots = $null + if ($vcApiUri) { + try { + $OnlineDepots = Invoke-RestMethod -Uri "$vcApiUri/esx/settings/depots/online" ` + -Method Get -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.DepotError -f $_.Exception.Message) + } + try { + $OfflineDepots = Invoke-RestMethod -Uri "$vcApiUri/esx/settings/depots/offline" ` + -Method Get -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.DepotError -f $_.Exception.Message) + } + } + + if ($VUMBaselines -or $OnlineDepots -or $OfflineDepots) { + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region VUM Baseline Detailed Information + if ($VUMBaselines) { + Section -Style Heading3 $LocalizedData.Baselines { + $VUMBaselineInfo = foreach ($VUMBaseline in $VUMBaselines) { + [PSCustomObject]@{ + $LocalizedData.BaselineName = $VUMBaseline.Name + $LocalizedData.Description = $VUMBaseline.Description + $LocalizedData.Type = $VUMBaseline.BaselineType + $LocalizedData.TargetType = $VUMBaseline.TargetType + $LocalizedData.LastUpdate = ($VUMBaseline.LastUpdateTime).ToLocalTime().ToString() + $LocalizedData.NumPatches = $VUMBaseline.CurrentPatches.Count + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMBaselines -f $vCenterServerName) + ColumnWidths = 25, 25, 10, 10, 20, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VUMBaselineInfo | Sort-Object $LocalizedData.BaselineName | Table @TableParams + } + } + #endregion VUM Baseline Detailed Information + + #region VUM Comprehensive Information + try { + $VUMPatches = Get-Patch -Server $vCenter | Sort-Object -Descending ReleaseDate + } catch { + Write-PScriboMessage -Message $LocalizedData.PatchNotAvailable + } + if ($VUMPatches -and $InfoLevel.VUM -ge 5) { + Section -Style Heading3 $LocalizedData.Patches { + $VUMPatchInfo = foreach ($VUMPatch in $VUMPatches) { + [PSCustomObject]@{ + $LocalizedData.PatchName = $VUMPatch.Name + $LocalizedData.PatchProduct = ($VUMPatch.Product).Name + $LocalizedData.PatchDescription = $VUMPatch.Description + $LocalizedData.PatchReleaseDate = $VUMPatch.ReleaseDate + $LocalizedData.PatchVendorID = $VUMPatch.IdByVendor + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVUMPatches -f $vCenterServerName) + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VUMPatchInfo | Table @TableParams + } + } + #endregion VUM Comprehensive Information + + #region Software Depots + if ($OnlineDepots -or $OfflineDepots) { + Section -Style Heading3 $LocalizedData.SoftwareDepots { + if ($OnlineDepots) { + Section -Style Heading4 $LocalizedData.OnlineDepots { + $OnlineDepotInfo = foreach ($id in $OnlineDepots.PSObject.Properties.Name) { + $depot = $OnlineDepots.$id + # vSphere 7.x uses 'depot_url'; vSphere 8.x uses 'url' + $depotUrl = if ($depot.url) { $depot.url } ` + elseif ($depot.depot_url) { $depot.depot_url } ` + else { '--' } + [PSCustomObject]@{ + $LocalizedData.Description = $depot.description + $LocalizedData.DepotUrl = $depotUrl + $LocalizedData.SystemDefined = $depot.system_defined + $LocalizedData.DepotEnabled = $depot.enabled + } + } + $TableParams = @{ + Name = ($LocalizedData.TableOnlineDepots -f $vCenterServerName) + ColumnWidths = 30, 40, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OnlineDepotInfo | Sort-Object $LocalizedData.Description | Table @TableParams + } + } + if ($OfflineDepots) { + $OfflineDepotInfo = foreach ($id in $OfflineDepots.PSObject.Properties.Name) { + $depot = $OfflineDepots.$id + # Skip system-generated bundles (HA, WCP, etc.) which have no location + if (-not $depot.location) { continue } + [PSCustomObject]@{ + $LocalizedData.Description = $depot.description + $LocalizedData.DepotLocation = $depot.location + } + } + if ($OfflineDepotInfo) { + if ($OnlineDepots) { BlankLine } + Section -Style Heading4 $LocalizedData.OfflineDepots { + $TableParams = @{ + Name = ($LocalizedData.TableOfflineDepots -f $vCenterServerName) + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OfflineDepotInfo | Sort-Object $LocalizedData.Description | Table @TableParams + } + } + } + } + } + #endregion Software Depots + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevCenter.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevCenter.ps1 new file mode 100644 index 0000000..e148b7a --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevCenter.ps1 @@ -0,0 +1,816 @@ +function Get-AbrVSpherevCenter { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vCenter Server information. + .DESCRIPTION + Documents the configuration of VMware vCenter Server in Word/HTML/Text formats using PScribo. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSpherevCenter + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.vCenter) + } + + process { + try { + if ($InfoLevel.vCenter -ge 1) { + Write-PScriboMessage -Message $LocalizedData.Collecting + Section -Style Heading2 $LocalizedData.SectionHeading { + if ($InfoLevel.vCenter -le 2) { + Paragraph ($LocalizedData.ParagraphSummaryBrief -f $vCenterServerName) + } else { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + } + BlankLine + # Gather basic vCenter Server Information + $vCenterServerInfo = [PSCustomObject]@{ + $LocalizedData.vCenterServer = $vCenterServerName + $LocalizedData.IPAddress = ($vCenterAdvSettings | Where-Object { $_.name -like 'VirtualCenter.AutoManagedIPV4' }).Value + $LocalizedData.Version = $vCenter.Version + $LocalizedData.Build = $vCenter.Build + } + #region vCenter Server Summary & Advanced Summary + if ($InfoLevel.vCenter -le 2) { + $TableParams = @{ + Name = ($LocalizedData.TablevCenterSummary -f $vCenterServerName) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterServerInfo | Table @TableParams + + #region Resource Summary + Section -Style Heading3 $LocalizedData.ResourceSummary { + $totalCpuMhz = ($VMHosts | Measure-Object -Property CpuTotalMhz -Sum).Sum + $usedCpuMhz = ($VMHosts | Measure-Object -Property CpuUsageMhz -Sum).Sum + $freeCpuMhz = $totalCpuMhz - $usedCpuMhz + $totalCpuGHz = [Math]::Round($totalCpuMhz / 1000, 2) + $usedCpuGHz = [Math]::Round($usedCpuMhz / 1000, 2) + $freeCpuGHz = [Math]::Round($freeCpuMhz / 1000, 2) + + $totalMemGB = ($VMHosts | Measure-Object -Property MemoryTotalGB -Sum).Sum + $usedMemGB = ($VMHosts | Measure-Object -Property MemoryUsageGB -Sum).Sum + $freeMemGB = $totalMemGB - $usedMemGB + $totalMem = Convert-DataSize -Size $totalMemGB -InputUnit GB + $usedMem = Convert-DataSize -Size $usedMemGB -InputUnit GB + $freeMem = Convert-DataSize -Size $freeMemGB -InputUnit GB + + $totalStorageGB = ($Datastores | Measure-Object -Property CapacityGB -Sum).Sum + $freeStorageGB = ($Datastores | Measure-Object -Property FreeSpaceGB -Sum).Sum + $usedStorageGB = $totalStorageGB - $freeStorageGB + $totalStorage = Convert-DataSize -Size $totalStorageGB -InputUnit GB + $usedStorage = Convert-DataSize -Size $usedStorageGB -InputUnit GB + $freeStorage = Convert-DataSize -Size $freeStorageGB -InputUnit GB + + $vCenterResourceSummary = @( + [PSCustomObject]@{ + $LocalizedData.SummaryResource = $LocalizedData.CPU + $LocalizedData.Free = "$freeCpuGHz GHz" + $LocalizedData.Used = "$usedCpuGHz GHz" + $LocalizedData.Total = "$totalCpuGHz GHz" + } + [PSCustomObject]@{ + $LocalizedData.SummaryResource = $LocalizedData.Memory + $LocalizedData.Free = $freeMem + $LocalizedData.Used = $usedMem + $LocalizedData.Total = $totalMem + } + [PSCustomObject]@{ + $LocalizedData.SummaryResource = $LocalizedData.Storage + $LocalizedData.Free = $freeStorage + $LocalizedData.Used = $usedStorage + $LocalizedData.Total = $totalStorage + } + ) + $TableParams = @{ + Name = ($LocalizedData.TablevCenterResourceSummary -f $vCenterServerName) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterResourceSummary | Table @TableParams + } # end Section ResourceSummary + + Section -Style Heading3 $LocalizedData.VirtualMachines { + $vmPoweredOn = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOn' }).Count + $vmPoweredOff = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOff' }).Count + $vmSuspended = ($VMs | Where-Object { $_.PowerState -eq 'Suspended' }).Count + $vCenterVMSummary = [PSCustomObject]@{ + $LocalizedData.PoweredOn = $vmPoweredOn + $LocalizedData.PoweredOff = $vmPoweredOff + $LocalizedData.Suspended = $vmSuspended + $LocalizedData.Total = $vmPoweredOn + $vmPoweredOff + $vmSuspended + } + $TableParams = @{ + Name = ($LocalizedData.TablevCenterVMSummary -f $vCenterServerName) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterVMSummary | Table @TableParams + } # end Section VirtualMachines + + Section -Style Heading3 $LocalizedData.Hosts { + $hostsConnected = ($VMHosts | Where-Object { $_.ConnectionState -eq 'Connected' }).Count + $hostsDisconnected = ($VMHosts | Where-Object { $_.ConnectionState -eq 'Disconnected' }).Count + $hostsMaintenance = ($VMHosts | Where-Object { $_.ConnectionState -eq 'Maintenance' }).Count + $vCenterHostSummary = [PSCustomObject]@{ + $LocalizedData.Connected = $hostsConnected + $LocalizedData.Disconnected = $hostsDisconnected + $LocalizedData.Maintenance = $hostsMaintenance + $LocalizedData.Total = $hostsConnected + $hostsDisconnected + $hostsMaintenance + } + $TableParams = @{ + Name = ($LocalizedData.TablevCenterHostSummary -f $vCenterServerName) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterHostSummary | Table @TableParams + } # end Section Hosts + #endregion Resource Summary + } + #endregion vCenter Server Summary & Advanced Summary + + #region vCenter Server Detailed Information + if ($InfoLevel.vCenter -ge 3) { + $MemberProps = @{ + 'InputObject' = $vCenterServerInfo + 'MemberType' = 'NoteProperty' + } + #region vCenter Server Detail + if ($UserPrivileges -contains 'Global.Licenses') { + try { + $vCenterLicense = Get-License -vCenter $vCenter + Add-Member @MemberProps -Name $LocalizedData.Product -Value $vCenterLicense.Product + Add-Member @MemberProps -Name $LocalizedData.LicenseKey -Value $vCenterLicense.LicenseKey + Add-Member @MemberProps -Name $LocalizedData.LicenseExpiration -Value $vCenterLicense.Expiration + } catch { + Write-PScriboMessage -IsWarning $LocalizedData.InsufficientPrivLicense + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivLicense + } + + Add-Member @MemberProps -Name $LocalizedData.InstanceID -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'instance.id' }).Value + + if ($vCenter.Version -ge 6) { + Add-Member @MemberProps -Name $LocalizedData.HTTPPort -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.rhttpproxy.httpport' }).Value + Add-Member @MemberProps -Name $LocalizedData.HTTPSPort -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.rhttpproxy.httpsport' }).Value + Add-Member @MemberProps -Name $LocalizedData.PSC -Value ((($vCenterAdvSettings).Where{ $_.name -eq 'config.vpxd.sso.admin.uri' }).Value).Split('/')[2] + } + if ($VumServer.Name) { + Add-Member @MemberProps -Name $LocalizedData.UpdateManagerServer -Value $VumServer.Name + } + if ($SrmServer.Name) { + Add-Member @MemberProps -Name $LocalizedData.SRMServer -Value $SrmServer.Name + } + if ($NsxtServer.Name) { + Add-Member @MemberProps -Name $LocalizedData.NSXTServer -Value $NsxtServer.Name + } + if ($VxRailMgr.Name) { + Add-Member @MemberProps -Name $LocalizedData.VxRailServer -Value $VxRailMgr.Name + } + if ($Healthcheck.vCenter.Licensing) { + $vCenterServerInfo | Where-Object { $_.$($LocalizedData.Product) -like '*Evaluation*' } | Set-Style -Style Warning -Property $LocalizedData.Product + $vCenterServerInfo | Where-Object { $null -eq $_.$($LocalizedData.Product) } | Set-Style -Style Warning -Property $LocalizedData.Product + $vCenterServerInfo | Where-Object { $_.$($LocalizedData.LicenseKey) -like '*-00000-00000' } | Set-Style -Style Warning -Property $LocalizedData.LicenseKey + $vCenterServerInfo | Where-Object { $_.$($LocalizedData.LicenseExpiration) -eq 'Expired' } | Set-Style -Style Critical -Property $LocalizedData.LicenseExpiration + } + $TableParams = @{ + Name = ($LocalizedData.TablevCenterConfig -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterServerInfo | Table @TableParams + #endregion vCenter Server Detail + + #region vCenter Server Database Settings + Section -Style Heading3 $LocalizedData.DatabaseSettings { + $vCenterDbInfo = [PSCustomObject]@{ + $LocalizedData.DatabaseType = $TextInfo.ToTitleCase(($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.odbc.dbtype' }).Value) + $LocalizedData.DataSourceName = ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.odbc.dsn' }).Value + $LocalizedData.MaxDBConnection = ($vCenterAdvSettings | Where-Object { $_.name -eq 'VirtualCenter.MaxDBConnection' }).Value + } + $TableParams = @{ + Name = ($LocalizedData.TableDatabaseSettings -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterDbInfo | Table @TableParams + } + #endregion vCenter Server Database Settings + + #region vCenter Server Mail Settings + Section -Style Heading3 $LocalizedData.MailSettings { + $vCenterMailInfo = [PSCustomObject]@{ + $LocalizedData.SMTPServer = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.smtp.server' }).Value + $LocalizedData.SMTPPort = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.smtp.port' }).Value + $LocalizedData.MailSender = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.sender' }).Value + } + if ($Healthcheck.vCenter.Mail) { + $vCenterMailInfo | Where-Object { !($_.$($LocalizedData.SMTPServer)) } | Set-Style -Style Critical -Property $LocalizedData.SMTPServer + $vCenterMailInfo | Where-Object { !($_.$($LocalizedData.SMTPPort)) } | Set-Style -Style Critical -Property $LocalizedData.SMTPPort + $vCenterMailInfo | Where-Object { !($_.$($LocalizedData.MailSender)) } | Set-Style -Style Critical -Property $LocalizedData.MailSender + } + $TableParams = @{ + Name = ($LocalizedData.TableMailSettings -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterMailInfo | Table @TableParams + } + #endregion vCenter Server Mail Settings + + #region vCenter Server Backup + Section -Style Heading3 $LocalizedData.BackupSettings { + if (-not $vcApiUri) { + Paragraph $LocalizedData.BackupApiNotAvailable + } else { + #region Backup Schedule + $BackupSchedules = $null + try { + $BackupSchedules = Invoke-RestMethod -Uri "$vcApiUri/appliance/recovery/backup/schedules" -Method Get -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.BackupApiError -f $_.Exception.Message) + } + Section -Style Heading4 $LocalizedData.BackupSchedule { + if ($BackupSchedules -and $BackupSchedules.PSObject.Properties.Name.Count -gt 0) { + $ApplianceTimezone = $null + try { + $ApplianceTimezone = Invoke-RestMethod -Uri "$vcApiUri/appliance/system/time/timezone" -Method Get -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + } catch {} + $BackupScheduleInfo = foreach ($schedId in $BackupSchedules.PSObject.Properties.Name) { + $sched = $BackupSchedules.$schedId + $recurrence = if ($sched.recurrence_info) { + $h = [int]$sched.recurrence_info.hour % 12 + if ($h -eq 0) { $h = 12 } + $ap = if ([int]$sched.recurrence_info.hour -ge 12) { 'P.M.' } else { 'A.M.' } + $timeStr = '{0}:{1:D2} {2}' -f $h, [int]$sched.recurrence_info.minute, $ap + $dayStr = if ($sched.recurrence_info.days -and $sched.recurrence_info.days.Count -gt 0) { + ($sched.recurrence_info.days | ForEach-Object { $TextInfo.ToTitleCase($_.ToLower()) }) -join ', ' + } else { $LocalizedData.BackupDaily } + $tz = if ($ApplianceTimezone) { " $ApplianceTimezone" } else { '' } + "$dayStr, $timeStr$tz" + } else { '--' } + $partsFormatted = ($sched.parts | ForEach-Object { + switch ($_) { + 'supervisors' { $LocalizedData.BackupPartSeat } + 'seat' { $LocalizedData.BackupPartSeat } + 'common' { $LocalizedData.BackupPartCommon } + 'stats' { $LocalizedData.BackupPartStats } + default { $_ } + } + }) -join ', ' + [PSCustomObject]@{ + $LocalizedData.BackupEnabled = if ($sched.enable) { $LocalizedData.BackupActivated } else { $LocalizedData.BackupDeactivated } + $LocalizedData.BackupRecurrence = $recurrence + $LocalizedData.BackupLocation = $sched.location + $LocalizedData.BackupParts = $partsFormatted + $LocalizedData.BackupRetentionCount = $sched.retention_info.max_count + } + } + if ($Healthcheck.vCenter.Backup) { + $BackupScheduleInfo | Where-Object { $_.$($LocalizedData.BackupEnabled) -eq $LocalizedData.BackupDeactivated } | Set-Style -Style Warning -Property $LocalizedData.BackupEnabled + } + $TableParams = @{ + Name = ($LocalizedData.TableBackupSchedule -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $BackupScheduleInfo | Table @TableParams + } else { + Paragraph $LocalizedData.BackupNotConfigured + } + } + #endregion Backup Schedule + + #region Backup Job History + $BackupJobRecords = $null + try { + $jobDetailsResponse = Invoke-RestMethod -Uri "$vcApiUri/appliance/recovery/backup/job/details" -Method Get -Headers $vcApiHeaders -SkipCertificateCheck -ErrorAction Stop + if ($jobDetailsResponse -and $jobDetailsResponse.PSObject.Properties.Name.Count -gt 0) { + $BackupJobRecords = $jobDetailsResponse.PSObject.Properties | + Sort-Object Name -Descending | Select-Object -First 10 | ForEach-Object { + $job = $_.Value + $jobDuration = if ($job.start_time -and $job.end_time) { ([datetime]$job.end_time - [datetime]$job.start_time).TotalSeconds } elseif ($job.duration) { $job.duration } else { $null } + [PSCustomObject]@{ + Location = $job.location + Type = $job.type + State = $job.state ?? $job.status + Size = $job.size + Duration = $jobDuration + Timestamp = $job.end_time + } + } + } + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.BackupApiError -f $_.Exception.Message) + } + Section -Style Heading4 $LocalizedData.BackupJobHistory { + if ($BackupJobRecords -and $BackupJobRecords.Count -gt 0) { + $BackupJobInfo = foreach ($record in $BackupJobRecords) { + $duration = if ($record.Duration) { $ts = [timespan]::FromSeconds($record.Duration); '{0:D2}:{1:D2}:{2:D2}' -f $ts.Hours, $ts.Minutes, $ts.Seconds } else { '--' } + $dataTransferred = if ($record.Size -gt 0) { '{0:N2} GB' -f ($record.Size / 1GB) } else { '--' } + [PSCustomObject]@{ + $LocalizedData.BackupJobLocation = if ($record.Location) { $record.Location } else { '--' } + $LocalizedData.BackupJobType = switch ($record.Type) { + 'SCHEDULED' { $LocalizedData.BackupJobScheduled } + default { if ($record.Type) { $TextInfo.ToTitleCase($record.Type.ToString().ToLower()) } else { '--' } } + } + $LocalizedData.BackupJobStatus = switch ($record.State) { + 'SUCCEEDED' { $LocalizedData.BackupJobComplete } + default { if ($record.State) { $TextInfo.ToTitleCase($record.State.ToString().ToLower()) } else { '--' } } + } + $LocalizedData.BackupJobDataTransferred = $dataTransferred + $LocalizedData.BackupJobDuration = $duration + $LocalizedData.BackupJobEndTime = if ($record.Timestamp) { ([datetime]$record.Timestamp).ToLocalTime().ToString() } else { '--' } + } + } + if ($Healthcheck.vCenter.Backup) { + $BackupJobInfo | Where-Object { $_.$($LocalizedData.BackupJobStatus) -eq 'Failed' } | Set-Style -Style Critical -Property $LocalizedData.BackupJobStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableBackupJobHistory -f $vCenterServerName) + ColumnWidths = 28, 13, 13, 13, 13, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $BackupJobInfo | Table @TableParams + } else { + Paragraph $LocalizedData.BackupNoJobs + } + } + #endregion Backup Job History + } + } + #endregion vCenter Server Backup + + #region vCenter Server Historical Statistics + Section -Style Heading3 $LocalizedData.HistoricalStatistics { + $vCenterHistoricalStats = Get-vCenterStats | Select-Object @{L = $LocalizedData.IntervalDuration; E = { $_.IntervalDuration } }, + @{L = $LocalizedData.IntervalEnabled; E = { $_.IntervalEnabled } }, + @{L = $LocalizedData.SaveDuration; E = { $_.SaveDuration } }, + @{L = $LocalizedData.StatisticsLevel; E = { $_.StatsLevel } } -Unique + $TableParams = @{ + Name = ($LocalizedData.TableHistoricalStatistics -f $vCenterServerName) + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterHistoricalStats | Table @TableParams + } + #endregion vCenter Server Historical Statistics + + #region vCenter Server Licensing + if ($UserPrivileges -contains 'Global.Licenses') { + Section -Style Heading3 $LocalizedData.Licensing { + try { + $Licenses = Get-License -Licenses | Select-Object @{L = $LocalizedData.Product; E = { $_.Product } }, + @{L = $LocalizedData.LicenseKey; E = { ($_.LicenseKey) } }, + @{L = $LocalizedData.Total; E = { $_.Total } }, + @{L = $LocalizedData.Used; E = { $_.Used } }, + @{L = $LocalizedData.Available; E = { ($_.total) - ($_.Used) } }, + @{L = $LocalizedData.Expiration; E = { $_.Expiration } } -Unique + if ($Healthcheck.vCenter.Licensing) { + $Licenses | Where-Object { $_.$($LocalizedData.Product) -eq 'Product Evaluation' } | Set-Style -Style Warning + $Licenses | Where-Object { $_.$($LocalizedData.Expiration) -eq 'Expired' } | Set-Style -Style Critical + } + $TableParams = @{ + Name = ($LocalizedData.TableLicensing -f $vCenterServerName) + ColumnWidths = 25, 25, 12, 12, 12, 14 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $Licenses | Sort-Object $LocalizedData.Product, $LocalizedData.LicenseKey | Table @TableParams + } catch { + Write-PScriboMessage -IsWarning $LocalizedData.InsufficientPrivLicense + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivLicense + } + #endregion vCenter Server Licensing + + #region vCenter Server Certificate + if ($vCenter.Version -ge 6) { + Section -Style Heading3 $LocalizedData.Certificate { + try { + $SslCallback = [System.Net.Security.RemoteCertificateValidationCallback]{ + param($sender, $cert, $chain, $errors) $true + } + $TcpClient = New-Object -TypeName System.Net.Sockets.TcpClient -ArgumentList ($vCenterServerName, 443) + $SslStream = New-Object -TypeName System.Net.Security.SslStream -ArgumentList ( + $TcpClient.GetStream(), $false, $SslCallback + ) + $SslStream.AuthenticateAsClient($vCenterServerName) + $VIMachineCert = [System.Security.Cryptography.X509Certificates.X509Certificate2]$SslStream.RemoteCertificate + $SslStream.Dispose() + $TcpClient.Dispose() + $SoftThresholdDays = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.softThreshold' }).Value + $HardThresholdDays = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.hardThreshold' }).Value + $DaysRemaining = ($VIMachineCert.NotAfter - (Get-Date)).Days + $CertificateStatus = if ($DaysRemaining -le 0) { + 'EXPIRED' + } elseif ($null -ne $HardThresholdDays -and $DaysRemaining -le [int]$HardThresholdDays) { + 'EXPIRING' + } elseif ($null -ne $SoftThresholdDays -and $DaysRemaining -le [int]$SoftThresholdDays) { + 'EXPIRING_SOON' + } else { + 'VALID' + } + $VcenterCertMgmt = [PSCustomObject]@{ + $LocalizedData.Subject = $VIMachineCert.Subject + $LocalizedData.Issuer = $VIMachineCert.Issuer + $LocalizedData.ValidFrom = $VIMachineCert.NotBefore.ToString() + $LocalizedData.ValidTo = $VIMachineCert.NotAfter.ToString() + $LocalizedData.Thumbprint = $VIMachineCert.Thumbprint + $LocalizedData.CertStatus = $CertificateStatus + $LocalizedData.Mode = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.mode' }).Value + $LocalizedData.SoftThreshold = "$(($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.softThreshold' }).Value) days" + $LocalizedData.HardThreshold = "$(($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.hardThreshold' }).Value) days" + $LocalizedData.MinutesBefore = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.minutesBefore' }).Value + $LocalizedData.PollInterval = "$(($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.pollIntervalDays' }).Value) days" + } + if ($Healthcheck.vCenter.Certificate) { + $VcenterCertMgmt | Where-Object { $_.$($LocalizedData.CertStatus) -in @('EXPIRED', 'EXPIRING') } | Set-Style -Style Critical -Property $LocalizedData.CertStatus + $VcenterCertMgmt | Where-Object { $_.$($LocalizedData.CertStatus) -eq 'EXPIRING_SOON' } | Set-Style -Style Warning -Property $LocalizedData.CertStatus + } + $TableParams = @{ + Name = ($LocalizedData.TableCertificate -f $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VcenterCertMgmt | Table @TableParams + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.InsufficientPrivCertificate -f $_.Exception.Message) + } + } + } + #endregion vCenter Server Certificate + + #region vCenter Server Roles + if ($Options.ShowRoles) { + Section -Style Heading3 $LocalizedData.Roles { + $VIRoles = Get-VIRole -Server $vCenter | Where-Object { $null -ne $_.PrivilegeList } | Sort-Object Name + $VIRoleInfo = foreach ($VIRole in $VIRoles) { + [PSCustomObject]@{ + $LocalizedData.Role = $VIRole.Name + $LocalizedData.SystemRole = if ($VIRole.IsSystem) { $LocalizedData.Yes } else { $LocalizedData.No } + $LocalizedData.PrivilegeList = ($VIRole.PrivilegeList).Replace(".", " > ") | Select-Object -Unique + } + } + if ($InfoLevel.vCenter -ge 4) { + $VIRoleInfo | ForEach-Object { + Section -Style NOTOCHeading5 -ExcludeFromTOC $_.$($LocalizedData.Role) { + $TableParams = @{ + Name = ($LocalizedData.TableRole -f $_.$($LocalizedData.Role), $vCenterServerName) + ColumnWidths = 35, 15, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $_ | Table @TableParams + } + } + } else { + $TableParams = @{ + Name = ($LocalizedData.TableRoles -f $vCenterServerName) + Columns = $LocalizedData.Role, $LocalizedData.SystemRole + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VIRoleInfo | Table @TableParams + } + } + } # end if ShowRoles + #endregion vCenter Server Roles + + #region vCenter Server Tags + if ($Options.ShowTags -and $Tags) { + Section -Style Heading3 $LocalizedData.Tags { + $TagInfo = foreach ($Tag in $Tags) { + [PSCustomObject]@{ + $LocalizedData.TagName = $Tag.Name + $LocalizedData.TagDescription = if ($Tag.Description) { $Tag.Description } else { $LocalizedData.None } + $LocalizedData.TagCategory = if ($Tag.Category) { $Tag.Category } else { $LocalizedData.None } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableTags -f $vCenterServerName) + ColumnWidths = 30, 40, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $TagInfo | Table @TableParams + } + } + #endregion vCenter Server Tags + + #region vCenter Server Tag Categories + if ($Options.ShowTags -and $TagCategories) { + Section -Style Heading3 $LocalizedData.TagCategories { + $TagCategoryInfo = foreach ($TagCategory in $TagCategories) { + [PSCustomObject]@{ + $LocalizedData.TagCategory = if ($TagCategory.Name) { $TagCategory.Name } else { $LocalizedData.None } + $LocalizedData.TagDescription = if ($TagCategory.Description) { $TagCategory.Description } else { $LocalizedData.None } + $LocalizedData.TagCardinality = if ($TagCategory.Cardinality) { $TagCategory.Cardinality } else { $LocalizedData.None } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableTagCategories -f $vCenterServerName) + ColumnWidths = 30, 40, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $TagCategoryInfo | Table @TableParams + } + } + #endregion vCenter Server Tag Categories + + #region vCenter Server Tag Assignments + if ($Options.ShowTags -and $TagAssignments) { + Section -Style Heading3 $LocalizedData.TagAssignments { + $TagAssignmentInfo = foreach ($TagAssignment in $TagAssignments) { + [PSCustomObject]@{ + $LocalizedData.TagEntity = $TagAssignment.Entity.Name + $LocalizedData.TagName = $TagAssignment.Tag.Name + $LocalizedData.TagCategory = $TagAssignment.Tag.Category + } + } + $TableParams = @{ + Name = ($LocalizedData.TableTagAssignments -f $vCenterServerName) + ColumnWidths = 30, 40, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $TagAssignmentInfo | Sort-Object $LocalizedData.TagEntity | Table @TableParams + } + } + #endregion vCenter Server Tag Assignments + + #region VM Storage Policies + if ($UserPrivileges -contains 'StorageProfile.View') { + $SpbmStoragePolicies = Get-SpbmStoragePolicy | Sort-Object Name + if ($SpbmStoragePolicies) { + Section -Style Heading3 $LocalizedData.VMStoragePolicies { + $VmStoragePolicies = foreach ($SpbmStoragePolicy in $SpbmStoragePolicies) { + [PSCustomObject]@{ + $LocalizedData.StoragePolicy = $SpbmStoragePolicy.Name + $LocalizedData.Description = $SpbmStoragePolicy.Description + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVMStoragePolicies -f $vCenterServerName) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VmStoragePolicies | Table @TableParams + } + } + } else { + Write-PScriboMessage -Message $LocalizedData.InsufficientPrivStoragePolicy + } + #endregion VM Storage Policies + + #region Content Libraries + $ContentLibraries = $null + try { + $ContentLibraries = Get-ContentLibrary -Server $vCenter -ErrorAction Stop | Sort-Object Name + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.ContentLibraryError -f $_.Exception.Message) + } + if ($ContentLibraries) { + Write-PScriboMessage -Message $LocalizedData.CollectingContentLibrary + Section -Style Heading3 $LocalizedData.ContentLibraries { + if ($InfoLevel.vCenter -eq 3) { + $LibrarySummaryInfo = foreach ($Library in $ContentLibraries) { + $LibItems = $null + try { $LibItems = Get-ContentLibraryItem -ContentLibrary $Library -ErrorAction Stop } catch {} + [PSCustomObject]@{ + $LocalizedData.ContentLibrary = $Library.Name + $LocalizedData.LibraryType = if ($Library.Type -eq 'Local') { $LocalizedData.LibraryLocal } else { $LocalizedData.LibrarySubscribed } + $LocalizedData.Datastore = if ($Library.Datastore) { $Library.Datastore.Name } else { '--' } + $LocalizedData.ItemCount = if ($LibItems) { $LibItems.Count } else { 0 } + $LocalizedData.Description = if ($Library.Description) { $Library.Description } else { $LocalizedData.None } + } + } + if ($Healthcheck.vCenter.ContentLibrary) { + foreach ($Library in $ContentLibraries) { + if ($Library.Type -ne 'Local' -and -not $Library.AutomaticSync) { + $LibrarySummaryInfo | Where-Object { $_.$($LocalizedData.ContentLibrary) -eq $Library.Name } | + Set-Style -Style Warning -Property $LocalizedData.LibraryType + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableContentLibraries -f $vCenterServerName) + ColumnWidths = 25, 15, 20, 10, 30 + } + if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } + $LibrarySummaryInfo | Table @TableParams + } + if ($InfoLevel.vCenter -ge 4) { + foreach ($Library in $ContentLibraries) { + Section -Style Heading4 $Library.Name { + $LibItems = $null + try { + $LibItems = Get-ContentLibraryItem -ContentLibrary $Library -ErrorAction Stop | Sort-Object Name + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.ContentLibraryItemError -f $Library.Name, $_.Exception.Message) + } + $LibDetailObj = [PSCustomObject]@{ + $LocalizedData.ContentLibrary = $Library.Name + $LocalizedData.LibraryType = if ($Library.Type -eq 'Local') { $LocalizedData.LibraryLocal } else { $LocalizedData.LibrarySubscribed } + $LocalizedData.Datastore = if ($Library.Datastore) { $Library.Datastore.Name } else { '--' } + $LocalizedData.ItemCount = if ($LibItems) { $LibItems.Count } else { 0 } + $LocalizedData.Description = if ($Library.Description) { $Library.Description } else { $LocalizedData.None } + $LocalizedData.CreationTime = if ($Library.CreateDate) { $Library.CreateDate.ToString() } else { '--' } + $LocalizedData.LastModified = if ($Library.UpdateDate) { $Library.UpdateDate.ToString() } else { '--' } + } + if ($Library.Type -ne 'Local') { + $MemberProps = @{ InputObject = $LibDetailObj; MemberType = 'NoteProperty' } + Add-Member @MemberProps -Name $LocalizedData.SubscriptionUrl -Value $(if ($Library.SubscriptionUri) { $Library.SubscriptionUri } else { '--' }) + Add-Member @MemberProps -Name $LocalizedData.AutomaticSync -Value $(if ($Library.AutomaticSync) { $LocalizedData.Enabled } else { $LocalizedData.Disabled }) + Add-Member @MemberProps -Name $LocalizedData.OnDemandSync -Value $(if ($Library.DownloadContentOnDemand) { $LocalizedData.Enabled } else { $LocalizedData.Disabled }) + } + if ($Healthcheck.vCenter.ContentLibrary) { + $LibDetailObj | Where-Object { $_.$($LocalizedData.AutomaticSync) -eq $LocalizedData.Disabled } | + Set-Style -Style Warning -Property $LocalizedData.AutomaticSync + } + $TableParams = @{ + Name = ($LocalizedData.TableContentLibrary -f $Library.Name, $vCenterServerName) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } + $LibDetailObj | Table @TableParams + + if ($LibItems) { + $ItemsInfo = foreach ($Item in $LibItems) { + $itemSize = if ($Item.SizeGB -gt 0) { Convert-DataSize -Size $Item.SizeGB -InputUnit GB } else { '--' } + [PSCustomObject]@{ + $LocalizedData.ItemName = $Item.Name + $LocalizedData.ContentType = if ($Item.ItemType) { $Item.ItemType } else { '--' } + $LocalizedData.ItemSize = $itemSize + $LocalizedData.Description = if ($Item.Description) { $Item.Description } else { $LocalizedData.None } + $LocalizedData.CreationTime = if ($Item.CreationTime) { $Item.CreationTime.ToString() } else { '--' } + $LocalizedData.LastModified = if ($Item.LastWriteTime) { $Item.LastWriteTime.ToString() } else { '--' } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableLibraryItems -f $Library.Name) + ColumnWidths = 25, 13, 13, 21, 14, 14 + } + if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } + $ItemsInfo | Table @TableParams + } else { + Paragraph $LocalizedData.ContentLibraryNoItems + } + } + } + } + } + } + #endregion Content Libraries + } + #endregion vCenter Server Detailed Information + + #region vCenter Server Advanced Detail Information + if ($InfoLevel.vCenter -ge 4) { + #region vCenter Alarms + if ($Options.ShowAlarms) { + Section -Style Heading3 $LocalizedData.Alarms { + $Alarms = Get-AlarmDefinition -PipelineVariable alarm | ForEach-Object -Process { + Get-AlarmAction -AlarmDefinition $_ -PipelineVariable action | ForEach-Object -Process { + Get-AlarmActionTrigger -AlarmAction $_ | + Select-Object @{N = $LocalizedData.Alarm; E = { $alarm.Name } }, + @{N = $LocalizedData.AlarmDescription; E = { $alarm.Description } }, + @{N = $LocalizedData.AlarmEnabled; E = { if ($alarm.Enabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } }, + @{N = $LocalizedData.TagEntityType; E = { $alarm.Entity.Type } }, + @{N = $LocalizedData.AlarmTriggered; E = { + "{0}:{1}->{2} (Repeat={3})" -f $action.ActionType, + $_.StartStatus, + $_.EndStatus, + $_.Repeat + } + }, + @{N = $LocalizedData.AlarmAction; E = { switch ($action.ActionType) { + 'SendEmail' { + "To: $($action.To -join ', ') ` + Cc: $($action.Cc -join ', ') ` + Subject: $($action.Subject) ` + Body: $($action.Body)" + } + 'ExecuteScript' { + "$($action.ScriptFilePath)" + } + default { '--' } + } + } + } + } + } + $Alarms = ($Alarms).Where{ $_.$($LocalizedData.Alarm) -ne "" } | Sort-Object $LocalizedData.Alarm, $LocalizedData.AlarmTriggered + if ($Healthcheck.vCenter.Alarms) { + $Alarms | Where-Object { $_.$($LocalizedData.AlarmEnabled) -eq $LocalizedData.Disabled } | Set-Style -Style Warning -Property $LocalizedData.AlarmEnabled + } + if ($InfoLevel.vCenter -ge 5) { + foreach ($Alarm in $Alarms) { + Section -Style NOTOCHeading5 -ExcludeFromTOC $Alarm.$($LocalizedData.Alarm) { + $TableParams = @{ + Name = ($LocalizedData.TableAlarm -f $Alarm.$($LocalizedData.Alarm), $vCenterServerName) + List = $true + ColumnWidths = 25, 75 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $Alarm | Table @TableParams + } + } + } else { + $TableParams = @{ + Name = ($LocalizedData.TableAlarms -f $vCenterServerName) + Columns = $LocalizedData.Alarm, $LocalizedData.AlarmDescription, $LocalizedData.AlarmEnabled, $LocalizedData.TagEntityType, $LocalizedData.AlarmTriggered + ColumnWidths = 20, 20, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $Alarms | Table @TableParams + } + } + } # end if ShowAlarms + #endregion vCenter Alarms + } + #endregion vCenter Server Advanced Detail Information + + #region vCenter Server Comprehensive Information + if ($InfoLevel.vCenter -ge 5) { + #region vCenter Advanced System Settings + Section -Style Heading3 $LocalizedData.AdvancedSystemSettings { + $TableParams = @{ + Name = ($LocalizedData.TableAdvancedSystemSettings -f $vCenterServerName) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vCenterAdvSettings | + Select-Object @{L = $LocalizedData.Key; E = { $_.Name } }, + @{L = $LocalizedData.Value; E = { $_.Value } } | + Sort-Object $LocalizedData.Key | Table @TableParams + } + #endregion vCenter Advanced System Settings + } + #endregion vCenter Server Comprehensive Information + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevSAN.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevSAN.ps1 new file mode 100644 index 0000000..f26c3d3 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-AbrVSpherevSAN.ps1 @@ -0,0 +1,591 @@ +function Get-AbrVSpherevSAN { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere vSAN information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSpherevSAN + Write-PScriboMessage -Message ($LocalizedData.InfoLevel -f $InfoLevel.vSAN) + } + + process { + try { + if (($InfoLevel.vSAN -ge 1) -and ($vCenter.Version -gt 6)) { + Write-PScriboMessage -Message $LocalizedData.Collecting + $VsanClusters = Get-VsanClusterConfiguration -Server $vCenter | Where-Object { $_.vsanenabled -eq $true } | Sort-Object Name + if ($VsanClusters) { + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + #region vSAN Cluster Advanced Summary + if ($InfoLevel.vSAN -le 2) { + BlankLine + $VsanClusterInfo = foreach ($VsanCluster in $VsanClusters) { + [PSCustomObject]@{ + $LocalizedData.Cluster = $VsanCluster.Name + $LocalizedData.StorageType = if ($VsanCluster.VsanEsaEnabled) { + 'ESA' + } else { + 'OSA' + } + $LocalizedData.NumHosts = $VsanCluster.Cluster.ExtensionData.Host.Count + $LocalizedData.Stretched = if ($VsanCluster.StretchedClusterEnabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Deduplication = if ($VsanCluster.SpaceEfficiencyEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Encryption = if ($VsanCluster.EncryptionEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSANClusterSummary -f $vCenterServerName) + ColumnWidths = 25, 15, 15, 15, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanClusterInfo | Table @TableParams + } + #endregion vSAN Cluster Advanced Summary + + #region vSAN Cluster Detailed Information + if ($InfoLevel.vSAN -ge 3) { + foreach ($VsanCluster in $VsanClusters) { + $VsanSpaceUsage = Get-VsanSpaceUsage -Cluster $VsanCluster.Name + $VsanUsedCapacity = $VsanSpaceUsage.CapacityGB - $VsanSpaceUsage.FreeSpaceGB + + # Calculate percentages + $VsanUsedPercent = if (0 -in @($VsanUsedCapacity, $VsanSpaceUsage.CapacityGB)) { 0 } else { [math]::Round(($VsanUsedCapacity / $VsanSpaceUsage.CapacityGB) * 100, 2) } + $VsanFreePercent = if (0 -in @($VsanUsedCapacity, $VsanSpaceUsage.CapacityGB)) { 0 } else { [math]::Round(($VsanSpaceUsage.FreeSpaceGB / $VsanSpaceUsage.CapacityGB) * 100, 2) } + + #region vSAN Cluster Section + Section -Style Heading3 $VsanCluster.Name { + if ($VsanCluster.VsanEsaEnabled) { + Write-PScriboMessage -Message ($LocalizedData.CollectingESA -f $VsanCluster.Name) + try { + $VsanStoragePoolDisk = Get-VsanStoragePoolDisk -Cluster $VsanCluster.Cluster + $VsanDiskFormat = $VsanStoragePoolDisk.DiskFormatVersion | Select-Object -First 1 -Unique + $VsanClusterDetail = [PSCustomObject]@{ + $LocalizedData.Cluster = $VsanCluster.Name + $LocalizedData.ID = $VsanCluster.Id + $LocalizedData.StorageType = if ($VsanCluster.VsanEsaEnabled) { + 'ESA' + } else { + 'OSA' + } + $LocalizedData.Stretched = if ($VsanCluster.StretchedClusterEnabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.NumberOfHosts = $VsanCluster.Cluster.ExtensionData.Host.Count + $LocalizedData.NumberOfDisks = $VsanStoragePoolDisk.Count + $LocalizedData.DiskClaimMode = $VsanCluster.VsanDiskClaimMode + $LocalizedData.DisksFormat = $VsanDiskFormat + $LocalizedData.PerformanceService = if ($VsanCluster.PerformanceServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.FileService = if ($VsanCluster.FileServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.iSCSITargetService = if ($VsanCluster.IscsiTargetServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Deduplication = if ($VsanCluster.SpaceEfficiencyEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Encryption = if ($VsanCluster.EncryptionEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.HistoricalHealthService = if ($VsanCluster.HistoricalHealthEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.HealthCheck = if ($VsanCluster.HealthCheckEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.TotalCapacity = Convert-DataSize $VsanSpaceUsage.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $VsanUsedCapacity), $VsanUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $VsanSpaceUsage.FreeSpaceGB), $VsanFreePercent + $LocalizedData.PercentUsed = $VsanUsedPercent + $LocalizedData.HCLLastUpdated = ($VsanCluster.TimeOfHclUpdate).ToLocalTime().ToString() + } + if ($Healthcheck.vSAN.CapacityUtilization) { + $VsanClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $VsanClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and + $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + if ($InfoLevel.vSAN -ge 4) { + $VsanClusterDetail | Add-Member -MemberType NoteProperty -Name $LocalizedData.Hosts -Value (($VsanStoragePoolDisk.Host | Select-Object -Unique | Sort-Object Name) -join ', ') + } + $TableParams = @{ + Name = ($LocalizedData.TableVSANConfiguration -f $VsanCluster.Name) + List = $true + Columns = $LocalizedData.Cluster, $LocalizedData.ID, $LocalizedData.StorageType, $LocalizedData.Stretched, $LocalizedData.NumberOfHosts, $LocalizedData.NumberOfDisks, $LocalizedData.DiskClaimMode, $LocalizedData.DisksFormat, $LocalizedData.PerformanceService, $LocalizedData.FileService, $LocalizedData.iSCSITargetService, $LocalizedData.Deduplication, $LocalizedData.Encryption, $LocalizedData.HistoricalHealthService, $LocalizedData.HealthCheck, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity, $LocalizedData.HCLLastUpdated + ColumnWidths = 40, 60 + } + if ($InfoLevel.vSAN -ge 4) { + $TableParams['Columns'] += $LocalizedData.Hosts + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanClusterDetail | Table @TableParams + } catch { + Write-PScriboMessage -Message ($LocalizedData.ESAError -f $VsanCluster.Name, $_.Exception.Message) + } + + #region vSAN Services + try { + Section -Style Heading4 $LocalizedData.ServicesSection { + $VsanServices = @( + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.PerformanceService; $LocalizedData.Status = if ($VsanCluster.PerformanceServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.FileService; $LocalizedData.Status = if ($VsanCluster.FileServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.iSCSITargetService; $LocalizedData.Status = if ($VsanCluster.IscsiTargetServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.Deduplication; $LocalizedData.Status = if ($VsanCluster.SpaceEfficiencyEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.Encryption; $LocalizedData.Status = if ($VsanCluster.EncryptionEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.HistoricalHealthService; $LocalizedData.Status = if ($VsanCluster.HistoricalHealthEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.HealthCheck; $LocalizedData.Status = if ($VsanCluster.HealthCheckEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + ) + $TableParams = @{ + Name = ($LocalizedData.TableVSANServices -f $VsanCluster.Name) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanServices | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.ServicesError -f $VsanCluster.Name, $_.Exception.Message) + } + #endregion vSAN Services + + if ($VsanStoragePoolDisk) { + Write-PScriboMessage -Message ($LocalizedData.CollectingDisks -f $VsanCluster.Name) + try { + Section -Style Heading4 $LocalizedData.DisksSection { + $vDisks = foreach ($Disk in $VsanStoragePoolDisk) { + [PSCustomObject]@{ + $LocalizedData.DiskName = $Disk.Name + $LocalizedData.Name = $Disk.ExtensionData.DisplayName + $LocalizedData.DriveType = if ($Disk.IsSsd) { + $LocalizedData.Flash + } else { + $LocalizedData.HDD + } + $LocalizedData.Host = $Disk.Host.Name + $LocalizedData.State = if ($Disk.IsMounted) { + $LocalizedData.Mounted + } else { + $LocalizedData.Unmounted + } + $LocalizedData.Encrypted = if ($Disk.IsEncryped) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.Capacity = Convert-DataSize $Disk.CapacityGB + $LocalizedData.SerialNumber = $Disk.ExtensionData.SerialNumber + $LocalizedData.Vendor = $Disk.ExtensionData.Vendor + $LocalizedData.Model = $Disk.ExtensionData.Model + $LocalizedData.DiskType = $Disk.DiskType + $LocalizedData.DiskFormatVersion = $Disk.DiskFormatVersion + } + } + + if ($InfoLevel.vSAN -ge 4) { + $vDisks | Sort-Object $LocalizedData.Host | ForEach-Object { + $vDisk = $_ + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($vDisk.$($LocalizedData.Name)) - $($vDisk.$($LocalizedData.Host))" { + $TableParams = @{ + Name = ($LocalizedData.TableDisk -f $vDisk.$($LocalizedData.Name), $vDisk.$($LocalizedData.Host)) + List = $true + Columns = $LocalizedData.Name, $LocalizedData.State, $LocalizedData.DriveType, $LocalizedData.Encrypted, $LocalizedData.Capacity, $LocalizedData.Host, $LocalizedData.SerialNumber, $LocalizedData.Vendor, $LocalizedData.Model, $LocalizedData.DiskFormatVersion, $LocalizedData.DiskType + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vDisk | Table @TableParams + } + } + } else { + $TableParams = @{ + Name = ($LocalizedData.TableVSANDisks -f $VsanCluster.Name) + Columns = $LocalizedData.DiskName, $LocalizedData.Capacity, $LocalizedData.State, $LocalizedData.Host + ColumnWidths = 40, 15, 15, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vDisks | Sort-Object $LocalizedData.Host | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.DiskError -f $VsanCluster.Name, $_.Exception.Message) + } + } + } else { + try { + Write-PScriboMessage -Message ($LocalizedData.CollectingOSA -f $VsanCluster.Name) + # Get vSAN Disk Groups + $VsanDiskGroup = Get-VsanDiskGroup -Cluster $VsanCluster.Cluster + $NumVsanDiskGroup = $VsanDiskGroup.Count + # Get vSAN Disks (guard against null disk groups — e.g. unclaimed OSA cluster) + if ($VsanDiskGroup) { + $VsanDisk = Get-VsanDisk -VsanDiskGroup $VsanDiskGroup + } + $VsanDiskFormat = $VsanDisk.DiskFormatVersion | Select-Object -Unique + # Count SSDs and HDDs + $NumVsanSsd = ($VsanDisk | Where-Object { $_.IsSsd -eq $true } | Measure-Object).Count + $NumVsanHdd = ($VsanDisk | Where-Object { $_.IsSsd -eq $false } | Measure-Object).Count + # Determine Storage Type + $VsanClusterType = if ($NumVsanHdd -gt 0) { $LocalizedData.HybridMode } else { $LocalizedData.AllFlash } + $VsanClusterDetail = [PSCustomObject]@{ + $LocalizedData.Cluster = $VsanCluster.Name + $LocalizedData.ID = $VsanCluster.Id + $LocalizedData.StorageType = if ($VsanCluster.VsanEsaEnabled) { + 'ESA' + } else { + 'OSA' + } + $LocalizedData.ClusterType = $VsanClusterType + $LocalizedData.Stretched = if ($VsanCluster.StretchedClusterEnabled) { + $LocalizedData.Yes + } else { + $LocalizedData.No + } + $LocalizedData.NumberOfHosts = $VsanCluster.Cluster.ExtensionData.Host.Count + $LocalizedData.NumberOfDisks = $NumVsanSsd + $NumVsanHdd + $LocalizedData.NumberOfDiskGroups = $NumVsanDiskGroup + $LocalizedData.DiskClaimMode = $VsanCluster.VsanDiskClaimMode + $LocalizedData.DisksFormat = $VsanDiskFormat + $LocalizedData.PerformanceService = if ($VsanCluster.PerformanceServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.FileService = if ($VsanCluster.FileServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.iSCSITargetService = if ($VsanCluster.IscsiTargetServiceEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Deduplication = if ($VsanCluster.SpaceEfficiencyEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.Encryption = if ($VsanCluster.EncryptionEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.HistoricalHealthService = if ($VsanCluster.HistoricalHealthEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.HealthCheck = if ($VsanCluster.HealthCheckEnabled) { + $LocalizedData.Enabled + } else { + $LocalizedData.Disabled + } + $LocalizedData.TotalCapacity = Convert-DataSize $VsanSpaceUsage.CapacityGB + $LocalizedData.UsedCapacity = "{0} ({1}%)" -f (Convert-DataSize $VsanUsedCapacity), $VsanUsedPercent + $LocalizedData.FreeCapacity = "{0} ({1}%)" -f (Convert-DataSize $VsanSpaceUsage.FreeSpaceGB), $VsanFreePercent + $LocalizedData.PercentUsed = $VsanUsedPercent + $LocalizedData.HCLLastUpdated = ($VsanCluster.TimeOfHclUpdate).ToLocalTime().ToString() + } + if ($Healthcheck.vSAN.CapacityUtilization) { + $VsanClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 90 } | Set-Style -Style Critical -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + $VsanClusterDetail | Where-Object { $_.$($LocalizedData.PercentUsed) -ge 75 -and + $_.$($LocalizedData.PercentUsed) -lt 90 } | Set-Style -Style Warning -Property $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity + } + if ($InfoLevel.vSAN -ge 4) { + $VsanClusterDetail | Add-Member -MemberType NoteProperty -Name $LocalizedData.Hosts -Value (($VsanDiskGroup.VMHost | Select-Object -Unique | Sort-Object Name) -join ', ') + } + $TableParams = @{ + Name = ($LocalizedData.TableVSANConfiguration -f $VsanCluster.Name) + List = $true + Columns = $LocalizedData.Cluster, $LocalizedData.ID, $LocalizedData.StorageType, $LocalizedData.ClusterType, $LocalizedData.Stretched, $LocalizedData.NumberOfHosts, $LocalizedData.NumberOfDisks, $LocalizedData.NumberOfDiskGroups, $LocalizedData.DiskClaimMode, $LocalizedData.DisksFormat, $LocalizedData.PerformanceService, $LocalizedData.FileService, $LocalizedData.iSCSITargetService, $LocalizedData.Deduplication, $LocalizedData.Encryption, $LocalizedData.HistoricalHealthService, $LocalizedData.HealthCheck, $LocalizedData.TotalCapacity, $LocalizedData.UsedCapacity, $LocalizedData.FreeCapacity, $LocalizedData.HCLLastUpdated + ColumnWidths = 40, 60 + } + if ($InfoLevel.vSAN -ge 4) { + $TableParams['Columns'] += $LocalizedData.Hosts + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanClusterDetail | Table @TableParams + } catch { + Write-PScriboMessage -Message ($LocalizedData.OSAError -f $VsanCluster.Name, $_.Exception.Message) + } + + #region vSAN Services + try { + Section -Style Heading4 $LocalizedData.ServicesSection { + $VsanServices = @( + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.PerformanceService; $LocalizedData.Status = if ($VsanCluster.PerformanceServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.FileService; $LocalizedData.Status = if ($VsanCluster.FileServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.iSCSITargetService; $LocalizedData.Status = if ($VsanCluster.IscsiTargetServiceEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.Deduplication; $LocalizedData.Status = if ($VsanCluster.SpaceEfficiencyEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.Encryption; $LocalizedData.Status = if ($VsanCluster.EncryptionEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.HistoricalHealthService; $LocalizedData.Status = if ($VsanCluster.HistoricalHealthEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + [PSCustomObject]@{ $LocalizedData.Service = $LocalizedData.HealthCheck; $LocalizedData.Status = if ($VsanCluster.HealthCheckEnabled) { $LocalizedData.Enabled } else { $LocalizedData.Disabled } } + ) + $TableParams = @{ + Name = ($LocalizedData.TableVSANServices -f $VsanCluster.Name) + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanServices | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.ServicesError -f $VsanCluster.Name, $_.Exception.Message) + } + #endregion vSAN Services + + if ($VsanDiskGroup) { + Write-PScriboMessage -Message ($LocalizedData.CollectingDiskGroups -f $VsanCluster.Name) + try { + Section -Style Heading4 $LocalizedData.DiskGroupsSection { + $VsanDiskGroups = foreach ($DiskGroup in $VsanDiskGroup) { + $Disks = $DiskGroup | Get-VsanDisk + [PSCustomObject]@{ + $LocalizedData.DiskGroup = $DiskGroup.Uuid + $LocalizedData.Host = $Diskgroup.VMHost.Name + $LocalizedData.NumDisks = $Disks.Count + $LocalizedData.State = if ($DiskGroup.IsMounted) { + $LocalizedData.Mounted + } else { + $LocalizedData.Unmounted + } + $LocalizedData.Type = switch ($DiskGroup.DiskGroupType) { + 'AllFlash' { $LocalizedData.AllFlash } + default { $DiskGroup.DiskGroupType } + } + $LocalizedData.DisksFormat = $DiskGroup.DiskFormatVersion + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSANDiskGroups -f $VsanCluster.Name) + ColumnWidths = 30, 30, 7, 11, 11, 11 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanDiskGroups | Sort-Object $LocalizedData.Host | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.DiskGroupError -f $VsanCluster.Name, $_.Exception.Message) + } + } + + if ($VsanDisk) { + Write-PScriboMessage -Message ($LocalizedData.CollectingDisks -f $VsanCluster.Name) + try { + Section -Style Heading4 $LocalizedData.DisksSection { + $vDisks = foreach ($Disk in $VsanDisk) { + [PSCustomObject]@{ + $LocalizedData.DiskName = $Disk.Name + $LocalizedData.Name = $Disk.ExtensionData.DisplayName + $LocalizedData.State = if ($Disk.IsMounted) { + $LocalizedData.Mounted + } else { + $LocalizedData.Unmounted + } + $LocalizedData.DriveType = if ($Disk.IsSsd) { + $LocalizedData.Flash + } else { + $LocalizedData.HDD + } + $LocalizedData.Host = $Disk.VsanDiskGroup.VMHost.Name + $LocalizedData.ClaimedAs = if ($Disk.IsCacheDisk) { + $LocalizedData.Cache + } else { + $LocalizedData.Capacity + } + $LocalizedData.Capacity = Convert-DataSize $Disk.CapacityGB + $LocalizedData.SerialNumber = $Disk.ExtensionData.SerialNumber + $LocalizedData.Vendor = $Disk.ExtensionData.Vendor + $LocalizedData.Model = $Disk.ExtensionData.Model + $LocalizedData.DiskGroup = $Disk.VsanDiskGroup.Uuid + $LocalizedData.DiskFormatVersion = $Disk.DiskFormatVersion + } + } + + if ($InfoLevel.vSAN -ge 4) { + $vDisks | Sort-Object $LocalizedData.Host | ForEach-Object { + $vDisk = $_ + Section -Style NOTOCHeading5 -ExcludeFromTOC "$($vDisk.$($LocalizedData.Name)) - $($vDisk.$($LocalizedData.Host))" { + $TableParams = @{ + Name = ($LocalizedData.TableDisk -f $vDisk.$($LocalizedData.Name), $vDisk.$($LocalizedData.Host)) + List = $true + Columns = $LocalizedData.Name, $LocalizedData.DriveType, $LocalizedData.ClaimedAs, $LocalizedData.Capacity, $LocalizedData.Host, $LocalizedData.DiskGroup, $LocalizedData.SerialNumber, $LocalizedData.Vendor, $LocalizedData.Model, $LocalizedData.DiskFormatVersion + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vDisk | Table @TableParams + } + } + } else { + $TableParams = @{ + Name = ($LocalizedData.TableVSANDisks -f $VsanCluster.Name) + Columns = $LocalizedData.Name, $LocalizedData.DriveType, $LocalizedData.ClaimedAs, $LocalizedData.Capacity, $LocalizedData.Host, $LocalizedData.DiskGroup + ColumnWidths = 21, 10, 10, 10, 21, 28 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $vDisks | Sort-Object $LocalizedData.Host | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.DiskError -f $VsanCluster.Name, $_.Exception.Message) + } + } + } + + $VsanIscsiTargets = Get-VsanIscsiTarget -Cluster $VsanCluster.Cluster -ErrorAction SilentlyContinue + if ($VsanIscsiTargets) { + Write-PScriboMessage -Message ($LocalizedData.CollectingiSCSITargets -f $VsanCluster.Name) + try { + Section -Style Heading4 $LocalizedData.iSCSITargetsSection { + $VsanIscsiTargetInfo = foreach ($VsanIscsiTarget in $VsanIscsiTargets) { + [PSCustomObject]@{ + $LocalizedData.IQN = $VsanIscsiTarget.IscsiQualifiedName + $LocalizedData.Alias = $VsanIscsiTarget.Name + $LocalizedData.LUNsCount = $VsanIscsiTarget.NumLuns + $LocalizedData.NetworkInterface = $VsanIscsiTarget.NetworkInterface + $LocalizedData.IOOwnerHost = $VsanIscsiTarget.IoOwnerVMHost.Name + $LocalizedData.TCPPort = $VsanIscsiTarget.TcpPort + $LocalizedData.Health = $TextInfo.ToTitleCase($VsanIscsiTarget.VsanHealth) + $LocalizedData.StoragePolicy = if ($VsanIscsiTarget.StoragePolicy.Name) { + $VsanIscsiTarget.StoragePolicy.Name + } else { + '--' + } + $LocalizedData.ComplianceStatus = $TextInfo.ToTitleCase($VsanIscsiTarget.SpbmComplianceStatus) + $LocalizedData.Authentication = $VsanIscsiTarget.AuthenticationType + } + } + $TableParams = @{ + Name = ($LocalizedData.TableVSANiSCSITargets -f $VsanCluster.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanIscsiTargetInfo | Table @TableParams + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.iSCSITargetError -f $VsanCluster.Name, $_.Exception.Message) + } + } + + $VsanIscsiLuns = Get-VsanIscsiLun -Cluster $VsanCluster.Cluster -ErrorAction SilentlyContinue | Sort-Object Name, LunId + if ($VsanIscsiLuns) { + Write-PScriboMessage -Message ($LocalizedData.CollectingiSCSILUNs -f $VsanCluster.Name) + try { + Section -Style Heading4 $LocalizedData.iSCSILUNsSection { + $VsanIscsiLunInfo = foreach ($VsanIscsiLun in $VsanIscsiLuns) { + [PSCustomObject]@{ + $LocalizedData.LUNName = $VsanIscsiLun.Name + $LocalizedData.LUNID = $VsanIscsiLun.LunId + $LocalizedData.Capacity = Convert-DataSize $VsanIscsiLun.CapacityGB + $LocalizedData.UsedCapacity = Convert-DataSize $VsanIscsiLun.UsedCapacityGB + $LocalizedData.State = if ($VsanIscsiLun.IsOnline) { + $LocalizedData.Online + } else { + $LocalizedData.Offline + } + $LocalizedData.Health = $TextInfo.ToTitleCase($VsanIscsiLun.VsanHealth) + $LocalizedData.StoragePolicy = if ($VsanIscsiLun.StoragePolicy.Name) { + $VsanIscsiLun.StoragePolicy.Name + } else { + '--' + } + $LocalizedData.ComplianceStatus = $TextInfo.ToTitleCase($VsanIscsiLun.SpbmComplianceStatus) + } + } + if ($InfoLevel.vSAN -ge 4) { + $TableParams = @{ + Name = ($LocalizedData.TableVSANiSCSILUNs -f $VsanCluster.Name) + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanIscsiLunInfo | Table @TableParams + } else { + $TableParams = @{ + Name = ($LocalizedData.TableVSANiSCSILUNs -f $VsanCluster.Name) + ColumnWidths = 28, 18, 18, 18, 18 + Columns = $LocalizedData.LUNName, $LocalizedData.LUNID, $LocalizedData.Capacity, $LocalizedData.UsedCapacity, $LocalizedData.State + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $VsanIscsiLunInfo | Table @TableParams + } + } + } catch { + Write-PScriboMessage -Message ($LocalizedData.iSCSILUNError -f $VsanCluster.Name, $_.Exception.Message) + } + } + } + #endregion vSAN Cluster Section + } + } + #endregion vSAN Cluster Detailed Information + } + } + } + } catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} diff --git a/Src/Private/Get-ESXiBootDevice.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-ESXiBootDevice.ps1 similarity index 100% rename from Src/Private/Get-ESXiBootDevice.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-ESXiBootDevice.ps1 diff --git a/Src/Private/Get-InstallDate.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-InstallDate.ps1 similarity index 100% rename from Src/Private/Get-InstallDate.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-InstallDate.ps1 diff --git a/Src/Private/Get-License.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-License.ps1 similarity index 91% rename from Src/Private/Get-License.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-License.ps1 index 4d7c222..901d42b 100644 --- a/Src/Private/Get-License.ps1 +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-License.ps1 @@ -42,12 +42,15 @@ function Get-License { $ServiceInstance = Get-View ServiceInstance -Server $vCenter $LicenseManager = Get-View $ServiceInstance.Content.LicenseManager -Server $vCenter $LicenseManagerAssign = Get-View $LicenseManager.LicenseAssignmentManager -Server $vCenter + if (-not $LicenseManagerAssign) { return } if ($VMHost) { $VMHostId = $VMHost.Extensiondata.Config.Host.Value $VMHostAssignedLicense = $LicenseManagerAssign.QueryAssignedLicenses($VMHostId) $VMHostLicense = $VMHostAssignedLicense.AssignedLicense $VMHostLicenseExpiration = ($VMHostLicense.Properties | Where-Object { $_.Key -eq 'expirationDate' } | Select-Object Value).Value - if ($VMHostLicense.LicenseKey -and $Options.ShowLicenseKeys) { + if ([string]::IsNullOrEmpty($VMHostLicense.LicenseKey)) { + $VMHostLicenseKey = 'N/A' + } elseif ($Options.ShowLicenseKeys) { $VMHostLicenseKey = $VMHostLicense.LicenseKey } else { $keyParts = $VMHostLicense.LicenseKey -split '-' @@ -69,10 +72,12 @@ function Get-License { } } if ($vCenter) { - $vCenterAssignedLicense = $LicenseManagerAssign.GetType().GetMethod("QueryAssignedLicenses").Invoke($LicenseManagerAssign, @($_.MoRef.Value)) | Where-Object { $_.EntityID -eq $vCenter.InstanceUuid } + $vCenterAssignedLicense = $LicenseManagerAssign.QueryAssignedLicenses($null) | Where-Object { $_.EntityId -eq $vCenter.InstanceUuid } $vCenterLicense = $vCenterAssignedLicense.AssignedLicense $vCenterLicenseExpiration = ($vCenterLicense.Properties | Where-Object { $_.Key -eq 'expirationDate' } | Select-Object Value).Value - if ($vCenterLicense.LicenseKey -and $Options.ShowLicenseKeys) { + if ([string]::IsNullOrEmpty($vCenterLicense.LicenseKey)) { + $vCenterLicenseKey = 'N/A' + } elseif ($Options.ShowLicenseKeys) { $vCenterLicenseKey = $vCenterLicense.LicenseKey } else { $keyParts = $vCenterLicense.LicenseKey -split '-' diff --git a/AsBuiltReport.VMware.vSphere/Src/Private/Get-PciDeviceDetail.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-PciDeviceDetail.ps1 new file mode 100644 index 0000000..728d1b1 --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Private/Get-PciDeviceDetail.ps1 @@ -0,0 +1,119 @@ +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. + .PARAMETER VMHost + VMHost object. Required for ESXi 8.x compatibility where VMkernelName is no longer + populated in esxcli hardware.pci.list; used to build a PCI address to VMkernel name map. + .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 -VMHost $VMHost + 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, + [Parameter(Mandatory = $false)] + $VMHost + ) + Begin { } + + Process { + # Build PCI address -> VMkernel name mapping for ESXi 8 compatibility. + # VMkernelName is no longer populated in esxcli hardware.pci.list on ESXi 8.x, + # so we derive it from the PowerCLI API using the PCI address as the join key. + $addrToVmkernel = @{} + if ($null -ne $VMHost) { + Get-VMHostNetworkAdapter -VMHost $VMHost -Physical | ForEach-Object { + if ($_.PciId) { $addrToVmkernel[$_.PciId] = $_.DeviceName } + } + Get-VMHostHba -VMHost $VMHost | ForEach-Object { + if ($_.Pci) { $addrToVmkernel[$_.Pci] = $_.Device } + } + (Get-VMHost $VMHost | Get-View -Property Config).Config.GraphicsInfo | ForEach-Object { + if ($_.pciId) { $addrToVmkernel[$_.pciId] = $_.deviceName } + } + } + + $pciDevices = $esxcli.hardware.pci.list.Invoke() | Where-Object { + $vmkName = if ($_.VMkernelName -match 'vmhba|vmnic|vmgfx') { + $_.VMkernelName + } else { + $addrToVmkernel[$_.Address] + } + $vmkName -match 'vmhba|vmnic|vmgfx' -and $_.ModuleName -ne 'None' + } + $nicList = $esxcli.network.nic.list.Invoke() | Sort-Object Name + foreach ($pciDevice in $pciDevices) { + # Resolve VMkernel name: populated directly on ESXi < 8, address lookup required on ESXi 8+ + $vmkernelName = if ($pciDevice.VMkernelName -match 'vmhba|vmnic|vmgfx') { + $pciDevice.VMkernelName + } else { + $addrToVmkernel[$pciDevice.Address] + } + + # Reset per-device defaults on every iteration + $firmwareVersion = 'N/A' + $driverVib = @{ Name = 'N/A'; Version = 'N/A' } + + $driverVersion = $esxcli.system.module.get.Invoke(@{module = $pciDevice.ModuleName }) | Select-Object -ExpandProperty Version + # Get NIC Firmware version + if (($vmkernelName -like 'vmnic*') -and ($nicList.Name -contains $vmkernelName)) { + $vmnicDetail = $esxcli.network.nic.get.Invoke(@{nicname = $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 ($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' = $vmkernelName + 'Model' = $pciDevice.DeviceName + 'Driver' = $pciDevice.ModuleName + 'Driver Version' = $driverVersion + 'Firmware Version' = $firmwareVersion + 'VIB Name' = $driverVib.Name + 'VIB Version' = $driverVib.Version + } + } + } + End { } +} diff --git a/Src/Private/Get-ScsiDeviceDetail.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-ScsiDeviceDetail.ps1 similarity index 100% rename from Src/Private/Get-ScsiDeviceDetail.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-ScsiDeviceDetail.ps1 diff --git a/Src/Private/Get-Uptime.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-Uptime.ps1 similarity index 100% rename from Src/Private/Get-Uptime.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-Uptime.ps1 diff --git a/Src/Private/Get-VMHostNetworkAdapterDP.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-VMHostNetworkAdapterDP.ps1 similarity index 100% rename from Src/Private/Get-VMHostNetworkAdapterDP.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-VMHostNetworkAdapterDP.ps1 diff --git a/Src/Private/Get-vCenterStats.ps1 b/AsBuiltReport.VMware.vSphere/Src/Private/Get-vCenterStats.ps1 similarity index 100% rename from Src/Private/Get-vCenterStats.ps1 rename to AsBuiltReport.VMware.vSphere/Src/Private/Get-vCenterStats.ps1 diff --git a/AsBuiltReport.VMware.vSphere/Src/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 b/AsBuiltReport.VMware.vSphere/Src/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 new file mode 100644 index 0000000..c99e28c --- /dev/null +++ b/AsBuiltReport.VMware.vSphere/Src/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 @@ -0,0 +1,207 @@ +function Invoke-AsBuiltReport.VMware.vSphere { + <# + .SYNOPSIS + PowerShell script to document the configuration of VMware vSphere infrastructure in Word/HTML/Text formats + .DESCRIPTION + Documents the configuration of VMware vSphere infrastructure in Word/HTML/Text formats using PScribo. + .NOTES + Version: 2.0.0 + Date: 4th March 2026 + Author: Tim Carman + Twitter: @tpcarman + Github: tpcarman + Credits: Iain Brighton (@iainbrighton) - PScribo module + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere + #> + + param ( + [String[]] $Target, + [PSCredential] $Credential + ) + + # Check for required modules + Get-RequiredModule -Name 'VCF.PowerCLI' -Version '9.0' + + # Display report module information using Core function + Write-ReportModuleInfo -ModuleName 'VMware.vSphere' + + # Import Report Configuration + $Report = $ReportConfig.Report + $InfoLevel = $ReportConfig.InfoLevel + $Options = $ReportConfig.Options + $LocalizedData = $reportTranslate.InvokeAsBuiltReportVMwarevSphere + + # Used to set values to TitleCase where required + $TextInfo = (Get-Culture).TextInfo + + #region Script Body + # Connect to vCenter Server using supplied credentials + foreach ($VIServer in $Target) { + try { + Write-PScriboMessage -Message ($LocalizedData.Connecting -f $VIServer) + $vCenter = Connect-VIServer $VIServer -Credential $Credential -ErrorAction Stop + } catch { + Write-Error $_ + } + + #region Generate vSphere report + if ($vCenter) { + # Check logged in user has sufficient privileges to generate an As Built Report + Write-PScriboMessage -Message $LocalizedData.CheckPrivileges + Try { + $AuthMgr = Get-View $($vCenter.ExtensionData.Content.AuthorizationManager) + $UserPrivileges = ($AuthMgr.FetchUserPrivilegeOnEntities("Folder-group-d1", $vCenter.User)).privileges + } Catch { + Write-PScriboMessage -Message $LocalizedData.UnablePrivileges + } + + # Create a lookup hashtable to quickly link VM MoRefs to Names + # Exclude VMware Site Recovery Manager placeholder VMs + Write-PScriboMessage -Message $LocalizedData.VMHashtable + $VMs = Get-VM -Server $vCenter | Where-Object { + $_.ExtensionData.Config.ManagedBy.ExtensionKey -notlike 'com.vmware.vcDr*' + } | Sort-Object Name + $VMLookup = @{ } + foreach ($VM in $VMs) { + $VMLookup.($VM.Id) = $VM.Name + } + + # 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 + Write-PScriboMessage -Message $LocalizedData.VMHostHashtable + $VMHosts = Get-VMHost -Server $vCenter | Where-Object { $_.Model -notlike "*VMware Mobility Platform" -and $_.Version -gt 5 } | Sort-Object Name + $VMHostLookup = @{ } + foreach ($VMHost in $VMHosts) { + $VMHostLookup.($VMHost.Id) = $VMHost.Name + } + + # Create a lookup hashtable to link Datastore MoRefs to Names + Write-PScriboMessage -Message $LocalizedData.DatastoreHashtable + $Datastores = Get-Datastore -Server $vCenter | 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 + Write-PScriboMessage -Message $LocalizedData.VDPortGrpHashtable + $VDPortGroups = Get-VDPortgroup -Server $vCenter | Sort-Object Name + $VDPortGroupLookup = @{ } + foreach ($VDPortGroup in $VDPortGroups) { + $VDPortGroupLookup.($VDPortGroup.Key) = $VDPortGroup.Name + } + + # Create a lookup hashtable to link EVC Modes to Names + Write-PScriboMessage -Message $LocalizedData.EVCHashtable + $SupportedEvcModes = $vCenter.ExtensionData.Capability.SupportedEVCMode + $EvcModeLookup = @{ } + foreach ($EvcMode in $SupportedEvcModes) { + $EvcModeLookup.($EvcMode.Key) = $EvcMode.Label + } + + $si = Get-View ServiceInstance -Server $vCenter + $extMgr = Get-View -Id $si.Content.ExtensionManager -Server $vCenter + + #region VMware Update Manager Server Name + Write-PScriboMessage -Message $LocalizedData.CheckVUM + $VumServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vcIntegrity' } | + Select-Object @{ + N = 'Name'; + E = { ($_.Server | Where-Object { $_.Type -eq 'SOAP' -and $_.Company -eq 'VMware, Inc.' } | + Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } + } + #endregion VMware Update Manager Server Name + + #region vCenter REST API + $vcApiUri = $null + $vcApiHeaders = $null + if ([version]$vCenter.Version -ge [version]'7.0') { + $vcApiBaseUri = "https://$($vCenter.Name)/api" + try { + $restToken = Invoke-RestMethod -Uri "$vcApiBaseUri/session" -Method Post -Credential $Credential -SkipCertificateCheck -ErrorAction Stop + $vcApiUri = $vcApiBaseUri + $vcApiHeaders = @{ + 'vmware-api-session-id' = $restToken + } + } catch { + Write-PScriboMessage -IsWarning ($LocalizedData.RestApiSessionError -f $_.Exception.Message) + } + } + #endregion vCenter REST API + + #region VxRail Manager Server Name + Write-PScriboMessage -Message $LocalizedData.CheckVxRail + $VxRailMgr = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vxrail' } | + Select-Object @{ + N = 'Name'; + E = { ($_.Server | Where-Object { $_.Type -eq 'HTTPS' } | + Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } + } + #endregion VxRail Manager Server Name + + #region Site Recovery Manager Server Name + Write-PScriboMessage -Message $LocalizedData.CheckSRM + $SrmServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vcDr' } | + Select-Object @{ + N = 'Name'; + E = { ($_.Server | Where-Object { $_.Company -eq 'VMware, Inc.' } | + Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } + } + #endregion Site Recovery Manager Server Name + + #region NSX-T Manager Server Name + Write-PScriboMessage -Message $LocalizedData.CheckNSXT + $NsxtServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.nsx.management.nsxt' } | + Select-Object @{ + N = 'Name'; + E = { ($_.Server | Where-Object { ($_.Company -eq 'VMware') -and ($_.Type -eq 'VIP') } | + Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } + } + #endregion NSX-T Manager Server Name + + #region Tag Information + Try { + Write-PScriboMessage -Message $LocalizedData.CollectingTags + $TagAssignments = Get-TagAssignment -Server $vCenter -ErrorAction SilentlyContinue + $Tags = Get-Tag -Server $vCenter | Sort-Object Name, Category + $TagCategories = Get-TagCategory -Server $vCenter | Sort-Object Name | Select-Object Name, Description, Cardinality -Unique + } Catch { + Write-PScriboMessage -Message "$($LocalizedData.TagError). $($_.Exception.Message)" + } + #endregion Tag Information + + #region vCenter Advanced Settings + Write-PScriboMessage -Message ($LocalizedData.CollectingAdvSettings -f $vCenter) + $vCenterAdvSettings = Get-AdvancedSetting -Entity $vCenter + $vCenterServerName = ($vCenterAdvSettings | Where-Object { $_.name -eq 'VirtualCenter.FQDN' }).Value + $vCenterServerName = $vCenterServerName.ToString().ToLower() + #endregion vCenter Advanced Settings + + #region vCenter Server Heading1 Section + Section -Style Heading1 $vCenterServerName { + Get-AbrVSpherevCenter + Get-AbrVSphereCluster + Get-AbrVSphereResourcePool + Get-AbrVSphereVMHost + Get-AbrVSphereNetwork + Get-AbrVSpherevSAN + Get-AbrVSphereDatastore + Get-AbrVSphereDSCluster + Get-AbrVSphereVM + Get-AbrVSphereVUM + } + #endregion vCenter Server Heading1 Section + + # Disconnect vCenter Server + $Null = Disconnect-VIServer -Server $VIServer -Confirm:$false -ErrorAction SilentlyContinue + } # End of If $vCenter + #endregion Generate vSphere report + + #region Variable cleanup + Clear-Variable -Name vCenter + #endregion Variable cleanup + + } # End of Foreach $VIServer + #endregion Script Body +} diff --git a/CHANGELOG.md b/CHANGELOG.md index b7dda7f..58aeadf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,94 +5,170 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 1.3.6 - 2025-08-24 +## [[2.0.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v2.0.0)] - Unreleased ### Fixed -- Fix divide by zero error (@rebelinux) ([Fix #129](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/129)) + +- Fix PCI Drivers & Firmware section not reporting on vSphere 8; `VMkernelName` is no longer populated in `esxcli hardware.pci.list` on ESXi 8.x so a PCI address to VMkernel name map is now built via the PowerCLI API as fallback. Also fixes per-device defaults not being reset between loop iterations ([#105]([#111](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/111)), [#111](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/111), [#127](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/127)) +- Fix vCenter Server Certificate section reporting VMCA template defaults instead of the actual deployed TLS certificate; now reads the live certificate directly from port 443 ([#88](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/88)) +- Fix null disk group crash in OSA vSAN clusters where disk groups have not yet been claimed ([#113](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/113)) +- ~~Fix `An item with the same key has already been added. Key: LinkedView` error when generating TEXT format reports; raw VMOMI/PowerCLI objects stored directly as PSCustomObject property values cause PScribo's serializer to encounter duplicate `LinkedView` members — all affected properties now store string primitives instead ([#130](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/130))~~ - Issues still evident. Still working on this fix. +- Fix "Index operation failed; the array index evaluated to null" crash and `Global.Licenses` privilege errors when querying ESXi host/vCenter licensing on vCenter 8.0.2 ([#123](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/123)) + +### Added +- Modular architecture: each report section is now a dedicated private function (`Get-AbrVSphere*`) +- Internationalization (i18n) support via `Language/` `.psd1` files (`en-US`, `en-GB`, `es-ES`, `fr-FR`, `de-DE`) +- Pester test suite (`AsBuiltReport.VMware.vSphere.Tests.ps1`, `LocalizationData.Tests.ps1`, `Invoke-Tests.ps1`) +- GitHub Actions Pester workflow (`.github/workflows/Pester.yml`) +- Add TPM attestation state and host encryption settings to VMHost Security section; includes recovery key reporting (gated behind `ShowEncryptionKeys` option) and `TpmAttestation` healthcheck ([#101](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/101)) +- Add I/O Device Identifiers subsection to VMHost Hardware report, displaying VID/DID/SVID/SSID in lowercase hex for HCL validation ([#126](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/126)) +- Add vSphere Lifecycle Manager (vLCM) cluster reporting: image composition (base image, vendor add-on), component list (InfoLevel 4+), hardware support manager, and image compliance with per-host breakdown (InfoLevel 4+); clusters in VUM baseline mode are silently skipped +- Add Software Depots section to VMware Update Manager report; online depots show description, URL, system-defined flag, and enabled state; offline depots show description and location; system-generated bundles (HA, WCP) with no location are excluded from the offline table +- Add VM Update Manager baseline compliance reporting per VM, with `VUMCompliance` healthcheck (Warning: Unknown, Critical: Not Compliant / Incompatible) +- Add `LCMCompliance` healthcheck for cluster/host vLCM image compliance +- Add SDRS rules reporting to Datastore Cluster section; shows rule name, enabled state, type (Affinity / Anti-Affinity), and member VMs +- Add Space Load Balance Configuration and I/O Load Balance Configuration subsections to Datastore Cluster section +- Add Distributed Switch LACP reporting (enabled state, mode) at InfoLevel 3+ +- Add Distributed Switch NetFlow reporting (collector IP/port, flow timeouts, sampling rate) at InfoLevel 3+ +- Add Network I/O Control resource pool reporting (shares level, shares, limit) at InfoLevel 4+ when NIOC is enabled +- Add Proactive HA Providers subsection to Cluster Proactive HA section +- Add VM Swap File Location subsection to VMHost System section; shows placement policy and local swap datastore +- Add ESXi host certificate reporting to VMHost System section; shows subject, issuer, validity period, and SHA-256 thumbprint +- Add syslog log directory, rotation count, and log size to VMHost Syslog section; section now always renders regardless of whether a remote syslog server is configured +- Add vSAN Services section to vSAN cluster reporting (both OSA and ESA); shows enabled/disabled state of Performance Service, File Service, iSCSI Target Service, Deduplication, Encryption, Historical Health Service, and Health Check +- Add tag reporting to Datastore, Datastore Cluster, Distributed Switch, Resource Pool, Virtual Machine, and VMHost sections +- Extract Cluster VUM Baselines and Compliance into dedicated `Get-AbrVSphereClusterVUM` sub-function +- Add vCenter Server Backup Settings section (InfoLevel 3+); Backup Schedule table shows status (Activated/Deactivated), schedule recurrence with appliance timezone, backup location, data components, and retention count; Backup Job History table shows the 10 most recent jobs (location, type, status, data transferred, duration, end time) via `GET /api/appliance/recovery/backup/job/details`; requires vSphere 7.0+ REST API; includes `Backup` healthcheck (Warning: schedule deactivated, Critical: job failed) +- Add `Certificate` healthcheck to vCenter Server Certificate section (Critical: EXPIRED/EXPIRING, Warning: EXPIRING_SOON) +- Add Content Libraries section to vCenter Server report (InfoLevel 3+); summary table shows library name, type, backing datastore, item count, and description; InfoLevel 4+ adds per-library detail (including subscription URL, automatic and on-demand sync settings for subscribed libraries) and a flat items table showing name, content type, size, description, creation time, and last modified; includes `ContentLibrary` healthcheck (Warning: automatic synchronisation disabled) +- Add `ShowRoles` and `ShowAlarms` options to suppress vCenter Server Roles and Alarm Definitions sections; both default to `true`; useful for reducing report size in large environments ([#122](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/122)) +- Add `ShowTags` option to gate all tag reporting across the report (vCenter Tags, Categories, Assignments, VMHost, VM, Datastore, Datastore Cluster, Resource Pool, Distributed Switch); defaults to `true` +- Add vCenter Server resource and inventory summary tables at InfoLevel 1+; resource table shows CPU (GHz), Memory (GB/TB), and Storage (GB/TB/PB) with free/used/total columns (auto-scaled to most relevant unit); separate Virtual Machine table shows Powered On/Off/Suspended/Total counts; separate Host table shows Connected/Disconnected/Maintenance/Total counts ([#30](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/30)) + +### Changed + +- Complete module rewrite for improved maintainability and extensibility +- Module source now uses nested folder structure (`AsBuiltReport.VMware.vSphere/`) +- Requires `AsBuiltReport.Core` >= 1.6.2 +- Minimum PowerShell version raised to 7.4; refer to the [VMware PowerCLI Installation Guide](https://developer.broadcom.com/powercli/installation-guide) +- `CompatiblePSEditions` updated to `Core` only + +### Removed + +- Windows PowerShell 5.1 (Desktop edition) support dropped + +## [[1.3.6.1](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.6.1)] - 2025-08-24 + +### Fixed + +- Fix issue with gathering ESXi Host Image Profile information + +## [[1.3.6](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.6)] - 2025-08-24 + +### Fixed + +- Fix divide by zero error (@rebelinux) ([#129](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/129)) - Fix PowerCLI module dependency ([#134](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/134)) - Update colour placeholders in `README.md` ### Changed + - Improve vSAN Capacity reporting and healthchecks -- Add `VCF.PowerCLI` to `ExternalModuleDependencies` in the module manifest. +- Add `VCF.PowerCLI` to `ExternalModuleDependencies` in the module manifest ### Removed -- Remove `Get-RequiredModule` function to check for PowerCLI versions. + +- Remove `Get-RequiredModule` function to check for PowerCLI versions - Remove VMware document style script -## 1.3.5 - 2025-02-27 -### Fixed -- Fix issue with license reporting ([Fix #128](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/128)) -- Fix issue with vCenter user privileges not handling groups (@nathcoad) ([Fix #102](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/102)) -- Fix time & date outputs showing incorrect date format -- Fix VMware Update Manager reporting with PowerShell 7 +## [[1.3.5](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.5)] - 2025-02-27 ### Added + - Add Free resource capacity reporting to VMhost hardware section ### Changed + - Update VMware PowerCLI requirements to version 13.3 - Improve error reporting for vSAN section -- Improve data size reporting. Data sizes are now displayed in more appropriately sized data units. +- Improve data size reporting. Data sizes are now displayed in more appropriately sized data units - Change list tables to 40/60 column widths - Change datastore capacity reporting to include percentage used & free values - Update GitHub release workflow to add post to Bluesky social platform -## 1.3.4.1 - 2024-03-28 - ### Fixed -- Add VSAN ESA support ([Fix #113](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/113)) + +- Fix issue with license reporting ([#128](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/128)) +- Fix issue with vCenter user privileges not handling groups (@nathcoad) ([#102](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/102)) +- Fix time & date outputs showing incorrect date format +- Fix VMware Update Manager reporting with PowerShell 7 ## [[1.3.4](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.4)] - 2024-02-28 +### Added + +- Add vSAN ESA support ([#113](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/113)) + ### Changed -- Update VMware PowerCLI requirements to version 13.2 ([Fix #107](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/107)) + +- Update VMware PowerCLI requirements to version 13.2 ([#107](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/107)) - Improve bug and feature request templates (@rebelinux) - Improve TOC structure - Update VMware style script for improved TOC structure - Update GitHub action workflows ### Fixed -- Update VMHost PCI Devices reporting to fix issues with ESXi 8.x hosts (@orb71) ([Fix #105](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/105)) & ([Fix #111](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/111)) -- Add Try/Catch stated PCI Drivers and Firmware section to provide a workaround for ESXi 8.x hosts ([Fix #116](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/116)) -- Update vCenter Server alarms reporting ([Fix #106](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/106)) -- Fix issue with Platform Services Controller reporting ([Fix #103](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/103)) -- Fix NSX-T virtual switch network labels ([Fix #118](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/118)) + +- Update VMHost PCI Devices reporting to fix issues with ESXi 8.x hosts (@orb71) ([#105](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/105)) & ([#111](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/111)) +- Add Try/Catch to PCI Drivers and Firmware section to provide a workaround for ESXi 8.x hosts ([#116](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/116)) +- Update vCenter Server alarms reporting ([#106](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/106)) +- Fix issue with Platform Services Controller reporting ([#103](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/103)) +- Fix NSX-T virtual switch network labels ([#118](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/118)) ### Removed -- Removed reporting of vCenter Server OS type + +- Remove reporting of vCenter Server OS type ## [[1.3.3.1](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.3.1)] - 2022-04-21 ### Added + - Add VMHost IPMI / BMC configuration information ### Fixed + - Fix GitHub Action release workflow ## [[1.3.2](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.2)] - 2022-03-24 ### Added + - Automated tweet release workflow ### Fixed + - Fix colour placeholders in `README.md` ## [[1.3.1](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.1)] - 2021-09-03 ### Added + - VMHost network adapter LLDP reporting ## [[1.3.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.3.0)] - 2021-08-29 + ### Added + - PowerShell 7 compatibility - PSScriptAnalyzer & PublishPSModule GitHub Action workflows - Advanced detailed reporting for VI roles - Advanced detailed reporting for vSAN disks -- Support for VMware Cloud environments (VCF, VMC, AVS, GVE) ([Fix #87](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/87)) -- NSX TCP/IP stacks for VMkernel Adpater reporting +- Support for VMware Cloud environments (VCF, VMC, AVS, GVE) ([#87](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/87)) +- NSX TCP/IP stacks for VMkernel Adapter reporting - Include release and issue links in `CHANGELOG.md` + ### Fixed + - Incorrect section reporting with certain InfoLevels - Datastore table now sorts by Datastore Name - vSAN advanced detailed reporting @@ -100,156 +176,196 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Display issues with highlights in `README.md` ## [[1.2.1](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.2.1)] - 2020-09-29 -### Fixed -- Fixed sort order of VMHost PCI Devices -- Fixed VMHost reporting for InfoLevels 1 & 2 -- Fixed DSCluster reporting for InfoLevels 1 & 2 ### Changed + - Set fixed table column widths for improved formatting -- Corrected section header colours in VMware default style +- Correct section header colours in VMware default style + +### Fixed + +- Fix sort order of VMHost PCI Devices +- Fix VMHost reporting for InfoLevels 1 & 2 +- Fix DSCluster reporting for InfoLevels 1 & 2 ## [[1.2.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.2.0)] - 2020-08-31 + ### Added + - vCenter Server advanced system settings - vCenter Server alarm health check - Basic VM storage policy reporting - Headers, footers & table captions/numbering ### Changed -- Improved table formatting -- Enhanced vCenter alarm reporting -- Changed Tag Assignment section to separate the category and tag to their own table columns -- Changed Tag Assignment section to sort on Entity -- Renamed InfoLevel `Informative` to `Adv Summary` -- Moved script functions from main script to private functions + +- Improve table formatting +- Enhance vCenter alarm reporting +- Change Tag Assignment section to separate the category and tag to their own table columns +- Change Tag Assignment section to sort on Entity +- Rename InfoLevel `Informative` to `Adv Summary` +- Move script functions from main script to private functions ### Fixed + - Section error with vSAN InfoLevel 4 or above -- Fixed text color for highlighted cells in default VMware style -- Fixed reporting of stateless boot devices ([Fix #76](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/76)) -- Fixed issue where script was failing trying to parse vSphere Tag data ([Fix #77](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/77)) -- Fixed issue with reporting on PCI-E device drivers by adding additional filter ([Fix #75](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/75)) +- Fix text color for highlighted cells in default VMware style +- Fix reporting of stateless boot devices ([#76](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/76)) +- Fix issue where script was failing trying to parse vSphere Tag data ([#77](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/77)) +- Fix issue with reporting on PCI-E device drivers by adding additional filter ([#75](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/75)) ## [[1.1.3](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.1.3)] - 2020-02-04 + ### Added -- Added vCenter Server certificate information ([Fix #31](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/31)) -- Added VM summary information -- Added VM disk and guest volume information -- Added Virtual Switch to VMkernel adapter information -- Added Virtual Switch & Port Group Traffic Shaping information -- Added vSAN Disk Groups, iSCSI Targets & LUN reporting -- Added number of paths to SCSI LUN information -- Added VMHost CPU & Memory totals to Informative level -- Added VM Connection State information & health check -- Added number of targets, devices & paths to storage adapters -- Added VMHost storage and network adapter health checks -- Added License expiration information -- Added additional information to VMkernel adapters -- Added NTP, SSH & ESXi Shell health checks + +- Add vCenter Server certificate information ([#31](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/31)) +- Add VM summary information +- Add VM disk and guest volume information +- Add Virtual Switch to VMkernel adapter information +- Add Virtual Switch & Port Group Traffic Shaping information +- Add vSAN Disk Groups, iSCSI Targets & LUN reporting +- Add number of paths to SCSI LUN information +- Add VMHost CPU & Memory totals to Informative level +- Add VM Connection State information & health check +- Add number of targets, devices & paths to storage adapters +- Add VMHost storage and network adapter health checks +- Add License expiration information +- Add additional information to VMkernel adapters +- Add NTP, SSH & ESXi Shell health checks ### Changed -- Improved report formatting -- Improved VMHost storage adapter reporting ([Fix #32](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/32)) -- Improved VMHost network adapter CDP reporting -- Improved VM SCSI controller reporting -- Updated VMHost CPU & Memory totals/usage in Detailed level -- Updated report JSON structure & default settings. A new report JSON must be generated for this release, use `New-AsBuiltReportConfig -Report VMware.vSphere -Path -Overwrite`. -- Updated README with minimum required privileges to generate a VMware vSphere As Built Report. Full administrator privileges should no longer be required. + +- Improve report formatting +- Improve VMHost storage adapter reporting ([#32](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/32)) +- Improve VMHost network adapter CDP reporting +- Improve VM SCSI controller reporting +- Update VMHost CPU & Memory totals/usage in Detailed level +- Update report JSON structure & default settings. A new report JSON must be generated for this release, use `New-AsBuiltReportConfig -Report VMware.vSphere -Path -Overwrite` +- Update README with minimum required privileges to generate a VMware vSphere As Built Report. Full administrator privileges should no longer be required ### Fixed -- Resolved issue with VMHost PCI device reporting ([Fix #33](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/33)) -- Resolved issue with reporting of ESXi boot device size ([Fix #65](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/65)) -- Resolved issue with vSphere licensing ([Fix #68](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/68) & [Fix #69](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/69)) -- Resolved vSwitch reporting issue with physical adpaters ([Fix #27](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/27)) -- Resolved issue with VMHost uptime health check reporting + +- Resolve issue with VMHost PCI device reporting ([#33](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/33)) +- Resolve issue with reporting of ESXi boot device size ([#65](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/65)) +- Resolve issue with vSphere licensing ([#68](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/68) & [Fix #69](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/69)) +- Resolve vSwitch reporting issue with physical adapters ([#27](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/27)) +- Resolve issue with VMHost uptime health check reporting ### Removed -- Removed support for ESX/ESXi hosts prior to vSphere 5.0 ([Fix #67](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/67)) -- Removed VMHost CPU & Memory usage from Informative level + +- Remove support for ESX/ESXi hosts prior to vSphere 5.0 ([#67](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues/67)) +- Remove VMHost CPU & Memory usage from Informative level ## [[1.0.7](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.0.7)] - 2019-06-21 + ### Changed -- Fixed font in default VMware style -- Updated module manifest for icon and release notes + +- Update module manifest for icon and release notes + +### Fixed + +- Fix font in default VMware style ### Removed -- Removed Services health check + +- Remove Services health check ## [[1.0.6](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.0.6)] - 2019-05-16 + ### Changed -- Fixed code errors which prevented a report from being generated -- Improved code and report readability -- Fixed vCenter Server licensing reporting -- Fixed Datastore reporting when an empty datastore cluster exists -- Fixed DRS Cluster Group reporting when group does not contain any members -- Fixed DRS Cluster Group sorting -- Fixed VMHost reporting to exclude HCX Cloud Gateway host -- Updated VMware default style to more closely align with Clarity + +- Improve code and report readability +- Update VMware default style to more closely align with Clarity + +### Fixed + +- Fix code errors which prevented a report from being generated +- Fix vCenter Server licensing reporting +- Fix Datastore reporting when an empty datastore cluster exists +- Fix DRS Cluster Group reporting when group does not contain any members +- Fix DRS Cluster Group sorting +- Fix VMHost reporting to exclude HCX Cloud Gateway host ## [[1.0.0](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/tag/v1.0.0)] - 2019-03-27 + ### Added -- Added Update Manager Server name to vCenter Server detailed information -### Changed -- Fixed VMHost count for Distributed Virtual Switches -- Fixed vCenter Server licensing for vCenter Server 5.5/6.0 -- Fixed script termination where ESXi hosts do not have a datastore +- Add Update Manager Server name to vCenter Server detailed information + +### Fixed + +- Fix VMHost count for Distributed Virtual Switches +- Fix vCenter Server licensing for vCenter Server 5.5/6.0 +- Fix script termination where ESXi hosts do not have a datastore ## [0.4.0] - 2019-03-15 + ### Changed -- Refactored into PowerShell module -- Updated default VMware style sheet to include page orientation -- Changed VM Snapshot reporting to be per VM for InfoLevel 3 + +- Refactor into PowerShell module +- Update default VMware style sheet to include page orientation +- Change VM Snapshot reporting to be per VM for InfoLevel 3 ### Removed -- Removed NSX-V reporting + +- Remove NSX-V reporting ## [0.3.0] - 2019-02-01 + ### Added -- Added Cluster VM Overrides section + +- Add Cluster VM Overrides section ### Changed -- Improved code structure & readability -- Improved output formatting -- Improved vSphere HA/DRS Cluster reporting and health checks -- Improved VM reporting and health checks -- Fixed sorting of numerous table entries -- Fixed VMHost & VM uptime calculations -- Fixed display of 3rd party Multipath Policy plugins -- Fixed vSAN type & disk count -- Updated Get-Uptime & Get-License functions + +- Improve code structure & readability +- Improve output formatting +- Improve vSphere HA/DRS Cluster reporting and health checks +- Improve VM reporting and health checks +- Fix sorting of numerous table entries +- Fix VMHost & VM uptime calculations +- Fix display of 3rd party Multipath Policy plugins +- Fix vSAN type & disk count +- Update `Get-Uptime` & `Get-License` functions ## [0.2.2] - 2018-09-19 + ### Added -- Added new VM health checks for CPU Hot Add/Remove, Memory Hot Add & Change Block Tracking -- Improved VM reporting for Guest OS, CPU Hot Add/Remove, Memory Hot Add & Change Block Tracking + +- Add new VM health checks for CPU Hot Add/Remove, Memory Hot Add & Change Block Tracking +- Improve VM reporting for Guest OS, CPU Hot Add/Remove, Memory Hot Add & Change Block Tracking - Minor updates to section paragraph text ## [0.2.1] + ### Added -- Added SDRS VM Overrides to Datastore Cluster section + +- Add SDRS VM Overrides to Datastore Cluster section ### Changed -- SCSI LUN section rewritten to improve script performance -- Fixed issues with current working directory paths -- Changed InfoLevel settings and definitions -- Script formatting improvements to some sections to align with PowerShell best practice guidelines -- vCenter Server SSL Certificate section removed temporarily + +- Rewrite SCSI LUN section to improve script performance +- Fix issues with current working directory paths +- Change InfoLevel settings and definitions +- Improve script formatting to align with PowerShell best practice guidelines +- Temporarily remove vCenter Server SSL Certificate section ## [0.2.0] + ### Added -- Added regions/endregions to all sections of script -- Added Resource Pool summary information -- Added vSAN summary information -- Added vCenter Server mail settings health check -- Added DSCluster health checks -- Added VM Power State health check -- Added support for NSX-V reporting + +- Add regions/endregions to all sections of script +- Add Resource Pool summary information +- Add vSAN summary information +- Add vCenter Server mail settings health check +- Add DSCluster health checks +- Add VM Power State health check +- Add support for NSX-V reporting ### Changed -- Updated about_Requires to PScribo module 0.7.24 -- Formatting improvements -- Datastore Clusters now has it's own dedicated section -- Renamed Storage section to Datastores -- Renamed Storage health checks section to Datastore + +- Update about_Requires to PScribo module 0.7.24 +- Improve formatting +- Move Datastore Clusters to its own dedicated section +- Rename Storage section to Datastores +- Rename Storage health checks section to Datastore diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3ea1f28 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,284 @@ +# AsBuiltReport.VMware.vSphere – Developer Guide + +## Module Architecture + +This module follows the nested-folder pattern established by `AsBuiltReport.Microsoft.Azure`. + +``` +AsBuiltReport.VMware.vSphere/ ← repo root +├── AsBuiltReport.VMware.vSphere/ ← module source (published to PSGallery) +│ ├── AsBuiltReport.VMware.vSphere.psd1 +│ ├── AsBuiltReport.VMware.vSphere.psm1 +│ ├── AsBuiltReport.VMware.vSphere.json ← report configuration schema +│ ├── Language/ +│ │ ├── en-US/VMwarevSphere.psd1 ← primary translation template +│ │ ├── en-GB/VMwarevSphere.psd1 ← British English +│ │ ├── es-ES/VMwarevSphere.psd1 ← Spanish +│ │ ├── fr-FR/VMwarevSphere.psd1 ← French +│ │ └── de-DE/VMwarevSphere.psd1 ← German +│ └── Src/ +│ ├── Public/ +│ │ └── Invoke-AsBuiltReport.VMware.vSphere.ps1 ← entry point +│ └── Private/ +│ ├── Convert-DataSize.ps1 ← helper functions +│ ├── Get-ESXiBootDevice.ps1 +│ ├── Get-InstallDate.ps1 +│ ├── Get-License.ps1 +│ ├── Get-PciDeviceDetail.ps1 +│ ├── Get-ScsiDeviceDetail.ps1 +│ ├── Get-Uptime.ps1 +│ ├── Get-vCenterStats.ps1 +│ ├── Get-VMHostNetworkAdapterDP.ps1 +│ ├── Get-AbrVSpherevCenter.ps1 ← section functions +│ ├── Get-AbrVSphereCluster.ps1 +│ ├── Get-AbrVSphereClusterHA.ps1 +│ ├── Get-AbrVSphereClusterProactiveHA.ps1 +│ ├── Get-AbrVSphereClusterDRS.ps1 +│ ├── Get-AbrVSphereClusterVUM.ps1 +│ ├── Get-AbrVSphereClusterLCM.ps1 +│ ├── Get-AbrVSphereResourcePool.ps1 +│ ├── Get-AbrVSphereVMHost.ps1 +│ ├── Get-AbrVSphereVMHostHardware.ps1 +│ ├── Get-AbrVSphereVMHostSystem.ps1 +│ ├── Get-AbrVSphereVMHostStorage.ps1 +│ ├── Get-AbrVSphereVMHostNetwork.ps1 +│ ├── Get-AbrVSphereVMHostSecurity.ps1 +│ ├── Get-AbrVSphereNetwork.ps1 +│ ├── Get-AbrVSpherevSAN.ps1 +│ ├── Get-AbrVSphereDatastore.ps1 +│ ├── Get-AbrVSphereDSCluster.ps1 +│ ├── Get-AbrVSphereVM.ps1 +│ └── Get-AbrVSphereVUM.ps1 +├── Tests/ +│ ├── AsBuiltReport.VMware.vSphere.Tests.ps1 +│ ├── LocalizationData.Tests.ps1 +│ └── Invoke-Tests.ps1 +├── CHANGELOG.md +├── README.md +└── LICENSE +``` + +## Naming Conventions + +| Type | Pattern | Example | +|------|---------|---------| +| Top-level section function | `Get-AbrVSphere{Component}` | `Get-AbrVSpherevCenter` | +| Sub-section function | `Get-AbrVSphere{Parent}{Sub}` | `Get-AbrVSphereClusterHA` | +| Language key (section) | `GetAbrVSphere{Component}` | `GetAbrVSpherevCenter` | +| Language key (sub-section) | `GetAbrVSphere{Parent}{Sub}` | `GetAbrVSphereClusterHA` | + +The language key is derived from the function name by removing the hyphen: `Get-AbrVSpherevCenter` → `GetAbrVSpherevCenter`. + +## Function Structure + +Every section function follows this begin/process/end pattern: + +```powershell +function Get-AbrVSphere{Name} { + <# + .SYNOPSIS + Used by As Built Report to retrieve VMware vSphere {Name} information. + .NOTES + Version: 2.0.0 + Author: Tim Carman + #> + [CmdletBinding()] + param () + + begin { + $LocalizedData = $reportTranslate.GetAbrVSphere{Name} + Write-PScriboMessage ($LocalizedData.InfoLevel -f $InfoLevel.{Section}) + } + + process { + Try { + if ($InfoLevel.{Section} -ge 1) { + Write-PScriboMessage $LocalizedData.Collecting + Section -Style Heading2 $LocalizedData.SectionHeading { + Paragraph ($LocalizedData.ParagraphSummary -f $vCenterServerName) + # ... section content + } + } + } Catch { + Write-PScriboMessage -IsWarning $($_.Exception.Message) + } + } + + end {} +} +``` + +**Key rules:** +- Functions use variables from parent scope (not parameters) — `$vCenter`, `$InfoLevel`, `$Report`, `$Healthcheck`, `$TextInfo`, `$vCenterServerName`, `$reportTranslate`, `$vcApiUri`, `$vcApiHeaders`, etc. +- `$LocalizedData` is always set in `begin {}` from `$reportTranslate.{KeyName}` +- All PSCustomObject property names (column headers), section headings, table names, and user-visible strings use `$LocalizedData` keys +- Table names (`Name =`) in `$TableParams` also use `$LocalizedData` keys for localization +- **PSCustomObject keys must NOT use parentheses around `$LocalizedData` expressions.** Use `$LocalizedData.Key = value`, never `($LocalizedData.Key) = value`. The brackets are unnecessary — PowerShell evaluates `$LocalizedData.Key` as a key name directly in hashtable/PSCustomObject literals. + +## Language / i18n Structure + +### Loading mechanism +The `AsBuiltReport.Core` module loads `Language/{culture}/VMwarevSphere.psd1` automatically. The `$reportTranslate` variable is set globally by `New-AsBuiltReport.ps1` before the Invoke- function runs. + +The file name `VMwarevSphere` is derived from the report name `VMware.vSphere` by removing the dot. + +### File format +```powershell +# culture = 'en-US' +@{ + GetAbrVSpherevCenter = ConvertFrom-StringData @' + InfoLevel = Tab:2 vCenter InfoLevel set to {0}. + Collecting = Collecting vCenter Server information. + SectionHeading = vCenter Server + ParagraphSummary = The following sections detail the configuration of vCenter Server {0}. + # ... more keys + '@ + + GetAbrVSphereCluster = ConvertFrom-StringData @' + # ... + '@ +} +``` + +### Adding a new locale +1. Copy `Language/en-US/VMwarevSphere.psd1` to `Language/{culture}/VMwarevSphere.psd1` +2. Update the culture comment at the top +3. Translate string values (keep keys identical) +4. Run `Tests/Invoke-Tests.ps1` — `LocalizationData.Tests.ps1` will verify key consistency + +## Development Commands + +### Lint (PSScriptAnalyzer) +```powershell +# From repo root +Invoke-ScriptAnalyzer -Path .\AsBuiltReport.VMware.vSphere\Src -Recurse -Severity Warning, Error +``` + +### Run tests +```powershell +.\Tests\Invoke-Tests.ps1 + +# With code coverage +.\Tests\Invoke-Tests.ps1 -CodeCoverage + +# With JUnit output (for CI) +.\Tests\Invoke-Tests.ps1 -OutputFormat JUnitXml +``` + +### Import module (smoke test, no vCenter required) +```powershell +Import-Module .\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1 -Force +Get-Command -Module AsBuiltReport.VMware.vSphere +``` + +### Reload module during development +```powershell +Remove-Module AsBuiltReport.VMware.vSphere -ErrorAction SilentlyContinue +Import-Module .\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1 -Force +``` + +## How to Add a New Section Function + +1. **Create the function file** in `Src/Private/Get-AbrVSphere{Name}.ps1` + - Follow the begin/process/end template above + - Use `$InfoLevel.{Section}` for the info level check + +2. **Add the language key** to `Language/en-US/VMwarevSphere.psd1`: + ```powershell + GetAbrVSphere{Name} = ConvertFrom-StringData @' + InfoLevel = {Section} InfoLevel set to {0}. + Collecting = Collecting {Section} information. + SectionHeading = {Section Heading} + ParagraphSummary = The following sections detail... + '@ + ``` + +3. **Copy the key** to all other locale files (en-GB, etc.) with identical keys (translate values only) + +4. **Call the function** from `Invoke-AsBuiltReport.VMware.vSphere.ps1` inside the `Section -Style Heading1` block + +5. **Run tests** to verify: + - `LocalizationData.Tests.ps1` checks all locale files have matching keys + - `AsBuiltReport.VMware.vSphere.Tests.ps1` checks the .ps1 file exists in Private/ + +## InfoLevel Reference + +| Level | Description | +|-------|-------------| +| 0 | Disabled (section not rendered) | +| 1 | Enabled / Summary | +| 2 | Advanced Summary | +| 3 | Detailed | +| 4 | Advanced Detailed | +| 5 | Comprehensive | + +## Report JSON Configuration + +The report configuration is in `AsBuiltReport.VMware.vSphere.json`. InfoLevel keys correspond to section names: `vCenter`, `Cluster`, `ResourcePool`, `VMHost`, `Network`, `vSAN`, `Datastore`, `DSCluster`, `VM`, `VUM`. + +## Known Gotchas + +### Pester 5 Discovery vs. Runtime Scoping +The `-Skip:()` expression in `It` blocks is evaluated at **discovery** time, before `BeforeAll {}` runs. Variables set in `BeforeAll` are not available to `-Skip:()` conditions. Use `BeforeDiscovery {}` for variables that control skip logic. Example in `AsBuiltReport.VMware.vSphere.Tests.ps1`: + +```powershell +# Correct — BeforeDiscovery runs before -Skip:() is evaluated +BeforeDiscovery { + $AnalyzerAvailable = $null -ne (Get-Module -Name PSScriptAnalyzer -ListAvailable | Select-Object -First 1) +} +``` + +### psm1 Module Exports +The `.psm1` only exports public functions (`Export-ModuleMember -Function $Public.BaseName`). Private section functions (`Get-AbrVSphere*`) are dot-sourced and available in module scope without being exported. The `FunctionsToExport` in the `.psd1` manifest acts as the final authoritative allow-list. + +### vCenter REST API Authentication +The `$vcApiUri` and `$vcApiHeaders` variables are set in `Invoke-AsBuiltReport.VMware.vSphere.ps1` only when the connected vCenter is vSphere 8.0+. A REST API session is established via `POST /api/session` using the report `$Credential`: + +```powershell +$restToken = Invoke-RestMethod -Uri "$vcApiBaseUri/session" -Method Post -Credential $Credential -SkipCertificateCheck +$vcApiHeaders = @{ 'vmware-api-session-id' = $restToken } +``` + +**Do not** use `$vCenter.SessionId` as the session token — that is the PowerCLI SOAP/VMOMI session ID and is rejected by the REST API with HTTP 401. + +Functions that call the REST API check `if (-not $vcApiUri) { return }` to silently skip on unsupported versions or when session establishment failed. + +### `Get-Compliance` Non-Terminating Warning +The PowerCLI `Get-Compliance` cmdlet emits a non-terminating warning alongside its return value. Use `-ErrorAction SilentlyContinue` (not `-ErrorAction Stop`) to suppress the warning without discarding the compliance data. The null check on the result variable handles genuine failures: + +```powershell +$Compliances = $Entity | Get-Compliance -ErrorAction SilentlyContinue +if ($Compliances) { ... } +``` + +Using `-ErrorAction Stop` converts the warning to a terminating error and the catch block fires, losing the data even though the cmdlet succeeded. + +### LinkedView Error — Never Store Raw VMOMI Objects in PSCustomObject +PScribo serializes every `PSCustomObject` when rendering TEXT/Word/HTML output. VMOMI/PowerCLI objects (e.g., `ClusterComputeResource`, `VIPermission`, `VirtualMachine`) expose a duplicate `LinkedView` property internally, which causes: + +``` +An item with the same key has already been added. Key: LinkedView +``` + +**Rule:** PSCustomObject property values must always be **string primitives**, never raw PowerCLI objects. + +```powershell +# WRONG — stores raw VMOMI object +[PSCustomObject]@{ ($LocalizedData.Entity) = $ClusterCompliance.Entity } + +# CORRECT — store the string name +[PSCustomObject]@{ ($LocalizedData.Entity) = $ClusterCompliance.Entity.Name } +``` + +This applies to any property that holds a PowerCLI object: use `.Name`, `.Id`, `.ToString()`, or any other string extraction. Using the object in a `Where-Object` comparison (not as a stored value) is safe. + +### Locale Key Consistency +The `en-US` locale file is the authoritative template. All other locales must have **identical key sets** — the `LocalizationData.Tests.ps1` Pester test enforces this. To quickly check parity without running Pester, compare key counts: +```powershell +# Count keys per locale manually +foreach ($locale in 'en-US','en-GB','es-ES','fr-FR','de-DE') { + $count = (Get-Content ".\AsBuiltReport.VMware.vSphere\Language\$locale\VMwarevSphere.psd1" | + Where-Object { $_ -match '^\s+\w+\s*=' -and $_ -notmatch "^'@" }).Count + Write-Host "$locale`: $count keys" +} +``` diff --git a/LICENSE b/LICENSE index d8002d2..53f3c82 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 AsBuiltReport +Copyright (c) 2026 AsBuiltReport Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 19fce59..b99c1ab 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

@@ -18,14 +19,22 @@

+

+ + + + + +

- Buy Me a Coffee at ko-fi.com + Want to keep alive this project? Support me on Ko-fi

+ # VMware vSphere As Built Report @@ -35,49 +44,72 @@ VMware vSphere As Built Report is a PowerShell module which works in conjunction The VMware vSphere As Built Report module is used to generate as built documentation for VMware vSphere / vCenter Server environments. -Please refer to the [VMware ESXi AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport.VMware.ESXi) for reporting of standalone VMware ESXi servers. +> [!TIP] +> Please refer to the [VMware ESXi](https://github.com/AsBuiltReport/AsBuiltReport.VMware.ESXi) AsBuiltReport for reporting of standalone VMware ESXi servers. 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 vSphere As Built report. ## :floppy_disk: Supported Versions - -### VMware vSphere The VMware vSphere As Built Report supports the following vSphere versions; -- vSphere 7.0 - vSphere 8.0 -#### End of Support +> [!IMPORTANT] +> Ongoing VMware product and licensing restrictions, combined with limited access to development environments and resources, prevent further development and support of this report module beyond VMware vSphere 8.0. + +## :no_entry_sign: Unsupported Versions The following VMware vSphere versions are no longer being tested and/or supported; - vSphere 5.5 - vSphere 6.0 - vSphere 6.5 - vSphere 6.7 +- vSphere 7.0 ### PowerShell This report is compatible with the following PowerShell versions; + | Windows PowerShell 5.1 | PowerShell 7 | |:----------------------:|:--------------------:| -| :white_check_mark: | :white_check_mark: | +| :x: | :white_check_mark: | + +## 🌐 Language Support + +The VMware vSphere As Built Report supports the following languages; + +| Language | Culture Code | +|----------|--------------| +| English (US) | en-US (Default) | +| English (GB) | en-GB | +| French | fr-FR | +| German | de-DE | +| Spanish | es-ES | ## :wrench: System Requirements -PowerShell 5.1 or PowerShell 7, and the following PowerShell modules are required for generating a VMware vSphere As Built report. + +PowerShell 7.4 or higher, and the following PowerShell modules are required for generating a VMware vSphere As Built report. + +> [!NOTE] +> Windows PowerShell 5.1 is not supported. Please refer to the [VMware PowerCLI Installation Guide](https://developer.broadcom.com/powercli/installation-guide) for instructions on installing PowerShell 7 and PowerCLI. Each of these modules can be easily downloaded and installed via the PowerShell Gallery -- [VCF PowerCLI Module](https://www.powershellgallery.com/packages/VCF.PowerCLI/) +- [VCF PowerCLI Module](https://www.powershellgallery.com/packages/VCF.PowerCLI/) version 9.0 or higher - [AsBuiltReport.VMware.vSphere Module](https://www.powershellgallery.com/packages/AsBuiltReport.VMware.vSphere/) ### :closed_lock_with_key: Required Privileges + + A VMware vSphere As Built Report can be generated with read-only privileges, however the following sections will be skipped; @@ -93,21 +125,45 @@ For a complete report, the following role assigned privileges are required; * Profile-driven Storage > Profile-driven storage view * VMware vSphere Update Manager > View Compliance Status +> [!NOTE] +> The vSphere Lifecycle Manager (vLCM) image composition, compliance, and Software Depot sections use the vCenter REST API. The credentials supplied to `New-AsBuiltReport` are used to authenticate automatically — no additional configuration is required. + ## :package: Module Installation +### PowerShell + Open a PowerShell terminal window and install each of the required modules. -:warning: VCF PowerCLI 9.0 or higher is required. Please ensure older PowerCLI versions have been uninstalled. +> [!NOTE] +> VCF PowerCLI 9.0 or higher is required. Please ensure older PowerCLI versions have been uninstalled. ```powershell +# Install install-module VCF.PowerCLI -MinimumVersion 9.0 -AllowClobber -SkipPublisherCheck install-module AsBuiltReport.VMware.vSphere ``` +### GitHub +If you are unable to use the PowerShell Gallery, you can still install the module manually. Ensure you repeat the following steps for the [system requirements](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere#wrench-system-requirements) also. + +1. Download the code package / [latest release](https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/releases/latest) zip from GitHub +2. Extract the zip file +3. Copy the folder `AsBuiltReport.VMware.vSphere` to a path that is set in `$env:PSModulePath`. +4. Open a PowerShell terminal window and unblock the downloaded files with + ```powershell + $path = (Get-Module -Name AsBuiltReport.VMware.vSphere -ListAvailable).ModuleBase; Unblock-File -Path $path\*.psd1; Unblock-File -Path $path\Src\Public\*.ps1; Unblock-File -Path $path\Src\Private\*.ps1 + ``` +5. Close and reopen the PowerShell terminal window. + +_Note: You are not limited to installing the module to those example paths, you can add a new entry to the environment variable PSModulePath if you want to use another path._ + ## :pencil2: Configuration The vSphere As Built Report utilises a JSON file to allow configuration of report information, options, detail and healthchecks. -A vSphere report configuration file can be generated by executing the following command; +> [!IMPORTANT] +> Please remember to generate a new report JSON configuration file after each module update to ensure the report functions correctly. + +A VMware vSphere report configuration file can be generated by executing the following command; ```powershell New-AsBuiltReportConfig -Report VMware.vSphere -FolderPath -Filename ``` @@ -118,6 +174,7 @@ 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** schema provides configuration of the vSphere report information. @@ -125,7 +182,8 @@ The **Report** schema provides configuration of the vSphere report information. |---------------------|--------------|--------------------------------|--------------------------------------------------------------| | Name | User defined | VMware vSphere 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 | +| Status | User defined | Released | The report release status +| Language | User defined | en-US | The default report language. This can be customised if the report module provides multilingual support | | | ShowCoverPageImage | true / false | true | Toggle to enable/disable the display of the cover page image | | ShowTableOfContents | true / false | true | Toggle to enable/disable table of contents | | ShowHeaderFooter | true / false | true | Toggle to enable/disable document headers & footers | @@ -136,9 +194,14 @@ The **Options** schema allows certain options within the report to be toggled on | Sub-Schema | Setting | Default | Description | |-----------------|--------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ShowLicenseKeys | true / false | false | Toggle to mask/unmask vSphere license keys

**Masked License Key**
\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-AS12K

**Unmasked License Key**
AKLU4-PFG8M-W2D8J-56YDM-AS12K | -| ShowVMSnapshots | true / false | true | Toggle to enable/disable reporting of VM snapshots | - +| ShowLicenseKeys | true / false | false | Toggle to mask/unmask vSphere license keys

**Masked License Key**
\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-\*\*\*\*\*-AS12K

**Unmasked License Key**
AKLU4-PFG8M-W2D8J-56YDM-AS12K | +| ShowEncryptionKeys | true / false | false | Toggle to show/hide ESXi host encryption recovery keys in the report. When disabled, the recovery keys table is suppressed even at InfoLevel 3+ | +| ShowVMSnapshots | true / false | true | Toggle to enable/disable reporting of VM snapshots | +| ShowRoles | true / false | true | Toggle to enable/disable reporting of vCenter Server roles and privileges. Disable to reduce report size in environments with many custom roles | +| ShowAlarms | true / false | true | Toggle to enable/disable reporting of vCenter Server alarm definitions. Disable to reduce report size in environments with many alarm definitions | +| ShowTags | true / false | true | Toggle to enable/disable tag reporting across all sections (vCenter Tags/Categories/Assignments, VMHost, VM, Datastore, Datastore Cluster, Resource Pool, Distributed Switch) | + + ### InfoLevel The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set. @@ -176,89 +239,96 @@ The **vCenter** schema is used to configure health checks for vCenter Server. | Sub-Schema | Setting | Default | Description | Highlight | |------------|--------------|---------|-----------------------------------------------------|-------------------------------------------------------------------------------------------| -| Mail | true / false | true | Highlights mail settings which are not configured | ![Critical](https://place-hold.it/15/ffb38f/ffb38f) Not Configured | -| Licensing | true / false | true | Highlights product evaluation licenses | ![Warning](https://place-hold.it/15/ffe860/ffe860) Product evaluation license in use | -| Alarms | true / false | true | Highlights vCenter Server alarms which are disabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Alarm disabled | +| Mail | true / false | true | Highlights mail settings which are not configured | ![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Not Configured | +| Licensing | true / false | true | Highlights product evaluation licenses | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Product evaluation license in use | +| Alarms | true / false | true | Highlights vCenter Server alarms which are disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Alarm disabled | +| Certificate | true / false | true | Highlights vCenter Server certificates which are expired or approaching expiry | ![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Expired / Expiring
![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Expiring Soon | +| Backup | true / false | true | Highlights vCenter Server backup schedules which are deactivated and backup jobs which have failed (requires vSphere 7.0 or later REST API access) | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Backup schedule deactivated
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Backup job failed | +| ContentLibrary | true / false | true | Highlights subscribed content libraries with automatic synchronisation disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Automatic synchronisation disabled | #### Cluster The **Cluster** schema is used to configure health checks for vSphere Clusters. | Sub-Schema | Setting | Default | Description | Highlight | |-----------------------------|--------------|---------|--------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| HAEnabled | true / false | true | Highlights vSphere Clusters which do not have vSphere HA enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA disabled | -| HAAdmissionControl | true / false | true | Highlights vSphere Clusters which do not have vSphere HA Admission Control enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA Admission Control disabled | -| HostFailureResponse | true / false | true | Highlights vSphere Clusters which have vSphere HA Failure Response set to disabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA Host Failure Response disabled | -| HostMonitoring | true / false | true | Highlights vSphere Clusters which do not have vSphere HA Host Monitoring enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA Host Monitoring disabled | -| DatastoreOnPDL | true / false | true | Highlights vSphere Clusters which do not have Datastore on PDL enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA Datastore on PDL disabled | -| DatastoreOnAPD | true / false | true | Highlights vSphere Clusters which do not have Datastore on APD enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere HA Datastore on APD disabled | -| APDTimeOut | true / false | true | Highlights vSphere Clusters which do not have APDTimeOut enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) APDTimeOut disabled | -| vmMonitoing | true / false | true | Highlights vSphere Clusters which do not have VM Monitoting enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) VM Monitoring disabled | -| DRSEnabled | true / false | true | Highlights vSphere Clusters which do not have vSphere DRS enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere DRS disabled | -| DRSAutomationLevelFullyAuto | true / false | true | Checks the vSphere DRS Automation Level is set to 'Fully Automated' | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere DRS Automation Level not set to 'Fully Automated' | -| PredictiveDRS | true / false | false | Highlights vSphere Clusters which do not have Predictive DRS enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Predictive DRS disabled | -| DRSVMHostRules | true / false | true | Highlights DRS VMHost rules which are disabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) DRS VMHost rule disabled | -| DRSRules | true / false | true | Highlights DRS rules which are disabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) DRS rule disabled | -| vSANEnabled | true / false | true | Highlights vSphere Clusters which do not have Virtual SAN enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Virtual SAN disabled | -| EVCEnabled | true / false | true | Highlights vSphere Clusters which do not have Enhanced vMotion Compatibility (EVC) enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) vSphere EVC disabled | -| VUMCompliance | true / false | true | Highlights vSphere Clusters which do not comply with VMware Update Manager baselines | ![Warning](https://place-hold.it/15/ffe860/ffe860) Unknown
![Critical](https://place-hold.it/15/ffb38f/ffb38f) Not Compliant | +| HAEnabled | true / false | true | Highlights vSphere Clusters which do not have vSphere HA enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA disabled | +| HAAdmissionControl | true / false | true | Highlights vSphere Clusters which do not have vSphere HA Admission Control enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA Admission Control disabled | +| HostFailureResponse | true / false | true | Highlights vSphere Clusters which have vSphere HA Failure Response set to disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA Host Failure Response disabled | +| HostMonitoring | true / false | true | Highlights vSphere Clusters which do not have vSphere HA Host Monitoring enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA Host Monitoring disabled | +| DatastoreOnPDL | true / false | true | Highlights vSphere Clusters which do not have Datastore on PDL enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA Datastore on PDL disabled | +| DatastoreOnAPD | true / false | true | Highlights vSphere Clusters which do not have Datastore on APD enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere HA Datastore on APD disabled | +| APDTimeOut | true / false | true | Highlights vSphere Clusters which do not have APDTimeOut enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) APDTimeOut disabled | +| vmMonitoring | true / false | true | Highlights vSphere Clusters which do not have VM Monitoring enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) VM Monitoring disabled | +| DRSEnabled | true / false | true | Highlights vSphere Clusters which do not have vSphere DRS enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere DRS disabled | +| DRSAutomationLevelFullyAuto | true / false | true | Checks the vSphere DRS Automation Level is set to 'Fully Automated' | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere DRS Automation Level not set to 'Fully Automated' | +| PredictiveDRS | true / false | false | Highlights vSphere Clusters which do not have Predictive DRS enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Predictive DRS disabled | +| DRSVMHostRules | true / false | true | Highlights DRS VMHost rules which are disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) DRS VMHost rule disabled | +| DRSRules | true / false | true | Highlights DRS rules which are disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) DRS rule disabled | +| vSANEnabled | true / false | true | Highlights vSphere Clusters which do not have Virtual SAN enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Virtual SAN disabled | +| EVCEnabled | true / false | true | Highlights vSphere Clusters which do not have Enhanced vMotion Compatibility (EVC) enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) vSphere EVC disabled | +| VUMCompliance | true / false | true | Highlights vSphere Clusters which do not comply with VMware Update Manager baselines | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Unknown
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Not Compliant | +| LCMCompliance | true / false | true | Highlights clusters and hosts where the vLCM image compliance status is not Compliant | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Non-compliant | #### VMHost The **VMHost** schema is used to configure health checks for VMHosts. | Sub-Schema | Setting | Default | Description | Highlight | |-----------------|--------------|---------|--------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ConnectionState | true / false | true | Highlights VMHosts which are in maintenance mode or disconnected | ![Warning](https://place-hold.it/15/ffe860/ffe860) Maintenance
![Critical](https://place-hold.it/15/ffb38f/ffb38f) Disconnected | -| HyperThreading | true / false | true | Highlights VMHosts which have HyperThreading disabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) HyperThreading disabled
| -| ScratchLocation | true / false | true | Highlights VMHosts which are configured with the default scratch location | ![Warning](https://place-hold.it/15/ffe860/ffe860) Scratch location is /tmp/scratch | -| IPv6 | true / false | true | Highlights VMHosts which do not have IPv6 enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) IPv6 disabled | -| UpTimeDays | true / false | true | Highlights VMHosts with uptime days greater than 9 months | ![Warning](https://place-hold.it/15/ffe860/ffe860) 9 - 12 months
![Critical](https://place-hold.it/15/ffb38f/ffb38f) >12 months | -| Licensing | true / false | true | Highlights VMHosts which are using production evaluation licenses | ![Warning](https://place-hold.it/15/ffe860/ffe860) Product evaluation license in use | -| SSH | true / false | true | Highlights if the SSH service is enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) TSM / TSM-SSH service enabled | -| ESXiShell | true / false | true | Highlights if the ESXi Shell service is enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) TSM / TSM-EsxiShell service enabled | -| NTP | true / false | true | Highlights if the NTP service has stopped or is disabled on a VMHost | ![Critical](https://place-hold.it/15/ffb38f/ffb38f) NTP service stopped / disabled | -| StorageAdapter | true / false | true | Highlights storage adapters which are not 'Online' | ![Warning](https://place-hold.it/15/ffe860/ffe860) Storage adapter status is 'Unknown'
![Critical](https://place-hold.it/15/ffb38f/ffb38f) 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](https://place-hold.it/15/ffb38f/ffb38f) Network adapter is 'Disconnected'
![Critical](https://place-hold.it/15/ffb38f/ffb38f) Network adapter is 'Down' | -| LockdownMode | true / false | true | Highlights VMHosts which do not have Lockdown mode enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Lockdown Mode disabled
| -| VUMCompliance | true / false | true | Highlights VMHosts which are not compliant with VMware Update Manager software packages | ![Warning](https://place-hold.it/15/ffe860/ffe860) Unknown
![Critical](https://place-hold.it/15/ffb38f/ffb38f) Incompatible | +| ConnectionState | true / false | true | Highlights VMHosts which are in maintenance mode or disconnected | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Maintenance
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Disconnected | +| HyperThreading | true / false | true | Highlights VMHosts which have HyperThreading disabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) HyperThreading disabled
| +| ScratchLocation | true / false | true | Highlights VMHosts which are configured with the default scratch location | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Scratch location is /tmp/scratch | +| IPv6 | true / false | true | Highlights VMHosts which do not have IPv6 enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) IPv6 disabled | +| UpTimeDays | true / false | true | Highlights VMHosts with uptime days greater than 9 months | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) 9 - 12 months
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) >12 months | +| Licensing | true / false | true | Highlights VMHosts which are using production evaluation licenses | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Product evaluation license in use | +| SSH | true / false | true | Highlights if the SSH service is enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) TSM / TSM-SSH service enabled | +| ESXiShell | true / false | true | Highlights if the ESXi Shell service is enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) TSM / TSM-EsxiShell service enabled | +| NTP | true / false | true | Highlights if the NTP service has stopped or is disabled on a VMHost | ![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) NTP service stopped / disabled | +| StorageAdapter | true / false | true | Highlights storage adapters which are not 'Online' | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Storage adapter status is 'Unknown'
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) 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](https://placehold.co/15x15/FEDDD7/FEDDD7) Network adapter is 'Disconnected'
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Network adapter is 'Down' | +| LockdownMode | true / false | true | Highlights VMHosts which do not have Lockdown mode enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Lockdown Mode disabled
| +| VUMCompliance | true / false | true | Highlights VMHosts which are not compliant with VMware Update Manager software packages | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Unknown
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Incompatible | +| TpmAttestation | true / false | true | Highlights VMHosts where a TPM is present but attestation status is not 'attested' | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) TPM attestation status is not attested | #### vSAN The **vSAN** schema is used to configure health checks for vSAN. | Sub-Schema | Setting | Default | Description | Highlight | |---------------------|--------------|---------|------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| -| CapacityUtilization | true / false | true | Highlights vSAN clusters with storage capacity utilization over 75% | ![Warning](https://place-hold.it/15/ffe860/ffe860) 75 - 90% utilized
![Critical](https://place-hold.it/15/ffb38f/ffb38f) >90% utilized | +| CapacityUtilization | true / false | true | Highlights vSAN clusters with storage capacity utilization over 75% | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) 75 - 90% utilized
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) >90% utilized | #### Datastore The **Datastore** schema is used to configure health checks for Datastores. | Sub-Schema | Setting | Default | Description | Highlight | |---------------------|--------------|---------|------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| -| CapacityUtilization | true / false | true | Highlights datastores with storage capacity utilization over 75% | ![Warning](https://place-hold.it/15/ffe860/ffe860) 75 - 90% utilized
![Critical](https://place-hold.it/15/ffb38f/ffb38f) >90% utilized | +| CapacityUtilization | true / false | true | Highlights datastores with storage capacity utilization over 75% | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) 75 - 90% utilized
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) >90% utilized | #### DSCluster The **DSCluster** schema is used to configure health checks for Datastore Clusters. | Sub-Schema | Setting | Default | Description | Highlight | |------------------------------|--------------|---------|-------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| -| CapacityUtilization | true / false | true | Highlights datastore clusters with storage capacity utilization over 75% | ![Warning](https://place-hold.it/15/ffe860/ffe860) 75 - 90% utilized
![Critical](https://place-hold.it/15/ffb38f/ffb38f) >90% utilized | -| SDRSAutomationLevelFullyAuto | true / false | true | Highlights if the Datastore Cluster SDRS Automation Level is not set to 'Fully Automated' | ![Warning](https://place-hold.it/15/ffe860/ffe860) Storage DRS Automation Level not set to 'Fully Automated' | +| CapacityUtilization | true / false | true | Highlights datastore clusters with storage capacity utilization over 75% | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) 75 - 90% utilized
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) >90% utilized | +| SDRSAutomationLevelFullyAuto | true / false | true | Highlights if the Datastore Cluster SDRS Automation Level is not set to 'Fully Automated' | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Storage DRS Automation Level not set to 'Fully Automated' | #### VM 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](https://place-hold.it/15/ffe860/ffe860) VM is powered off | -| ConnectionState | true / false | true | Highlights VMs which are orphaned or inaccessible | ![Critical](https://place-hold.it/15/ffb38f/ffb38f) VM is orphaned or inaccessible | -| CpuHotAdd | true / false | true | Highlights virtual machines which have CPU Hot Add enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) CPU Hot Add enabled | -| CpuHotRemove | true / false | true | Highlights virtual machines which have CPU Hot Remove enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) CPU Hot Remove enabled | -| MemoryHotAdd | true / false | true | Highlights VMs which have Memory Hot Add enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Memory Hot Add enabled | -| ChangeBlockTracking | true / false | true | Highlights VMs which do not have Change Block Tracking enabled | ![Warning](https://place-hold.it/15/ffe860/ffe860) Change Block Tracking disabled | -| SpbmPolicyCompliance | true / false | true | Highlights VMs which do not comply with storage based policies | ![Warning](https://place-hold.it/15/ffe860/ffe860) VM storage based policy compliance is unknown
![Critical](https://place-hold.it/15/ffb38f/ffb38f) 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](https://place-hold.it/15/ffe860/ffe860) 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](https://place-hold.it/15/ffe860/ffe860) VM Snapshot age >= 7 days
![Critical](https://place-hold.it/15/ffb38f/ffb38f) VM Snapshot age >= 14 days | +| PowerState | true / false | true | Highlights VMs which are powered off | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) VM is powered off | +| ConnectionState | true / false | true | Highlights VMs which are orphaned or inaccessible | ![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) VM is orphaned or inaccessible | +| CpuHotAdd | true / false | true | Highlights virtual machines which have CPU Hot Add enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) CPU Hot Add enabled | +| CpuHotRemove | true / false | true | Highlights virtual machines which have CPU Hot Remove enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) CPU Hot Remove enabled | +| MemoryHotAdd | true / false | true | Highlights VMs which have Memory Hot Add enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Memory Hot Add enabled | +| ChangeBlockTracking | true / false | true | Highlights VMs which do not have Change Block Tracking enabled | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Change Block Tracking disabled | +| SpbmPolicyCompliance | true / false | true | Highlights VMs which do not comply with storage based policies | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) VM storage based policy compliance is unknown
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) 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](https://placehold.co/15x15/FFF4C7/FFF4C7) 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](https://placehold.co/15x15/FFF4C7/FFF4C7) VM Snapshot age >= 7 days
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) VM Snapshot age >= 14 days | +| VUMCompliance | true / false | true | Highlights VMs which do not comply with VMware Update Manager baselines | ![Warning](https://placehold.co/15x15/FFF4C7/FFF4C7) Unknown
![Critical](https://placehold.co/15x15/FEDDD7/FEDDD7) Not Compliant / Incompatible | ## :computer: Examples + ```powershell # Generate a vSphere As Built Report for vCenter Server 'vcenter-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' @@ -276,4 +346,7 @@ PS C:\> New-AsBuiltReport -Report VMware.vSphere -Target 'vcenter-01.corp.local' # Generate a vSphere As Built Report for vCenter 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.vSphere -Target 'vcenter-01.corp.local' -Username 'administrator@vsphere.local' -Password 'VMware1!' -Format Html,Word -OutputFolderPath 'C:\Users\Tim\Documents' -SendEmail + +# Generate a vSphere As Built Report for vCenter Server 'vcenter-01.corp.local' using specified credentials. Export report to HTML format. Use default report style. Generate the report in French. Save reports to 'C:\Users\Tim\Documents'. +PS C:\> New-AsBuiltReport -Report VMware.vSphere -Target 'vcenter-01.corp.local' -Username 'administrator@vsphere.local' -Password 'VMware1!' -Format Html -OutputFolderPath 'C:\Users\Tim\Documents' -ReportLanguage 'fr-FR' ``` diff --git a/Samples/Sample vSphere As-Built Report.html b/Samples/Sample vSphere As-Built Report.html deleted file mode 100644 index 3e3c695..0000000 --- a/Samples/Sample vSphere As-Built Report.html +++ /dev/null @@ -1,686 +0,0 @@ - - -Sample vSphere As-Built Report - -
-










Sample vSphere As-Built Report
ACME & Co



























Author:Tim Carman
Date:05 August 2018
Version:1.0
-
-

Table of Contents

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1192.168.1.110
1.1   vCenter Server
1.1.1      Database Settings
1.1.2      Mail Settings
1.1.3      Historical Statistics
1.1.4      Licensing
1.1.5      SSL Certificate
1.1.6      Roles
1.2   Clusters
1.2.1      New Cluster
1.2.1.1         HA Configuration
1.2.1.2         DRS Configuration
1.2.1.3         Permissions
1.2.2      Test Cluster
1.2.2.1         HA Configuration
1.2.2.2         DRS Configuration
1.2.2.3         Permissions
1.2.3      VSAN-Cluster
1.2.3.1         HA Configuration
1.2.3.2         DRS Configuration
1.2.3.2.1            DRS Cluster Groups
1.2.3.2.2            DRS VM/Host Rules
1.2.3.2.3            DRS Rules
1.2.3.3         Update Manager Baselines
1.2.3.4         Permissions
1.3   Resource Pools
1.4   Hosts
1.4.1      192.168.1.111
1.4.1.1         Hardware
1.4.1.1.1            Boot Devices
1.4.1.1.2            PCI Devices
1.4.1.2         System
1.4.1.2.1            Licensing
1.4.1.2.2            Host Profile
1.4.1.2.3            Image Profile
1.4.1.2.4            Time Configuration
1.4.1.2.5            Syslog Configuration
1.4.1.2.6            Update Manager Compliance
1.4.1.3         Storage
1.4.1.3.1            Datastores
1.4.1.4         Network
1.4.1.4.1            Physical Adapters
1.4.1.4.2            Cisco Discovery Protocol
1.4.1.4.3            VMkernel Adapters
1.4.1.4.4            Standard Virtual Switches
1.4.1.4.5            Virtual Switch Security Policy
1.4.1.4.6            Virtual Switch NIC Teaming
1.4.1.4.7            Virtual Port Groups
1.4.1.4.8            Virtual Port Group Security Policy
1.4.1.4.9            Virtual Port Group NIC Teaming
1.4.1.5         Security
1.4.1.5.1            Lockdown Mode
1.4.1.5.2            Services
1.4.1.5.3            Authentication Services
1.4.2      192.168.1.112
1.4.2.1         Hardware
1.4.2.1.1            Boot Devices
1.4.2.1.2            PCI Devices
1.4.2.2         System
1.4.2.2.1            Licensing
1.4.2.2.2            Host Profile
1.4.2.2.3            Image Profile
1.4.2.2.4            Time Configuration
1.4.2.2.5            Syslog Configuration
1.4.2.2.6            Update Manager Compliance
1.4.2.3         Storage
1.4.2.3.1            Datastores
1.4.2.4         Network
1.4.2.4.1            Physical Adapters
1.4.2.4.2            Cisco Discovery Protocol
1.4.2.4.3            VMkernel Adapters
1.4.2.4.4            Standard Virtual Switches
1.4.2.4.5            Virtual Switch Security Policy
1.4.2.4.6            Virtual Switch NIC Teaming
1.4.2.4.7            Virtual Port Groups
1.4.2.4.8            Virtual Port Group Security Policy
1.4.2.4.9            Virtual Port Group NIC Teaming
1.4.2.5         Security
1.4.2.5.1            Lockdown Mode
1.4.2.5.2            Services
1.4.2.5.3            Authentication Services
1.4.3      192.168.1.113
1.4.3.1         Hardware
1.4.3.1.1            Boot Devices
1.4.3.1.2            PCI Devices
1.4.3.2         System
1.4.3.2.1            Licensing
1.4.3.2.2            Host Profile
1.4.3.2.3            Image Profile
1.4.3.2.4            Time Configuration
1.4.3.2.5            Syslog Configuration
1.4.3.2.6            Update Manager Compliance
1.4.3.3         Storage
1.4.3.3.1            Datastores
1.4.3.4         Network
1.4.3.4.1            Physical Adapters
1.4.3.4.2            Cisco Discovery Protocol
1.4.3.4.3            VMkernel Adapters
1.4.3.4.4            Standard Virtual Switches
1.4.3.4.5            Virtual Switch Security Policy
1.4.3.4.6            Virtual Switch NIC Teaming
1.4.3.4.7            Virtual Port Groups
1.4.3.4.8            Virtual Port Group Security Policy
1.4.3.4.9            Virtual Port Group NIC Teaming
1.4.3.5         Security
1.4.3.5.1            Lockdown Mode
1.4.3.5.2            Services
1.4.3.5.3            Authentication Services
1.5   Distributed Virtual Switches
1.5.1      DSwitch
1.5.1.1         General Properties
1.5.1.2         Uplinks
1.5.1.3         Security
1.5.1.4         Traffic Shaping
1.5.1.5         Port Groups
1.5.1.6         Port Group Security
1.5.1.7         Port Group NIC Teaming
1.5.1.8         Private VLANs
1.5.2      DSwitch 1
1.5.2.1         General Properties
1.5.2.2         Security
1.5.2.3         Traffic Shaping
1.5.2.4         Port Groups
1.5.2.5         Port Group Security
1.5.2.6         Port Group NIC Teaming
1.6   vSAN
1.6.1      VSAN-Cluster
1.7   Storage
1.7.1      Datastore Specifications
1.8   Virtual Machines
1.8.1      Test_1
1.8.2      Test_2
1.8.3      Test_3
1.8.4      VM Snapshots
1.9   VMware Update Manager
1.9.1      Baselines
-
-

1 192.168.1.110

1.1 vCenter Server

The following section provides detailed information on the configuration of vCenter server 192.168.1.110.

-
Name192.168.1.110
IP Address192.168.1.110
Version6.5.0
Build5973321
OS Typelinux-x64
Instance Id42
Password Expiry in Days30
HTTP Port80
HTTPS Port443
Platform Services Controller192.168.1.110
-

1.1.1 Database Settings

-
Database Typeembedded
Data Source NameVMware VirtualCenter
Maximum Database Connections50
-

1.1.2 Mail Settings

-
SMTP Serversmtp.gmail.com
SMTP Port25
Mail Sender 
-

1.1.3 Historical Statistics

- - - - - -
Interval DurationInterval EnabledSave DurationStatistics Level
5 MinutesTruePast day1
30 MinutesTruePast week1
2 HoursTruePast month1
1 DayTruePast year1
-

1.1.4 Licensing

- - - - - -
Product NameLicense KeyTotalUsedAvailable
Product Evaluation*****-*****-*****-00000-000000 0
VMware vCenter Server 6 Standard*****-*****-*****-0J9U6-0NF2M211
VMware vSAN Enterprise*****-*****-*****-061A0-2NA7H1064
VMware vSphere 6 Enterprise Plus*****-*****-*****-079HM-29JHN3006294
-

1.1.5 SSL Certificate

-
CountryUS
StateCalifornia
LocalityPalo Alto
OrganizationVMware
Organizational UnitVMware Engineering
Emailvmca@vmware.com
Validity5 Years
-

1.1.6 Roles

- - - - - - - - - - - - - - - - -
NameSystem Role
AdminTrue
AnonymousTrue
com.vmware.Content.AdminFalse
DatastoreConsumerFalse
InventoryService.Tagging.TaggingAdminFalse
NetworkConsumerFalse
NoAccessTrue
NoCryptoAdminTrue
ReadOnlyTrue
ResourcePoolAdministratorFalse
ViewTrue
VirtualMachineConsoleUserFalse
VirtualMachinePowerUserFalse
VirtualMachineUserFalse
VMwareConsolidatedBackupUserFalse
-
-

1.2 Clusters

The following section provides information on the configuration of each vSphere HA/DRS cluster.

- - - -
NameDatacenterHost CountHA EnabledDRS EnabledvSAN EnabledEVC ModeVM Swap File PolicyVM Count
New ClusterDatacenter 10TrueTrueFalse WithVM0
Test ClusterDatacenter0FalseFalseFalseintel-ivybridgeWithVM0
VSAN-ClusterDatacenter3TrueTrueTrue WithVM3
-

1.2.1 New Cluster

The following table details the cluster configuration for cluster New Cluster.

-
NameNew Cluster
DatacenterDatacenter 1
Number of Hosts0
Number of VMs0
HA EnabledTrue
DRS EnabledTrue
vSAN EnabledFalse
EVC Mode 
VM Swap File PolicyWithVM
Connected Hosts 
-

1.2.1.1 HA Configuration

The following table details the vSphere HA configuration for cluster New Cluster.

-
HA EnabledTrue
HA Admission Control EnabledTrue
HA Failover Level1
HA Restart PriorityMedium
HA Isolation ResponseDoNothing
Heartbeat Selection PolicyallFeasibleDsWithUserPreference
Heartbeat Datastores 
-

1.2.1.2 DRS Configuration

The following table details the vSphere DRS configuration for cluster New Cluster.

-
DRS EnabledTrue
DRS Automation LevelFullyAutomated
DRS Migration Threshold3
-
-
VM Distribution 
Memory Metric for Load Balancing 
CPU Over-Commitment 
-

1.2.1.3 Permissions

The following table details the permissions assigned to cluster New Cluster.

- - - - - -
User/GroupIs Group?RoleDefined InPropagate
VSPHERE.LOCAL\vpxd-extension-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vpxd-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vsphere-webclient-0cd516db-cbaa-434b-8b6f-90452748e378FalseReadOnlyDatacentersTrue
VSPHERE.LOCAL\AdministratorFalseAdminDatacentersTrue
VSPHERE.LOCAL\AdministratorsTrueAdminDatacentersTrue
-

1.2.2 Test Cluster

The following table details the cluster configuration for cluster Test Cluster.

-
NameTest Cluster
DatacenterDatacenter
Number of Hosts0
Number of VMs0
HA EnabledFalse
DRS EnabledFalse
vSAN EnabledFalse
EVC Modeintel-ivybridge
VM Swap File PolicyWithVM
Connected Hosts 
-

1.2.2.1 HA Configuration

The following table details the vSphere HA configuration for cluster Test Cluster.

-
HA EnabledFalse
HA Admission Control EnabledFalse
HA Failover Level1
HA Restart PriorityMedium
HA Isolation ResponseDoNothing
Heartbeat Selection PolicyallFeasibleDsWithUserPreference
Heartbeat Datastores 
-

1.2.2.2 DRS Configuration

The following table details the vSphere DRS configuration for cluster Test Cluster.

-
DRS EnabledFalse
DRS Automation LevelFullyAutomated
DRS Migration Threshold3
-
-
VM Distribution 
Memory Metric for Load Balancing 
CPU Over-Commitment 
-

1.2.2.3 Permissions

The following table details the permissions assigned to cluster Test Cluster.

- - - - - -
User/GroupIs Group?RoleDefined InPropagate
VSPHERE.LOCAL\vpxd-extension-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vpxd-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vsphere-webclient-0cd516db-cbaa-434b-8b6f-90452748e378FalseReadOnlyDatacentersTrue
VSPHERE.LOCAL\AdministratorFalseAdminDatacentersTrue
VSPHERE.LOCAL\AdministratorsTrueAdminDatacentersTrue
-

1.2.3 VSAN-Cluster

The following table details the cluster configuration for cluster VSAN-Cluster.

-
NameVSAN-Cluster
DatacenterDatacenter
Number of Hosts3
Number of VMs3
HA EnabledTrue
DRS EnabledTrue
vSAN EnabledTrue
EVC Mode 
VM Swap File PolicyWithVM
Connected Hosts192.168.1.111, 192.168.1.112, 192.168.1.113
-

1.2.3.1 HA Configuration

The following table details the vSphere HA configuration for cluster VSAN-Cluster.

-
HA EnabledTrue
HA Admission Control EnabledTrue
HA Failover Level1
HA Restart PriorityMedium
HA Isolation ResponseDoNothing
Heartbeat Selection PolicyallFeasibleDsWithUserPreference
Heartbeat Datastores 
-

1.2.3.2 DRS Configuration

The following table details the vSphere DRS configuration for cluster VSAN-Cluster.

-
DRS EnabledTrue
DRS Automation LevelFullyAutomated
DRS Migration Threshold3
-
-
VM Distribution1
Memory Metric for Load Balancing100
CPU Over-Commitment 
-
1.2.3.2.1 DRS Cluster Groups
- - -
NameGroup TypeMembers
Test_VMsVMGroupTest_1, Test_2
Prod_HostsVMHostGroup192.168.1.111, 192.168.1.112, 192.168.1.113
-
1.2.3.2.2 DRS VM/Host Rules
- - -
NameTypeEnabledVM GroupVMHost Group
VM not on HostShouldNotRunOnFalseTest_VMsProd_Hosts
VM_to_HostShouldRunOnFalseTest_VMsProd_Hosts
-
1.2.3.2.3 DRS Rules
- - -
NameTypeEnabledMandatoryVirtual Machines
Test_VMsVMAntiAffinityTrueFalseTest_1, Test_2
TestVMAffinityFalseFalseTest_1, Test_2
-

1.2.3.3 Update Manager Baselines

- - - -
NameDescriptionTypeTarget TypeLast Update TimeNumber of Patches
Critical Host Patches (Predefined)A predefined baseline for all critical patches for HostsPatchHost28/02/2017 9:35:00 PM71
Non-Critical Host Patches (Predefined)A predefined baseline for all non-critical patches for HostsPatchHost28/02/2017 9:35:00 PM236
VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)PatchHost23/05/2018 9:28:38 AM1
-

1.2.3.4 Permissions

The following table details the permissions assigned to cluster VSAN-Cluster.

- - - - - - -
User/GroupIs Group?RoleDefined InPropagate
VSPHERE.LOCAL\SolutionUsersTrueReadOnlyVSAN-ClusterFalse
VSPHERE.LOCAL\vpxd-extension-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vpxd-0cd516db-cbaa-434b-8b6f-90452748e378FalseAdminDatacentersTrue
VSPHERE.LOCAL\vsphere-webclient-0cd516db-cbaa-434b-8b6f-90452748e378FalseReadOnlyDatacentersTrue
VSPHERE.LOCAL\AdministratorFalseAdminDatacentersTrue
VSPHERE.LOCAL\AdministratorsTrueAdminDatacentersTrue
-
-

1.3 Resource Pools

The following section provides information on the configuration of resource pools.

-
NameResources
IdResourcePool-resgroup-35
ParentNew Cluster
CPU Shares LevelNormal
Number of CPU Shares4000
CPU Reservation0 MHz
CPU Expandable ReservationTrue
CPU LimitUnlimited
Memory Shares LevelNormal
Number of Memory Shares163840
Memory Reservation0 GB
Memory Expandable ReservationTrue
Memory LimitUnlimited
-

-

-
NameTesting
IdResourcePool-resgroup-62
ParentResources
CPU Shares LevelNormal
Number of CPU Shares4000
CPU Reservation0 MHz
CPU Expandable ReservationTrue
CPU Limit1000 MHz
Memory Shares LevelNormal
Number of Memory Shares163840
Memory Reservation0 GB
Memory Expandable ReservationTrue
Memory LimitUnlimited
-

-

-
NameResources
IdResourcePool-resgroup-28
ParentTest Cluster
CPU Shares LevelNormal
Number of CPU Shares4000
CPU Reservation0 MHz
CPU Expandable ReservationTrue
CPU LimitUnlimited
Memory Shares LevelNormal
Number of Memory Shares163840
Memory Reservation0 GB
Memory Expandable ReservationTrue
Memory LimitUnlimited
-

-

-
NameResources
IdResourcePool-resgroup-8
ParentVSAN-Cluster
CPU Shares LevelNormal
Number of CPU Shares4000
CPU Reservation6612 MHz
CPU Expandable ReservationTrue
CPU Limit6612 MHz
Memory Shares LevelNormal
Number of Memory Shares163840
Memory Reservation0.70 GB
Memory Expandable ReservationTrue
Memory Limit0.70 GB
-
-

1.4 Hosts

The following section provides information on the configuration of VMware ESXi hosts.

- - - -
NameVersionBuildParentConnection StateCPU Usage MHzMemory Usage GBVM Count
192.168.1.1116.5.05969303VSAN-ClusterConnected1703.331
192.168.1.1126.5.05969303VSAN-ClusterConnected1353.331
192.168.1.1136.5.05969303VSAN-ClusterConnected1263.331
-

1.4.1 192.168.1.111

1.4.1.1 Hardware

The following section provides information on the host hardware configuration of 192.168.1.111.

-
Name192.168.1.111
ParentVSAN-Cluster
ManufacturerVMware, Inc.
ModelVMware Virtual Platform
Serial Number 
Asset Tag 
Processor TypeIntel(R) Xeon(R) CPU D-1528 @ 1.90GHz
HyperThreadingFalse
CPU Socket Count2
CPU Core Count2
CPU Thread Count2
CPU Speed1.9 GHz
Memory6 GB
NUMA Nodes1
NIC Count2
Maximum EVC Modeintel-broadwell
Power Management PolicyHigh Performance
Scratch Location/tmp/scratch
Bios Version6.00
Bios Release Date28/07/2017 12:00:00 AM
ESXi Version6.5.0
ESXi Build5969303
Uptime Days74.7
-
1.4.1.1.1 Boot Devices
-
Host192.168.1.111
Devicenaa.6000c29e041dd7e2fea7da7634a3eaf0
Boot Typelocal
VendorVMware
ModelVirtual disk
Size MB2048
Is SASfalse
Is SSDfalse
Is USBfalse
-
1.4.1.1.2 PCI Devices
- - - - -
VMkernel NamePCI AddressDevice ClassDevice NameVendor NameSlot Description
vmhba00000:13:00.0Serial Attached SCSI controllerPVSCSI SCSI ControllerVMware Inc.SCSI0
vmhba10000:00:07.1IDE interfacePIIX4 for 430TX/440BX/MX IDE ControllerIntel Corporation 
vmnic00000:03:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet0
vmnic10000:0b:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet1
-

1.4.1.2 System

The following section provides information on the host system configuration of 192.168.1.111.
1.4.1.2.1 Licensing
- - -
License TypeLicense Key
VMware vSphere 6 Enterprise Plus*****-*****-*****-079HM-29JHN
-
1.4.1.2.2 Host Profile
- - -
NameDescription
Host Profile TestHost Profile for doco report
-
1.4.1.2.3 Image Profile
- - -
Image ProfileVendorInstallation Date
(Updated) ESXi-6.5.0-4564106-standardVMware, Inc.28/02/2017 9:16:02 PM
-
1.4.1.2.4 Time Configuration
- - -
Time ZoneNTP Service RunningNTP Server(s)
UTCFalse0.au.pool.ntp.org, 1.au.pool.ntp.org
-
1.4.1.2.5 Syslog Configuration
- - -
SysLog ServerPort
192.168.1.110 
-
1.4.1.2.6 Update Manager Compliance
- - - - -
BaselineStatus
VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)NotCompliant
Non-Critical Host Patches (Predefined)NotCompliant
Critical Host Patches (Predefined)NotCompliant
-

1.4.1.3 Storage

The following section provides information on the host storage configuration of 192.168.1.111.
1.4.1.3.1 Datastores
- -
NameTypeVersionTotal Capacity GBUsed Capacity GBFree Space GB% Used
vsanDatastorevsan 23.982.6321.3410.98
-

1.4.1.4 Network

The following section provides information on the host network configuration of 192.168.1.111.

-
VMHost192.168.1.111
Virtual SwitchesvSwitch0
VMKernel Adaptersvmk0
Physical Adaptersvmnic0, vmnic1
VMKernel Gateway192.168.1.1
IPv6 EnabledTrue
VMKernel IPv6 Gateway 
DNS Servers192.168.1.10, 8.8.8.8
Host Namevesxi65-1
Domain Name 
Search Domainlab.local
-
1.4.1.4.1 Physical Adapters
The following table details the physical network adapters for 192.168.1.111.

- - - -
Device NameMAC AddressBitrate/SecondFull DuplexWake on LAN Support
vmnic000:0c:29:57:f3:9810000TrueFalse
vmnic100:0c:29:57:f3:a210000TrueFalse
-
1.4.1.4.2 Cisco Discovery Protocol
- - - -
NICConnectedSwitchHardware PlatformPort ID
vmnic0Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
vmnic1Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
-
1.4.1.4.3 VMkernel Adapters
The following table details the VMkernel adapters for 192.168.1.111

-
Device Namevmk0
Network LabelManagement Network
MTU1500
MAC Address00:0c:29:57:f3:98
IP Address192.168.1.111
Subnet Mask255.255.255.0
vMotion TrafficFalse
FT LoggingFalse
Management TrafficTrue
vSAN TrafficTrue
-
1.4.1.4.4 Standard Virtual Switches
The following sections detail the standard virtual switch configuration for 192.168.1.111.

-
NamevSwitch0
MTU1500
Number of Ports1536
Number of Ports Available1528
Load BalancingLoadBalanceSrcId
Failover DetectionLinkStatus
Notify SwitchesTrue
Failback EnabledTrue
Active NICsvmnic0
Standby NICs 
Unused NICs 
-
1.4.1.4.5 Virtual Switch Security Policy
- -
vSwitchMAC Address ChangesForged TransmitsPromiscuous Mode
vSwitch0TrueTrueFalse
-
1.4.1.4.6 Virtual Switch NIC Teaming
- -
vSwitchLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0LoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-
1.4.1.4.7 Virtual Port Groups
- - -
vSwitchPortgroupVLAN ID
vSwitch0Management Network0
vSwitch0VM Network0
-
1.4.1.4.8 Virtual Port Group Security Policy
- - -
vSwitchPortgroupMAC ChangesForged TransmitsPromiscuous Mode
vSwitch0VM NetworkTrueTrueFalse
vSwitch0Management NetworkTrueTrueFalse
-
1.4.1.4.9 Virtual Port Group NIC Teaming
- - -
vSwitchPortgroupLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0VM NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
vSwitch0Management NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-

1.4.1.5 Security

The following section provides information on the host security configuration of 192.168.1.111.
1.4.1.5.1 Lockdown Mode
-
Lockdown ModeTrue
-
1.4.1.5.2 Services
- - - - - - - - - - - - - -
NameLabelPolicyRunningRequired
DCUIDirect Console UIonTrueFalse
lbtdLoad-Based Teaming DaemononTrueFalse
lwsmdActive Directory ServiceonTrueFalse
ntpdNTP DaemonoffFalseFalse
pcscdPC/SC Smart Card DaemonoffFalseFalse
sfcbd-watchdogCIM ServeronFalseFalse
snmpdSNMP ServeronFalseFalse
TSMESXi ShellonTrueFalse
TSM-SSHSSHonTrueFalse
vmsyslogdSyslog ServeronTrueTrue
vmware-fdmvSphere High Availability AgentonTrueFalse
vpxaVMware vCenter AgentonTrueFalse
xorgX.Org ServeronFalseFalse
-
1.4.1.5.3 Authentication Services
- - -
DomainDomain MembershipTrusted Domains
LAB.LOCALOk 
-

1.4.2 192.168.1.112

1.4.2.1 Hardware

The following section provides information on the host hardware configuration of 192.168.1.112.

-
Name192.168.1.112
ParentVSAN-Cluster
ManufacturerVMware, Inc.
ModelVMware Virtual Platform
Serial Number 
Asset Tag 
Processor TypeIntel(R) Xeon(R) CPU D-1528 @ 1.90GHz
HyperThreadingFalse
CPU Socket Count2
CPU Core Count2
CPU Thread Count2
CPU Speed1.9 GHz
Memory6 GB
NUMA Nodes1
NIC Count2
Maximum EVC Modeintel-broadwell
Power Management PolicyHigh Performance
Scratch Location/tmp/scratch
Bios Version6.00
Bios Release Date28/07/2017 12:00:00 AM
ESXi Version6.5.0
ESXi Build5969303
Uptime Days74.7
-
1.4.2.1.1 Boot Devices
-
Host192.168.1.112
Devicenaa.6000c29a60075960e1284ed911495826
Boot Typelocal
VendorVMware
ModelVirtual disk
Size MB2048
Is SASfalse
Is SSDfalse
Is USBfalse
-
1.4.2.1.2 PCI Devices
- - - - -
VMkernel NamePCI AddressDevice ClassDevice NameVendor NameSlot Description
vmhba00000:13:00.0Serial Attached SCSI controllerPVSCSI SCSI ControllerVMware Inc.SCSI0
vmhba10000:00:07.1IDE interfacePIIX4 for 430TX/440BX/MX IDE ControllerIntel Corporation 
vmnic00000:03:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet0
vmnic10000:0b:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet1
-

1.4.2.2 System

The following section provides information on the host system configuration of 192.168.1.112.
1.4.2.2.1 Licensing
- - -
License TypeLicense Key
VMware vSphere 6 Enterprise Plus*****-*****-*****-079HM-29JHN
-
1.4.2.2.2 Host Profile
- - -
NameDescription
Host Profile TestHost Profile for doco report
-
1.4.2.2.3 Image Profile
- - -
Image ProfileVendorInstallation Date
(Updated) ESXi-6.5.0-4564106-standardVMware, Inc.28/02/2017 9:16:28 PM
-
1.4.2.2.4 Time Configuration
- - -
Time ZoneNTP Service RunningNTP Server(s)
UTCFalse0.au.pool.ntp.org, 1.au.pool.ntp.org
-
1.4.2.2.5 Syslog Configuration
- - -
SysLog ServerPort
192.168.1.110 
-
1.4.2.2.6 Update Manager Compliance
- - - - -
BaselineStatus
VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)NotCompliant
Non-Critical Host Patches (Predefined)NotCompliant
Critical Host Patches (Predefined)NotCompliant
-

1.4.2.3 Storage

The following section provides information on the host storage configuration of 192.168.1.112.
1.4.2.3.1 Datastores
- -
NameTypeVersionTotal Capacity GBUsed Capacity GBFree Space GB% Used
vsanDatastorevsan 23.982.6321.3410.98
-

1.4.2.4 Network

The following section provides information on the host network configuration of 192.168.1.112.

-
VMHost192.168.1.112
Virtual SwitchesvSwitch0
VMKernel Adaptersvmk0
Physical Adaptersvmnic0, vmnic1
VMKernel Gateway192.168.1.1
IPv6 EnabledTrue
VMKernel IPv6 Gateway 
DNS Servers192.168.1.10, 8.8.8.8
Host Namevesxi65-2
Domain Name 
Search Domainlab.local
-
1.4.2.4.1 Physical Adapters
The following table details the physical network adapters for 192.168.1.112.

- - - -
Device NameMAC AddressBitrate/SecondFull DuplexWake on LAN Support
vmnic000:0c:29:0a:c0:5710000TrueFalse
vmnic100:0c:29:0a:c0:6110000TrueFalse
-
1.4.2.4.2 Cisco Discovery Protocol
- - - -
NICConnectedSwitchHardware PlatformPort ID
vmnic0Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
vmnic1Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
-
1.4.2.4.3 VMkernel Adapters
The following table details the VMkernel adapters for 192.168.1.112

-
Device Namevmk0
Network LabelManagement Network
MTU1500
MAC Address00:0c:29:0a:c0:57
IP Address192.168.1.112
Subnet Mask255.255.255.0
vMotion TrafficFalse
FT LoggingFalse
Management TrafficTrue
vSAN TrafficTrue
-
1.4.2.4.4 Standard Virtual Switches
The following sections detail the standard virtual switch configuration for 192.168.1.112.

-
NamevSwitch0
MTU1500
Number of Ports1536
Number of Ports Available1528
Load BalancingLoadBalanceSrcId
Failover DetectionLinkStatus
Notify SwitchesTrue
Failback EnabledTrue
Active NICsvmnic0
Standby NICs 
Unused NICs 
-
1.4.2.4.5 Virtual Switch Security Policy
- -
vSwitchMAC Address ChangesForged TransmitsPromiscuous Mode
vSwitch0TrueTrueFalse
-
1.4.2.4.6 Virtual Switch NIC Teaming
- -
vSwitchLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0LoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-
1.4.2.4.7 Virtual Port Groups
- - -
vSwitchPortgroupVLAN ID
vSwitch0Management Network0
vSwitch0VM Network0
-
1.4.2.4.8 Virtual Port Group Security Policy
- - -
vSwitchPortgroupMAC ChangesForged TransmitsPromiscuous Mode
vSwitch0VM NetworkTrueTrueFalse
vSwitch0Management NetworkTrueTrueFalse
-
1.4.2.4.9 Virtual Port Group NIC Teaming
- - -
vSwitchPortgroupLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0VM NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
vSwitch0Management NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-

1.4.2.5 Security

The following section provides information on the host security configuration of 192.168.1.112.
1.4.2.5.1 Lockdown Mode
-
Lockdown ModeFalse
-
1.4.2.5.2 Services
- - - - - - - - - - - - - -
NameLabelPolicyRunningRequired
DCUIDirect Console UIonTrueFalse
lbtdLoad-Based Teaming DaemononTrueFalse
lwsmdActive Directory ServiceonTrueFalse
ntpdNTP DaemonoffFalseFalse
pcscdPC/SC Smart Card DaemonoffFalseFalse
sfcbd-watchdogCIM ServeronFalseFalse
snmpdSNMP ServeronFalseFalse
TSMESXi ShellonTrueFalse
TSM-SSHSSHonTrueFalse
vmsyslogdSyslog ServeronTrueTrue
vmware-fdmvSphere High Availability AgentonTrueFalse
vpxaVMware vCenter AgentonTrueFalse
xorgX.Org ServeronFalseFalse
-
1.4.2.5.3 Authentication Services
- - -
DomainDomain MembershipTrusted Domains
LAB.LOCALOk 
-

1.4.3 192.168.1.113

1.4.3.1 Hardware

The following section provides information on the host hardware configuration of 192.168.1.113.

-
Name192.168.1.113
ParentVSAN-Cluster
ManufacturerVMware, Inc.
ModelVMware Virtual Platform
Serial Number 
Asset Tag 
Processor TypeIntel(R) Xeon(R) CPU D-1528 @ 1.90GHz
HyperThreadingFalse
CPU Socket Count2
CPU Core Count2
CPU Thread Count2
CPU Speed1.9 GHz
Memory6 GB
NUMA Nodes1
NIC Count2
Maximum EVC Modeintel-broadwell
Power Management PolicyHigh Performance
Scratch Location/tmp/scratch
Bios Version6.00
Bios Release Date28/07/2017 12:00:00 AM
ESXi Version6.5.0
ESXi Build5969303
Uptime Days74.7
-
1.4.3.1.1 Boot Devices
-
Host192.168.1.113
Devicenaa.6000c2994ed56a57b2049108de88effd
Boot Typelocal
VendorVMware
ModelVirtual disk
Size MB2048
Is SASfalse
Is SSDfalse
Is USBfalse
-
1.4.3.1.2 PCI Devices
- - - - -
VMkernel NamePCI AddressDevice ClassDevice NameVendor NameSlot Description
vmhba00000:13:00.0Serial Attached SCSI controllerPVSCSI SCSI ControllerVMware Inc.SCSI0
vmhba10000:00:07.1IDE interfacePIIX4 for 430TX/440BX/MX IDE ControllerIntel Corporation 
vmnic00000:03:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet0
vmnic10000:0b:00.0Ethernet controllervmxnet3 Virtual Ethernet ControllerVMware Inc.Ethernet1
-

1.4.3.2 System

The following section provides information on the host system configuration of 192.168.1.113.
1.4.3.2.1 Licensing
- - -
License TypeLicense Key
VMware vSphere 6 Enterprise Plus*****-*****-*****-079HM-29JHN
-
1.4.3.2.2 Host Profile
- - -
NameDescription
Host Profile TestHost Profile for doco report
-
1.4.3.2.3 Image Profile
- - -
Image ProfileVendorInstallation Date
(Updated) ESXi-6.5.0-4564106-standardVMware, Inc.28/02/2017 9:17:02 PM
-
1.4.3.2.4 Time Configuration
- - -
Time ZoneNTP Service RunningNTP Server(s)
UTCFalse0.au.pool.ntp.org, 1.au.pool.ntp.org
-
1.4.3.2.5 Syslog Configuration
- - -
SysLog ServerPort
192.168.1.110 
-
1.4.3.2.6 Update Manager Compliance
- - - - -
BaselineStatus
VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)NotCompliant
Non-Critical Host Patches (Predefined)NotCompliant
Critical Host Patches (Predefined)NotCompliant
-

1.4.3.3 Storage

The following section provides information on the host storage configuration of 192.168.1.113.
1.4.3.3.1 Datastores
- -
NameTypeVersionTotal Capacity GBUsed Capacity GBFree Space GB% Used
vsanDatastorevsan 23.982.6321.3410.98
-

1.4.3.4 Network

The following section provides information on the host network configuration of 192.168.1.113.

-
VMHost192.168.1.113
Virtual SwitchesvSwitch0
VMKernel Adaptersvmk0
Physical Adaptersvmnic0, vmnic1
VMKernel Gateway192.168.1.1
IPv6 EnabledTrue
VMKernel IPv6 Gateway 
DNS Servers192.168.1.10, 8.8.8.8
Host Namevesxi65-3
Domain Name 
Search Domainlab.local
-
1.4.3.4.1 Physical Adapters
The following table details the physical network adapters for 192.168.1.113.

- - - -
Device NameMAC AddressBitrate/SecondFull DuplexWake on LAN Support
vmnic000:0c:29:a2:26:0410000TrueFalse
vmnic100:0c:29:a2:26:0e10000TrueFalse
-
1.4.3.4.2 Cisco Discovery Protocol
- - - -
NICConnectedSwitchHardware PlatformPort ID
vmnic0Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
vmnic1Truedca5f4a56b91Cisco SG200-26P (PID:SLM2024PT)-VSDgi1
-
1.4.3.4.3 VMkernel Adapters
The following table details the VMkernel adapters for 192.168.1.113

-
Device Namevmk0
Network LabelManagement Network
MTU1500
MAC Address00:0c:29:a2:26:04
IP Address192.168.1.113
Subnet Mask255.255.255.0
vMotion TrafficFalse
FT LoggingFalse
Management TrafficTrue
vSAN TrafficTrue
-
1.4.3.4.4 Standard Virtual Switches
The following sections detail the standard virtual switch configuration for 192.168.1.113.

-
NamevSwitch0
MTU1500
Number of Ports1536
Number of Ports Available1528
Load BalancingLoadBalanceSrcId
Failover DetectionLinkStatus
Notify SwitchesTrue
Failback EnabledTrue
Active NICsvmnic0
Standby NICs 
Unused NICs 
-
1.4.3.4.5 Virtual Switch Security Policy
- -
vSwitchMAC Address ChangesForged TransmitsPromiscuous Mode
vSwitch0TrueTrueFalse
-
1.4.3.4.6 Virtual Switch NIC Teaming
- -
vSwitchLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0LoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-
1.4.3.4.7 Virtual Port Groups
- - -
vSwitchPortgroupVLAN ID
vSwitch0Management Network0
vSwitch0VM Network0
-
1.4.3.4.8 Virtual Port Group Security Policy
- - -
vSwitchPortgroupMAC ChangesForged TransmitsPromiscuous Mode
vSwitch0VM NetworkTrueTrueFalse
vSwitch0Management NetworkTrueTrueFalse
-
1.4.3.4.9 Virtual Port Group NIC Teaming
- - -
vSwitchPortgroupLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive NICsStandby NICsUnused NICs
vSwitch0VM NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
vSwitch0Management NetworkLoadBalanceSrcIdLinkStatusTrueTruevmnic0  
-

1.4.3.5 Security

The following section provides information on the host security configuration of 192.168.1.113.
1.4.3.5.1 Lockdown Mode
-
Lockdown ModeFalse
-
1.4.3.5.2 Services
- - - - - - - - - - - - - -
NameLabelPolicyRunningRequired
DCUIDirect Console UIonTrueFalse
lbtdLoad-Based Teaming DaemononTrueFalse
lwsmdActive Directory ServiceonTrueFalse
ntpdNTP DaemonoffFalseFalse
pcscdPC/SC Smart Card DaemonoffFalseFalse
sfcbd-watchdogCIM ServeronFalseFalse
snmpdSNMP ServeronFalseFalse
TSMESXi ShellonTrueFalse
TSM-SSHSSHonTrueFalse
vmsyslogdSyslog ServeronTrueTrue
vmware-fdmvSphere High Availability AgentonTrueFalse
vpxaVMware vCenter AgentonTrueFalse
xorgX.Org ServeronFalseFalse
-
1.4.3.5.3 Authentication Services
- - -
DomainDomain MembershipTrusted Domains
LAB.LOCALOk 
-
-

1.5 Distributed Virtual Switches

The following section provides information on the Distributed Virtual Switch configuration.

- - -
VDSwitchDatacenterManufacturerVersionNumber of UplinksNumber of PortsHost Count
DSwitchDatacenterVMware, Inc.6.5.04203
DSwitch 1DatacenterVMware, Inc.5.5.0280
-

1.5.1 DSwitch

1.5.1.1 General Properties

-
NameDSwitch
DatacenterDatacenter
ManufacturerVMware, Inc.
Version6.5.0
Number of Uplinks4
Number of Ports20
MTU1500
Network I/O Control EnabledFalse
Discovery ProtocolCDP
Discovery Protocol OperationListen
Connected Hosts192.168.1.111, 192.168.1.112, 192.168.1.113
-

1.5.1.2 Uplinks

- - - - - - - - - - - - -
VDSwitchVM HostUplink NamePhysical Network AdapterUplink Port Group
DSwitch192.168.1.111Uplink 1 DSwitch-DVUplinks-21
DSwitch192.168.1.111Uplink 2vmnic1DSwitch-DVUplinks-21
DSwitch192.168.1.111Uplink 3 DSwitch-DVUplinks-21
DSwitch192.168.1.111Uplink 4 DSwitch-DVUplinks-21
DSwitch192.168.1.112Uplink 1 DSwitch-DVUplinks-21
DSwitch192.168.1.112Uplink 2vmnic1DSwitch-DVUplinks-21
DSwitch192.168.1.112Uplink 3 DSwitch-DVUplinks-21
DSwitch192.168.1.112Uplink 4 DSwitch-DVUplinks-21
DSwitch192.168.1.113Uplink 1 DSwitch-DVUplinks-21
DSwitch192.168.1.113Uplink 2vmnic1DSwitch-DVUplinks-21
DSwitch192.168.1.113Uplink 3 DSwitch-DVUplinks-21
DSwitch192.168.1.113Uplink 4 DSwitch-DVUplinks-21
-

1.5.1.3 Security

- -
VDSwitchAllow PromiscuousForged TransmitsMAC Address Changes
DSwitchFalseFalseFalse
-

1.5.1.4 Traffic Shaping

- - -
VDSwitchDirectionEnabledAverage Bandwidth (kbit/s)Peak Bandwidth (kbit/s)Burst Size (KB)
DSwitchInFalse100000000100000000104857600
DSwitchOutFalse100000000100000000104857600
-

1.5.1.5 Port Groups

- - -
VDSwitchPortgroupDatacenterVLAN ConfigurationPort BindingNumber of Ports
DSwitchDPortGroupDatacenterVLAN 8Static8
DSwitchDSwitch-DVUplinks-21DatacenterVLAN Trunk [0-4094]Static12
-

1.5.1.6 Port Group Security

- - -
VDSwitchPort GroupAllow PromiscuousForged TransmitsMAC Address Changes
DSwitchDSwitch-DVUplinks-21FalseTrueFalse
DSwitchDPortGroupFalseFalseFalse
-

1.5.1.7 Port Group NIC Teaming

- - -
VDSwitchPort GroupLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive UplinksStandby UplinksUnused Uplinks
DSwitchDPortGroupLoadBalanceSrcIdLinkStatusTrueTrueUplink 1
Uplink 2
Uplink 3
Uplink 4
  
DSwitchDSwitch-DVUplinks-21LoadBalanceSrcIdLinkStatusTrueTrue  Uplink 1
Uplink 2
Uplink 3
Uplink 4
-

1.5.1.8 Private VLANs

- - - -
Primary VLAN IDPrivate VLAN TypeSecondary VLAN ID
1Promiscuous1
1Isolated2
1Community3
-

1.5.2 DSwitch 1

1.5.2.1 General Properties

-
NameDSwitch 1
DatacenterDatacenter
ManufacturerVMware, Inc.
Version5.5.0
Number of Uplinks2
Number of Ports8
MTU1500
Network I/O Control EnabledFalse
Discovery ProtocolCDP
Discovery Protocol OperationListen
Connected Hosts 
-

1.5.2.2 Security

- -
VDSwitchAllow PromiscuousForged TransmitsMAC Address Changes
DSwitch 1FalseFalseFalse
-

1.5.2.3 Traffic Shaping

- - -
VDSwitchDirectionEnabledAverage Bandwidth (kbit/s)Peak Bandwidth (kbit/s)Burst Size (KB)
DSwitch 1InFalse100000000100000000104857600
DSwitch 1OutFalse100000000100000000104857600
-

1.5.2.4 Port Groups

- - -
VDSwitchPortgroupDatacenterVLAN ConfigurationPort BindingNumber of Ports
DSwitch 1DPortGroup 1Datacenter Static8
DSwitch 1DSwitch 1-DVUplinks-24DatacenterVLAN Trunk [0-4094]Static0
-

1.5.2.5 Port Group Security

- - -
VDSwitchPort GroupAllow PromiscuousForged TransmitsMAC Address Changes
DSwitch 1DPortGroup 1FalseFalseFalse
DSwitch 1DSwitch 1-DVUplinks-24FalseTrueFalse
-

1.5.2.6 Port Group NIC Teaming

- - -
VDSwitchPort GroupLoad BalancingFailover DetectionNotify SwitchesFailback EnabledActive UplinksStandby UplinksUnused Uplinks
DSwitch 1DPortGroup 1LoadBalanceSrcIdLinkStatusTrueTrueUplink 1
Uplink 2
  
DSwitch 1DSwitch 1-DVUplinks-24LoadBalanceSrcIdLinkStatusTrueTrue  Uplink 1
Uplink 2
-
-

1.6 vSAN

The following section provides information on the vSAN configuration.

1.6.1 VSAN-Cluster

-
NameVSAN-Cluster
TypeAll-Flash
Version6.6.1
Number of Hosts3
Stretched ClusterFalse
Disk Format Version5
Total Number of Disks6
Total Number of Disk Groups3
Disk Claim ModeManual
Deduplication and CompressionFalse
Encryption EnabledFalse
Health Check EnabledTrue
HCL Last Updated5/08/2018 5:03:21 AM
-

1.7 Storage

The following section provides information on the VMware vSphere storage configuration.

- -
NameTypeTotal Capacity GBUsed Capacity GBFree Space GB% UsedHost Count
vsanDatastorevsan23.982.6321.3410.983
-

1.7.1 Datastore Specifications

- -
NameDatacenterTypeVersionStateSIOC EnabledCongestion Threshold ms
vsanDatastoreDatacentervsan AvailableFalse 
-
-

1.8 Virtual Machines

The following section provides detailed information on Virtual Machines.

1.8.1 Test_1

-
NameTest_1
Operating System 
Hardware Versionv13
Power StatePoweredOff
VM Tools StatustoolsNotInstalled
Host192.168.1.112
Parent FolderDiscovered virtual machine
Parent Resource PoolResources
vCPUs1
Cores per Socket1
Total vCPUs1
CPU ResourcesNormal / 1000
CPU Reservation0
CPU Limit0 MHz
Memory Allocation4 GB
Memory ResourcesNormal / 40960
-

1.8.2 Test_2

-
NameTest_2
Operating System 
Hardware Versionv13
Power StatePoweredOff
VM Tools StatustoolsNotInstalled
Host192.168.1.111
Parent Foldervm
Parent Resource PoolResources
vCPUs1
Cores per Socket1
Total vCPUs1
CPU ResourcesNormal / 1000
CPU Reservation0
CPU Limit0 MHz
Memory Allocation4 GB
Memory ResourcesNormal / 40960
-

1.8.3 Test_3

-
NameTest_3
Operating System 
Hardware Versionv13
Power StatePoweredOff
VM Tools Status 
Host192.168.1.113
Parent Foldervm
Parent Resource PoolResources
vCPUs1
Cores per Socket1
Total vCPUs1
CPU ResourcesNormal / 1000
CPU Reservation0
CPU Limit0 MHz
Memory Allocation4 GB
Memory ResourcesNormal / 40960
-

1.8.4 VM Snapshots

- -
Virtual MachineNameDescriptionDays Old
Test_2VM Snapshot 3%252f9%252f2018 3:00 PM UTC+11:00 149
-
-

1.9 VMware Update Manager

The following section provides information on VMware Update Manager.

1.9.1 Baselines

- - - -
NameDescriptionTypeTarget TypeLast Update TimeNumber of Patches
Critical Host Patches (Predefined)A predefined baseline for all critical patches for HostsPatchHost28/02/2017 9:35:00 PM71
Non-Critical Host Patches (Predefined)A predefined baseline for all non-critical patches for HostsPatchHost28/02/2017 9:35:00 PM236
VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)VMware ESXi 6.5.0 U2 (vSAN 6.6.1 Update 2, build 8294253)PatchHost23/05/2018 9:28:38 AM1
-
diff --git a/Samples/Sample_vSphere_Report_1.png b/Samples/Sample_vSphere_Report_1.png deleted file mode 100644 index db1bf3f..0000000 Binary files a/Samples/Sample_vSphere_Report_1.png and /dev/null differ diff --git a/Samples/Sample_vSphere_Report_2.png b/Samples/Sample_vSphere_Report_2.png deleted file mode 100644 index 4eb9b77..0000000 Binary files a/Samples/Sample_vSphere_Report_2.png and /dev/null differ diff --git a/Src/Private/Get-PciDeviceDetail.ps1 b/Src/Private/Get-PciDeviceDetail.ps1 deleted file mode 100644 index 7c99425..0000000 --- a/Src/Private/Get-PciDeviceDetail.ps1 +++ /dev/null @@ -1,81 +0,0 @@ -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/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 b/Src/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 deleted file mode 100644 index b6e6066..0000000 --- a/Src/Public/Invoke-AsBuiltReport.VMware.vSphere.ps1 +++ /dev/null @@ -1,5100 +0,0 @@ -function Invoke-AsBuiltReport.VMware.vSphere { - <# - .SYNOPSIS - PowerShell script to document the configuration of VMware vSphere infrastucture in Word/HTML/Text formats - .DESCRIPTION - Documents the configuration of VMware vSphere infrastucture in Word/HTML/Text formats using PScribo. - .NOTES - Version: 1.3.6 - Author: Tim Carman - Twitter: @tpcarman - Github: tpcarman - Credits: Iain Brighton (@iainbrighton) - PScribo module - .LINK - https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere - #> - - param ( - [String[]] $Target, - [PSCredential] $Credential - ) - - Write-PScriboMessage -Plugin "Module" -IsWarning "Please refer to www.asbuiltreport.com for more detailed information about this project." - Write-PScriboMessage -Plugin "Module" -IsWarning "Do not forget to update your report configuration file after each new version release." - Write-PScriboMessage -Plugin "Module" -IsWarning "Documentation: https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere" - Write-PScriboMessage -Plugin "Module" -IsWarning "Issues or bug reporting: https://github.com/AsBuiltReport/AsBuiltReport.VMware.vSphere/issues" - - # Check the current AsBuiltReport.VMware.vSphere module - Try { - $InstalledVersion = Get-Module -ListAvailable -Name AsBuiltReport.VMware.vSphere -ErrorAction SilentlyContinue | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version - - if ($InstalledVersion) { - Write-PScriboMessage -Plugin "Module" -IsWarning "AsBuiltReport.VMware.vSphere $($InstalledVersion.ToString()) is currently installed." - $LatestVersion = Find-Module -Name AsBuiltReport.VMware.vSphere -Repository PSGallery -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version - if ($LatestVersion -gt $InstalledVersion) { - Write-PScriboMessage -Plugin "Module" -IsWarning "AsBuiltReport.VMware.vSphere $($LatestVersion.ToString()) is available." - Write-PScriboMessage -Plugin "Module" -IsWarning "Run 'Update-Module -Name AsBuiltReport.VMware.vSphere -Force' to install the latest version." - } - } - } Catch { - Write-PScriboMessage -Plugin "Module" -IsWarning $_.Exception.Message - } - - # Import Report Configuration - $Report = $ReportConfig.Report - $InfoLevel = $ReportConfig.InfoLevel - $Options = $ReportConfig.Options - # Used to set values to TitleCase where required - $TextInfo = (Get-Culture).TextInfo - - #region Script Body - #---------------------------------------------------------------------------------------------# - # SCRIPT BODY # - #---------------------------------------------------------------------------------------------# - # Connect to vCenter Server using supplied credentials - foreach ($VIServer in $Target) { - try { - Write-PScriboMessage "Connecting to vCenter Server '$VIServer'." - $vCenter = Connect-VIServer $VIServer -Credential $Credential -ErrorAction Stop - } catch { - Write-Error $_ - } - - #region Generate vSphere report - if ($vCenter) { - # Check logged in user has sufficient privileges to generate an As Built Report - Write-PScriboMessage 'Checking vCenter user privileges.' - Try { - $AuthMgr = Get-View $($vCenter.ExtensionData.Content.AuthorizationManager) - $UserPrivileges = ($authMgr.FetchUserPrivilegeOnEntities("Folder-group-d1", $vCenter.User)).privileges - } Catch { - Write-PScriboMessage 'Unable to obtain vCenter user privileges.' - } - - # 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 $vCenter | Where-Object { - $_.ExtensionData.Config.ManagedBy.ExtensionKey -notlike 'com.vmware.vcDr*' - } | Sort-Object Name - $VMLookup = @{ } - foreach ($VM in $VMs) { - $VMLookup.($VM.Id) = $VM.Name - } - - # 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 - Write-PScriboMessage 'Creating VMHost lookup hashtable.' - $VMHosts = Get-VMHost -Server $vCenter | Where-Object { $_.Model -notlike "*VMware Mobility Platform" -and $_.Version -gt 5 } | Sort-Object Name - $VMHostLookup = @{ } - foreach ($VMHost in $VMHosts) { - $VMHostLookup.($VMHost.Id) = $VMHost.Name - } - - # Create a lookup hashtable to link Datastore MoRefs to Names - Write-PScriboMessage 'Creating Datastore lookup hashtable.' - $Datastores = Get-Datastore -Server $vCenter | 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 - Write-PScriboMessage 'Creating VDPortGroup lookup hashtable.' - $VDPortGroups = Get-VDPortgroup -Server $vCenter | Sort-Object Name - $VDPortGroupLookup = @{ } - foreach ($VDPortGroup in $VDPortGroups) { - $VDPortGroupLookup.($VDPortGroup.Key) = $VDPortGroup.Name - } - - # Create a lookup hashtable to link EVC Modes to Names - Write-PScriboMessage 'Creating EVC lookup hashtable.' - $SupportedEvcModes = $vCenter.ExtensionData.Capability.SupportedEVCMode - $EvcModeLookup = @{ } - foreach ($EvcMode in $SupportedEvcModes) { - $EvcModeLookup.($EvcMode.Key) = $EvcMode.Label - } - - $si = Get-View ServiceInstance -Server $vCenter - $extMgr = Get-View -Id $si.Content.ExtensionManager -Server $vCenter - - #region VMware Update Manager Server Name - Write-PScriboMessage 'Checking for VMware Update Manager Server.' - $VumServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vcIntegrity' } | - Select-Object @{ - N = 'Name'; - E = { ($_.Server | Where-Object { $_.Type -eq 'SOAP' -and $_.Company -eq 'VMware, Inc.' } | - Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } - } - #endregion VMware Update Manager Server Name - - #region VxRail Manager Server Name - Write-PScriboMessage 'Checking for VxRail Manager Server.' - $VxRailMgr = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vxrail' } | - Select-Object @{ - N = 'Name'; - E = { ($_.Server | Where-Object { $_.Type -eq 'HTTPS' } | - Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } - } - #endregion VxRail Manager Server Name - - #region Site Recovery Manager Server Name - Write-PScriboMessage 'Checking for VMware Site Recovery Manager Server.' - $SrmServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.vcDr' } | - Select-Object @{ - N = 'Name'; - E = { ($_.Server | Where-Object { $_.Company -eq 'VMware, Inc.' } | - Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } - } - #endregion Site Recovery Manager Server Name - - #region NSX-T Manager Server Name - Write-PScriboMessage 'Checking for VMware NSX-T Manager Server.' - $NsxtServer = $extMgr.ExtensionList | Where-Object { $_.Key -eq 'com.vmware.nsx.management.nsxt' } | - Select-Object @{ - N = 'Name'; - E = { ($_.Server | Where-Object { ($_.Company -eq 'VMware') -and ($_.Type -eq 'VIP') } | - Select-Object -ExpandProperty Url).Split('/')[2].Split(':')[0] } - } - #endregion NSX-T Manager Server Name - - #region Tag Information - Try { - Write-PScriboMessage "Collecting tag information." - $TagAssignments = Get-TagAssignment -Server $vCenter -ErrorAction SilentlyContinue - $Tags = Get-Tag -Server $vCenter | Sort-Object Name, Category - $TagCategories = Get-TagCategory -Server $vCenter | Sort-Object Name | Select-Object Name, Description, Cardinality -Unique - } Catch { - Write-PScriboMessage -IsWarning "Error collecting tag information. $($_.Exception.Message)" - } - #endregion Tag Information - - #region vCenter Advanced Settings - Write-PScriboMessage "Collecting $vCenter advanced settings." - $vCenterAdvSettings = Get-AdvancedSetting -Entity $vCenter - $vCenterServerName = ($vCenterAdvSettings | Where-Object { $_.name -eq 'VirtualCenter.FQDN' }).Value - $vCenterServerName = $vCenterServerName.ToString().ToLower() - #endregion vCenter Advanced Settings - - #region vCenter Server Heading1 Section - Section -Style Heading1 $vCenterServerName { - #region vCenter Server Section - Write-PScriboMessage "vCenter InfoLevel set at $($InfoLevel.vCenter)." - if ($InfoLevel.vCenter -ge 1) { - Section -Style Heading2 'vCenter Server' { - Paragraph "The following sections detail the configuration of vCenter Server $vCenterServerName." - BlankLine - # Gather basic vCenter Server Information - $vCenterServerInfo = [PSCustomObject]@{ - 'vCenter Server' = $vCenterServerName - 'IP Address' = ($vCenterAdvSettings | Where-Object { $_.name -like 'VirtualCenter.AutoManagedIPV4' }).Value - 'Version' = $vCenter.Version - 'Build' = $vCenter.Build - } - #region vCenter Server Summary & Advanced Summary - if ($InfoLevel.vCenter -le 2) { - $TableParams = @{ - Name = "vCenter Server Summary - $vCenterServerName" - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterServerInfo | Table @TableParams - } - #endregion vCenter Server Summary & Advanced Summary - - #region vCenter Server Detailed Information - if ($InfoLevel.vCenter -ge 3) { - $MemberProps = @{ - 'InputObject' = $vCenterServerInfo - 'MemberType' = 'NoteProperty' - } - #region vCenter Server Detail - if ($UserPrivileges -contains 'Global.Licenses') { - $vCenterLicense = Get-License -vCenter $vCenter - Add-Member @MemberProps -Name 'Product' -Value $vCenterLicense.Product - Add-Member @MemberProps -Name 'License Key' -Value $vCenterLicense.LicenseKey - Add-Member @MemberProps -Name 'License Expiration' -Value $vCenterLicense.Expiration - } else { - Write-PScriboMessage "Insufficient user privileges to report vCenter Server licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned." - } - - Add-Member @MemberProps -Name 'Instance ID' -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'instance.id' }).Value - - if ($vCenter.Version -ge 6) { - Add-Member @MemberProps -Name 'HTTP Port' -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.rhttpproxy.httpport' }).Value - Add-Member @MemberProps -Name 'HTTPS Port' -Value ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.rhttpproxy.httpsport' }).Value - Add-Member @MemberProps -Name 'Platform Services Controller' -Value ((($vCenterAdvSettings).Where{ $_.name -eq 'config.vpxd.sso.admin.uri' }).Value).Split('/')[2] - } - if ($VumServer.Name) { - Add-Member @MemberProps -Name 'Update Manager Server' -Value $VumServer.Name - } - if ($SrmServer.Name) { - Add-Member @MemberProps -Name 'Site Recovery Manager Server' -Value $SrmServer.Name - } - if ($NsxtServer.Name) { - Add-Member @MemberProps -Name 'NSX-T Manager Server' -Value $NsxtServer.Name - } - if ($VxRailMgr.Name) { - Add-Member @MemberProps -Name 'VxRail Manager Server' -Value $VxRailMgr.Name - } - if ($Healthcheck.vCenter.Licensing) { - $vCenterServerInfo | Where-Object { $_.'Product' -like '*Evaluation*' } | Set-Style -Style Warning -Property 'Product' - $vCenterServerInfo | Where-Object { $null -eq $_.'Product' } | Set-Style -Style Warning -Property 'Product' - $vCenterServerInfo | Where-Object { $_.'License Key' -like '*-00000-00000' } | Set-Style -Style Warning -Property 'License Key' - $vCenterServerInfo | Where-Object { $_.'License Expiration' -eq 'Expired' } | Set-Style -Style Critical -Property 'License Expiration' - } - $TableParams = @{ - Name = "vCenter Server Configuration - $vCenterServerName" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterServerInfo | Table @TableParams - #endregion vCenter Server Detail - - #region vCenter Server Database Settings - Section -Style Heading3 'Database Settings' { - $vCenterDbInfo = [PSCustomObject]@{ - 'Database Type' = $TextInfo.ToTitleCase(($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.odbc.dbtype' }).Value) - 'Data Source Name' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'config.vpxd.odbc.dsn' }).Value - 'Maximum Database Connection' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'VirtualCenter.MaxDBConnection' }).Value - } - $TableParams = @{ - Name = "Database Settings - $vCenterServerName" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterDbInfo | Table @TableParams - } - #endregion vCenter Server Database Settings - - #region vCenter Server Mail Settings - Section -Style Heading3 'Mail Settings' { - $vCenterMailInfo = [PSCustomObject]@{ - 'SMTP Server' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.smtp.server' }).Value - 'SMTP Port' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.smtp.port' }).Value - 'Mail Sender' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'mail.sender' }).Value - } - if ($Healthcheck.vCenter.Mail) { - $vCenterMailInfo | Where-Object { !($_.'SMTP Server') } | Set-Style -Style Critical -Property 'SMTP Server' - $vCenterMailInfo | Where-Object { !($_.'SMTP Port') } | Set-Style -Style Critical -Property 'SMTP Port' - $vCenterMailInfo | Where-Object { !($_.'Mail Sender') } | Set-Style -Style Critical -Property 'Mail Sender' - } - $TableParams = @{ - Name = "Mail Settings - $vCenterServerName" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterMailInfo | Table @TableParams - } - #endregion vCenter Server Mail Settings - - #region vCenter Server Historical Statistics - Section -Style Heading3 'Historical Statistics' { - $vCenterHistoricalStats = Get-vCenterStats | Select-Object @{L = 'Interval Duration'; E = { $_.IntervalDuration } }, @{L = 'Interval Enabled'; E = { $_.IntervalEnabled } }, - @{L = 'Save Duration'; E = { $_.SaveDuration } }, @{L = 'Statistics Level'; E = { $_.StatsLevel } } -Unique - $TableParams = @{ - Name = "Historical Statistics - $vCenterServerName" - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterHistoricalStats | Table @TableParams - } - #endregion vCenter Server Historical Statistics - - #region vCenter Server Licensing - if ($UserPrivileges -contains 'Global.Licenses') { - Section -Style Heading3 'Licensing' { - $Licenses = Get-License -Licenses | Select-Object Product, @{L = 'License Key'; E = { ($_.LicenseKey) } }, Total, Used, @{L = 'Available'; E = { ($_.total) - ($_.Used) } }, Expiration -Unique - if ($Healthcheck.vCenter.Licensing) { - $Licenses | Where-Object { $_.Product -eq 'Product Evaluation' } | Set-Style -Style Warning - $Licenses | Where-Object { $_.Expiration -eq 'Expired' } | Set-Style -Style Critical - } - $TableParams = @{ - Name = "Licensing - $vCenterServerName" - ColumnWidths = 25, 25, 12, 12, 12, 14 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $Licenses | Sort-Object 'Product', 'License Key' | Table @TableParams - } - } else { - Write-PScriboMessage "Insufficient user privileges to report vCenter Server licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned." - } - #endregion vCenter Server Licensing - - #region vCenter Server Certificate - if ($vCenter.Version -ge 6) { - Section -Style Heading3 'Certificate' { - $VcenterCertMgmt = [PSCustomObject]@{ - 'Country' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.country' }).Value - 'Email' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.email' }).Value - 'Locality' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.localityName' }).Value - 'State' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.state' }).Value - 'Organization' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.organizationName' }).Value - 'Organization Unit' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.cn.organizationalUnitName' }).Value - 'Validity' = "$(($vCenterAdvSettings | Where-Object {$_.name -eq 'vpxd.certmgmt.certs.daysValid'}).Value / 365) years" - 'Mode' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.mode' }).Value - 'Soft Threshold' = "$(($vCenterAdvSettings | Where-Object {$_.name -eq 'vpxd.certmgmt.certs.softThreshold'}).Value) days" - 'Hard Threshold' = "$(($vCenterAdvSettings | Where-Object {$_.name -eq 'vpxd.certmgmt.certs.hardThreshold'}).Value) days" - 'Minutes Before' = ($vCenterAdvSettings | Where-Object { $_.name -eq 'vpxd.certmgmt.certs.minutesBefore' }).Value - 'Poll Interval' = "$(($vCenterAdvSettings | Where-Object {$_.name -eq 'vpxd.certmgmt.certs.pollIntervalDays'}).Value) days" - } - $TableParams = @{ - Name = "Certificate - $vCenterServerName" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VcenterCertMgmt | Table @TableParams - } - } - #endregion vCenter Server Certificate - - #region vCenter Server Roles - Section -Style Heading3 'Roles' { - $VIRoles = Get-VIRole -Server $vCenter | Where-Object { $null -ne $_.PrivilegeList } | Sort-Object Name - $VIRoleInfo = foreach ($VIRole in $VIRoles) { - [PSCustomObject]@{ - 'Role' = $VIRole.Name - 'System Role' = if ($VIRole.IsSystem) { - 'Yes' - } else { - 'No' - } - 'Privilege List' = ($VIRole.PrivilegeList).Replace(".", " > ") | Select-Object -Unique - } - } - if ($InfoLevel.vCenter -ge 4) { - $VIRoleInfo | ForEach-Object { - Section -Style NOTOCHeading5 -ExcludeFromTOC $($_.Role) { - $TableParams = @{ - Name = "Role $($_.Role) - $vCenterServerName" - ColumnWidths = 35, 15, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $_ | Table @TableParams - } - } - } else { - $TableParams = @{ - Name = "Roles - $vCenterServerName" - Columns = 'Role', 'System Role' - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VIRoleInfo | Table @TableParams - } - } - #endregion vCenter Server Roles - - #region vCenter Server Tags - if ($Tags) { - Section -Style Heading3 'Tags' { - $TagInfo = foreach ($Tag in $Tags) { - [PSCustomObject] @{ - 'Tag' = $Tag.Name - 'Description' = if ($Tag.Description) { - $Tag.Description - } else { - 'None' - } - 'Category' = if ($Tag.Category) { - $Tag.Category - } else { - 'None' - } - } - } - $TableParams = @{ - Name = "Tags - $vCenterServerName" - ColumnWidths = 30, 40, 30 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $TagInfo | Table @TableParams - } - } - #endregion vCenter Server Tags - - #region vCenter Server Tag Categories - if ($TagCategories) { - Section -Style Heading3 'Tag Categories' { - $TagCategoryInfo = foreach ($TagCategory in $TagCategories) { - [PSCustomObject] @{ - 'Category' = $TagCategory.Name - 'Description' = if ($TagCategory.Description) { - $TagCategory.Description - } else { - 'None' - } - 'Cardinality' = if ($TagCategory.Cardinality) { - $TagCategory.Cardinality - } else { - 'None' - } - } - } - $TableParams = @{ - Name = "Tag Categories - $vCenterServerName" - ColumnWidths = 30, 40, 30 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $TagCategoryInfo | Table @TableParams - } - } - #endregion vCenter Server Tag Categories - - #region vCenter Server Tag Assignments - if ($TagAssignments) { - Section -Style Heading3 'Tag Assignments' { - $TagAssignmentInfo = foreach ($TagAssignment in $TagAssignments) { - [PSCustomObject]@{ - 'Entity' = $TagAssignment.Entity.Name - 'Tag' = $TagAssignment.Tag.Name - 'Category' = $TagAssignment.Tag.Category - } - } - $TableParams = @{ - Name = "Tag Assignments - $vCenterServerName" - ColumnWidths = 30, 40, 30 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $TagAssignmentInfo | Sort-Object Entity | Table @TableParams - } - } - #endregion vCenter Server Tag Assignments - - #region VM Storage Policies - if ($UserPrivileges -contains 'StorageProfile.View') { - $SpbmStoragePolicies = Get-SpbmStoragePolicy | Sort-Object Name - if ($SpbmStoragePolicies) { - Section -Style Heading3 'VM Storage Policies' { - $VmStoragePolicies = foreach ($SpbmStoragePolicy in $SpbmStoragePolicies) { - [PSCustomObject]@{ - 'VM Storage Policy' = $SpbmStoragePolicy.Name - 'Description' = $SpbmStoragePolicy.Description - } - } - $TableParams = @{ - Name = "VM Storage Policies - $vCenterServerName" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VmStoragePolicies | Table @TableParams - } - } - } else { - Write-PScriboMessage "Insufficient user privileges to report VM storage policies. Please ensure the user account has the 'Storage Profile > View' privilege assigned." - } - #endregion VM Storage Policies - } - #endregion vCenter Server Detailed Information - - #region vCenter Server Advanced Detail Information - if ($InfoLevel.vCenter -ge 4) { - #region vCenter Alarms - Section -Style Heading3 'Alarms' { - $Alarms = Get-AlarmDefinition -PipelineVariable alarm | ForEach-Object -Process { - Get-AlarmAction -AlarmDefinition $_ -PipelineVariable action | ForEach-Object -Process { - Get-AlarmActionTrigger -AlarmAction $_ | - Select-Object @{N = 'Alarm'; E = { $alarm.Name } }, - @{N = 'Description'; E = { $alarm.Description } }, - @{N = 'Enabled'; E = { if ($alarm.Enabled) { 'Enabled' } else { 'Disabled' } } }, - @{N = 'Entity'; E = { $alarm.Entity.Type } }, - @{N = 'Trigger'; E = { - "{0}:{1}->{2} (Repeat={3})" -f $action.ActionType, - $_.StartStatus, - $_.EndStatus, - $_.Repeat - } - }, - @{N = 'Trigger Info'; E = { Switch ($action.ActionType) { - 'SendEmail' { - "To: $($action.To -join ', ') ` - Cc: $($action.Cc -join ', ') ` - Subject: $($action.Subject) ` - Body: $($action.Body)" - } - 'ExecuteScript' { - "$($action.ScriptFilePath)" - } - default { '--' } - } - } - } - } - } - $Alarms = ($Alarms).Where{ $_.alarm -ne "" } | Sort-Object 'Alarm', 'Trigger' - if ($Healthcheck.vCenter.Alarms) { - $Alarms | Where-Object { $_.'Enabled' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Enabled' - } - if ($InfoLevel.vCenter -ge 5) { - foreach ($Alarm in $Alarms) { - Section -Style NOTOCHeading5 -ExcludeFromTOC $($Alarm.Alarm) { - $TableParams = @{ - Name = "$($Alarm.Alarm) - $vCenterServerName" - List = $true - ColumnWidths = 25, 75 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $Alarm | Table @TableParams - } - } - } else { - $TableParams = @{ - Name = "Alarms - $vCenterServerName" - Columns = 'Alarm', 'Description', 'Enabled', 'Entity', 'Trigger' - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $Alarms | Table @TableParams - } - } - #endregion vCenter Alarms - } - #endregion vCenter Server Advanced Detail Information - - #region vCenter Server Comprehensive Information - if ($InfoLevel.vCenter -ge 5) { - #region vCenter Advanced System Settings - Section -Style Heading3 'Advanced System Settings' { - $TableParams = @{ - Name = "vCenter Advanced System Settings - $vCenterServerName" - Columns = 'Name', 'Value' - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vCenterAdvSettings | Sort-Object Name | Table @TableParams - } - #endregion vCenter Advanced System Settings - } - #endregion vCenter Server Comprehensive Information - } - } - #endregion vCenter Server Section - - #region Clusters - Write-PScriboMessage "Cluster InfoLevel set at $($InfoLevel.Cluster)." - if ($InfoLevel.Cluster -ge 1) { - $Clusters = Get-Cluster -Server $vCenter | Sort-Object Name - if ($Clusters) { - #region Cluster Section - Section -Style Heading2 'Clusters' { - Paragraph "The following sections detail the configuration of vSphere HA/DRS clusters managed by vCenter Server $vCenterServerName." - #region Cluster Advanced Summary - if ($InfoLevel.Cluster -le 2) { - BlankLine - $ClusterInfo = foreach ($Cluster in $Clusters) { - [PSCustomObject]@{ - 'Cluster' = $Cluster.Name - 'Datacenter' = $Cluster | Get-Datacenter - '# of Hosts' = $Cluster.ExtensionData.Host.Count - '# of VMs' = $Cluster.ExtensionData.VM.Count - 'vSphere HA' = if ($Cluster.HAEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'vSphere DRS' = if ($Cluster.DrsEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Virtual SAN' = if ($Cluster.VsanEnabled -or $VsanCluster.VsanEsaEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'EVC Mode' = if ($Cluster.EVCMode) { - $EvcModeLookup."$($Cluster.EVCMode)" - } else { - 'Disabled' - } - 'VM Swap File Policy' = Switch ($Cluster.VMSwapfilePolicy) { - 'WithVM' { 'With VM' } - 'InHostDatastore' { 'In Host Datastore' } - default { $Cluster.VMSwapfilePolicy } - } - } - } - if ($Healthcheck.Cluster.HAEnabled) { - $ClusterInfo | Where-Object { $_.'vSphere HA' -eq 'Disabled' } | Set-Style -Style Warning -Property 'vSphere HA' - } - if ($Healthcheck.Cluster.DrsEnabled) { - $ClusterInfo | Where-Object { $_.'vSphere DRS' -eq 'Disabled' } | Set-Style -Style Warning -Property 'vSphere DRS' - } - if ($Healthcheck.Cluster.VsanEnabled) { - $ClusterInfo | Where-Object { $_.'Virtual SAN' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Virtual SAN' - } - if ($Healthcheck.Cluster.EvcEnabled) { - $ClusterInfo | Where-Object { $_.'EVC Mode' -eq 'Disabled' } | Set-Style -Style Warning -Property 'EVC Mode' - } - $TableParams = @{ - Name = "Cluster Summary - $vCenterServerName" - ColumnWidths = 15, 15, 7, 7, 11, 11, 11, 15, 8 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterInfo | Table @TableParams - } - #endregion Cluster Advanced Summary - - #region Cluster Detailed Information - # TODO: Test Tags - if ($InfoLevel.Cluster -ge 3) { - foreach ($Cluster in $Clusters) { - $ClusterDasConfig = $Cluster.ExtensionData.Configuration.DasConfig - $ClusterDrsConfig = $Cluster.ExtensionData.Configuration.DrsConfig - $ClusterConfigEx = $Cluster.ExtensionData.ConfigurationEx - #region Cluster Section - Section -Style Heading3 $Cluster { - Paragraph "The following table details the configuration for cluster $Cluster." - BlankLine - #region Cluster Configuration - $ClusterDetail = [PSCustomObject]@{ - 'Cluster' = $Cluster.Name - 'ID' = $Cluster.Id - 'Datacenter' = $Cluster | Get-Datacenter - 'Number of Hosts' = $Cluster.ExtensionData.Host.Count - 'Number of VMs' = ($Cluster | Get-VM).Count - 'vSphere HA' = if ($Cluster.HAEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'vSphere DRS' = if ($Cluster.DrsEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Virtual SAN' = if ($Cluster.VsanEnabled -or $Cluster.VsanEsaEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'EVC Mode' = if ($Cluster.EVCMode) { - $EvcModeLookup."$($Cluster.EVCMode)" - } else { - 'Disabled' - } - 'VM Swap File Policy' = Switch ($Cluster.VMSwapfilePolicy) { - 'WithVM' { 'Virtual machine directory' } - 'InHostDatastore' { 'Datastore specified by host' } - default { $Cluster.VMSwapfilePolicy } - } - } - $MemberProps = @{ - 'InputObject' = $ClusterDetail - 'MemberType' = 'NoteProperty' - } - <# - if ($TagAssignments | Where-Object {$_.entity -eq $Cluster}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $Cluster}).Tag -join ',') - } - #> - if ($Healthcheck.Cluster.HAEnabled) { - $ClusterDetail | Where-Object { $_.'vSphere HA' -eq 'Disabled' } | Set-Style -Style Warning -Property 'vSphere HA' - } - if ($Healthcheck.Cluster.DrsEnabled) { - $ClusterDetail | Where-Object { $_.'vSphere DRS' -eq 'Disabled' } | Set-Style -Style Warning -Property 'vSphere DRS' - } - if ($Healthcheck.Cluster.VsanEnabled) { - $ClusterDetail | Where-Object { $_.'Virtual SAN' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Virtual SAN' - } - if ($Healthcheck.Cluster.EvcEnabled) { - $ClusterDetail | Where-Object { $_.'EVC Mode' -eq 'Disabled' } | Set-Style -Style Warning -Property 'EVC Mode' - } - #region Cluster Advanced Detailed Information - if ($InfoLevel.Cluster -ge 4) { - $ClusterDetail | ForEach-Object { - $ClusterHosts = $Cluster | Get-VMHost | Sort-Object Name - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Hosts' -Value ($ClusterHosts.Name -join ', ') - $ClusterVMs = $Cluster | Get-VM | Sort-Object Name - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Virtual Machines' -Value ($ClusterVMs.Name -join ', ') - } - } - #endregion Cluster Advanced Detailed Information - $TableParams = @{ - Name = "Cluster Configuration - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterDetail | Table @TableParams - #endregion Cluster Configuration - - #region vSphere HA Cluster Configuration - if ($Cluster.HAEnabled) { - Section -Style Heading4 'vSphere HA Configuration' { - Paragraph "The following section details the vSphere HA configuration for $Cluster cluster." - #region vSphere HA Cluster Failures and Responses - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Failures and Responses' { - $HAClusterResponses = [PSCustomObject]@{ - 'Host Monitoring' = $TextInfo.ToTitleCase($ClusterDasConfig.HostMonitoring) - } - if ($ClusterDasConfig.HostMonitoring -eq 'Enabled') { - $MemberProps = @{ - 'InputObject' = $HAClusterResponses - 'MemberType' = 'NoteProperty' - } - if ($ClusterDasConfig.DefaultVmSettings.RestartPriority -eq 'Disabled') { - Add-Member @MemberProps -Name 'Host Failure Response' -Value 'Disabled' - } else { - Add-Member @MemberProps -Name 'Host Failure Response' -Value 'Restart VMs' - Switch ($Cluster.HAIsolationResponse) { - 'DoNothing' { - Add-Member @MemberProps -Name 'Host Isolation Response' -Value 'Disabled' - } - 'Shutdown' { - Add-Member @MemberProps -Name 'Host Isolation Response' -Value 'Shutdown and restart VMs' - } - 'PowerOff' { - Add-Member @MemberProps -Name 'Host Isolation Response' -Value 'Power off and restart VMs' - } - } - Add-Member @MemberProps -Name 'VM Restart Priority' -Value $Cluster.HARestartPriority - Switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL) { - 'disabled' { - Add-Member @MemberProps -Name 'Datastore with Permanent Device Loss' -Value 'Disabled' - } - 'warning' { - Add-Member @MemberProps -Name 'Datastore with Permanent Device Loss' -Value 'Issue events' - } - 'restartAggressive' { - Add-Member @MemberProps -Name 'Datastore with Permanent Device Loss' -Value 'Power off and restart VMs' - } - } - Switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD) { - 'disabled' { - Add-Member @MemberProps -Name 'Datastore with All Paths Down' -Value 'Disabled' - } - 'warning' { - Add-Member @MemberProps -Name 'Datastore with All Paths Down' -Value 'Issue events' - } - 'restartConservative' { - Add-Member @MemberProps -Name 'Datastore with All Paths Down' -Value 'Power off and restart VMs (conservative)' - } - 'restartAggressive' { - Add-Member @MemberProps -Name 'Datastore with All Paths Down' -Value 'Power off and restart VMs (aggressive)' - } - } - Switch ($ClusterDasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared) { - 'none' { - Add-Member @MemberProps -Name 'APD recovery after APD timeout' -Value 'Disabled' - } - 'reset' { - Add-Member @MemberProps -Name 'APD recovery after APD timeout' -Value 'Reset VMs' - } - } - } - Switch ($ClusterDasConfig.VmMonitoring) { - 'vmMonitoringDisabled' { - Add-Member @MemberProps -Name 'VM Monitoring' -Value 'Disabled' - } - 'vmMonitoringOnly' { - Add-Member @MemberProps -Name 'VM Monitoring' -Value 'VM monitoring only' - } - 'vmAndAppMonitoring' { - Add-Member @MemberProps -Name 'VM Monitoring' -Value 'VM and application monitoring' - } - } - } - if ($Healthcheck.Cluster.HostFailureResponse) { - $HAClusterResponses | Where-Object { $_.'Host Failure Response' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Host Failure Response' - } - if ($Healthcheck.Cluster.HostMonitoring) { - $HAClusterResponses | Where-Object { $_.'Host Monitoring' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Host Monitoring' - } - if ($Healthcheck.Cluster.DatastoreOnPDL) { - $HAClusterResponses | Where-Object { $_.'Datastore with Permanent Device Loss' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Datastore with Permanent Device Loss' - } - if ($Healthcheck.Cluster.DatastoreOnAPD) { - $HAClusterResponses | Where-Object { $_.'Datastore with All Paths Down' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Datastore with All Paths Down' - } - if ($Healthcheck.Cluster.APDTimeout) { - $HAClusterResponses | Where-Object { $_.'APD recovery after APD timeout' -eq 'Disabled' } | Set-Style -Style Warning -Property 'APD recovery after APD timeout' - } - if ($Healthcheck.Cluster.vmMonitoring) { - $HAClusterResponses | Where-Object { $_.'VM Monitoring' -eq 'Disabled' } | Set-Style -Style Warning -Property 'VM Monitoring' - } - $TableParams = @{ - Name = "vSphere HA Failures and Responses - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $HAClusterResponses | Table @TableParams - } - #endregion vSphere HA Cluster Failures and Responses - - #region vSphere HA Cluster Admission Control - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Admission Control' { - $HAAdmissionControl = [PSCustomObject]@{ - 'Admission Control' = if ($Cluster.HAAdmissionControlEnabled) { - 'Enabled' - } else { - 'Disabled' - } - } - if ($Cluster.HAAdmissionControlEnabled) { - $MemberProps = @{ - 'InputObject' = $HAAdmissionControl - 'MemberType' = 'NoteProperty' - } - Add-Member @MemberProps -Name 'Host Failures Cluster Tolerates' -Value $Cluster.HAFailoverLevel - Switch ($ClusterDasConfig.AdmissionControlPolicy.GetType().Name) { - 'ClusterFailoverHostAdmissionControlPolicy' { - Add-Member @MemberProps -Name 'Host Failover Capacity Policy' -Value 'Dedicated failover hosts' - } - 'ClusterFailoverResourcesAdmissionControlPolicy' { - Add-Member @MemberProps -Name 'Host Failover Capacity Policy' -Value 'Cluster resource percentage' - } - 'ClusterFailoverLevelAdmissionControlPolicy' { - Add-Member @MemberProps -Name 'Host Failover Capacity Policy' -Value 'Slot policy' - } - } - if ($ClusterDasConfig.AdmissionControlPolicy.AutoComputePercentages) { - Add-Member @MemberProps -Name 'Override Calculated Failover Capacity' -Value 'No' - } else { - Add-Member @MemberProps -Name 'Override Calculated Failover Capacity' -Value 'Yes' - Add-Member @MemberProps -Name 'CPU %' -Value $ClusterDasConfig.AdmissionControlPolicy.CpuFailoverResourcesPercent - Add-Member @MemberProps -Name 'Memory %' -Value $ClusterDasConfig.AdmissionControlPolicy.MemoryFailoverResourcesPercent - } - if ($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy) { - Add-Member @MemberProps -Name 'Slot Policy' -Value 'Fixed slot size' - Add-Member @MemberProps -Name 'CPU Slot Size' -Value "$($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy.Cpu) MHz" - Add-Member @MemberProps -Name 'Memory Slot Size' -Value "$($ClusterDasConfig.AdmissionControlPolicy.SlotPolicy.Memory) MB" - } else { - Add-Member @MemberProps -Name 'Slot Policy' -Value 'Cover all powered-on virtual machines' - } - if ($ClusterDasConfig.AdmissionControlPolicy.ResourceReductionToToleratePercent) { - Add-Member @MemberProps -Name 'Performance Degradation VMs Tolerate' -Value "$($ClusterDasConfig.AdmissionControlPolicy.ResourceReductionToToleratePercent)%" - } - } - if ($Healthcheck.Cluster.HAAdmissionControl) { - $HAAdmissionControl | Where-Object { $_.'Admission Control' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Admission Control' - } - $TableParams = @{ - Name = "vSphere HA Admission Control - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $HAAdmissionControl | Table @TableParams - } - #endregion vSphere HA Cluster Admission Control - - #region vSphere HA Cluster Heartbeat Datastores - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Heartbeat Datastores' { - $HeartbeatDatastores = [PSCustomObject]@{ - 'Heartbeat Selection Policy' = Switch ($ClusterDasConfig.HBDatastoreCandidatePolicy) { - 'allFeasibleDsWithUserPreference' { 'Use datastores from the specified list and complement automatically if needed' } - 'allFeasibleDs' { 'Automatically select datastores accessible from the host' } - 'userSelectedDs' { 'Use datastores only from the specified list' } - default { $ClusterDasConfig.HBDatastoreCandidatePolicy } - } - 'Heartbeat Datastores' = try { - (((Get-View -Id $ClusterDasConfig.HeartbeatDatastore -Property Name).Name | Sort-Object) -join ', ') - } catch { - 'None specified' - } - } - $TableParams = @{ - Name = "vSphere HA Heartbeat Datastores - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $HeartbeatDatastores | Table @TableParams - } - #endregion vSphere HA Cluster Heartbeat Datastores - - #region vSphere HA Cluster Advanced Options - $HAAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterHA' } - if ($HAAdvancedSettings) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'vSphere HA Advanced Options' { - $HAAdvancedOptions = @() - foreach ($HAAdvancedSetting in $HAAdvancedSettings) { - $HAAdvancedOption = [PSCustomObject]@{ - 'Option' = $HAAdvancedSetting.Name - 'Value' = $HAAdvancedSetting.Value - } - $HAAdvancedOptions += $HAAdvancedOption - } - $TableParams = @{ - Name = "vSphere HA Advanced Options - $Cluster" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $HAAdvancedOptions | Sort-Object Option | Table @TableParams - } - } - #endregion vSphere HA Cluster Advanced Options - } - } - #endregion vSphere HA Cluster Configuration - - #region Proactive HA Configuration - # TODO: Proactive HA Providers - # Proactive HA is only available in vSphere 6.5 and above - if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled -and $vCenter.Version -ge 6.5) { - Section -Style Heading4 'Proactive HA' { - Paragraph "The following section details the Proactive HA configuration for $Cluster cluster." - #region Proactive HA Failures and Responses Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Failures and Responses' { - $ProactiveHa = [PSCustomObject]@{ - 'Proactive HA' = if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled) { - 'Enabled' - } else { - 'Disabled' - } - } - if ($ClusterConfigEx.InfraUpdateHaConfig.Enabled) { - $ProactiveHaModerateRemediation = Switch ($ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation) { - 'MaintenanceMode' { 'Maintenance Mode' } - 'QuarantineMode' { 'Quarantine Mode' } - default { $ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation } - } - $ProactiveHaSevereRemediation = Switch ($ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation) { - 'MaintenanceMode' { 'Maintenance Mode' } - 'QuarantineMode' { 'Quarantine Mode' } - default { $ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation } - } - $MemberProps = @{ - 'InputObject' = $ProactiveHa - 'MemberType' = 'NoteProperty' - } - Add-Member @MemberProps -Name 'Automation Level' -Value $ClusterConfigEx.InfraUpdateHaConfig.Behavior - if ($ClusterConfigEx.InfraUpdateHaConfig.ModerateRemediation -eq $ClusterConfigEx.InfraUpdateHaConfig.SevereRemediation) { - Add-Member @MemberProps -Name 'Remediation' -Value $ProactiveHaModerateRemediation - } else { - Add-Member @MemberProps -Name 'Remediation' -Value 'Mixed Mode' - Add-Member @MemberProps -Name 'Moderate Remediation' -Value $ProactiveHaModerateRemediation - Add-Member @MemberProps -Name 'Severe Remediation' -Value $ProactiveHaSevereRemediation - } - } - if ($Healthcheck.Cluster.ProactiveHA) { - $ProactiveHa | Where-Object { $_.'Proactive HA' -eq 'Disabled' } | Set-Style -Style Warning -Property 'Proactive HA' - } - $TableParams = @{ - Name = "Proactive HA - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ProactiveHa | Table @TableParams - } - #endregion Proactive HA Failures and Responses Section - } - } - #endregion Proactive HA Configuration - - #region vSphere DRS Cluster Configuration - if ($Cluster.DrsEnabled) { - Section -Style Heading4 'vSphere DRS Configuration' { - Paragraph ("The following table details the vSphere DRS configuration " + - "for cluster $Cluster.") - BlankLine - - #region vSphere DRS Cluster Specifications - $DrsCluster = [PSCustomObject]@{ - 'vSphere DRS' = if ($Cluster.DrsEnabled) { - 'Enabled' - } else { - 'Disabled' - } - } - $MemberProps = @{ - 'InputObject' = $DrsCluster - 'MemberType' = 'NoteProperty' - } - Switch ($Cluster.DrsAutomationLevel) { - 'Manual' { - Add-Member @MemberProps -Name 'Automation Level' -Value 'Manual' - } - 'PartiallyAutomated' { - Add-Member @MemberProps -Name 'Automation Level' -Value 'Partially Automated' - } - 'FullyAutomated' { - Add-Member @MemberProps -Name 'Automation Level' -Value 'Fully Automated' - } - } - Add-Member @MemberProps -Name 'Migration Threshold' -Value $ClusterDrsConfig.VmotionRate - if ($ClusterConfigEx.ProactiveDrsConfig.Enabled) { - Add-Member @MemberProps -Name 'Predictive DRS' -Value 'Enabled' - } else { - Add-Member @MemberProps -Name 'Predictive DRS' -Value 'Disabled' - } - if ($ClusterDrsConfig.EnableVmBehaviorOverrides) { - Add-Member @MemberProps -Name 'Virtual Machine Automation' -Value 'Enabled' - } else { - Add-Member @MemberProps -Name 'Virtual Machine Automation' -Value 'Disabled' - } - if ($Healthcheck.Cluster.DrsEnabled) { - $DrsCluster | Where-Object { $_.'vSphere DRS' -eq 'Disabled' } | Set-Style -Style Warning -Property 'vSphere DRS' - } - if ($Healthcheck.Cluster.DrsAutomationLevelFullyAuto) { - $DrsCluster | Where-Object { $_.'Automation Level' -ne 'Fully Automated' } | Set-Style -Style Warning -Property 'Automation Level' - } - $TableParams = @{ - Name = "vSphere DRS Configuration - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsCluster | Table @TableParams - #endregion vSphere DRS Cluster Specfications - - #region DRS Cluster Additional Options - $DrsAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterDRS' } - if ($DrsAdvancedSettings) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Additional Options' { - $DrsAdditionalOptions = [PSCustomObject] @{ - 'VM Distribution' = Switch (($DrsAdvancedSettings | Where-Object { $_.name -eq 'TryBalanceVmsPerHost' }).Value) { - '1' { 'Enabled' } - $null { 'Disabled' } - } - 'Memory Metric for Load Balancing' = Switch (($DrsAdvancedSettings | Where-Object { $_.name -eq 'PercentIdleMBInMemDemand' }).Value) { - '100' { 'Enabled' } - $null { 'Disabled' } - } - 'CPU Over-Commitment' = if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerCore' }).Value) { - 'Enabled' - } else { - 'Disabled' - } - } - $MemberProps = @{ - 'InputObject' = $DrsAdditionalOptions - 'MemberType' = 'NoteProperty' - } - if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerCore' }).Value) { - Add-Member @MemberProps -Name 'Over-Commitment Ratio' -Value "$(($DrsAdvancedSettings | Where-Object {$_.name -eq 'MaxVcpusPerCore'}).Value):1 (vCPU:pCPU)" - } - if (($DrsAdvancedSettings | Where-Object { $_.name -eq 'MaxVcpusPerClusterPct' }).Value) { - Add-Member @MemberProps -Name 'Over-Commitment Ratio (% of cluster capacity)' -Value "$(($DrsAdvancedSettings | Where-Object {$_.name -eq 'MaxVcpusPerClusterPct'}).Value) %" - } - $TableParams = @{ - Name = "DRS Additional Options - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsAdditionalOptions | Table @TableParams - } - } - #endregion DRS Cluster Additional Options - - #region vSphere DPM Configuration - if ($ClusterConfigEx.DpmConfigInfo.Enabled) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Power Management' { - $DpmConfig = [PSCustomObject]@{ - 'DPM' = if ($ClusterConfigEx.DpmConfigInfo.Enabled) { - 'Enabled' - } else { - 'Disabled' - } - } - $MemberProps = @{ - 'InputObject' = $DpmConfig - 'MemberType' = 'NoteProperty' - } - Switch ($ClusterConfigEx.DpmConfigInfo.DefaultDpmBehavior) { - 'manual' { - Add-Member @MemberProps -Name 'Automation Level' -Value 'Manual' - } - 'automated' { - Add-Member @MemberProps -Name 'Automation Level' -Value 'Automated' - } - } - if ($ClusterConfigEx.DpmConfigInfo.DefaultDpmBehavior -eq 'automated') { - Add-Member @MemberProps -Name 'DPM Threshold' -Value $ClusterConfigEx.DpmConfigInfo.HostPowerActionRate - } - $TableParams = @{ - Name = "vSphere DPM - $Cluster" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DpmConfig | Table @TableParams - } - } - #endregion vSphere DPM Configuration - - #region vSphere DRS Cluster Advanced Options - $DrsAdvancedSettings = $Cluster | Get-AdvancedSetting | Where-Object { $_.Type -eq 'ClusterDRS' } - if ($DrsAdvancedSettings) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Advanced Options' { - $DrsAdvancedOptions = @() - foreach ($DrsAdvancedSetting in $DrsAdvancedSettings) { - $DrsAdvancedOption = [PSCustomObject]@{ - 'Option' = $DrsAdvancedSetting.Name - 'Value' = $DrsAdvancedSetting.Value - } - $DrsAdvancedOptions += $DrsAdvancedOption - } - $TableParams = @{ - Name = "vSphere DRS Advanced Options - $Cluster" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsAdvancedOptions | Sort-Object Option | Table @TableParams - } - } - #endregion vSphere DRS Cluster Advanced Options - - #region vSphere DRS Cluster Group - $DrsClusterGroups = $Cluster | Get-DrsClusterGroup - if ($DrsClusterGroups) { - #region vSphere DRS Cluster Group Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'DRS Cluster Groups' { - $DrsGroups = foreach ($DrsClusterGroup in $DrsClusterGroups) { - [PSCustomObject]@{ - 'DRS Cluster Group' = $DrsClusterGroup.Name - 'Type' = Switch ($DrsClusterGroup.GroupType) { - 'VMGroup' { 'VM Group' } - 'VMHostGroup' { 'Host Group' } - default { $DrsClusterGroup.GroupType } - } - 'Members' = if (($DrsClusterGroup.Member).Count -gt 0) { - ($DrsClusterGroup.Member | Sort-Object) -join ', ' - } else { - "None" - } - } - } - $TableParams = @{ - Name = "DRS Cluster Groups - $Cluster" - ColumnWidths = 42, 16, 42 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsGroups | Sort-Object 'DRS Cluster Group', 'Type' | Table @TableParams - } - #endregion vSphere DRS Cluster Group Section - - #region vSphere DRS Cluster VM/Host Rules - $DrsVMHostRules = $Cluster | Get-DrsVMHostRule - if ($DrsVMHostRules) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'DRS VM/Host Rules' { - $DrsVMHostRuleDetail = foreach ($DrsVMHostRule in $DrsVMHostRules) { - [PSCustomObject]@{ - 'DRS VM/Host Rule' = $DrsVMHostRule.Name - 'Type' = Switch ($DrsVMHostRule.Type) { - 'MustRunOn' { 'Must run on hosts in group' } - 'ShouldRunOn' { 'Should run on hosts in group' } - 'MustNotRunOn' { 'Must not run on hosts in group' } - 'ShouldNotRunOn' { 'Should not run on hosts in group' } - default { $DrsVMHostRule.Type } - } - 'Enabled' = if ($DrsVMHostRule.Enabled) { - 'Yes' - } else { - 'No' - } - 'VM Group' = $DrsVMHostRule.VMGroup - 'Host Group' = $DrsVMHostRule.VMHostGroup - } - } - if ($Healthcheck.Cluster.DrsVMHostRules) { - $DrsVMHostRuleDetail | Where-Object { $_.Enabled -eq 'No' } | Set-Style -Style Warning -Property 'Enabled' - } - $TableParams = @{ - Name = "DRS VM/Host Rules - $Cluster" - ColumnWidths = 22, 22, 12, 22, 22 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsVMHostRuleDetail | Sort-Object 'DRS VM/Host Rule' | Table @TableParams - } - } - #endregion vSphere DRS Cluster VM/Host Rules - - #region vSphere DRS Cluster Rules - $DrsRules = $Cluster | Get-DrsRule - if ($DrsRules) { - #region vSphere DRS Cluster Rules Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'DRS Rules' { - $DrsRuleDetail = foreach ($DrsRule in $DrsRules) { - [PSCustomObject]@{ - 'DRS Rule' = $DrsRule.Name - 'Type' = Switch ($DrsRule.Type) { - 'VMAffinity' { 'Keep Vitrual Machines Together' } - 'VMAntiAffinity' { 'Separate Virtual Machines' } - } - 'Enabled' = if ($DrsRule.Enabled) { - 'Yes' - } else { - 'No' - } - 'Mandatory' = $DrsRule.Mandatory - 'Virtual Machines' = ($DrsRule.VMIds | ForEach-Object { (Get-View -Id $_).name }) -join ', ' - } - if ($Healthcheck.Cluster.DrsRules) { - $DrsRuleDetail | Where-Object { $_.Enabled -eq 'No' } | Set-Style -Style Warning -Property 'Enabled' - } - } - $TableParams = @{ - Name = "DRS Rules - $Cluster" - ColumnWidths = 26, 25, 12, 12, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsRuleDetail | Sort-Object Type | Table @TableParams - } - #endregion vSphere DRS Cluster Rules Section - } - #endregion vSphere DRS Cluster Rules - } - #endregion vSphere DRS Cluster Group - - #region Cluster VM Overrides - $DrsVmOverrides = $Cluster.ExtensionData.Configuration.DrsVmConfig - $DasVmOverrides = $Cluster.ExtensionData.Configuration.DasVmConfig - if ($DrsVmOverrides -or $DasVmOverrides) { - #region VM Overrides Section - Section -Style NOTOCHeading4 -ExcludeFromTOC 'VM Overrides' { - #region vSphere DRS VM Overrides - if ($DrsVmOverrides) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'vSphere DRS' { - $DrsVmOverrideDetails = foreach ($DrsVmOverride in $DrsVmOverrides) { - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($DrsVmOverride.Key.Type)-$($DrsVmOverride.Key.Value)" - 'vSphere DRS Automation Level' = if ($DrsVmOverride.Enabled -eq $false) { - 'Disabled' - } else { - Switch ($DrsVmOverride.Behavior) { - 'manual' { 'Manual' } - 'partiallyAutomated' { 'Partially Automated' } - 'fullyAutomated' { 'Fully Automated' } - default { $DrsVmOverride.Behavior } - } - } - } - } - $TableParams = @{ - Name = "DRS VM Overrides - $Cluster" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DrsVmOverrideDetails | Sort-Object 'Virtual Machine' | Table @TableParams - } - } - #endregion vSphere DRS VM Overrides - - #region vSphere HA VM Overrides - if ($DasVmOverrides) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'vSphere HA' { - $DasVmOverrideDetails = foreach ($DasVmOverride in $DasVmOverrides) { - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" - 'VM Restart Priority' = Switch ($DasVmOverride.DasSettings.RestartPriority) { - $null { '--' } - 'lowest' { 'Lowest' } - 'low' { 'Low' } - 'medium' { 'Medium' } - 'high' { 'High' } - 'highest' { 'Highest' } - 'disabled' { 'Disabled' } - 'clusterRestartPriority' { 'Cluster default' } - } - 'VM Dependency Restart Condition Timeout' = Switch ($DasVmOverride.DasSettings.RestartPriorityTimeout) { - $null { '--' } - '-1' { 'Disabled' } - default { "$($DasVmOverride.DasSettings.RestartPriorityTimeout) seconds" } - } - 'Host Isolation Response' = Switch ($DasVmOverride.DasSettings.IsolationResponse) { - $null { '--' } - 'none' { 'Disabled' } - 'powerOff' { 'Power off and restart VMs' } - 'shutdown' { 'Shutdown and restart VMs' } - 'clusterIsolationResponse' { 'Cluster default' } - } - } - } - $TableParams = @{ - Name = "HA VM Overrides - $Cluster" - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DasVmOverrideDetails | Sort-Object 'Virtual Machine' | Table @TableParams - - #region PDL/APD Protection Settings Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'PDL/APD Protection Settings' { - $DasVmOverridePdlApd = foreach ($DasVmOverride in $DasVmOverrides) { - $DasVmComponentProtection = $DasVmOverride.DasSettings.VmComponentProtectionSettings - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" - 'PDL Failure Response' = Switch ($DasVmComponentProtection.VmStorageProtectionForPDL) { - $null { '--' } - 'clusterDefault' { 'Cluster default' } - 'warning' { 'Issue events' } - 'restartAggressive' { 'Power off and restart VMs' } - 'disabled' { 'Disabled' } - } - 'APD Failure Response' = Switch ($DasVmComponentProtection.VmStorageProtectionForAPD) { - $null { '--' } - 'clusterDefault' { 'Cluster default' } - 'warning' { 'Issue events' } - 'restartConservative' { 'Power off and restart VMs - Conservative restart policy' } - 'restartAggressive' { 'Power off and restart VMs - Aggressive restart policy' } - 'disabled' { 'Disabled' } - } - 'VM Failover Delay' = Switch ($DasVmComponentProtection.VmTerminateDelayForAPDSec) { - $null { '--' } - '-1' { 'Disabled' } - default { "$(($DasVmComponentProtection.VmTerminateDelayForAPDSec)/60) minutes" } - } - 'Response Recovery' = Switch ($DasVmComponentProtection.VmReactionOnAPDCleared) { - $null { '--' } - 'reset' { 'Reset VMs' } - 'disabled' { 'Disabled' } - 'useClusterDefault' { 'Cluster default' } - } - } - } - $TableParams = @{ - Name = "HA VM Overrides PDL/APD Settings - $Cluster" - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DasVmOverridePdlApd | Sort-Object 'Virtual Machine' | Table @TableParams - } - #endregion PDL/APD Protection Settings Section - - #region VM Monitoring Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'VM Monitoring' { - $DasVmOverrideVmMonitoring = foreach ($DasVmOverride in $DasVmOverrides) { - $DasVmMonitoring = $DasVmOverride.DasSettings.VmToolsMonitoringSettings - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($DasVmOverride.Key.Type)-$($DasVmOverride.Key.Value)" - 'VM Monitoring' = Switch ($DasVmMonitoring.VmMonitoring) { - $null { '--' } - 'vmMonitoringDisabled' { 'Disabled' } - 'vmMonitoringOnly' { 'VM Monitoring Only' } - 'vmAndAppMonitoring' { 'VM and App Monitoring' } - } - 'Failure Interval' = Switch ($DasVmMonitoring.FailureInterval) { - $null { '--' } - default { - if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { - '--' - } else { - "$($DasVmMonitoring.FailureInterval) seconds" - } - } - } - 'Minimum Uptime' = Switch ($DasVmMonitoring.MinUptime) { - $null { '--' } - default { - if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { - '--' - } else { - "$($DasVmMonitoring.MinUptime) seconds" - } - } - } - 'Maximum Per-VM Resets' = Switch ($DasVmMonitoring.MaxFailures) { - $null { '--' } - default { - if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { - '--' - } else { - $DasVmMonitoring.MaxFailures - } - } - } - 'Maximum Resets Time Window' = Switch ($DasVmMonitoring.MaxFailureWindow) { - $null { '--' } - '-1' { 'No window' } - default { - if ($DasVmMonitoring.VmMonitoring -eq 'vmMonitoringDisabled') { - '--' - } else { - "Within $(($DasVmMonitoring.MaxFailureWindow)/3600) hrs" - } - } - } - } - } - $TableParams = @{ - Name = "HA VM Overrides VM Monitoring - $Cluster" - ColumnWidths = 40, 12, 12, 12, 12, 12 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DasVmOverrideVmMonitoring | Sort-Object 'Virtual Machine' | Table @TableParams - } - #endregion VM Monitoring Section - } - } - #endregion vSphere HA VM Overrides - } - #endregion VM Overrides Section - } - #endregion Cluster VM Overrides - - #region Cluster VUM Baselines - if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { - if ($VUMConnection) { - Try { - $ClusterPatchBaselines = $Cluster | Get-PatchBaseline - } Catch { - Write-PScriboMessage 'Cluster VUM baseline information is not currently available with your version of PowerShell.' - } - if ($ClusterPatchBaselines) { - Section -Style Heading4 'Update Manager Baselines' { - $ClusterBaselines = foreach ($ClusterBaseline in $ClusterPatchBaselines) { - [PSCustomObject]@{ - 'Baseline' = $ClusterBaseline.Name - 'Description' = $ClusterBaseline.Description - 'Type' = $ClusterBaseline.BaselineType - 'Target Type' = $ClusterBaseline.TargetType - 'Last Update Time' = ($ClusterBaseline.LastUpdateTime).ToLocalTime().ToString() - '# of Patches' = $ClusterBaseline.CurrentPatches.Count - } - } - $TableParams = @{ - Name = "Update Manager Baselines - $Cluster" - ColumnWidths = 25, 25, 10, 10, 20, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterBaselines | Sort-Object 'Baseline' | Table @TableParams - } - } - if ($Healthcheck.Cluster.VUMCompliance) { - $ClusterComplianceInfo | Where-Object { $_.Status -eq 'Unknown' } | Set-Style -Style Warning - $ClusterComplianceInfo | Where-Object { $_.Status -eq 'Not Compliant' -or $_.Status -eq 'Incompatible' } | Set-Style -Style Critical - } - $TableParams = @{ - Name = "Update Manager Compliance - $Cluster" - ColumnWidths = 25, 50, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterComplianceInfo | Sort-Object Name, Baseline | Table @TableParams - } - } else { - Write-PScriboMessage "Insufficient user privileges to report Cluster baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned." - } - #endregion Cluster VUM Baselines - - #region Cluster VUM Compliance (Advanced Detail Information) - if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { - if ($InfoLevel.Cluster -ge 4 -and $VumServer.Name) { - Try { - $ClusterCompliances = $Cluster | Get-Compliance - } Catch { - Write-PScriboMessage 'Cluster VUM compliance information is not currently available with your version of PowerShell.' - } - if ($ClusterCompliances) { - Section -Style Heading4 'Update Manager Compliance' { - $ClusterComplianceInfo = foreach ($ClusterCompliance in $ClusterCompliances) { - [PSCustomObject]@{ - 'Entity' = $ClusterCompliance.Entity - 'Baseline' = $ClusterCompliance.Baseline.Name - 'Status' = Switch ($ClusterCompliance.Status) { - 'NotCompliant' { 'Not Compliant' } - default { $ClusterCompliance.Status } - } - } - } - if ($Healthcheck.Cluster.VUMCompliance) { - $ClusterComplianceInfo | Where-Object { $_.Status -eq 'Unknown' } | Set-Style -Style Warning - $ClusterComplianceInfo | Where-Object { $_.Status -eq 'Not Compliant' -or $_.Status -eq 'Incompatible' } | Set-Style -Style Critical - } - $TableParams = @{ - Name = "Update Manager Compliance - $Cluster" - ColumnWidths = 25, 50, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterComplianceInfo | Sort-Object Entity, Baseline | Table @TableParams - } - } - } - } else { - Write-PScriboMessage "Insufficient user privileges to report Cluster compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned." - } - - #endregion Cluster VUM Compliance (Advanced Detail Information) - - #region Cluster Permissions - Section -Style NOTOCHeading4 -ExcludeFromTOC 'Permissions' { - Paragraph "The following table details the permissions assigned to cluster $Cluster." - BlankLine - $VIPermissions = $Cluster | Get-VIPermission - $ClusterVIPermissions = foreach ($VIPermission in $VIPermissions) { - [PSCustomObject]@{ - 'User/Group' = $VIPermission.Principal - 'Is Group?' = if ($VIPermission.IsGroup) { - 'Yes' - } else { - 'No' - } - 'Role' = $VIPermission.Role - 'Defined In' = $VIPermission.Entity - 'Propagate' = if ($VIPermission.Propagate) { - 'Yes' - } else { - 'No' - } - } - } - $TableParams = @{ - Name = "Permissions - $Cluster" - ColumnWidths = 42, 12, 20, 14, 12 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ClusterVIPermissions | Sort-Object 'User/Group' | Table @TableParams - } - #endregion Cluster Permissions - } - } - #endregion vSphere DRS Cluster Configuration - } - #endregion Cluster Section - } - } - #endregion Cluster Detailed Information - } - #endregion Cluster Section - } - } - #endregion Clusters - - #region Resource Pool Section - Write-PScriboMessage "ResourcePool InfoLevel set at $($InfoLevel.ResourcePool)." - if ($InfoLevel.ResourcePool -ge 1) { - $ResourcePools = Get-ResourcePool -Server $vCenter | Sort-Object Parent, Name - if ($ResourcePools) { - #region Resource Pools Section - Section -Style Heading2 'Resource Pools' { - Paragraph "The following sections detail the configuration of resource pools managed by vCenter Server $vCenterServerName." - #region Resource Pool Advanced Summary - if ($InfoLevel.ResourcePool -le 2) { - BlankLine - $ResourcePoolInfo = foreach ($ResourcePool in $ResourcePools) { - [PSCustomObject]@{ - 'Resource Pool' = $ResourcePool.Name - 'Parent' = $ResourcePool.Parent - 'CPU Shares Level' = $ResourcePool.CpuSharesLevel - 'CPU Reservation MHz' = $ResourcePool.CpuReservationMHz - 'CPU Limit MHz' = Switch ($ResourcePool.CpuLimitMHz) { - '-1' { 'Unlimited' } - default { $ResourcePool.CpuLimitMHz } - } - 'Memory Shares Level' = $ResourcePool.MemSharesLevel - 'Memory Reservation' = Convert-DataSize $ResourcePool.MemReservationGB -RoundUnits 0 - 'Memory Limit' = Switch ($ResourcePool.MemLimitGB) { - '-1' { 'Unlimited' } - default { Convert-DataSize $ResourcePool.MemLimitGB -RoundUnits 0 } - } - } - } - $TableParams = @{ - Name = "Resource Pool Summary - $($vCenterServerName)" - ColumnWidths = 20, 20, 10, 10, 10, 10, 10, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ResourcePoolInfo | Sort-Object Name | Table @TableParams - } - #endregion Resource Pool Advanced Summary - - #region Resource Pool Detailed Information - # TODO: Test Tags - if ($InfoLevel.ResourcePool -ge 3) { - foreach ($ResourcePool in $ResourcePools) { - Section -Style Heading3 $ResourcePool.Name { - $ResourcePoolDetail = [PSCustomObject]@{ - 'Resource Pool' = $ResourcePool.Name - 'ID' = $ResourcePool.Id - 'Parent' = $ResourcePool.Parent - 'CPU Shares Level' = $ResourcePool.CpuSharesLevel - 'Number of CPU Shares' = $ResourcePool.NumCpuShares - 'CPU Reservation' = "$($ResourcePool.CpuReservationMHz) MHz" - 'CPU Expandable Reservation' = if ($ResourcePool.CpuExpandableReservation) { - 'Enabled' - } else { - 'Disabled' - } - 'CPU Limit MHz' = Switch ($ResourcePool.CpuLimitMHz) { - '-1' { 'Unlimited' } - default { "$($ResourcePool.CpuLimitMHz) MHz" } - } - 'Memory Shares Level' = $ResourcePool.MemSharesLevel - 'Number of Memory Shares' = $ResourcePool.NumMemShares - 'Memory Reservation' = Convert-DataSize $ResourcePool.MemReservationGB -RoundUnits 0 - 'Memory Expandable Reservation' = if ($ResourcePool.MemExpandableReservation) { - 'Enabled' - } else { - 'Disabled' - } - 'Memory Limit' = Switch ($ResourcePool.MemLimitGB) { - '-1' { 'Unlimited' } - default { Convert-DataSize $ResourcePool.MemLimitGB -RoundUnits 0 } - } - 'Number of VMs' = $ResourcePool.ExtensionData.VM.Count - } - <# - $MemberProps = @{ - 'InputObject' = $ResourcePoolDetail - 'MemberType' = 'NoteProperty' - } - - if ($TagAssignments | Where-Object {$_.entity -eq $ResourcePool}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $ResourcePool}).Tag -join ',') - } - #> - #region Resource Pool Advanced Detail Information - if ($InfoLevel.ResourcePool -ge 4) { - $ResourcePoolDetail | ForEach-Object { - # Query for VMs by resource pool Id - $ResourcePoolId = $_.Id - $ResourcePoolVMs = $VMs | Where-Object { $_.ResourcePoolId -eq $ResourcePoolId } | Sort-Object Name - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Virtual Machines' -Value ($ResourcePoolVMs.Name -join ', ') - } - } - #endregion Resource Pool Advanced Detail Information - $TableParams = @{ - Name = "Resource Pool Configuration - $($ResourcePool.Name)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ResourcePoolDetail | Table @TableParams - } - } - } - #endregion Resource Pool Detailed Information - } - #endregion Resource Pools Section - } - } - #endregion Resource Pool Section - - #region ESXi VMHost Section - Write-PScriboMessage "VMHost InfoLevel set at $($InfoLevel.VMHost)." - if ($InfoLevel.VMHost -ge 1) { - if ($VMHosts) { - #region Hosts Section - Section -Style Heading2 'Hosts' { - Paragraph "The following sections detail the configuration of VMware ESXi hosts managed by vCenter Server $vCenterServerName." - #region ESXi Host Advanced Summary - if ($InfoLevel.VMHost -le 2) { - BlankLine - $VMHostInfo = foreach ($VMHost in $VMHosts) { - [PSCustomObject]@{ - 'Host' = $VMHost.Name - 'Version' = $VMHost.Version - 'Build' = $VMHost.Build - 'Parent' = $VMHost.Parent - 'Connection State' = Switch ($VMHost.ConnectionState) { - 'NotResponding' { 'Not Responding' } - default { $TextInfo.ToTitleCase($VMHost.ConnectionState) } - } - 'CPU Sockets' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuPackages - 'CPU Cores' = $VMHost.ExtensionData.Hardware.CpuInfo.NumCpuCores - 'Memory' = Convert-DataSize $VMHost.MemoryTotalGB -RoundUnits 0 - '# of VMs' = $VMHost.ExtensionData.Vm.Count - } - } - if ($Healthcheck.VMHost.ConnectionState) { - $VMHostInfo | Where-Object { $_.'Connection State' -eq 'Maintenance' } | Set-Style -Style Warning - $VMHostInfo | Where-Object { $_.'Connection State' -eq 'Not Responding' } | Set-Style -Style Critical - $VMHostInfo | Where-Object { $_.'Connection State' -eq 'Disconnected' } | Set-Style -Style Critical - } - $TableParams = @{ - Name = "Host Summary - $($vCenterServerName)" - ColumnWidths = 17, 9, 11, 15, 13, 9, 9, 9, 8 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostInfo | Table @TableParams - } - #endregion ESXi Host Advanced Summary - - #region ESXi Host Detailed Information - if ($InfoLevel.VMHost -ge 3) { - #region foreach VMHost Detailed Information loop - foreach ($VMHost in ($VMHosts | Where-Object { $_.ConnectionState -eq 'Connected' -or $_.ConnectionState -eq 'Maintenance' })) { - #region VMHost Section - Section -Style Heading3 $VMHost { - # TODO: Host Certificate, Swap File Location - # TODO: Test Tags - #region ESXi Host Hardware Section - Section -Style Heading4 'Hardware' { - Paragraph "The following section details the host hardware configuration for $VMHost." - BlankLine - - #region ESXi Host Specifications - $VMHostUptime = Get-Uptime -VMHost $VMHost - $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter - $ScratchLocation = Get-AdvancedSetting -Entity $VMHost | Where-Object { $_.Name -eq 'ScratchConfig.CurrentScratchLocation' } - $VMHostCpuTotal = [math]::Round(($VMHost.CpuTotalMhz) / 1000, 2) - $VMHostCpuUsed = [math]::Round(($VMHost.CpuUsageMhz) / 1000, 2) - $VMHostCpuFree = $VMHostCpuTotal - $VMHostCpuUsed - $VMHostDetail = [PSCustomObject]@{ - 'Host' = $VMHost.Name - 'Connection State' = Switch ($VMHost.ConnectionState) { - 'NotResponding' { 'Not Responding' } - default { $TextInfo.ToTitleCase($VMHost.ConnectionState) } - } - 'ID' = $VMHost.Id - 'Parent' = $VMHost.Parent - 'Manufacturer' = $VMHost.Manufacturer - 'Model' = $VMHost.Model - 'Serial Number' = if ($VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber) { - $VMHost.ExtensionData.Hardware.SystemInfo.SerialNumber - } else { - '--' - } - 'Asset Tag' = if ($VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue) { - $VMHost.ExtensionData.Summary.Hardware.OtherIdentifyingInfo[0].IdentifierValue - } else { - 'Unknown' - } - 'Processor Type' = $VMHost.Processortype - 'HyperThreading' = if ($VMHost.HyperthreadingActive) { - 'Enabled' - } else { - '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 / Free' = "{0:N2} GHz / {1:N2} GHz / {2:N2} GHz" -f $VMHostCpuTotal, $VMHostCpuUsed, $VMHostCpuFree - 'Memory Total / Used / Free' = "{0} / {1} / {2}" -f (Convert-DataSize $VMHost.MemoryTotalGB), (Convert-DataSize $VMHost.MemoryUsageGB), (Convert-DataSize ($VMHost.MemoryTotalGB - $VMHost.MemoryUsageGB)) - 'NUMA Nodes' = $VMHost.ExtensionData.Hardware.NumaInfo.NumNodes - 'Number of NICs' = $VMHost.ExtensionData.Summary.Hardware.NumNics - 'Number of HBAs' = $VMHost.ExtensionData.Summary.Hardware.NumHBAs - 'Number of Datastores' = ($VMHost.ExtensionData.Datastore).Count - 'Number of VMs' = $VMHost.ExtensionData.VM.Count - 'Maximum EVC Mode' = $EvcModeLookup."$($VMHost.MaxEVCMode)" - 'EVC Graphics Mode' = if ($VMHost.ExtensionData.Summary.CurrentEVCGraphicsModeKey) { - $VMHost.ExtensionData.Summary.CurrentEVCGraphicsModeKey - } else { - 'Not applicable' - } - '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).ToString() - 'ESXi Version' = $VMHost.Version - 'ESXi Build' = $VMHost.build - 'Boot Time' = ($VMHost.ExtensionData.Runtime.Boottime).ToLocalTime().ToString() - 'Uptime Days' = $VMHostUptime.UptimeDays - } - $MemberProps = @{ - 'InputObject' = $VMHostDetail - 'MemberType' = 'NoteProperty' - } - if ($UserPrivileges -contains 'Global.Licenses') { - $VMHostLicense = Get-License -VMHost $VMHost - Add-Member @MemberProps -Name 'Product' -Value $VMHostLicense.Product - Add-Member @MemberProps -Name 'License Key' -Value $VMHostLicense.LicenseKey - Add-Member @MemberProps -Name 'License Expiration' -Value $VMHostLicense.Expiration - } else { - Write-PScriboMessage "Insufficient user privileges to report ESXi host licensing. Please ensure the user account has the 'Global > Licenses' privilege assigned." - } - <# - if ($TagAssignments | Where-Object {$_.entity -eq $VMHost}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $VMHost}).Tag -join ',') - } - #> - 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 = "Hardware Configuration - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostDetail | Table @TableParams - #endregion ESXi Host Specifications - - #region ESXi IPMI/BMC Settings - Try { - $VMHostIPMI = $esxcli.hardware.ipmi.bmc.get.invoke() - } Catch { - Write-PScriboMessage -IsWarning "Unable to collect IPMI / BMC configuration from $VMHost." - } - if ($VMHostIPMI) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'IPMI / BMC' { - $VMHostIPMIInfo = [PSCustomObject]@{ - 'Manufacturer' = $VMHostIPMI.Manufacturer - 'MAC Address' = $VMHostIPMI.MacAddress - 'IP Address' = $VMHostIPMI.IPv4Address - 'Subnet Mask' = $VMHostIPMI.IPv4Subnet - 'Gateway' = $VMHostIPMI.IPv4Gateway - 'Firmware Version' = $VMHostIPMI.BMCFirmwareVersion - } - - $TableParams = @{ - Name = "IPMI / BMC - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostIPMIInfo | Table @TableParams - } - } - #endregion ESXi IPMI/BMC Settings - - #region ESXi Host Boot Device - Section -Style NOTOCHeading5 -ExcludeFromTOC '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' = Switch ($ESXiBootDevice.SizeMB) { - 'N/A' { 'N/A' } - default { Convert-DataSize $ESXiBootDevice.SizeMB -InputUnit MB -RoundUnits 0 } - } - 'Is SAS' = $ESXiBootDevice.IsSAS - 'Is SSD' = $ESXiBootDevice.IsSSD - 'Is USB' = $ESXiBootDevice.IsUSB - } - $TableParams = @{ - Name = "Boot Device - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostBootDevice | Table @TableParams - } - #endregion ESXi Host Boot Devices - - #region ESXi Host PCI Devices - Section -Style NOTOCHeading5 -ExcludeFromTOC 'PCI Devices' { - <# Move away from esxcli.v2 implementation to be compatible with 8.x branch. - 'Slot Description' information does not seem to be available through the API - Create an array with PCI Address and VMware Devices (vmnic,vmhba,?vmgfx?) - #> - $PciToDeviceMapping = @{} - $NetworkAdapters = Get-VMHostNetworkAdapter -VMHost $VMHost -Physical - foreach ($adapter in $NetworkAdapters) { - $PciToDeviceMapping[$adapter.PciId] = $adapter.DeviceName - } - $hbAdapters = Get-VMHostHba -VMHost $VMHost - foreach ($adapter in $hbAdapters) { - $PciToDeviceMapping[$adapter.Pci] = $adapter.Device - } - <# Data Object - HostGraphicsInfo(vim.host.GraphicsInfo) - This function has been available since version 5.5, but we can't be sure if it is still valid. - I don't have access to a vGPU-enabled system. - #> - $GpuAdapters = (Get-VMHost $VMhost | Get-View -Property Config).Config.GraphicsInfo - foreach ($adapter in $GpuAdapters) { - $PciToDeviceMapping[$adapter.pciId] = $adapter.deviceName - } - - $VMHostPciDevice = @{ - VMHost = $VMHost - DeviceClass = @('MassStorageController', 'NetworkController', 'DisplayController', 'SerialBusController') - } - $PciDevices = Get-VMHostPciDevice @VMHostPciDevice - - # Combine PciDevices and PciToDeviceMapping - - $VMHostPciDevices = $PciDevices | ForEach-Object { - $PciDevice = $_ - $device = $PCIToDeviceMapping[$pciDevice.Id] - - if ($device) { - [PSCustomObject]@{ - 'Device' = $device - 'PCI Address' = $PciDevice.Id - 'Device Class' = $PciDevice.DeviceClass -replace ('Controller', "") - 'Device Name' = $PciDevice.DeviceName - 'Vendor Name' = $PciDevice.VendorName - } - } - } - - $TableParams = @{ - Name = "PCI Devices - $VMHost" - ColumnWidths = 17, 18, 15, 30, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostPciDevices | Sort-Object 'Device' | Table @TableParams - } - #endregion ESXi Host PCI Devices - - #region ESXi Host PCI Devices Drivers & Firmware - $VMHostPciDevicesDetails = Get-PciDeviceDetail -Server $vCenter -esxcli $esxcli | Sort-Object 'Device' - if ($VMHostPciDevicesDetails) { - Try { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'PCI Devices Drivers & Firmware' { - $TableParams = @{ - Name = "PCI Devices Drivers & Firmware - $VMHost" - ColumnWidths = 12, 20, 11, 19, 11, 11, 16 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostPciDevicesDetails | Table @TableParams - } - } Catch { - Write-PScriboMessage -IsWarning "Unable to collect PCI Devices Drivers & Firmware configuration from $VMhost." - } - } - #endregion ESXi Host PCI Devices Drivers & Firmware - } - #endregion ESXi Host Hardware Section - - #region ESXi Host System Section - Section -Style Heading4 'System' { - Paragraph "The following section details the host system configuration for $VMHost." - #region ESXi Host Profile Information - if ($VMHost | Get-VMHostProfile) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Host Profile' { - $VMHostProfile = $VMHost | Get-VMHostProfile | Select-Object Name, Description - $TableParams = @{ - Name = "Host Profile - $VMHost" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostProfile | Sort-Object Name | Table @TableParams - } - } - #endregion ESXi Host Profile Information - - #region ESXi Host Image Profile Information - if ($UserPrivileges -contains 'Host.Config.Settings') { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Image Profile' { - $installdate = Get-InstallDate - $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter - $ImageProfile = $esxcli.software.profile.get.Invoke() - $SecurityProfile = [PSCustomObject]@{ - 'Image Profile' = $ImageProfile.Name - 'Vendor' = $ImageProfile.Vendor - 'Installation Date' = $InstallDate.InstallDate - } - $TableParams = @{ - Name = "Image Profile - $VMHost" - #ColumnWidths = 50, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $SecurityProfile | Table @TableParams - } - } else { - Write-PScriboMessage "Insufficient user privileges to report ESXi host image profiles. Please ensure the user account has the 'Host > Configuration > Change settings' privilege assigned." - } - #endregion ESXi Host Image Profile Information - - #region ESXi Host Time Configuration - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Time Configuration' { - $VMHostTimeSettings = [PSCustomObject]@{ - 'Time Zone' = $VMHost.timezone - 'NTP Service' = if ((Get-VMHostService -VMHost $VMHost | Where-Object { $_.key -eq 'ntpd' }).Running) { - 'Running' - } else { - '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" - 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 NOTOCHeading5 -ExcludeFromTOC '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" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $SyslogConfig | Table @TableParams - } - } - #endregion ESXi Host Syslog Configuration - - #region ESXi Update Manager Baseline Information - if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { - if ($VumServer.Name) { - Try { - $VMHostPatchBaselines = $VMHost | Get-PatchBaseline - } Catch { - Write-PScriboMessage 'ESXi VUM baseline information is not currently available with your version of PowerShell.' - } - if ($VMHostPatchBaselines) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Update Manager Baselines' { - $VMHostBaselines = foreach ($VMHostBaseline in $VMHostPatchBaselines) { - [PSCustomObject]@{ - 'Baseline' = $VMHostBaseline.Name - 'Description' = $VMHostBaseline.Description - 'Type' = $VMHostBaseline.BaselineType - 'Target Type' = $VMHostBaseline.TargetType - 'Last Update Time' = ($VMHostBaseline.LastUpdateTime).ToLocalTime().ToString() - '# of Patches' = $VMHostBaseline.CurrentPatches.Count - } - } - $TableParams = @{ - Name = "Update Manager Baselines - $VMHost" - ColumnWidths = 25, 25, 10, 10, 20, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostBaselines | Sort-Object 'Baseline' | Table @TableParams - } - } - } - } else { - Write-PScriboMessage "Insufficient user privileges to report ESXi host baselines. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned." - } - #endregion ESXi Update Manager Baseline Information - - #region ESXi Update Manager Compliance Information - if ($UserPrivileges -contains 'VcIntegrity.Updates.com.vmware.vcIntegrity.ViewStatus') { - if ($VumServer.Name) { - Try { - $VMHostCompliances = $VMHost | Get-Compliance - } Catch { - Write-PScriboMessage 'ESXi VUM compliance information is not currently available with your version of PowerShell.' - } - if ($VMHostCompliances) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Update Manager Compliance' { - $VMHostComplianceInfo = foreach ($VMHostCompliance in $VMHostCompliances) { - [PSCustomObject]@{ - 'Baseline' = $VMHostCompliance.Baseline.Name - 'Status' = Switch ($VMHostCompliance.Status) { - 'NotCompliant' { 'Not Compliant' } - default { $VMHostCompliance.Status } - } - } - } - if ($Healthcheck.VMHost.VUMCompliance) { - $VMHostComplianceInfo | Where-Object { $_.Status -eq 'Unknown' } | Set-Style -Style Warning - $VMHostComplianceInfo | Where-Object { $_.Status -eq 'Not Compliant' -or $_.Status -eq 'Incompatible' } | Set-Style -Style Critical - } - $TableParams = @{ - Name = "Update Manager Compliance - $VMHost" - ColumnWidths = 75, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostComplianceInfo | Sort-Object Baseline | Table @TableParams - } - } - } - } else { - Write-PScriboMessage "Insufficient user privileges to report ESXi host compliance. Please ensure the user account has the 'VMware Update Manager / VMware vSphere Lifecycle Manager > Manage Patches and Upgrades > View Compliance Status' privilege assigned." - } - #endregion ESXi Update Manager Compliance Information - - #region ESXi Host Comprehensive Information Section - if ($InfoLevel.VMHost -ge 5) { - #region ESXi Host Advanced System Settings - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Advanced System Settings' { - $AdvSettings = $VMHost | Get-AdvancedSetting | Select-Object Name, Value - $TableParams = @{ - Name = "Advanced System Settings - $VMHost" - ColumnWidths = 50, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $AdvSettings | Sort-Object Name | Table @TableParams - } - #endregion ESXi Host Advanced System Settings - - #region ESXi Host Software VIBs - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Software VIBs' { - $esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter - $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 - } - } - $TableParams = @{ - Name = "Software VIBs - $VMHost" - ColumnWidths = 15, 25, 15, 15, 15, 15 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostVibs | Sort-Object 'Install Date' -Descending | Table @TableParams - } - #endregion ESXi Host Software VIBs - } - #endregion ESXi Host Comprehensive Information Section - } - #endregion ESXi Host System Section - - #region ESXi Host Storage Section - Section -Style Heading4 'Storage' { - Paragraph "The following section details the host storage configuration for $VMHost." - - #region ESXi Host Datastore Specifications - $VMHostDatastores = $VMHost | Get-Datastore | Where-Object { ($_.State -eq 'Available') -and ($_.CapacityGB -gt 0) } | Sort-Object Name - if ($VMHostDatastores) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Datastores' { - $VMHostDsSpecs = foreach ($VMHostDatastore in $VMHostDatastores) { - - $VMHostDsUsedPercent = if (0 -in @($VMHostDatastore.FreeSpaceGB, $VMHostDatastore.CapacityGB)) {0} else {[math]::Round((100 - (($VMHostDatastore.FreeSpaceGB) / ($VMHostDatastore.CapacityGB) * 100)), 2)} - $VMHostDsFreePercent = if (0 -in @($VMHostDatastore.FreeSpaceGB, $VMHostDatastore.CapacityGB)) {0} else {[math]::Round(($VMHostDatastore.FreeSpaceGB / $VMHostDatastore.CapacityGB) * 100, 2)} - $VMHostDsUsedCapacityGB = ($VMHostDatastore.CapacityGB) - ($VMHostDatastore.FreeSpaceGB) - - [PSCustomObject]@{ - 'Datastore' = $VMHostDatastore.Name - 'Type' = $VMHostDatastore.Type - 'Version' = if ($VMHostDatastore.FileSystemVersion) { - $VMHostDatastore.FileSystemVersion - } else { - '--' - } - '# of VMs' = $VMHostDatastore.ExtensionData.VM.Count - 'Total Capacity' = Convert-DataSize $VMHostDatastore.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $VMHostDsUsedCapacityGB), $VMHostDsUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $VMHostDsFreePercent - '% Used' = $VMHostDsUsedPercent - } - } - if ($Healthcheck.Datastore.CapacityUtilization) { - $VMHostDsSpecs | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $VMHostDsSpecs | Where-Object { $_.'% Used' -ge 75 -and $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property 'Used Capacity', 'Free Capacity' - } - $TableParams = @{ - Name = "Datastores - $VMHost" - Columns = 'Datastore', 'Type', 'Version', '# of VMs', 'Total Capacity', 'Used Capacity', 'Free Capacity' - ColumnWidths = 21, 10, 9, 9, 17, 17, 17 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostDsSpecs | Sort-Object 'Datastore' | Table @TableParams - } - } - #endregion ESXi Host Datastore Specifications - - #region ESXi Host Storage Adapter Information - $VMHostHbas = $VMHost | Get-VMHostHba | Sort-Object Device - if ($VMHostHbas) { - #region ESXi Host Storage Adapters Section - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Storage Adapters' { - Paragraph "The following section details the storage adapter configuration for $VMHost." - 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 NOTOCHeading5 -ExcludeFromTOC "$($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' } - } - } - 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 -ge 4) { - Add-Member @MemberProps -Name 'Advanced Options' -Value (($VMHostHba.ExtensionData.AdvancedOptions | ForEach-Object { "$($_.Key) = $($_.Value)" }) -join [Environment]::NewLine) - } - } - 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' - } - $TableParams = @{ - Name = "Storage Adapter $($VMHostStorageAdapter.Adapter) - $VMHost" - List = $true - ColumnWidths = 25, 75 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostStorageAdapter | Table @TableParams - } - } - } - #endregion ESXi Host Storage Adapters Section - } - #endregion ESXi Host Storage Adapter Information - } - #endregion ESXi Host Storage Section - - #region ESXi Host Network Section - Section -Style Heading4 'Network' { - Paragraph "The following section details the host network configuration for $VMHost." - 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.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' = if ($VMHostNetwork.IPv6Enabled) { - 'Enabled' - } else { - 'Disabled' - } - 'VMkernel IPv6 Gateway' = if ($VMHostNetwork.IpRouteConfig.IpV6DefaultGateway) { - $VMHostNetwork.IpRouteConfig.IpV6DefaultGateway - } else { - '--' - } - '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" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostNetworkDetail | Table @TableParams - #endregion ESXi Host Network Configuration - - #region ESXi Host Physical Adapters - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Physical Adapters' { - Paragraph "The following section details the physical network adapter configuration for $VMHost." - $PhysicalNetAdapters = $VMHost.ExtensionData.Config.Network.Pnic | Sort-Object Device - $VMHostPhysicalNetAdapters = foreach ($PhysicalNetAdapter in $PhysicalNetAdapters) { - [PSCustomObject]@{ - 'Adapter' = $PhysicalNetAdapter.Device - 'Status' = if ($PhysicalNetAdapter.Linkspeed) { - 'Connected' - } else { - 'Disconnected' - } - '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' = if ($PhysicalNetAdapter.LinkSpeed.SpeedMb) { - if ($PhysicalNetAdapter.LinkSpeed.Duplex) { - "$($PhysicalNetAdapter.LinkSpeed.SpeedMb) Mbps, Full Duplex" - } else { - 'Auto negotiate' - } - } else { - 'Down' - } - 'Configured Speed, Duplex' = if ($PhysicalNetAdapter.Spec.LinkSpeed) { - if ($PhysicalNetAdapter.Spec.LinkSpeed.Duplex) { - "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps, Full Duplex" - } else { - "$($PhysicalNetAdapter.Spec.LinkSpeed.SpeedMb) Mbps" - } - } else { - 'Auto negotiate' - } - 'Wake on LAN' = if ($PhysicalNetAdapter.WakeOnLanSupported) { - 'Supported' - } else { - '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 NOTOCHeading5 -ExcludeFromTOC "$($VMHostPhysicalNetAdapter.Adapter)" { - $TableParams = @{ - Name = "Physical Adapter $($VMHostPhysicalNetAdapter.Adapter) - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostPhysicalNetAdapter | Table @TableParams - } - } - } else { - BlankLine - $TableParams = @{ - Name = "Physical Adapters - $VMHost" - 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-VMHostNetworkAdapterDP | Where-Object { $_.Status -eq 'Connected' } | Sort-Object Device - if ($VMHostNetworkAdapterCDP) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Cisco Discovery Protocol' { - Paragraph "The following section details the CDP information for $VMHost." - if ($InfoLevel.VMHost -ge 4) { - foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "$($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" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostCDP | Table @TableParams - } - } - } else { - BlankLine - $VMHostCDP = foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterCDP) { - [PSCustomObject]@{ - '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" - 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 NOTOCHeading5 -ExcludeFromTOC 'Link Layer Discovery Protocol' { - Paragraph "The following section details the LLDP information for $VMHost." - if ($InfoLevel.VMHost -ge 4) { - foreach ($VMHostNetworkAdapter in $VMHostNetworkAdapterLLDP) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "$($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 - } - $TableParams = @{ - Name = "Network Adapter $($VMHostNetworkAdapter.Device) LLDP Information - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostLLDP | Table @TableParams - } - } - } else { - BlankLine - $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" - 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 NOTOCHeading5 -ExcludeFromTOC 'VMkernel Adapters' { - Paragraph "The following section details the VMkernel adapter configuration for $VMHost" - $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 - 'Network Label' = & { - if ($_.Spec.Portgroup) { - $script:pg = $_.Spec.Portgroup - $script:pg - } elseif ($_.Spec.DistributedVirtualPort.Portgroupkey) { - $script:pg = Get-View -ViewType DistributedVirtualPortgroup -Property Name, Key -Filter @{'Key' = "$($_.Spec.DistributedVirtualPort.PortgroupKey)" } | Select-Object -ExpandProperty Name - $script:pg - } else { - '--' - } - } - 'Virtual Switch' = & { - if ($_.Spec.Portgroup) { - (Get-VirtualPortGroup -Standard -Name $script:pg -VMHost $VMHost).VirtualSwitchName - } elseif ($_.Spec.DistributedVirtualPort.Portgroupkey) { - (Get-VDPortgroup -Name $script:pg).VDSwitch.Name | Select-Object -Unique - } else { - # Haven't figured out how to gather this yet! - '--' - } - } - 'TCP/IP Stack' = Switch ($_.Spec.NetstackInstanceKey) { - 'defaultTcpipStack' { 'Default' } - 'vSphereProvisioning' { 'Provisioning' } - 'vmotion' { 'vMotion' } - 'vxlan' { 'nsx-overlay' } - 'hyperbus' { 'nsx-hyperbus' } - $null { 'Not Applicable' } - default { $_.Spec.NetstackInstanceKey } - } - 'MTU' = $_.Spec.Mtu - 'MAC Address' = $_.Spec.Mac - 'DHCP' = if ($_.Spec.Ip.Dhcp) { - 'Enabled' - } else { - 'Disabled' - } - 'IP Address' = & { - if ($_.Spec.IP.IPAddress) { - $script:ip = $_.Spec.IP.IPAddress - } else { - $script:ip = '--' - } - $script:ip - } - 'Subnet Mask' = & { - if ($_.Spec.IP.SubnetMask) { - $script:netmask = $_.Spec.IP.SubnetMask - } else { - $script:netmask = '--' - } - $script:netmask - } - 'Default Gateway' = if ($_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway) { - $_.Spec.IpRouteSpec.IpRouteConfig.DefaultGateway - } else { - '--' - } - 'vMotion' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vmotion' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'Provisioning' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereProvisioning' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'FT Logging' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'faultToleranceLogging' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'Management' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'management' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'vSphere Replication' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereReplication' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'vSphere Replication NFC' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereReplicationNFC' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'vSAN' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vsan' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'vSAN Witness' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vsanWitness' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - 'vSphere Backup NFC' = if ((($vnicMgr.Info.NetConfig | Where-Object { $_.NicType -eq 'vSphereBackupnNFC' }).SelectedVnic | ForEach-Object { $_ -match $device } ) -contains $true) { - 'Enabled' - } else { - 'Disabled' - } - } - } - } - foreach ($VMkernelAdapter in ($VMkernelAdapters | Sort-Object 'Adapter')) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "$($VMkernelAdapter.Adapter)" { - $TableParams = @{ - Name = "VMkernel Adapter $($VMkernelAdapter.Adapter) - $VMHost" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMkernelAdapter | Table @TableParams - } - } - } - #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 NOTOCHeading5 -ExcludeFromTOC '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" - 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 NOTOCHeading5 -ExcludeFromTOC 'Virtual Switch Security' { - $VssSecurity = foreach ($VssSec in $VssSecurity) { - [PSCustomObject]@{ - 'Virtual Switch' = $VssSec.VirtualSwitch - 'Promiscuous Mode' = if ($VssSec.AllowPromiscuous) { - 'Accept' - } else { - 'Reject' - } - 'MAC Address Changes' = if ($VssSec.MacChanges) { - 'Accept' - } else { - 'Reject' - } - 'Forged Transmits' = if ($VssSec.ForgedTransmits) { - 'Accept' - } else { - 'Reject' - } - } - } - $TableParams = @{ - Name = "Virtual Switch Security Policy - $VMHost" - 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 Virtual Switch Traffic Shaping Policy - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Virtual Switch Traffic Shaping' { - $VssTrafficShapingPolicy = foreach ($VSSwitch in $VSSwitches) { - [PSCustomObject]@{ - 'Virtual Switch' = $VSSwitch.Name - 'Status' = if ($VSSwitch.ExtensionData.Spec.Policy.ShapingPolicy.Enabled) { - 'Enabled' - } else { - '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" - 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 NOTOCHeading5 -ExcludeFromTOC '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' = if ($VssNicTeam.NotifySwitches) { - 'Yes' - } else { - 'No' - } - 'Failback' = if ($VssNicTeam.FailbackEnabled) { - 'Yes' - } else { - '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" - ColumnWidths = 20, 17, 12, 11, 10, 10, 10, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VssNicTeaming | Sort-Object 'Virtual Switch' | Table @TableParams - } - #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 NOTOCHeading5 -ExcludeFromTOC '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 Groups - $VMHost" - 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 NOTOCHeading5 -ExcludeFromTOC 'Virtual Switch Port Group Security' { - $VssPortgroupSecurity = foreach ($VssPortgroupSec in $VssPortgroupSecurity) { - [PSCustomObject]@{ - 'Port Group' = $VssPortgroupSec.VirtualPortGroup - 'Virtual Switch' = $VssPortgroupSec.virtualportgroup.virtualswitchname - 'Promiscuous Mode' = if ($VssPortgroupSec.AllowPromiscuous) { - 'Accept' - } else { - 'Reject' - } - 'MAC Changes' = if ($VssPortgroupSec.MacChanges) { - 'Accept' - } else { - 'Reject' - } - 'Forged Transmits' = if ($VssPortgroupSec.ForgedTransmits) { - 'Accept' - } else { - 'Reject' - } - } - } - $TableParams = @{ - Name = "Virtual Switch Port Group Security Policy - $VMHost" - ColumnWidths = 27, 25, 16, 16, 16 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VssPortgroupSecurity | Sort-Object 'Port Group', 'Virtual Switch' | Table @TableParams - } - #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 NOTOCHeading5 -ExcludeFromTOC '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' } - } - '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 - } - } - $TableParams = @{ - Name = "Virtual Switch Port Group Traffic Shaping Policy - $VMHost" - 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 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 NOTOCHeading5 -ExcludeFromTOC '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' = if ($VssPortgroupNicTeam.NotifySwitches) { - 'Yes' - } else { - 'No' - } - 'Failback' = if ($VssPortgroupNicTeam.FailbackEnabled) { - 'Yes' - } else { - '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 = "Virtual Switch Port Group Teaming & Failover - $VMHost" - 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 Port Group Teaming & Failover Section - } - #endregion ESXi Host Virtual Switch Port Group Teaming & Failover - } - } - #endregion Section Standard Virtual Switches - } - #endregion ESXi Host Standard Virtual Switches - } - #endregion ESXi Host Network Section - - #region ESXi Host Security Section - Section -Style Heading4 'Security' { - Paragraph "The following section details the host security configuration for $VMHost." - #region ESXi Host Lockdown Mode - if ($null -ne $VMHost.ExtensionData.Config.LockdownMode) { - Section -Style NOTOCHeading5 -ExcludeFromTOC '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" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $LockdownMode | Table @TableParams - } - } - #endregion ESXi Host Lockdown Mode - - #region ESXi Host Services - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Services' { - $VMHostServices = $VMHost | Get-VMHostService - $Services = foreach ($VMHostService in $VMHostServices) { - [PSCustomObject]@{ - 'Service' = $VMHostService.Label - 'Daemon' = if ($VMHostService.Running) { - 'Running' - } else { - '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" - 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 NOTOCHeading5 -ExcludeFromTOC 'Firewall' { - $VMHostFirewall = foreach ($VMHostFirewallException in $VMHostFirewallExceptions) { - [PScustomObject]@{ - 'Service' = $VMHostFirewallException.Name - 'Status' = if ($VMHostFirewallException.Enabled) { - 'Enabled' - } else { - '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 } - } - } - } - $TableParams = @{ - Name = "Firewall Configuration - $VMHost" - ColumnWidths = 22, 12, 21, 21, 12, 12 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostFirewall | Sort-Object 'Service' | Table @TableParams - } - #endregion Friewall Section - } - #endregion ESXi Host Firewall - - #region ESXi Host Authentication - $AuthServices = $VMHost | Get-VMHostAuthentication - if ($AuthServices.DomainMembershipStatus) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Authentication Services' { - $AuthServices = $AuthServices | Select-Object Domain, @{L = 'Domain Membership'; E = { $_.DomainMembershipStatus } }, @{L = 'Trusted Domains'; E = { $_.TrustedDomains } } - $TableParams = @{ - Name = "Authentication Services - $VMHost" - ColumnWidths = 25, 25, 50 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $AuthServices | Table @TableParams - } - } - #endregion ESXi Host Authentication - } - #endregion ESXi Host Advanced Detail Information - } - #endregion ESXi Host Security Section - - #region ESXi Host Virtual Machines Advanced Detail Information - if ($InfoLevel.VMHost -ge 4) { - $VMHostVMs = $VMHost | Get-VM | Sort-Object Name - if ($VMHostVMs) { - #region Virtual Machines Section - Section -Style Heading4 'Virtual Machines' { - Paragraph "The following section details the virtual machine configuration for $VMHost." - BlankLine - #region ESXi Host Virtual Machine Information - $VMHostVMInfo = foreach ($VMHostVM in $VMHostVMs) { - $VMHostVMView = $VMHostVM | Get-View - [PSCustomObject]@{ - 'Virtual Machine' = $VMHostVM.Name - 'Power State' = Switch ($VMHostVM.PowerState) { - 'PoweredOn' { 'On' } - 'PoweredOff' { 'Off' } - default { $VMHostVM.PowerState } - } - 'IP Address' = if ($VMHostVMView.Guest.IpAddress) { - $VMHostVMView.Guest.IpAddress - } else { - '--' - } - 'CPUs' = $VMHostVM.NumCpu - #'Cores per Socket' = $VMHostVM.CoresPerSocket - 'Memory' = Convert-DataSize $VMHostVM.memoryGB -RoundUnits 0 - 'Provisioned' = Convert-DataSize $VMHostVM.ProvisionedSpaceGB - 'Used' = Convert-DataSize $VMHostVM.UsedSpaceGB - 'HW Version' = ($VMHostVM.HardwareVersion).Replace('vmx-', 'v') - 'VM Tools Status' = Switch ($VMHostVM.ExtensionData.Guest.ToolsStatus) { - 'toolsOld' { 'Old' } - 'toolsOK' { 'OK' } - 'toolsNotRunning' { 'Not Running' } - 'toolsNotInstalled' { 'Not Installed' } - default { $VMHostVM.ExtensionData.Guest.ToolsStatus } - } - } - } - if ($Healthcheck.VM.VMToolsStatus) { - $VMHostVMInfo | Where-Object { $_.'VM Tools Status' -ne 'OK' } | Set-Style -Style Warning -Property 'VM Tools Status' - } - if ($Healthcheck.VM.PowerState) { - $VMHostVMInfo | Where-Object { $_.'Power State' -ne 'On' } | Set-Style -Style Warning -Property 'Power State' - } - $TableParams = @{ - Name = "Virtual Machines - $VMHost" - ColumnWidths = 21, 8, 16, 9, 9, 9, 9, 9, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMHostVMInfo | Table @TableParams - #endregion ESXi Host Virtual Machine Information - - #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 NOTOCHeading5 -ExcludeFromTOC 'VM Startup/Shutdown' { - $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' = if ($VMStartPol.WaitForHeartbeat) { - 'Continue if VMware Tools is started' - } else { - 'Wait for startup delay' - } - 'Shutdown Behavior' = Switch ($VMStartPol.StopAction) { - 'PowerOff' { 'Power Off' } - 'GuestShutdown' { 'Guest Shutdown' } - default { $VMStartPol.StopAction } - } - 'Shutdown Delay' = "$($VMStartPol.StopDelay) seconds" - } - } - $TableParams = @{ - Name = "VM Startup/Shutdown Policy - $VMHost" - ColumnWidths = 11, 34, 11, 11, 11, 11, 11 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMStartPolicies | Table @TableParams - } - #endregion VM Startup/Shutdown Section - } - #endregion ESXi Host VM Startup/Shutdown Information - } - #endregion Virtual Machines Section - } - } - #endregion ESXi Host Virtual Machines Advanced Detail Information - } - #endregion VMHost Section - } - #endregion foreach VMHost Detailed Information loop - } - #endregion ESXi Host Detailed Information - } - #endregion Hosts Section - } - } - #endregion ESXi VMHost Section - - #region Distributed Switch Section - Write-PScriboMessage "Network InfoLevel set at $($InfoLevel.Network)." - if ($InfoLevel.Network -ge 1) { - # Create Distributed Switch Section if they exist - $VDSwitches = Get-VDSwitch -Server $vCenter | Sort-Object Name - if ($VDSwitches) { - Section -Style Heading2 'Distributed Switches' { - Paragraph "The following sections detail the configuration of distributed switches managed by vCenter Server $vCenterServerName." - #region Distributed Switch Advanced Summary - if ($InfoLevel.Network -le 2) { - BlankLine - $VDSInfo = foreach ($VDS in $VDSwitches) { - [PSCustomObject]@{ - 'VDSwitch' = $VDS.Name - 'Datacenter' = $VDS.Datacenter - 'Manufacturer' = $VDS.Vendor - 'Version' = $VDS.Version - '# of Uplinks' = $VDS.NumUplinkPorts - '# of Ports' = $VDS.NumPorts - '# of Hosts' = $VDS.ExtensionData.Summary.HostMember.Count - '# of VMs' = $VDS.ExtensionData.Summary.VM.Count - } - } - $TableParams = @{ - Name = "Distributed Switch Summary - $($vCenterServerName)" - ColumnWidths = 20, 18, 18, 10, 10, 8, 8, 8 - } - 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 - # TODO: Test Tags - foreach ($VDS in ($VDSwitches)) { - #region VDS Section - Section -Style Heading3 $VDS { - #region Distributed Switch General Properties - $VDSwitchDetail = [PSCustomObject]@{ - 'Distributed Switch' = $VDS.Name - 'ID' = $VDS.Id - 'Datacenter' = $VDS.Datacenter - 'Manufacturer' = $VDS.Vendor - 'Version' = $VDS.Version - 'Number of Uplinks' = $VDS.NumUplinkPorts - 'Number of Ports' = $VDS.NumPorts - 'Number of Port Groups' = $VDS.ExtensionData.Summary.PortGroupName.Count - 'Number of Hosts' = $VDS.ExtensionData.Summary.HostMember.Count - 'Number of VMs' = $VDS.ExtensionData.Summary.VM.Count - 'MTU' = $VDS.Mtu - 'Network I/O Control' = if ($VDS.ExtensionData.Config.NetworkResourceManagementEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Discovery Protocol' = $VDS.LinkDiscoveryProtocol - 'Discovery Protocol Operation' = $VDS.LinkDiscoveryProtocolOperation - } - <# - $MemberProps = @{ - 'InputObject' = $VDSwitchDetail - 'MemberType' = 'NoteProperty' - } - if ($TagAssignments | Where-Object {$_.entity -eq $VDS}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $VDS}).Tag -join ',') - } - #> - #region Network Advanced Detail Information - if ($InfoLevel.Network -ge 4) { - $VDSwitchDetail | ForEach-Object { - $VDSwitchHosts = $VDS | Get-VMHost | Sort-Object Name - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Hosts' -Value ($VDSwitchHosts.Name -join ', ') - $VDSwitchVMs = $VDS | Get-VM | Sort-Object - Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Virtual Machines' -Value ($VDSwitchVMs.Name -join ', ') - } - } - #endregion Network Advanced Detail Information - $TableParams = @{ - Name = "Distributed Switch General Properties - $VDS" - List = $true - ColumnWidths = 40, 60 - } - 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 - 'Host' = $VdsUplink.ProxyHost - 'Uplink Name' = $VdsUplink.Name - 'Physical Network Adapter' = $VdsUplink.ConnectedEntity - 'Uplink Port Group' = $VdsUplink.Portgroup - } - } - $TableParams = @{ - Name = "Distributed Switch Uplink Ports - $VDS" - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VdsUplinkDetail | Sort-Object 'Distributed Switch', 'Host', 'Uplink Name' | Table @TableParams - } - } - #endregion Distributed Switch Uplink Ports - - #region Distributed Switch Security - $VDSecurityPolicy = $VDS | Get-VDSecurityPolicy - if ($VDSecurityPolicy) { - Section -Style Heading4 'Distributed Switch Security' { - $VDSecurityPolicyDetail = [PSCustomObject]@{ - 'Distributed Switch' = $VDSecurityPolicy.VDSwitch - 'Allow Promiscuous' = if ($VDSecurityPolicy.AllowPromiscuous) { - 'Accept' - } else { - 'Reject' - } - 'Forged Transmits' = if ($VDSecurityPolicy.ForgedTransmits) { - 'Accept' - } else { - 'Reject' - } - 'MAC Address Changes' = if ($VDSecurityPolicy.MacChanges) { - 'Accept' - } else { - 'Reject' - } - } - $TableParams = @{ - Name = "Distributed Switch Security - $VDS" - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSecurityPolicyDetail | Table @TableParams - } - } - #endregion Distributed Switch Security - - #region Distributed Switch Traffic Shaping - $VDSTrafficShaping = @() - $VDSTrafficShapingIn = $VDS | Get-VDTrafficShapingPolicy -Direction In - $VDSTrafficShapingOut = $VDS | Get-VDTrafficShapingPolicy -Direction Out - $VDSTrafficShaping += $VDSTrafficShapingIn - $VDSTrafficShaping += $VDSTrafficShapingOut - if ($VDSTrafficShapingIn -or $VDSTrafficShapingOut) { - Section -Style Heading4 'Distributed Switch Traffic Shaping' { - $VDSTrafficShapingDetail = foreach ($VDSTrafficShape in $VDSTrafficShaping) { - [PSCustomObject]@{ - 'Distributed Switch' = $VDSTrafficShape.VDSwitch - 'Direction' = $VDSTrafficShape.Direction - 'Status' = if ($VDSTrafficShape.Enabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Average Bandwidth (kbit/s)' = $VDSTrafficShape.AverageBandwidth - 'Peak Bandwidth (kbit/s)' = $VDSTrafficShape.PeakBandwidth - 'Burst Size (KB)' = $VDSTrafficShape.BurstSize - } - } - $TableParams = @{ - Name = "Distributed Switch Traffic Shaping - $VDS" - ColumnWidths = 25, 13, 11, 17, 17, 17 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSTrafficShapingDetail | Sort-Object 'Direction' | Table @TableParams - } - } - #endregion Distributed Switch Traffic Shaping - - #region Distributed Switch Port Groups - # TODO: Test Tags - $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 - 'Datacenter' = $VDSPortgroup.Datacenter - 'VLAN Configuration' = if ($VDSPortgroup.VlanConfiguration) { - $VDSPortgroup.VlanConfiguration - } else { - '--' - } - 'Port Binding' = $VDSPortgroup.PortBinding - '# of Ports' = $VDSPortgroup.NumPorts - <# - # Tags on portgroups cause Get-TagAssignments to error - 'Tags' = & { - if ($TagAssignments | Where-Object {$_.entity -eq $VDSPortgroup}) { - ($TagAssignments | Where-Object {$_.entity -eq $VDSPortgroup}).Tag -join ',' - } else { - '--' - } - } - #> - } - } - $TableParams = @{ - Name = "Distributed Switch Port Groups - $VDS" - ColumnWidths = 20, 20, 20, 15, 15, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSPortgroupDetail | Sort-Object 'Port Group' | Table @TableParams - } - } - #endregion Distributed Switch Port Groups - - #region Distributed Switch Port Group Security - $VDSPortgroupSecurity = $VDS | Get-VDPortgroup | Get-VDSecurityPolicy - if ($VDSPortgroupSecurity) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "Distributed Switch Port Group Security" { - $VDSSecurityPolicies = foreach ($VDSSecurityPolicy in $VDSPortgroupSecurity) { - [PSCustomObject]@{ - 'Port Group' = $VDSSecurityPolicy.VDPortgroup - 'Distributed Switch' = $VDS.Name - 'Allow Promiscuous' = if ($VDSSecurityPolicy.AllowPromiscuous) { - 'Accept' - } else { - 'Reject' - } - 'Forged Transmits' = if ($VDSSecurityPolicy.ForgedTransmits) { - 'Accept' - } else { - 'Reject' - } - 'MAC Address Changes' = if ($VDSSecurityPolicy.MacChanges) { - 'Accept' - } else { - 'Reject' - } - } - } - $TableParams = @{ - Name = "Distributed Switch Port Group Security - $VDS" - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSSecurityPolicies | Sort-Object 'Port Group' | Table @TableParams - } - } - #endregion Distributed Switch Port Group Security - - #region Distributed Switch Port Group Traffic Shaping - $VDSPortgroupTrafficShaping = @() - $VDSPortgroupTrafficShapingIn = $VDS | Get-VDPortgroup | Get-VDTrafficShapingPolicy -Direction In - $VDSPortgroupTrafficShapingOut = $VDS | Get-VDPortgroup | Get-VDTrafficShapingPolicy -Direction Out - $VDSPortgroupTrafficShaping += $VDSPortgroupTrafficShapingIn - $VDSPortgroupTrafficShaping += $VDSPortgroupTrafficShapingOut - if ($VDSPortgroupTrafficShaping) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "Distributed Switch Port Group Traffic Shaping" { - $VDSPortgroupTrafficShapingDetail = foreach ($VDSPortgroupTrafficShape in $VDSPortgroupTrafficShaping) { - [PSCustomObject]@{ - 'Port Group' = $VDSPortgroupTrafficShape.VDPortgroup - 'Distributed Switch' = $VDS.Name - 'Direction' = $VDSPortgroupTrafficShape.Direction - 'Status' = if ($VDSPortgroupTrafficShape.Enabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Average Bandwidth (kbit/s)' = $VDSPortgroupTrafficShape.AverageBandwidth - 'Peak Bandwidth (kbit/s)' = $VDSPortgroupTrafficShape.PeakBandwidth - 'Burst Size (KB)' = $VDSPortgroupTrafficShape.BurstSize - } - } - $TableParams = @{ - Name = "Distributed Switch Port Group Traffic Shaping - $VDS" - ColumnWidths = 16, 16, 10, 10, 16, 16, 16 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSPortgroupTrafficShapingDetail | Sort-Object 'Port Group', 'Direction', 'Port Group' | Table @TableParams - - } - } - #endregion Distributed Switch Port Group Traffic Shaping - - #region Distributed Switch Port Group Teaming & Failover - $VDUplinkTeamingPolicy = $VDS | Get-VDPortgroup | Get-VDUplinkTeamingPolicy - if ($VDUplinkTeamingPolicy) { - Section -Style NOTOCHeading5 -ExcludeFromTOC "Distributed Switch Port Group Teaming & Failover" { - $VDSPortgroupNICTeaming = foreach ($VDUplink in $VDUplinkTeamingPolicy) { - [PSCustomObject]@{ - 'Port Group' = $VDUplink.VDPortgroup - 'Distributed Switch' = $VDS.Name - 'Load Balancing' = Switch ($VDUplink.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 { $VDUplink.LoadBalancingPolicy } - } - 'Network Failure Detection' = Switch ($VDUplink.FailoverDetectionPolicy) { - 'LinkStatus' { 'Link status only' } - 'BeaconProbing' { 'Beacon probing' } - default { $VDUplink.FailoverDetectionPolicy } - } - 'Notify Switches' = if ($VDUplink.NotifySwitches) { - 'Yes' - } else { - 'No' - } - 'Failback Enabled' = if ($VDUplink.EnableFailback) { - 'Yes' - } else { - 'No' - } - 'Active Uplinks' = $VDUplink.ActiveUplinkPort -join [Environment]::NewLine - 'Standby Uplinks' = $VDUplink.StandbyUplinkPort -join [Environment]::NewLine - 'Unused Uplinks' = $VDUplink.UnusedUplinkPort -join [Environment]::NewLine - } - } - $TableParams = @{ - Name = "Distributed Switch Port Group Teaming & Failover - $VDS" - ColumnWidths = 12, 12, 12, 11, 10, 10, 11, 11, 11 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSPortgroupNICTeaming | Sort-Object 'Port Group' | Table @TableParams - } - } - #endregion Distributed Switch Port Group Teaming & Failover - - #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 - } - } - $TableParams = @{ - Name = "Distributed Switch Private VLANs - $VDS" - ColumnWidths = 33, 34, 33 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VDSPvlan | Sort-Object 'Primary VLAN ID', 'Secondary VLAN ID' | Table @TableParams - } - } - #endregion Distributed Switch Private VLANs - } - #endregion VDS Section - } - } - #endregion Distributed Switch Detailed Information - } - } - } - #endregion Distributed Switch Section - - #region vSAN Section - Write-PScriboMessage "vSAN InfoLevel set at $($InfoLevel.vSAN)." - if (($InfoLevel.vSAN -ge 1) -and ($vCenter.Version -gt 6)) { - $VsanClusters = Get-VsanClusterConfiguration -Server $vCenter | Where-Object { $_.vsanenabled -eq $true } | Sort-Object Name - if ($VsanClusters) { - Section -Style Heading2 'vSAN' { - Paragraph "The following sections detail the configuration of vSAN managed by vCenter Server $vCenterServerName." - #region vSAN Cluster Advanced Summary - if ($InfoLevel.vSAN -le 2) { - BlankLine - $VsanClusterInfo = foreach ($VsanCluster in $VsanClusters) { - [PSCustomObject]@{ - 'Cluster' = $VsanCluster.Name - 'Storage Type' = if ($VsanCluster.VsanEsaEnabled) { - 'ESA' - } else { - 'OSA' - } - '# of Hosts' = $VsanCluster.Cluster.ExtensionData.Host.Count - 'Stretched Cluster' = if ($VsanCluster.StretchedClusterEnabled) { - 'Yes' - } else { - 'No' - } - 'Deduplication & Compression' = if ($VsanCluster.SpaceEfficiencyEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Encryption' = if ($VsanCluster.EncryptionEnabled) { - 'Enabled' - } else { - 'Disabled' - } - } - } - $TableParams = @{ - Name = "vSAN Cluster Summary - $($vCenterServerName)" - ColumnWidths = 25, 15, 15, 15, 15, 15 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanClusterInfo | Table @TableParams - } - #endregion vSAN Cluster Advanced Summary - - #region vSAN Cluster Detailed Information - if ($InfoLevel.vSAN -ge 3) { - foreach ($VsanCluster in $VsanClusters) { - $VsanSpaceUsage = Get-VsanSpaceUsage -Cluster $VsanCluster.Name - $VsanUsedCapacity = $VsanSpaceUsage.CapacityGB - $VsanSpaceUsage.FreeSpaceGB - - # Calculate percentages - $VsanUsedPercent = if (0 -in @($VsanUsedCapacity, $VsanSpaceUsage.CapacityGB)) {0} else {[math]::Round(($VsanUsedCapacity / $VsanSpaceUsage.CapacityGB) * 100, 2)} - $VsanFreePercent = if (0 -in @($VsanUsedCapacity, $VsanSpaceUsage.CapacityGB)) {0} else {[math]::Round(($VsanSpaceUsage.FreeSpaceGB / $VsanSpaceUsage.CapacityGB) * 100, 2)} - - #region vSAN Cluster Section - Section -Style Heading3 $VsanCluster.Name { - if ($VsanCluster.VsanEsaEnabled) { - Write-PScriboMessage "Collecting vSAN ESA information for $($VsanCluster.Name)." - Try { - $VsanStoragePoolDisk = Get-VsanStoragePoolDisk -Cluster $VsanCluster.Cluster - $VsanDiskFormat = $VsanStoragePoolDisk.DiskFormatVersion | Select-Object -First 1 -Unique - $VsanClusterDetail = [PSCustomObject]@{ - 'Cluster' = $VsanCluster.Name - 'ID' = $VsanCluster.Id - 'Storage Type' = if ($VsanCluster.VsanEsaEnabled) { - 'ESA' - } else { - 'OSA' - } - 'Stretched Cluster' = if ($VsanCluster.StretchedClusterEnabled) { - 'Yes' - } else { - 'No' - } - 'Number of Hosts' = $VsanCluster.Cluster.ExtensionData.Host.Count - 'Number of Disks' = $VsanStoragePoolDisk.Count - 'Disk Claim Mode' = $VsanCluster.VsanDiskClaimMode - 'Disk Format Version' = $VsanDiskFormat - 'Performance Service' = if ($VsanCluster.PerformanceServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'File Service' = if ($VsanCluster.FileServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'iSCSI Target Service' = if ($VsanCluster.IscsiTargetServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Deduplication & Compression' = if ($VsanCluster.SpaceEfficiencyEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Encryption' = if ($VsanCluster.EncryptionEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Historical Health Service' = if ($VsanCluster.HistoricalHealthEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Health Check' = if ($VsanCluster.HealthCheckEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Total Capacity' = Convert-DataSize $VsanSpaceUsage.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $VsanUsedCapacity), $VsanUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $VsanSpaceUsage.FreeSpaceGB), $VsanFreePercent - '% Used' = $VsanUsedPercent - 'HCL Last Updated' = ($VsanCluster.TimeOfHclUpdate).ToLocalTime().ToString() - } - if ($Healthcheck.vSAN.CapacityUtilization) { - $VsanClusterDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $VsanClusterDetail | Where-Object { $_.'% Used' -ge 75 -and - $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property 'Used Capacity', 'Free Capacity' - } - if ($InfoLevel.vSAN -ge 4) { - $VsanClusterDetail | Add-Member -MemberType NoteProperty -Name 'Hosts' -Value (($VsanStoragePoolDisk.Host | Select-Object -Unique | Sort-Object Name) -join ', ') - } - - $TableParams = @{ - Name = "vSAN Configuration - $($VsanCluster.Name)" - List = $true - Columns = 'Cluster', 'ID', 'Storage Type', 'Stretched Cluster', 'Number of Hosts', 'Number of Disks', 'Disk Claim Mode', 'Disk Format Version', 'Performance Service', 'File Service', 'iSCSI Target Service', 'Deduplication & Compression', 'Encryption', 'Historical Health Service', 'Health Check', 'Total Capacity', 'Used Capacity', 'Free Capacity', 'HCL Last Updated' - ColumnWidths = 40, 60 - } - If ($InfoLevel.vSAN -ge 4) { - $TableParams['Columns'] += 'Hosts' - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanClusterDetail | Table @TableParams - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN ESA information for $($VsanCluster.Name). $($_.Exception.Message)" - } - - if ($VsanStoragePoolDisk) { - Write-PScriboMessage "Collecting vSAN disk information for $($VsanCluster.Name)." - Try { - Section -Style Heading4 'Disks' { - $vDisks = foreach ($Disk in $VsanStoragePoolDisk) { - [PSCustomObject]@{ - 'Disk' = $Disk.Name - 'Name' = $Disk.ExtensionData.DisplayName - 'Drive Type' = if ($Disk.IsSsd) { - 'Flash' - } else { - 'HDD' - } - 'Host' = $Disk.Host.Name - 'State' = if ($Disk.IsMounted) { - 'Mounted' - } else { - 'Unmounted' - } - 'Encrypted' = if ($Disk.IsEncryped) { - 'Yes' - } else { - 'No' - } - 'Capacity' = Convert-DataSize $Disk.CapacityGB - 'Serial Number' = $Disk.ExtensionData.SerialNumber - 'Vendor' = $Disk.ExtensionData.Vendor - 'Model' = $Disk.ExtensionData.Model - 'Disk Type' = $Disk.DiskType - 'Disk Format Version' = $Disk.DiskFormatVersion - } - } - - if ($InfoLevel.vSAN -ge 4) { - $vDisks | Sort-Object Host | ForEach-Object { - $vDisk = $_ - Section -Style NOTOCHeading5 -ExcludeFromTOC "$($vDisk.Name) - $($vDisk.Host)" { - $TableParams = @{ - Name = "Disk $($vDisk.Name) - $($vDisk.Host)" - List = $true - Columns = 'Name', 'State', 'Drive Type', 'Encrypted', 'Capacity', 'Host', 'Serial Number', 'Vendor', 'Model', 'Disk Format Version', 'Disk Type' - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vDisk | Table @TableParams - } - } - } else { - $TableParams = @{ - Name = "vSAN Disks - $($VsanCluster.Name)" - Columns = 'Disk', 'Capacity', 'State', 'Host' - ColumnWidths = 40, 15, 15, 30 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vDisks | Sort-Object Host | Table @TableParams - } - } - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN disk information for $($VsanCluster.Name). $($_.Exception.Message)" - } - } - } else { - Try { - Write-PScriboMessage "Collecting vSAN OSA information for $($VsanCluster.Name)." - # Get vSAN Disk Groups - $VsanDiskGroup = Get-VsanDiskGroup -Cluster $VsanCluster.Cluster - $NumVsanDiskGroup = $VsanDiskGroup.Count - # Get vSAN Disks - $VsanDisk = Get-VsanDisk -VsanDiskGroup $VsanDiskGroup - $VsanDiskFormat = $VsanDisk.DiskFormatVersion | Select-Object -Unique - # Count SSDs and HDDs - $NumVsanSsd = ($VsanDisk | Where-Object { $_.IsSsd -eq $true } | Measure-Object).Count - $NumVsanHdd = ($VsanDisk | Where-Object { $_.IsSsd -eq $false } | Measure-Object).Count - # Determine Storage Type - $VsanClusterType = if ($NumVsanHdd -gt 0) { "Hybrid" } else { "All Flash" } - $VsanClusterDetail = [PSCustomObject]@{ - 'Cluster' = $VsanCluster.Name - 'ID' = $VsanCluster.Id - 'Storage Type' = if ($VsanCluster.VsanEsaEnabled) { - 'ESA' - } else { - 'OSA' - } - 'Cluster Type' = $VsanClusterType - 'Stretched Cluster' = if ($VsanCluster.StretchedClusterEnabled) { - 'Yes' - } else { - 'No' - } - 'Number of Hosts' = $VsanCluster.Cluster.ExtensionData.Host.Count - 'Number of Disks' = $NumVsanSsd + $NumVsanHdd - 'Number of Disk Groups' = $NumVsanDiskGroup - 'Disk Claim Mode' = $VsanCluster.VsanDiskClaimMode - 'Disk Format Version' = $VsanDiskFormat - 'Performance Service' = if ($VsanCluster.PerformanceServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'File Service' = if ($VsanCluster.FileServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'iSCSI Target Service' = if ($VsanCluster.IscsiTargetServiceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Deduplication & Compression' = if ($VsanCluster.SpaceEfficiencyEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Encryption' = if ($VsanCluster.EncryptionEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Historical Health Service' = if ($VsanCluster.HistoricalHealthEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Health Check' = if ($VsanCluster.HealthCheckEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Total Capacity' = Convert-DataSize $VsanSpaceUsage.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $VsanUsedCapacity), $VsanUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $VsanSpaceUsage.FreeSpaceGB), $VsanFreePercent - '% Used' = $VsanUsedPercent - 'HCL Last Updated' = ($VsanCluster.TimeOfHclUpdate).ToLocalTime().ToString() - } - if ($Healthcheck.vSAN.CapacityUtilization) { - $VsanClusterDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $VsanClusterDetail | Where-Object { $_.'% Used' -ge 75 -and - $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property 'Used Capacity', 'Free Capacity' - } - if ($InfoLevel.vSAN -ge 4) { - $VsanClusterDetail | Add-Member -MemberType NoteProperty -Name 'Hosts' -Value (($VsanDiskGroup.VMHost | Select-Object -Unique | Sort-Object Name) -join ', ') - } - $TableParams = @{ - Name = "vSAN Configuration - $($VsanCluster.Name)" - List = $true - Columns = 'Cluster', 'ID', 'Storage Type', 'Cluster Type', 'Stretched Cluster', 'Number of Hosts', 'Number of Disks', 'Number of Disk Groups', 'Disk Claim Mode', 'Disk Format Version', 'Performance Service', 'File Service', 'iSCSI Target Service', 'Deduplication & Compression', 'Encryption', 'Historical Health Service', 'Health Check', 'Total Capacity', 'Used Capacity', 'Free Capacity', 'HCL Last Updated' - ColumnWidths = 40, 60 - } - If ($InfoLevel.vSAN -ge 4) { - $TableParams['Columns'] += 'Hosts' - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanClusterDetail | Table @TableParams - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN OSA information for $($VsanCluster.Name). $($_.Exception.Message)" - } - - # TODO: vSAN Services - if ($VsanDiskGroup) { - Write-PScriboMessage "Collecting vSAN disk group information for $($VsanCluster.Name)." - Try { - Section -Style Heading4 'Disk Groups' { - $VsanDiskGroups = foreach ($DiskGroup in $VsanDiskGroup) { - $Disks = $DiskGroup | Get-VsanDisk - [PSCustomObject]@{ - 'Disk Group' = $DiskGroup.Uuid - 'Host' = $Diskgroup.VMHost - '# of Disks' = $Disks.Count - 'State' = if ($DiskGroup.IsMounted) { - 'Mounted' - } else { - 'Unmounted' - } - 'Type' = Switch ($DiskGroup.DiskGroupType) { - 'AllFlash' { 'All Flash' } - default { $DiskGroup.DiskGroupType } - } - 'Disk Format Version' = $DiskGroup.DiskFormatVersion - } - } - $TableParams = @{ - Name = "vSAN Disk Groups - $($VsanCluster.Name)" - ColumnWidths = 30, 30, 7, 11, 11, 11 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanDiskGroups | Sort-Object Host | Table @TableParams - } - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN disk group information for $($VsanCluster.Name). $($_.Exception.Message)" - } - } - - if ($VsanDisk) { - Write-PScriboMessage "Collecting vSAN disk information for $($VsanCluster.Name)." - Try { - Section -Style Heading4 'Disks' { - $vDisks = foreach ($Disk in $VsanDisk) { - [PSCustomObject]@{ - 'Disk' = $Disk.Name - 'Name' = $Disk.ExtensionData.DisplayName - 'State' = if ($Disk.IsMounted) { - 'Mounted' - } else { - 'Unmounted' - } - 'Drive Type' = if ($Disk.IsSsd) { - 'Flash' - } else { - 'HDD' - } - 'Host' = $Disk.VsanDiskGroup.VMHost.Name - 'Claimed As' = if ($Disk.IsCacheDisk) { - 'Cache' - } else { - 'Capacity' - } - 'Capacity' = Convert-DataSize $Disk.CapacityGB - 'Serial Number' = $Disk.ExtensionData.SerialNumber - 'Vendor' = $Disk.ExtensionData.Vendor - 'Model' = $Disk.ExtensionData.Model - 'Disk Group' = $Disk.VsanDiskGroup.Uuid - 'Disk Format Version' = $Disk.DiskFormatVersion - } - } - - if ($InfoLevel.vSAN -ge 4) { - $vDisks | Sort-Object Host | ForEach-Object { - $vDisk = $_ - Section -Style NOTOCHeading5 -ExcludeFromTOC "$($vDisk.Name) - $($vDisk.Host)" { - $TableParams = @{ - Name = "Disk $($vDisk.Name) - $($vDisk.Host)" - List = $true - Columns = 'Name', 'Drive Type', 'Claimed As', 'Capacity', 'Host', 'Disk Group', 'Serial Number', 'Vendor', 'Model', 'Disk Format Version' - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vDisk | Table @TableParams - } - } - } else { - $TableParams = @{ - Name = "vSAN Disks - $($VsanCluster.Name)" - Columns = 'Name', 'Drive Type', 'Claimed As', 'Capacity', 'Host', 'Disk Group' - ColumnWidths = 21, 10, 10, 10, 21, 28 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $vDisks | Sort-Object Host | Table @TableParams - } - } - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN disk information for $($VsanCluster.Name). $($_.Exception.Message)" - } - } - } - - $VsanIscsiTargets = Get-VsanIscsiTarget -Cluster $VsanCluster.Cluster -ErrorAction SilentlyContinue - if ($VsanIscsiTargets) { - Write-PScriboMessage "Collecting vSAN iSCSI target information for $($VsanCluster.Name)." - Try { - Section -Style Heading4 'iSCSI Targets' { - $VsanIscsiTargetInfo = foreach ($VsanIscsiTarget in $VsanIscsiTargets) { - [PSCustomObject]@{ - 'IQN' = $VsanIscsiTarget.IscsiQualifiedName - 'Alias' = $VsanIscsiTarget.Name - 'LUNs' = $VsanIscsiTarget.NumLuns - 'Network Interface' = $VsanIscsiTarget.NetworkInterface - 'I/O Owner Host' = $VsanIscsiTarget.IoOwnerVMHost - 'TCP Port' = $VsanIscsiTarget.TcpPort - 'Health' = $TextInfo.ToTitleCase($VsanIscsiTarget.VsanHealth) - 'Storage Policy' = if ($VsanIscsiTarget.StoragePolicy.Name) { - $VsanIscsiTarget.StoragePolicy.Name - } else { - '--' - } - 'Compliance Status' = $TextInfo.ToTitleCase($VsanIscsiTarget.SpbmComplianceStatus) - 'Authentication' = $VsanIscsiTarget.AuthenticationType - } - } - $TableParams = @{ - Name = "vSAN iSCSI Targets - $($VsanCluster.Name)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanIscsiTargetInfo | Table @TableParams - } - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN iSCSI target information for $($VsanCluster.Name). $($_.Exception.Message)" - } - } - - $VsanIscsiLuns = Get-VsanIscsiLun -Cluster $VsanCluster.Cluster -ErrorAction SilentlyContinue | Sort-Object Name, LunId - if ($VsanIscsiLuns) { - Write-PScriboMessage "Collecting vSAN iSCSI LUN information for $($VsanCluster.Name)." - Try { - Section -Style Heading4 'iSCSI LUNs' { - $VsanIscsiLunInfo = foreach ($VsanIscsiLun in $VsanIscsiLuns) { - [PSCustomobject]@{ - 'LUN' = $VsanIscsiLun.Name - 'LUN ID' = $VsanIscsiLun.LunId - 'Capacity' = Convert-DataSize $VsanIscsiLun.CapacityGB - 'Used Capacity' = Convert-DataSize $VsanIscsiLun.UsedCapacityGB - 'State' = if ($VsanIscsiLun.IsOnline) { - 'Online' - } else { - 'Offline' - } - 'Health' = $TextInfo.ToTitleCase($VsanIscsiLun.VsanHealth) - 'Storage Policy' = if ($VsanIscsiLun.StoragePolicy.Name) { - $VsanIscsiLun.StoragePolicy.Name - } else { - '--' - } - 'Compliance Status' = $TextInfo.ToTitleCase($VsanIscsiLun.SpbmComplianceStatus) - } - } - if ($InfoLevel.vSAN -ge 4) { - $TableParams = @{ - Name = "vSAN iSCSI LUNs - $($VsanCluster.Name)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanIscsiLunInfo | Table @TableParams - } else { - $TableParams = @{ - Name = "vSAN iSCSI LUNs - $($VsanCluster.Name)" - ColumnWidths = 28 , 18, 18, 18, 18 - Columns = 'LUN', 'LUN ID', 'Capacity', 'Used Capacity', 'State' - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VsanIscsiLunInfo | Table @TableParams - } - } - } Catch { - Write-PScriboMessage -IsWarning "Error collecting vSAN iSCSI LUN information for $($VsanCluster.Name). $($_.Exception.Message)" - } - } - } - #endregion vSAN Cluster Section - } - } - #endregion vSAN Cluster Detailed Information - } - } - } - #endregion vSAN Section - - #region Datastore Section - Write-PScriboMessage "Datastore InfoLevel set at $($InfoLevel.Datastore)." - if ($InfoLevel.Datastore -ge 1) { - if ($Datastores) { - Section -Style Heading2 'Datastores' { - Paragraph "The following sections detail the configuration of datastores managed by vCenter Server $vCenterServerName." - #region Datastore Infomative Information - if ($InfoLevel.Datastore -le 2) { - BlankLine - $DatastoreInfo = foreach ($Datastore in $Datastores) { - - $DsUsedPercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) {0} else {[math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2)} - $DsFreePercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) {0} else {[math]::Round(($Datastore.FreeSpaceGB / $Datastore.CapacityGB) * 100, 2)} - $DsUsedCapacityGB = ($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB) - - [PSCustomObject]@{ - 'Datastore' = $Datastore.Name - 'Type' = $Datastore.Type - 'Version' = if ($Datastore.FileSystemVersion) { - $Datastore.FileSystemVersion - } else { - '--' - } - '# of Hosts' = $Datastore.ExtensionData.Host.Count - '# of VMs' = $Datastore.ExtensionData.VM.Count - 'Total Capacity' = Convert-DataSize $Datastore.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $DsUsedCapacityGB), $DsUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $DsFreePercent - '% Used' = $DsUsedPercent - } - } - if ($Healthcheck.Datastore.CapacityUtilization) { - $DatastoreInfo | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $DatastoreInfo | Where-Object { $_.'% Used' -ge 75 -and - $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property 'Used Capacity', 'Free Capacity' - } - $TableParams = @{ - Name = "Datastore Summary - $($vCenterServerName)" - Columns = 'Datastore', 'Type', 'Version', '# of Hosts', '# of VMs', 'Total Capacity', 'Used Capacity', 'Free Capacity' - ColumnWidths = 21, 10, 9, 9, 9, 14, 14, 14 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DatastoreInfo | Sort-Object Datastore | Table @TableParams - } - #endregion Datastore Advanced Summary - - #region Datastore Detailed Information - if ($InfoLevel.Datastore -ge 3) { - foreach ($Datastore in $Datastores) { - # TODO: Test Tags - - $DsUsedPercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) {0} else {[math]::Round((100 - (($Datastore.FreeSpaceGB) / ($Datastore.CapacityGB) * 100)), 2)} - $DSFreePercent = if (0 -in @($Datastore.FreeSpaceGB, $Datastore.CapacityGB)) {0} else {[math]::Round(($Datastore.FreeSpaceGB / $Datastore.CapacityGB) * 100, 2)} - $UsedCapacityGB = ($Datastore.CapacityGB) - ($Datastore.FreeSpaceGB) - - #region Datastore Section - Section -Style Heading3 $Datastore.Name { - $DatastoreDetail = [PSCustomObject]@{ - 'Datastore' = $Datastore.Name - 'ID' = $Datastore.Id - 'Datacenter' = $Datastore.Datacenter - 'Type' = $Datastore.Type - 'Version' = if ($Datastore.FileSystemVersion) { - $Datastore.FileSystemVersion - } else { - '--' - } - 'State' = $Datastore.State - 'Number of Hosts' = $Datastore.ExtensionData.Host.Count - 'Number of VMs' = $Datastore.ExtensionData.VM.Count - 'Storage I/O Control' = if ($Datastore.StorageIOControlEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Congestion Threshold' = if ($Datastore.CongestionThresholdMillisecond) { - "$($Datastore.CongestionThresholdMillisecond) ms" - } else { - '--' - } - 'Total Capacity' = Convert-DataSize $Datastore.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $UsedCapacityGB), $DsUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $Datastore.FreeSpaceGB), $DSFreePercent - '% Used' = $DsUsedPercent - } - if ($Healthcheck.Datastore.CapacityUtilization) { - $DatastoreDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $DatastoreDetail | Where-Object { $_.'% Used' -ge 75 -and - $_.'% Used' -lt 90 } | Set-Style -Style Warning -Property 'Used Capacity', 'Free Capacity' - } - $MemberProps = @{ - 'InputObject' = $DatastoreDetail - 'MemberType' = 'NoteProperty' - } - <# - if ($TagAssignments | Where-Object {$_.entity -eq $Datastore}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $Datastore}).Tag -join ',') - } - #> - - #region Datastore Advanced Detailed Information - if ($InfoLevel.Datastore -ge 4) { - $DatastoreHosts = foreach ($DatastoreHost in $Datastore.ExtensionData.Host.Key) { - $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" - } - Add-Member @MemberProps -Name 'Hosts' -Value (($DatastoreHosts | Sort-Object) -join ', ') - $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 - $TableParams = @{ - Name = "Datastore Configuration - $($Datastore.Name)" - List = $true - Columns = 'Datastore', 'ID', 'Datacenter', 'Type', 'Version', 'State', 'Number of Hosts', 'Number of VMs', 'Storage I/O Control', 'Congestion Threshold', 'Total Capacity', 'Used Capacity', 'Free Capacity' - ColumnWidths = 40, 60 - } - if ($InfoLevel.Datastore -ge 4) { - $TableParams['Columns'] += 'Hosts', 'Virtual Machines' - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DatastoreDetail | Sort-Object Datacenter, Name | 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 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 - - [PSCustomObject]@{ - 'Host' = $VMHostLookup."$($DatastoreHost.Type)-$($DatastoreHost.Value)" - 'Canonical Name' = $DiskName - 'Capacity' = Convert-DataSize $ScsiDeviceDetail.CapacityGB - 'Vendor' = $ScsiDeviceDetail.Vendor - 'Model' = $ScsiDeviceDetail.Model - 'Is SSD' = $ScsiDeviceDetail.Ssd - 'Multipath Policy' = $ScsiDeviceDetail.MultipathPolicy - 'Paths' = $ScsiDeviceDetail.Paths - } - } - $TableParams = @{ - Name = "SCSI LUN Information - $($vCenterServerName)" - ColumnWidths = 19, 19, 10, 10, 10, 10, 14, 8 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $ScsiLuns | Sort-Object Host | Table @TableParams - } - #endregion SCSI LUN Information Section - } - } - #endregion Datastore Section - } - } - #endregion Datastore Detailed Information - } - } - } - #endregion Datastore Section - - #region Datastore Clusters - Write-PScriboMessage "DSCluster InfoLevel set at $($InfoLevel.DSCluster)." - if ($InfoLevel.DSCluster -ge 1) { - $DSClusters = Get-DatastoreCluster -Server $vCenter - if ($DSClusters) { - #region Datastore Clusters Section - Section -Style Heading2 'Datastore Clusters' { - Paragraph "The following sections detail the configuration of datastore clusters managed by vCenter Server $vCenterServerName." - #region Datastore Cluster Advanced Summary - if ($InfoLevel.DSCluster -le 2) { - BlankLine - $DSClusterInfo = foreach ($DSCluster in $DSClusters) { - [PSCustomObject]@{ - 'Datastore Cluster' = $DSCluster.Name - 'SDRS Automation Level' = Switch ($DSCluster.SdrsAutomationLevel) { - 'FullyAutomated' { 'Fully Automated' } - 'Manual' { 'Manual' } - default { $DSCluster.SdrsAutomationLevel } - } - 'Space Utilization Threshold' = "$($DSCluster.SpaceUtilizationThresholdPercent)%" - 'I/O Load Balance' = if ($DSCluster.IOLoadBalanceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'I/O Latency Threshold' = "$($DSCluster.IOLatencyThresholdMillisecond) ms" - } - } - if ($Healthcheck.DSCluster.SDRSAutomationLevelFullyAuto) { - $DSClusterInfo | Where-Object { $_.'SDRS Automation Level' -ne 'Fully Automated' } | Set-Style -Style Warning -Property 'SDRS Automation Level' - } - $TableParams = @{ - Name = "Datastore Cluster Configuration - $($DSCluster.Name)" - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DSClusterInfo | Sort-Object Name | Table @TableParams - } - #endregion Datastore Cluster Advanced Summary - - #region Datastore Cluster Detailed Information - if ($InfoLevel.DSCluster -ge 3) { - foreach ($DSCluster in $DSClusters) { - # TODO: Space Load Balance Config, IO Load Balance Config, Rules - # TODO: Test Tags - - $DSCUsedPercent = if (0 -in @($DSCluster.FreeSpaceGB, $DSCluster.CapacityGB)) {0} else {[math]::Round((100 - (($DSCluster.FreeSpaceGB) / ($DSCluster.CapacityGB) * 100)), 2)} - $DSCFreePercent = if (0 -in @($DSCluster.FreeSpaceGB, $DSCluster.CapacityGB)) {0} else { [math]::Round(($DSCluster.FreeSpaceGB / $DSCluster.CapacityGB) * 100, 2) } - $DSCUsedCapacityGB = ($DSCluster.CapacityGB - $DSCluster.FreeSpaceGB) - - Section -Style Heading3 $DSCluster.Name { - Paragraph ("The following table details the configuration " + - "for datastore cluster $DSCluster.") - BlankLine - - $DSClusterDetail = [PSCustomObject]@{ - 'Datastore Cluster' = $DSCluster.Name - 'ID' = $DSCluster.Id - 'SDRS Automation Level' = Switch ($DSCluster.SdrsAutomationLevel) { - 'FullyAutomated' { 'Fully Automated' } - 'Manual' { 'Manual' } - default { $DSCluster.SdrsAutomationLevel } - } - 'Space Utilization Threshold' = "$($DSCluster.SpaceUtilizationThresholdPercent)%" - 'I/O Load Balance' = if ($DSCluster.IOLoadBalanceEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'I/O Latency Threshold' = "$($DSCluster.IOLatencyThresholdMillisecond) ms" - 'Total Capacity' = Convert-DataSize $DSCluster.CapacityGB - 'Used Capacity' = "{0} ({1}%)" -f (Convert-DataSize $DSCUsedCapacityGB), $DSCUsedPercent - 'Free Capacity' = "{0} ({1}%)" -f (Convert-DataSize $DSCluster.FreeSpaceGB), $DSCFreePercent - '% Used' = $DSCUsedPercent - } - <# - $MemberProps = @{ - 'InputObject' = $DSClusterDetail - 'MemberType' = 'NoteProperty' - } - - if ($TagAssignments | Where-Object {$_.entity -eq $DSCluster}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $DSCluster}).Tag -join ',') - } - #> - if ($Healthcheck.DSCluster.CapacityUtilization) { - $DSClusterDetail | Where-Object { $_.'% Used' -ge 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - $DSClusterDetail | Where-Object { $_.'% Used' -ge 75 -and $_.'% Used' -lt 90 } | Set-Style -Style Critical -Property 'Used Capacity', 'Free Capacity' - } - if ($Healthcheck.DSCluster.SDRSAutomationLevel) { - $DSClusterDetail | Where-Object { $_.'SDRS Automation Level' -ne 'Fully Automated' } | Set-Style -Style Warning -Property 'SDRS Automation Level' - } - $TableParams = @{ - Name = "Datastore Cluster Configuration - $($DSCluster.Name)" - List = $true - Columns = 'Datastore Cluster', 'ID', 'SDRS Automation Level', 'Space Utilization Threshold', 'I/O Load Balance', 'I/O Latency Threshold', 'Total Capacity', 'Used Capacity', 'Free Capacity' - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $DSClusterDetail | Table @TableParams - - #region SDRS VM Overrides - $StoragePodProps = @{ - 'ViewType' = 'StoragePod' - 'Filter' = @{'Name' = $DSCluster.Name } - } - $StoragePod = Get-View @StoragePodProps - if ($StoragePod) { - $PodConfig = $StoragePod.PodStorageDrsEntry.StorageDrsConfig.PodConfig - # Set default automation value variables - Switch ($PodConfig.DefaultVmBehavior) { - "automated" { $DefaultVmBehavior = "Default (Fully Automated)" } - "manual" { $DefaultVmBehavior = "Default (No Automation (Manual Mode))" } - } - if ($PodConfig.DefaultIntraVmAffinity) { - $DefaultIntraVmAffinity = "Default (Yes)" - } else { - $DefaultIntraVmAffinity = "Default (No)" - } - $VMOverrides = $StoragePod.PodStorageDrsEntry.StorageDrsConfig.VmConfig | Where-Object { - -not ( - ($null -eq $_.Enabled) -and - ($null -eq $_.IntraVmAffinity) - ) - } - } - - if ($VMOverrides) { - $VMOverrideDetails = foreach ($Override in $VMOverrides) { - [PSCustomObject]@{ - 'Virtual Machine' = $VMLookup."$($Override.Vm.Type)-$($Override.Vm.Value)" - 'SDRS Automation Level' = Switch ($Override.Enabled) { - $true { 'Fully Automated' } - $false { 'Disabled' } - $null { $DefaultVmBehavior } - } - 'Keep VMDKs Together' = Switch ($Override.IntraVmAffinity) { - $true { 'Yes' } - $false { 'No' } - $null { $DefaultIntraVmAffinity } - } - } - } - Section -Style Heading4 'SDRS VM Overrides' { - $TableParams = @{ - Name = "SDRS VM Overrides - $($DSCluster.Name)" - ColumnWidths = 50, 30, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMOverrideDetails | Sort-Object 'Virtual Machine' | Table @TableParams - } - } - #endregion SDRS VM Overrides - } - } - } - #endregion Datastore Cluster Detailed Information - } - #endregion Datastore Clusters Section - } - } - #endregion Datastore Clusters - - #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 sections detail the configuration of virtual machines managed by vCenter Server $vCenterServerName." - #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' = Convert-DataSize ($VMs | Measure-Object -Property MemoryGB -Sum).Sum - 'Total Provisioned Space' = Convert-DataSize ($VMs | Measure-Object -Property ProvisionedSpaceGB -Sum).Sum - 'Total Used Space' = Convert-DataSize ($VMs | Measure-Object -Property UsedSpaceGB -Sum).Sum - 'VMs Powered On' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOn' }).Count - 'VMs Powered Off' = ($VMs | Where-Object { $_.PowerState -eq 'PoweredOff' }).Count - 'VMs Orphaned' = ($VMs | Where-Object { $_.ExtensionData.Runtime.ConnectionState -eq 'Orphaned' }).Count - 'VMs Inaccessible' = ($VMs | Where-Object { $_.ExtensionData.Runtime.ConnectionState -eq 'Inaccessible' }).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 - $($vCenterServerName)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMSummary | Table @TableParams - } - #endregion Virtual Machine Summary Information - - #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]@{ - 'Virtual Machine' = $VM.Name - 'Power State' = Switch ($VM.PowerState) { - 'PoweredOn' { 'On' } - 'PoweredOff' { 'Off' } - default { $VM.PowerState } - } - 'IP Address' = if ($VMView.Guest.IpAddress) { - $VMView.Guest.IpAddress - } else { - '--' - } - 'vCPUs' = $VM.NumCpu - 'Memory' = Convert-DataSize $VM.MemoryGB -RoundUnits 0 - 'Provisioned' = Convert-DataSize $VM.ProvisionedSpaceGB - 'Used' = Convert-DataSize $VM.UsedSpaceGB - '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.VM.VMToolsStatus) { - $VMInfo | 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' - } - $TableParams = @{ - Name = "VM Advanced Summary - $($vCenterServerName)" - ColumnWidths = 21, 8, 16, 9, 9, 9, 9, 9, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMInfo | Table @TableParams - - #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 - } - $TableParams = @{ - Name = "VM Snapshot Summary - $($vCenterServerName)" - ColumnWidths = 30, 30, 30, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMSnapshotInfo | Table @TableParams - } - } - #endregion VM Snapshot Information - } - #endregion Virtual Machine Advanced Summary - - #region Virtual Machine Detailed Information - # TODO: Test Tags - if ($InfoLevel.VM -ge 3) { - if ($UserPrivileges -contains 'StorageProfile.View') { - $VMSpbmConfig = Get-SpbmEntityConfiguration -VM ($VMs) | Where-Object { $null -ne $_.StoragePolicy } - } else { - Write-PScriboMessage "Insufficient user privileges to report VM storage policies. Please ensure the user account has the 'Storage Profile > View' privilege assigned." - } - if ($InfoLevel.VM -ge 4) { - $VMHardDisks = Get-HardDisk -VM ($VMs) -Server $vCenter - } - foreach ($VM in $VMs) { - Section -Style Heading3 $VM.name { - $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 { $TextInfo.ToTitleCase($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 { $TextInfo.ToTitleCase($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 { $TextInfo.ToTitleCase($VMview.Runtime.FaultToleranceState) } - } - 'Host' = $VM.VMHost.Name - 'Parent' = $VM.VMHost.Parent.Name - 'Parent Folder' = $VM.Folder.Name - 'Parent Resource Pool' = $VM.ResourcePool.Name - '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' = if ($VMView.Config.CpuHotAddEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'CPU Hot Remove' = if ($VMView.Config.CpuHotRemoveEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Memory Allocation' = Convert-DataSize $VM.memoryGB -RoundUnits 0 - 'Memory Shares' = "$($VM.VMResourceConfiguration.MemSharesLevel) / $($VM.VMResourceConfiguration.NumMemShares)" - 'Memory Hot Add' = if ($VMView.Config.MemoryHotAddEnabled) { - 'Enabled' - } else { - '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 { $null -ne $_.Network } | Select-Object Network | Sort-Object Network).Network -join ', ') - } else { - '--' - } - 'IP Address' = if ($VMView.Guest.Net.IpAddress) { - (($VMView.Guest.Net | Where-Object { ($null -ne $_.Network) -and ($null -ne $_.IpAddress) } | Select-Object IpAddress | Sort-Object IpAddress).IpAddress -join ', ') - } else { - '--' - } - 'MAC Address' = if ($VMView.Guest.Net.MacAddress) { - (($VMView.Guest.Net | Where-Object { $null -ne $_.Network } | Select-Object -Property MacAddress).MacAddress -join ', ') - } else { - '--' - } - 'vDisks' = $VMView.Summary.Config.NumVirtualDisks - 'Provisioned Space' = Convert-DataSize $VM.ProvisionedSpaceGB - 'Used Space' = Convert-DataSize $VM.UsedSpaceGB - 'Changed Block Tracking' = if ($VMView.Config.ChangeTrackingEnabled) { - 'Enabled' - } else { - 'Disabled' - } - 'Storage Based Policy' = if ($VMSpbmPolicy.StoragePolicy.Name) { - $TextInfo.ToTitleCase($VMSpbmPolicy.StoragePolicy.Name) - } else { - '--' - } - 'Storage Based Policy Compliance' = Switch ($VMSpbmPolicy.ComplianceStatus) { - $null { '--' } - 'compliant' { 'Compliant' } - 'nonCompliant' { 'Non Compliant' } - 'unknown' { 'Unknown' } - default { $TextInfo.ToTitleCase($VMSpbmPolicy.ComplianceStatus) } - } - } - $MemberProps = @{ - 'InputObject' = $VMDetail - 'MemberType' = 'NoteProperty' - } - #if ($VMView.Config.CreateDate) { - # Add-Member @MemberProps -Name 'Creation Date' -Value ($VMView.Config.CreateDate).ToLocalTime().ToString() - #} - <# - if ($TagAssignments | Where-Object {$_.entity -eq $VM}) { - Add-Member @MemberProps -Name 'Tags' -Value $(($TagAssignments | Where-Object {$_.entity -eq $VM}).Tag -join ',') - } - #> - 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().ToString() - } - 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' - } - if ($Healthcheck.VM.SpbmPolicyCompliance) { - $VMDetail | Where-Object { $_.'Storage Based Policy Compliance' -eq 'Unknown' } | Set-Style -Style Warning -Property 'Storage Based Policy Compliance' - $VMDetail | Where-Object { $_.'Storage Based Policy Compliance' -eq 'Non Compliant' } | Set-Style -Style Critical -Property 'Storage Based Policy Compliance' - } - #endregion VM Health Checks - $TableParams = @{ - Name = "VM Configuration - $($VM.Name)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMDetail | Table @TableParams - - if ($InfoLevel.VM -ge 4) { - $VMnics = $VM.Guest.Nics | Where-Object { $null -ne $_.Device } | 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 - } - } - $TableParams = @{ - Name = "Network Adapters - $($VM.Name)" - ColumnWidths = 20, 12, 16, 12, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $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 } - } - } - } - $TableParams = @{ - Name = "SCSI Controllers - $($VM.Name)" - ColumnWidths = 33, 34, 33 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMScsiControllers | Sort-Object 'Device' | Table @TableParams - } - } - 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' = Convert-DataSize $VMHdd.CapacityGB - '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 = "Hard Disk Configuration - $($VM.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 NOTOCHeading5 -ExcludeFromTOC "$($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' = Convert-DataSize $VMHdd.CapacityGB - '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)" - } - $TableParams = @{ - Name = "Hard Disk $($VMHdd.Name) - $($VM.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' = Convert-DataSize $VMGuestVol.CapacityGB - 'Used Space' = Convert-DataSize (($VMGuestVol.CapacityGB) - ($VMGuestVol.FreeSpaceGB)) - 'Free Space' = Convert-DataSize $VMGuestVol.FreeSpaceGB - } - } - $TableParams = @{ - Name = "Guest Volumes - $($VM.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 - } - $TableParams = @{ - Name = "VM Snapshots - $($VM.Name)" - ColumnWidths = 45, 45, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VMSnapshots | Table @TableParams - } - } - } - } - } - #endregion Virtual Machine Detailed Information - } - } - } - #endregion Virtual Machine Section - - #region VMware Update Manager Section - Write-PScriboMessage "VUM InfoLevel set at $($InfoLevel.VUM)." - if (($InfoLevel.VUM -ge 1) -and ($VumServer.Name)) { - Try { - $VUMBaselines = Get-PatchBaseline -Server $vCenter - } Catch { - Write-PScriboMessage 'VUM patch baseline information is not currently available with your version of PowerShell.' - } - if ($VUMBaselines) { - Section -Style Heading2 'VMware Update Manager' { - Paragraph "The following sections detail the configuration of VMware Update Manager managed by vCenter Server $vCenterServerName." - #region VUM Baseline Detailed Information - Section -Style Heading3 'Baselines' { - $VUMBaselineInfo = foreach ($VUMBaseline in $VUMBaselines) { - [PSCustomObject]@{ - 'Baseline' = $VUMBaseline.Name - 'Description' = $VUMBaseline.Description - 'Type' = $VUMBaseline.BaselineType - 'Target Type' = $VUMBaseline.TargetType - 'Last Update Time' = ($VUMBaseline.LastUpdateTime).ToLocalTime().ToString() - '# of Patches' = $VUMBaseline.CurrentPatches.Count - } - } - $TableParams = @{ - Name = "VMware Update Manager Baseline Summary - $($vCenterServerName)" - ColumnWidths = 25, 25, 10, 10, 20, 10 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VUMBaselineInfo | Sort-Object Baseline | Table @TableParams - } - #endregion VUM Baseline Detailed Information - - #region VUM Comprehensive Information - Try { - $VUMPatches = Get-Patch -Server $vCenter | Sort-Object -Descending ReleaseDate - } Catch { - Write-PScriboMessage 'VUM patch information is not currently available with your version of PowerShell.' - } - if ($VUMPatches -and $InfoLevel.VUM -ge 5) { - BlankLine - Section -Style Heading3 'Patches' { - $VUMPatchInfo = foreach ($VUMPatch in $VUMPatches) { - [PSCustomObject]@{ - 'Patch' = $VUMPatch.Name - 'Product' = ($VUMPatch.Product).Name - 'Description' = $VUMPatch.Description - 'Release Date' = $VUMPatch.ReleaseDate - 'Vendor ID' = $VUMPatch.IdByVendor - } - } - $TableParams = @{ - Name = "VMware Update Manager Patch Information - $($vCenterServerName)" - ColumnWidths = 20, 20, 20, 20, 20 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $VUMPatchInfo | Table @TableParams - } - } - #endregion VUM Comprehensive Information - } - } - } - #endregion VMware Update Manager Section - } - #endregion vCenter Server Heading1 Section - - # Disconnect vCenter Server - $Null = Disconnect-VIServer -Server $VIServer -Confirm:$false -ErrorAction SilentlyContinue - } # End of If $vCenter - #endregion Generate vSphere report - - #region Variable cleanup - Clear-Variable -Name vCenter - #endregion Variable cleanup - - } # End of Foreach $VIServer - #endregion Script Body -} # End Invoke-AsBuiltReport.VMware.vSphere function \ No newline at end of file diff --git a/Tests/AsBuiltReport.VMware.vSphere.Tests.ps1 b/Tests/AsBuiltReport.VMware.vSphere.Tests.ps1 new file mode 100644 index 0000000..f3bb9dd --- /dev/null +++ b/Tests/AsBuiltReport.VMware.vSphere.Tests.ps1 @@ -0,0 +1,186 @@ +BeforeAll { + # Import the module + $ModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1' + $ModuleRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere' + try { + Import-Module $ModulePath -Force -ErrorAction Stop + } catch { + # Fallback: import .psm1 directly when required module dependencies are not available + $PsmPath = Join-Path -Path $ModuleRoot -ChildPath 'AsBuiltReport.VMware.vSphere.psm1' + Import-Module $PsmPath -Force + } +} + +Describe 'AsBuiltReport.VMware.vSphere Module Tests' { + Context 'Module Manifest' { + BeforeAll { + $ManifestPath = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psd1' + # Use Import-PowerShellDataFile so tests pass even when required modules are not installed + $ManifestData = Import-PowerShellDataFile -Path $ManifestPath -ErrorAction Stop + } + + It 'Should have a valid module manifest' { + $ManifestData | Should -Not -BeNullOrEmpty + } + + It 'Should have the correct module name' { + [System.IO.Path]::GetFileNameWithoutExtension($ManifestPath) | Should -Be 'AsBuiltReport.VMware.vSphere' + } + + It 'Should have a valid GUID' { + $ManifestData.GUID | Should -Be 'e1cbf1ce-cf01-4b6e-9cc2-56323da3c351' + } + + It 'Should have a valid version' { + $ManifestData.ModuleVersion | Should -Not -BeNullOrEmpty + [version]::TryParse($ManifestData.ModuleVersion, [ref]$null) | Should -Be $true + } + + It 'Should have version 2.0.0 or higher' { + [version]$ManifestData.ModuleVersion | Should -BeGreaterOrEqual ([version]'2.0.0') + } + + It 'Should have a valid author' { + $ManifestData.Author | Should -Not -BeNullOrEmpty + } + + It 'Should have a valid description' { + $ManifestData.Description | Should -Not -BeNullOrEmpty + } + + It 'Should have CompatiblePSEditions defined' { + $ManifestData.CompatiblePSEditions | Should -Not -BeNullOrEmpty + } + + It 'Should support Core PSEdition only' { + $ManifestData.CompatiblePSEditions | Should -Contain 'Core' + $ManifestData.CompatiblePSEditions | Should -Not -Contain 'Desktop' + } + + It 'Should require AsBuiltReport.Core' { + $RequiredModuleNames = $ManifestData.RequiredModules | ForEach-Object { + if ($_ -is [hashtable]) { $_['ModuleName'] } + else { $_ } + } + $RequiredModuleNames | Should -Contain 'AsBuiltReport.Core' + } + + It 'Should export Invoke-AsBuiltReport.VMware.vSphere' { + $ManifestData.FunctionsToExport | Should -Contain 'Invoke-AsBuiltReport.VMware.vSphere' + } + } + + Context 'Module Structure' { + BeforeAll { + $ModuleRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere' + } + + It 'Should have Language directory' { + $LangPath = Join-Path -Path $ModuleRoot -ChildPath 'Language' + Test-Path $LangPath | Should -Be $true + } + + It 'Should have en-US language folder' { + $EnUsPath = Join-Path -Path $ModuleRoot -ChildPath 'Language\en-US' + Test-Path $EnUsPath | Should -Be $true + } + + It 'Should have en-US VMwarevSphere.psd1 language file' { + $LangFile = Join-Path -Path $ModuleRoot -ChildPath 'Language\en-US\VMwarevSphere.psd1' + Test-Path $LangFile | Should -Be $true + } + + It 'Should have Src/Private directory' { + $PrivatePath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Private' + Test-Path $PrivatePath | Should -Be $true + } + + It 'Should have Src/Public directory' { + $PublicPath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Public' + Test-Path $PublicPath | Should -Be $true + } + + It 'Should have the Invoke- public function file' { + $InvokePath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Public\Invoke-AsBuiltReport.VMware.vSphere.ps1' + Test-Path $InvokePath | Should -Be $true + } + } + + Context 'Private Functions' { + BeforeAll { + $ModuleRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere' + $PrivatePath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Private' + } + + $ExpectedFunctions = @( + 'Convert-DataSize', + 'Get-ESXiBootDevice', + 'Get-InstallDate', + 'Get-License', + 'Get-PciDeviceDetail', + 'Get-ScsiDeviceDetail', + 'Get-Uptime', + 'Get-vCenterStats', + 'Get-VMHostNetworkAdapterDP', + 'Get-AbrVSpherevCenter', + 'Get-AbrVSphereCluster', + 'Get-AbrVSphereClusterHA', + 'Get-AbrVSphereClusterProactiveHA', + 'Get-AbrVSphereClusterDRS', + 'Get-AbrVSphereResourcePool', + 'Get-AbrVSphereVMHost', + 'Get-AbrVSphereVMHostHardware', + 'Get-AbrVSphereVMHostSystem', + 'Get-AbrVSphereVMHostStorage', + 'Get-AbrVSphereVMHostNetwork', + 'Get-AbrVSphereVMHostSecurity', + 'Get-AbrVSphereNetwork', + 'Get-AbrVSpherevSAN', + 'Get-AbrVSphereDatastore', + 'Get-AbrVSphereDSCluster', + 'Get-AbrVSphereVM', + 'Get-AbrVSphereVUM' + ) + + foreach ($FunctionName in $ExpectedFunctions) { + It "Should have a .ps1 file for function '$FunctionName'" -TestCases @(@{ FunctionName = $FunctionName }) { + param($FunctionName) + $FilePath = Join-Path -Path $PrivatePath -ChildPath "$FunctionName.ps1" + Test-Path $FilePath | Should -Be $true -Because "Expected file '$FunctionName.ps1' in Src/Private/" + } + } + } + + Context 'Module Import' { + It 'Should import without errors' { + $ModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere\AsBuiltReport.VMware.vSphere.psm1' + { Import-Module $ModulePath -Force -ErrorAction Stop } | Should -Not -Throw + } + } + + Context 'PSScriptAnalyzer' { + BeforeDiscovery { + $AnalyzerAvailable = $null -ne (Get-Module -Name PSScriptAnalyzer -ListAvailable | Select-Object -First 1) + } + BeforeAll { + $ModuleRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere' + $AnalyzerAvailable = $null -ne (Get-Module -Name PSScriptAnalyzer -ListAvailable | Select-Object -First 1) + } + + It 'PSScriptAnalyzer should be available' { + $AnalyzerAvailable | Should -Be $true + } + + It 'Public functions should pass PSScriptAnalyzer' -Skip:(-not $AnalyzerAvailable) { + $PublicPath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Public' + $Results = Invoke-ScriptAnalyzer -Path $PublicPath -Recurse -Severity Error + $Results | Should -BeNullOrEmpty -Because (($Results | ForEach-Object { "$($_.RuleName): $($_.Message) at $($_.ScriptName):$($_.Line)" }) -join "`n") + } + + It 'Private functions should pass PSScriptAnalyzer' -Skip:(-not $AnalyzerAvailable) { + $PrivatePath = Join-Path -Path $ModuleRoot -ChildPath 'Src\Private' + $Results = Invoke-ScriptAnalyzer -Path $PrivatePath -Recurse -Severity Error + $Results | Should -BeNullOrEmpty -Because (($Results | ForEach-Object { "$($_.RuleName): $($_.Message) at $($_.ScriptName):$($_.Line)" }) -join "`n") + } + } +} diff --git a/Tests/Invoke-Tests.ps1 b/Tests/Invoke-Tests.ps1 new file mode 100644 index 0000000..1e63158 --- /dev/null +++ b/Tests/Invoke-Tests.ps1 @@ -0,0 +1,203 @@ +<# +.SYNOPSIS + Invoke Pester tests for AsBuiltReport.VMware.vSphere module + +.DESCRIPTION + This script runs Pester tests with optional code coverage analysis. + It's designed to work with CI/CD pipelines and local development. + +.PARAMETER CodeCoverage + Enable code coverage analysis + +.PARAMETER OutputFormat + Specify the output format for test results (Console, NUnitXml, JUnitXml) + +.EXAMPLE + .\Invoke-Tests.ps1 + +.EXAMPLE + .\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [switch]$CodeCoverage, + + [Parameter(Mandatory = $false)] + [ValidateSet('Console', 'NUnitXml', 'JUnitXml')] + [string]$OutputFormat = 'Console' +) + +# Ensure we're in the Tests directory +$TestsPath = $PSScriptRoot +if (-not (Test-Path $TestsPath)) { + Write-Error "Tests directory not found at: $TestsPath" + exit 1 +} + +# Get the module root directory +$ModuleRoot = Split-Path -Path $TestsPath -Parent +$ModuleName = 'AsBuiltReport.VMware.vSphere' +$ModulePath = Join-Path -Path $ModuleRoot -ChildPath $ModuleName + +Write-Host "Module Root: $ModuleRoot" -ForegroundColor Cyan +Write-Host "Module Path: $ModulePath" -ForegroundColor Cyan +Write-Host "Tests Path: $TestsPath" -ForegroundColor Cyan + +# Check PowerShell version +$PSVersion = $PSVersionTable.PSVersion +Write-Host "PowerShell Version: $PSVersion" -ForegroundColor Cyan + +if ($PSVersion.Major -lt 7) { + Write-Warning "PowerShell 7 or higher is recommended for optimal test execution" +} + +# Install required modules +Write-Host "`nInstalling required modules..." -ForegroundColor Yellow + +$RequiredModules = @( + @{ Name = 'Pester'; MinimumVersion = '5.0.0' } + @{ Name = 'PScribo'; MinimumVersion = '0.11.1' } + @{ Name = 'PSScriptAnalyzer'; MinimumVersion = '1.0.0' } +) + +foreach ($Module in $RequiredModules) { + $InstalledModule = Get-Module -Name $Module.Name -ListAvailable | + Where-Object { $_.Version -ge [Version]$Module.MinimumVersion } | + Sort-Object -Property Version -Descending | + Select-Object -First 1 + + if (-not $InstalledModule) { + Write-Host "Installing $($Module.Name) (minimum version $($Module.MinimumVersion))..." -ForegroundColor Yellow + Install-Module -Name $Module.Name -MinimumVersion $Module.MinimumVersion -Repository PSGallery -Force -AllowClobber -Scope CurrentUser + } else { + Write-Host "$($Module.Name) version $($InstalledModule.Version) is already installed" -ForegroundColor Green + } +} + +# Remove any pre-loaded Pester module (PowerShell 5.1 ships with old Pester 3.4.0) +Get-Module Pester | Remove-Module -Force -ErrorAction SilentlyContinue + +# Import Pester with explicit minimum version +Import-Module Pester -MinimumVersion 5.0.0 -Force -ErrorAction Stop + +# Configure Pester +$PesterConfiguration = New-PesterConfiguration + +# Run settings +$PesterConfiguration.Run.Path = $TestsPath +$PesterConfiguration.Run.Exit = $false +$PesterConfiguration.Run.PassThru = $true + +# Output settings +$PesterConfiguration.Output.Verbosity = 'Detailed' + +# TestResult settings +if ($OutputFormat -ne 'Console') { + $PesterConfiguration.TestResult.Enabled = $true + $ResultFile = Join-Path -Path $TestsPath -ChildPath 'testResults.xml' + $PesterConfiguration.TestResult.OutputPath = $ResultFile + + if ($OutputFormat -eq 'NUnitXml') { + $PesterConfiguration.TestResult.OutputFormat = 'NUnitXml' + } elseif ($OutputFormat -eq 'JUnitXml') { + $PesterConfiguration.TestResult.OutputFormat = 'JUnitXml' + } + + Write-Host "Test results will be saved to: $ResultFile" -ForegroundColor Cyan +} + +# Code Coverage settings +if ($CodeCoverage) { + Write-Host "`nEnabling code coverage analysis..." -ForegroundColor Yellow + + $PesterConfiguration.CodeCoverage.Enabled = $true + $PesterConfiguration.CodeCoverage.OutputFormat = 'JaCoCo' + $CoverageFile = Join-Path -Path $TestsPath -ChildPath 'coverage.xml' + $PesterConfiguration.CodeCoverage.OutputPath = $CoverageFile + + # Include all PowerShell files in the module + $CoverageFiles = @( + "$ModulePath\*.psm1" + "$ModulePath\Src\Public\*.ps1" + "$ModulePath\Src\Private\*.ps1" + ) + + $PesterConfiguration.CodeCoverage.Path = $CoverageFiles + + Write-Host "Code coverage will be saved to: $CoverageFile" -ForegroundColor Cyan + Write-Host "Coverage files included:" -ForegroundColor Cyan + foreach ($File in $CoverageFiles) { + Write-Host " - $File" -ForegroundColor Gray + } +} + +# Run Pester tests +Write-Host "`nRunning Pester tests..." -ForegroundColor Yellow +Write-Host "======================================" -ForegroundColor Cyan + +$TestResults = Invoke-Pester -Configuration $PesterConfiguration + +# Display results +Write-Host "`n======================================" -ForegroundColor Cyan +Write-Host "Test Results Summary" -ForegroundColor Yellow +Write-Host "======================================" -ForegroundColor Cyan +Write-Host "Total Tests: $($TestResults.TotalCount)" -ForegroundColor White +Write-Host "Passed: $($TestResults.PassedCount)" -ForegroundColor Green +Write-Host "Failed: $($TestResults.FailedCount)" -ForegroundColor $(if ($TestResults.FailedCount -gt 0) { 'Red' } else { 'Green' }) +Write-Host "Skipped: $($TestResults.SkippedCount)" -ForegroundColor Yellow +Write-Host "Duration: $($TestResults.Duration)" -ForegroundColor White + +# Display failed tests +if ($TestResults.FailedCount -gt 0) { + Write-Host "`nFailed Tests:" -ForegroundColor Red + foreach ($FailedTest in $TestResults.Failed) { + Write-Host " - $($FailedTest.Name)" -ForegroundColor Red + Write-Host " $($FailedTest.ErrorRecord)" -ForegroundColor Gray + } +} + +# Display code coverage summary +if ($CodeCoverage -and $TestResults.CodeCoverage) { + Write-Host "`n======================================" -ForegroundColor Cyan + Write-Host "Code Coverage Summary" -ForegroundColor Yellow + Write-Host "======================================" -ForegroundColor Cyan + + $Coverage = $TestResults.CodeCoverage + + if ($Coverage.NumberOfCommandsAnalyzed -gt 0) { + $CoveragePercent = [math]::Round(($Coverage.NumberOfCommandsExecuted / $Coverage.NumberOfCommandsAnalyzed) * 100, 2) + } else { + $CoveragePercent = 0 + Write-Host "Warning: No commands were analyzed for code coverage" -ForegroundColor Yellow + } + + Write-Host "Commands Analyzed: $($Coverage.NumberOfCommandsAnalyzed)" -ForegroundColor White + Write-Host "Commands Executed: $($Coverage.NumberOfCommandsExecuted)" -ForegroundColor White + Write-Host "Commands Missed: $($Coverage.NumberOfCommandsMissed)" -ForegroundColor White + Write-Host "Coverage: $CoveragePercent%" -ForegroundColor $(if ($CoveragePercent -ge 80) { 'Green' } elseif ($CoveragePercent -ge 60) { 'Yellow' } else { 'Red' }) + + # Code coverage threshold enforcement + $MinimumCoverageThreshold = 50 # Minimum 50% code coverage + if ($CoveragePercent -lt $MinimumCoverageThreshold) { + Write-Host "`nWARNING: Code coverage ($CoveragePercent%) is below minimum threshold ($MinimumCoverageThreshold%)" -ForegroundColor Red + Write-Host "Consider adding more tests to improve coverage" -ForegroundColor Yellow + + # Uncomment the line below to fail builds when coverage is too low + # exit 1 + } else { + Write-Host "`nCode coverage meets minimum threshold ($MinimumCoverageThreshold%)" -ForegroundColor Green + } +} + +Write-Host "`n======================================" -ForegroundColor Cyan + +# Exit with appropriate code +if ($TestResults.FailedCount -gt 0) { + Write-Host "Tests FAILED" -ForegroundColor Red + exit 1 +} else { + Write-Host "All tests PASSED" -ForegroundColor Green + exit 0 +} diff --git a/Tests/LocalizationData.Tests.ps1 b/Tests/LocalizationData.Tests.ps1 new file mode 100644 index 0000000..a9895b3 --- /dev/null +++ b/Tests/LocalizationData.Tests.ps1 @@ -0,0 +1,74 @@ +BeforeAll { + # Get the language folder path + $LanguagePath = Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere\Language' + + # Helper function to extract nested localization keys in Section.Key format + function Get-NestedLocalizationKeys { + param([string]$FilePath) + + $keys = @() + $content = Get-Content -Path $FilePath + $currentSection = $null + + foreach ($line in $content) { + # Match section headers like: GetAbrVSpherevCenter = ConvertFrom-StringData @' + if ($line -match '^\s*(\w+)\s*=\s*ConvertFrom-StringData') { + $currentSection = $Matches[1] + } + # Match key-value pairs within sections + elseif ($currentSection -and $line -match '^\s+(\w+)\s*=' -and $line -notmatch "^'@") { + $keys += "$currentSection.$($Matches[1])" + } + # End of section + elseif ($line -match "^'@") { + $currentSection = $null + } + } + return $keys | Sort-Object + } +} + +Describe 'Localization Data Consistency Tests' { + Context 'VMwarevSphere.psd1 Localization Files' { + BeforeAll { + $TemplateFile = Join-Path -Path $LanguagePath -ChildPath 'en-US\VMwarevSphere.psd1' + $TemplateKeys = Get-NestedLocalizationKeys -FilePath $TemplateFile + $LanguageFolders = Get-ChildItem -Path $LanguagePath -Directory | Where-Object { $_.Name -ne 'en-US' } + } + + It "Template 'en-US' should have localization keys" { + $TemplateKeys.Count | Should -BeGreaterThan 0 + } + + It "Template 'en-US' VMwarevSphere.psd1 should be valid PowerShell" { + $TemplateFile = Join-Path -Path $LanguagePath -ChildPath 'en-US\VMwarevSphere.psd1' + { Import-LocalizedData -BaseDirectory $LanguagePath -UICulture 'en-US' -FileName 'VMwarevSphere' -ErrorAction Stop } | + Should -Not -Throw + } + + foreach ($folder in (Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath '..\AsBuiltReport.VMware.vSphere\Language') -Directory | Where-Object { $_.Name -ne 'en-US' })) { + It "Language '' should have all keys from en-US template for VMwarevSphere.psd1" -TestCases @(@{ Name = $folder.Name; FolderPath = $folder.FullName }) { + param($Name, $FolderPath) + + $LocalizedFile = Join-Path -Path $FolderPath -ChildPath 'VMwarevSphere.psd1' + if (Test-Path $LocalizedFile) { + $LocalizedKeys = Get-NestedLocalizationKeys -FilePath $LocalizedFile + $TemplatePath = Join-Path -Path $LanguagePath -ChildPath 'en-US\VMwarevSphere.psd1' + $TemplateKeysForTest = Get-NestedLocalizationKeys -FilePath $TemplatePath + + $MissingKeys = $TemplateKeysForTest | Where-Object { $_ -notin $LocalizedKeys } + $ExtraKeys = $LocalizedKeys | Where-Object { $_ -notin $TemplateKeysForTest } + + if ($MissingKeys) { + $MissingKeys | Should -BeNullOrEmpty -Because "Language '$Name' is missing keys: $($MissingKeys -join ', ')" + } + if ($ExtraKeys) { + $ExtraKeys | Should -BeNullOrEmpty -Because "Language '$Name' has extra keys not in template: $($ExtraKeys -join ', ')" + } + } else { + Set-ItResult -Skipped -Because "File not found: $LocalizedFile" + } + } + } + } +}