diff --git a/.github/workflows/Codeql.yml b/.github/workflows/Codeql.yml
new file mode 100644
index 0000000..832aa3e
--- /dev/null
+++ b/.github/workflows/Codeql.yml
@@ -0,0 +1,47 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+#
+# https://github.com/microsoft/action-psscriptanalyzer
+# For more information on PSScriptAnalyzer in general, see
+# https://github.com/PowerShell/PSScriptAnalyzer
+
+name: CodeQL
+
+on:
+ push:
+ branches: [ "dev" ]
+ pull_request:
+ branches: [ "dev" ]
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ permissions:
+ contents: read # for actions/checkout to fetch code
+ security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ name: PSScriptAnalyzer
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Run PSScriptAnalyzer
+ uses: microsoft/psscriptanalyzer-action@v1.1
+ with:
+ # Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options.
+ # The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules.
+ path: .\
+ recurse: true
+ # Include your own basic security rules. Removing this option will run all the rules
+ excludeRule: '"PSAvoidUsingPlainTextForPassword", "PSAvoidUsingUsernameAndPasswordParams", "PSAvoidUsingConvertToSecureStringWithPlainText"'
+ output: results.sarif
+
+ # Upload the SARIF file generated in the previous step
+ - name: Upload SARIF results file
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/PSScriptAnalyzer.yml b/.github/workflows/PSScriptAnalyzer.yml
index fe69d8f..a73694f 100644
--- a/.github/workflows/PSScriptAnalyzer.yml
+++ b/.github/workflows/PSScriptAnalyzer.yml
@@ -5,7 +5,7 @@ jobs:
name: Run PSScriptAnalyzer
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v5
- name: lint
uses: devblackops/github-action-psscriptanalyzer@master
with:
diff --git a/.github/workflows/PSScriptAnalyzerSettings.psd1 b/.github/workflows/PSScriptAnalyzerSettings.psd1
index c053761..3fe6424 100644
--- a/.github/workflows/PSScriptAnalyzerSettings.psd1
+++ b/.github/workflows/PSScriptAnalyzerSettings.psd1
@@ -3,6 +3,24 @@
'PSUseToExportFieldsInManifest',
'PSReviewUnusedParameter',
'PSUseDeclaredVarsMoreThanAssignments',
- 'PSAvoidGlobalVars'
+ 'PSAvoidGlobalVars',
+ 'PSAvoidUsingWriteHost'
)
+ Rules = @{
+ PSAvoidExclaimOperator = @{
+ Enable = $true
+ }
+ AvoidUsingDoubleQuotesForConstantString = @{
+ Enable = $true
+ }
+ UseCorrectCasing = @{
+ Enable = $true
+ }
+ PSAvoidUsingCmdletAliases = @{
+ Enable = $true
+ }
+ PSUseConsistentWhitespace = @{
+ Enable = $true
+ }
+ }
}
\ No newline at end of file
diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml
new file mode 100644
index 0000000..dd8ce4f
--- /dev/null
+++ b/.github/workflows/Release.yml
@@ -0,0 +1,62 @@
+name: Publish PowerShell Module
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ publish-to-gallery:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v5
+ - name: Set PSRepository to Trusted for PowerShell Gallery
+ shell: pwsh
+ run: |
+ Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
+ - name: Install AsBuiltReport.Core module
+ shell: pwsh
+ run: |
+ Install-Module -Name AsBuiltReport.Core -Repository PSGallery -Force
+ - name: Install PScriboCharts module
+ shell: pwsh
+ run: |
+ Install-Module -Name PScriboCharts -Repository PSGallery -Force
+ - name: Install Diagrammer.Core module
+ shell: pwsh
+ run: |
+ Install-Module -Name Diagrammer.Core -Repository PSGallery -Force
+ - name: Test Module Manifest
+ shell: pwsh
+ run: |
+ Test-ModuleManifest .\AsBuiltReport.Veeam.VBR.psd1
+ - name: Publish module to PowerShell Gallery
+ shell: pwsh
+ run: |
+ Publish-Module -Path ./ -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose
+
+ tweet:
+ needs: publish-to-gallery
+ 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:
+ # GitHub event payload
+ # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#release
+ tweet-message: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #Microsoft #SCVMM #AsBuiltReport #PowerShell #MicrosoftMVP #MVPBuzz"
+ 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
+ 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 }} #Microsoft #SCVMM #AsBuiltReport #PowerShell #MicrosoftMVP #MVPBuzz"
+ env:
+ BSKY_IDENTIFIER: ${{ secrets.BSKY_IDENTIFIER }}
+ BSKY_PASSWORD: ${{ secrets.BSKY_PASSWORD }}
diff --git a/.github/workflows/Stale.yml b/.github/workflows/Stale.yml
new file mode 100644
index 0000000..afebe72
--- /dev/null
+++ b/.github/workflows/Stale.yml
@@ -0,0 +1,18 @@
+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: 30
+ 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/AsBuiltReport.Microsoft.SCVMM.json b/AsBuiltReport.Microsoft.SCVMM.json
index 14426c2..04390bc 100644
--- a/AsBuiltReport.Microsoft.SCVMM.json
+++ b/AsBuiltReport.Microsoft.SCVMM.json
@@ -9,13 +9,34 @@
"ShowTableCaptions": true
},
"Options": {
-
+ "VmmServerPort": 8100,
+ "EnableDiagrams": true,
+ "EnableDiagramDebug": true,
+ "DiagramTheme": "White",
+ "DiagramWaterMark": "Acme Corporation",
+ "ExportDiagrams": true,
+ "ExportDiagramsFormat": [
+ "png"
+ ],
+ "EnableDiagramSignature": false,
+ "DiagramColumnSize": 4,
+ "SignatureAuthorName": "Jonathan Colon",
+ "SignatureCompanyName": "Zen PR Solutions"
},
"InfoLevel": {
- "_comment_": "Please refer to the AsBuiltReport project contributing guide for information about how to define InfoLevels.",
- "_comment_": "0 = Disabled, 1 = Enabled / Summary, 2 = Adv Summary, 3 = Detailed, 4 = Adv Detailed, 5 = Comprehensive"
+ "_comment_": "Please refer to the AsBuiltReport project contributing guide for information about how to define InfoLevels.",
+ "_comment_": "0 = Disabled, 1 = Enabled / Summary, 2 = Adv Summary, 3 = Detailed, 4 = Adv Detailed, 5 = Comprehensive",
+ "Infrastructure": 2,
+ "Networking": 2,
+ "LibraryTemplates": 2,
+ "Clusters": 2,
+ "Hosts": 2
},
"HealthCheck": {
-
+ "VMMServer": true,
+ "Database": true,
+ "AutoNetwork": true,
+ "Clusters": true,
+ "Hosts": true
}
-}
+}
\ No newline at end of file
diff --git a/AsBuiltReport.Microsoft.SCVMM.psd1 b/AsBuiltReport.Microsoft.SCVMM.psd1
index d78ac62..eaafedb 100644
--- a/AsBuiltReport.Microsoft.SCVMM.psd1
+++ b/AsBuiltReport.Microsoft.SCVMM.psd1
@@ -8,99 +8,108 @@
@{
-# Script module or binary module file associated with this manifest.
-RootModule = 'AsBuiltReport.Microsoft.SCVMM.psm1'
+ # Script module or binary module file associated with this manifest.
+ RootModule = 'AsBuiltReport.Microsoft.SCVMM.psm1'
-# Version number of this module.
-ModuleVersion = '0.1.0'
+ # Version number of this module.
+ ModuleVersion = '0.1.1'
-# Supported PSEditions
-# CompatiblePSEditions = @()
+ # Supported PSEditions
+ # CompatiblePSEditions = @()
-# ID used to uniquely identify this module
-GUID = 'b4a72506-7a52-40c6-8649-050db73f2ab7'
+ # ID used to uniquely identify this module
+ GUID = 'b4a72506-7a52-40c6-8649-050db73f2ab7'
-# Author of this module
-Author = 'Andrew Ramsay'
+ # Author of this module
+ Author = 'Andrew Ramsay'
-# Company or vendor of this module
-# CompanyName = 'Unknown'
+ # Company or vendor of this module
+ # CompanyName = 'Unknown'
-# Copyright statement for this module
-Copyright = '(c) 2021 Andrew Ramsay. All rights reserved.'
+ # Copyright statement for this module
+ Copyright = '(c) 2025 Andrew Ramsay. 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 Microsoft SCVMM.'
+ # Description of the functionality provided by this module
+ Description = 'A PowerShell module to generate an as built report on the configuration of Microsoft SCVMM.'
-# Minimum version of the Windows PowerShell engine required by this module
-PowerShellVersion = '5.1'
+ # Minimum version of the Windows PowerShell engine required by this module
+ PowerShellVersion = '5.1'
-# Name of the Windows PowerShell host required by this module
-# PowerShellHostName = ''
+ # Name of the Windows PowerShell host required by this module
+ # PowerShellHostName = ''
-# Minimum version of the Windows PowerShell host required by this module
-# PowerShellHostVersion = ''
+ # Minimum version of the Windows PowerShell host required by this module
+ # PowerShellHostVersion = ''
-# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
-# DotNetFrameworkVersion = ''
+ # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
+ # DotNetFrameworkVersion = ''
-# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
-# CLRVersion = ''
+ # 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 = ''
+ # Processor architecture (None, X86, Amd64) required by this module
+ # ProcessorArchitecture = ''
-# Modules that must be imported into the global environment prior to importing this module
- RequiredModules = @(
- @{
- ModuleName = 'AsBuiltReport.Core';
- ModuleVersion = '1.1.0'
- }
- )
+ # Modules that must be imported into the global environment prior to importing this module
+ RequiredModules = @(
+ @{
+ ModuleName = 'AsBuiltReport.Core';
+ ModuleVersion = '1.4.3'
+ },
+ @{
+ ModuleName = 'Diagrammer.Core';
+ ModuleVersion = '0.2.29'
+ },
+ @{
+ ModuleName = 'PScriboCharts';
+ ModuleVersion = '0.9.0'
+ }
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
+ )
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = @()
+ # Assemblies that must be loaded prior to importing this module
+ # RequiredAssemblies = @()
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
+ # Script files (.ps1) that are run in the caller's environment prior to importing this module.
+ # ScriptsToProcess = @()
-# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
+ # Type files (.ps1xml) to be loaded when importing this module
+ # TypesToProcess = @()
-# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-# NestedModules = @()
+ # Format files (.ps1xml) to be loaded when importing this module
+ # FormatsToProcess = @()
-# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
-FunctionsToExport = @('Invoke-AsBuiltReport.Microsoft.SCVMM')
+ # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
+ # NestedModules = @()
-# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
-# CmdletsToExport = '*'
+ # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
+ FunctionsToExport = @('Invoke-AsBuiltReport.Microsoft.SCVMM')
-# Variables to export from this module
-# VariablesToExport = '*'
+ # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
+ # CmdletsToExport = '*'
-# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
-# AliasesToExport = '*'
+ # Variables to export from this module
+ # VariablesToExport = '*'
-# DSC resources to export from this module
-# DscResourcesToExport = @()
+ # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
+ # AliasesToExport = '*'
-# List of all modules packaged with this module
-# ModuleList = @()
+ # DSC resources to export from this module
+ # DscResourcesToExport = @()
-# List of all files packaged with this module
-# FileList = @()
+ # List of all modules packaged with this module
+ # ModuleList = @()
-# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
-PrivateData = @{
+ # List of all files packaged with this module
+ # FileList = @()
- PSData = @{
+ # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
+ PrivateData = @{
+
+ PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
- Tags = 'AsBuiltReport', 'Report', 'Microsoft', 'SCVMM', 'Documentation', 'PScribo', 'Windows', 'Linux', 'MacOS', 'PSEdition_Desktop', 'PSEdition_Core'
+ Tags = 'AsBuiltReport', 'Report', 'Microsoft', 'SCVMM', 'Documentation', 'PScribo', 'Windows', 'PSEdition_Desktop', 'PSEdition_Core'
# A URL to the license for this module.
LicenseUri = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM/master/LICENSE'
@@ -116,13 +125,13 @@ PrivateData = @{
} # End of PSData hashtable
-} # End of PrivateData hashtable
+ } # End of PrivateData hashtable
-# HelpInfo URI of this module
-# HelpInfoURI = ''
+ # HelpInfo URI of this module
+ # HelpInfoURI = ''
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
+ # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
+ # DefaultCommandPrefix = ''
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0eb720e..6878fbb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,19 @@
# :arrows_counterclockwise: Microsoft SCVMM As Built Report Changelog
-## [0.1.0] - YYYY-MM-DD
+## [0.1.1] - 2024-06-10
### Added
+- Initial release of Microsoft SCVMM As Built Report module.
+- Basic changelog structure.
+
### Changed
+- N/A
### Fixed
+- N/A
### Removed
+- N/A
diff --git a/README.md b/README.md
index 0939e0f..3b9a7c6 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
-
+
+
@@ -22,90 +22,200 @@
+
+
+
# Microsoft SCVMM As Built Report
+Microsoft SCVMM As Built Report is a PowerShell module which works in conjunction with [AsBuiltReport.Core](https://github.com/AsBuiltReport/AsBuiltReport.Core).
+
+[AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport) is an open-sourced community project which utilizes PowerShell to produce as-built documentation in multiple document formats for multiple vendors and technologies.
+
+Please refer to the AsBuiltReport [website](https://www.asbuiltreport.com) for more detailed information about this project.
+
+# :books: Sample Reports
+
+## Sample Report - Custom Style 1
+
+Sample Microsoft SCVMM As Built report HTML file: [Sample Microsoft SCVMM As-Built Report.html](https://htmlpreview.github.io/?https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM/dev/Samples/Sample%20Microsoft%20Windows%20As%20Built%20Report.html "Sample Microsoft SCVMM As-Built Report")
+
# :beginner: Getting Started
+Below are the instructions on how to install, configure and generate a Microsoft SCVMM As Built report.
+
## :floppy_disk: Supported Versions
+
+The Microsoft SCVMM As Built Report supports the following SCVMM Server versions;
+
+- 2016, 2019, 2022 & 2025
+
+### PowerShell
+
+This report is compatible with the following PowerShell versions;
+
+| Windows PowerShell 5.1 | PowerShell 7 |
+| :--------------------: | :----------------: |
+| :white_check_mark: | :white_check_mark: |
## :wrench: System Requirements
+
+PowerShell 5.1/7 and the following PowerShell modules are required for generating a Microsoft SCVMM As Built report.
+
+- [AsBuiltReport.Microsoft.SCVMM Module](https://www.powershellgallery.com/packages/AsBuiltReport.Microsoft.SCVMM/)
+- [Hyper-V Module](https://docs.microsoft.com/en-us/powershell/module/hyper-v/?view=windowsserver2022-ps)
+- [FailoverClusters Module](https://learn.microsoft.com/en-us/powershell/module/failoverclusters/?view=windowsserver2022-ps)
+- [Diagrammer.Core Module](https://www.powershellgallery.com/packages/Diagrammer.Core/)
+### Linux & macOS
+
+This report does not support Linux or Mac due to the fact that the SCVMM modules are dependent on the .NET Framework. Until Microsoft migrates these modules to native PowerShell Core, only PowerShell >= 5.1.x will be supported on SCVMM.
+
### :closed_lock_with_key: Required Privileges
+A Microsoft SCVMM As Built Report can be generated with Administrator level role. Since this report relies extensively on the WinRM component, you should make sure that it is enabled and configured
## :package: Module Installation
-### PowerShell
+The installation of the modules will depend on the roles that are being served on the server to be documented.
+
+### PowerShell v5.x running on a Windows server (Target)
+
+```powershell
+Install-Module AsBuiltReport.Microsoft.SCVMM
+
+# Hyper-V Server powershell modules
+Install-WindowsFeature -Name Hyper-V-PowerShell
+
+# FailOver Cluster powershell modules
+Install-WindowsFeature -Name RSAT-Clustering-PowerShell
+```
+### PowerShell v5.x running on Windows client computer (Target)
+
```powershell
-install-module AsBuiltReport.Microsoft.SCVMM
+Install-Module AsBuiltReport.Microsoft.SCVMM
+
+#FailOver Cluster powershell modules
+Add-WindowsCapability -Online -Name 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0'
+
+# Hyper-V Server powershell modules
+Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell
```
### 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.Microsoft.SCVMM#wrench-system-requirements) also.
1. Download the code package / [latest release](https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM/releases/latest) zip from GitHub
2. Extract the zip file
3. Copy the folder `AsBuiltReport.Microsoft.SCVMM` 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.Microsoft.SCVMM -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 Microsoft SCVMM As Built Report utilises a JSON file to allow configuration of report information, options, detail and healthchecks.
+The Microsoft SCVMM As Built Report utilizes a JSON file to allow configuration of report information, options, detail and healthchecks.
A Microsoft SCVMM report configuration file can be generated by executing the following command;
+
```powershell
-New-AsBuiltReportConfig -Report AsBuiltReport.Microsoft.SCVMM -FolderPath -Filename
+New-AsBuiltReportConfig -Report Microsoft.SCVMM -FolderPath -Filename
```
-Executing this command will copy the default Microsoft SCVMM report JSON configuration to a user specified folder.
+Executing this command will copy the default Microsoft Windows report JSON configuration to a user specified folder.
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 Microsoft SCVMM report information.
-| Sub-Schema | Setting | Default | Description |
-|---------------------|--------------|--------------------------------|--------------------------------------------------------------|
+| Sub-Schema | Setting | Default | Description |
+| ------------------- | ------------ | ------------------------------- | ------------------------------------------------------------ |
| Name | User defined | Microsoft SCVMM As Built Report | The name of the As Built Report |
-| Version | User defined | 1.0 | The report version |
-| Status | User defined | Released | The report release status |
-| ShowCoverPageImage | true / false | true | Toggle to enable/disable the display of the cover page image |
-| ShowTableOfContents | true / false | true | Toggle to enable/disable table of contents |
-| ShowHeaderFooter | true / false | true | Toggle to enable/disable document headers & footers |
-| ShowTableCaptions | true / false | true | Toggle to enable/disable table captions/numbering |
+| Version | User defined | 1.0 | The report version |
+| Status | User defined | Released | The report release status |
+| ShowCoverPageImage | true / false | true | Toggle to enable/disable the display of the cover page image |
+| ShowTableOfContents | true / false | true | Toggle to enable/disable table of contents |
+| ShowHeaderFooter | true / false | true | Toggle to enable/disable document headers & footers |
+| ShowTableCaptions | true / false | true | Toggle to enable/disable table captions/numbering |
### Options
+
The **Options** schema allows certain options within the report to be toggled on or off.
+| Sub-Schema | Setting | Default | Description |
+| ---------------------- | ------------ | ------- | ----------------------------------------------------------------------------- |
+| DiagramColumnSize | int | 3 | Set the diagram node table size |
+| DiagramTheme | string | White | Set the diagram theme (Black/White/Neon) |
+| DiagramWaterMark | string | empty | Set the diagram watermark |
+| DiagramType | true / false | true | Toggle to enable/disable the export of individual diagram diagrams |
+| EnableDiagrams | true / false | false | Toggle to enable/disable infrastructure diagrams |
+| EnableDiagramsDebug | true / false | false | Toggle to enable/disable diagram debug option |
+| EnableDiagramSignature | true / false | false | Toggle to enable/disable diagram signature (bottom right corner) |
+| ExportDiagrams | true / false | true | Toggle to enable/disable diagram export option |
+| ExportDiagramsFormat | string array | png | Set the format used to export the infrastructure diagram (dot, png, pdf, svg) |
+| SignatureAuthorName | string | empty | Set the signature author name |
+| SignatureCompanyName | string | empty | Set the signature company name |
+
### InfoLevel
+
The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set.
-There are 6 levels (0-5) of detail granularity for each section as follows;
+There are 3 levels (0-2) of detail granularity for each section as follows;
-| Setting | InfoLevel | Description |
-|:-------:|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
-| 0 | Disabled | Does not collect or display any information |
-| 1 | Enabled / Summary | Provides summarised information for a collection of objects |
-| 2 | Adv Summary | Provides condensed, detailed information for a collection of objects |
-| 3 | Detailed | Provides detailed information for individual objects |
-| 4 | Adv Detailed | Provides detailed information for individual objects, as well as information for associated objects |
-| 5 | Comprehensive | Provides comprehensive information for individual objects, such as advanced configuration settings |
+| Setting | InfoLevel | Description |
+| :-----: | ----------- | -------------------------------------------------------------------- |
+| 0 | Disabled | Does not collect or display any information |
+| 1 | Enabled | Provides summarized information for a collection of objects |
+| 2 | Adv Summary | Provides condensed, detailed information for a collection of objects |
+
+The table below outlines the default and maximum **InfoLevel** settings for each section.
+
+| Sub-Schema | Default Setting | Maximum Setting |
+| --------------- | :-------------: | :-------------: |
+| Cluster | 1 | 1 |
+| Host | 1 | 2 |
+| Infrastructure | 1 | 1 |
+| LibraryTemplate | 1 | 2 |
+| Networking | 1 | 1 |
### Healthcheck
+
The **Healthcheck** schema is used to toggle health checks on or off.
-## :computer: Examples
+## :computer: Examples
+
+There are a few examples listed below on running the AsBuiltReport script against a Microsoft Windows server target. Refer to the `README.md` file in the main AsBuiltReport project repository for more examples.
+
+```powershell
+
+# Generate a Microsoft SCVMM As Built Report for Server 'scvmm-server-01v.contoso.local' using specified credentials. Export report to HTML & DOCX formats. Use default report style. Append timestamp to report filename. Save reports to 'C:\Users\Jon\Documents'
+PS C:\> New-AsBuiltReport -Report Microsoft.SCVMM -Target 'scvmm-server-01v.contoso.local' -Username 'administrator@contoso.local' -Password 'P@ssw0rd' -Format Html,Word -OutputFolderPath 'C:\Users\Jon\Documents' -Timestamp
+
+# Generate a Microsoft SCVMM As Built Report for Server 'scvmm-server-01v.contoso.local' using specified credentials and report configuration file. Export report to Text, HTML & DOCX formats. Use default report style. Save reports to 'C:\Users\Jon\Documents'. Display verbose messages to the console.
+PS C:\> New-AsBuiltReport -Report Microsoft.SCVMM -Target 'scvmm-server-01v.contoso.local' -Username 'administrator@contoso.local' -Password 'P@ssw0rd' -Format Text,Html,Word -OutputFolderPath 'C:\Users\Jon\Documents' -ReportConfigFilePath 'C:\Users\Jon\AsBuiltReport\AsBuiltReport.Microsoft.SCVMM.json' -Verbose
+
+# Generate a Microsoft SCVMM As Built Report for Server 'scvmm-server-01v.contoso.local' using stored credentials. Export report to HTML & Text formats. Use default report style. Highlight environment issues within the report. Save reports to 'C:\Users\Jon\Documents'.
+PS C:\> $Creds = Get-Credential
+PS C:\> New-AsBuiltReport -Report Microsoft.SCVMM -Target 'scvmm-server-01v.contoso.local' -Credential $Creds -Format Html,Text -OutputFolderPath 'C:\Users\Jon\Documents' -EnableHealthCheck
+
+# Generate a Microsoft SCVMM As Built Report for Server 'scvmm-server-01v.contoso.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 Microsoft.SCVMM -Target 'scvmm-server-01v.contoso.local' -Username 'administrator@contoso.local' -Password 'P@ssw0rd' -Format Html,Word -OutputFolderPath 'C:\Users\Jon\Documents' -SendEmail
+```
+## :x: Known Issues
+- Issues with WinRM when using the IP address instead of the "Fully Qualified Domain Name".
\ No newline at end of file
diff --git a/Src/Private/Export-AbrDiagram.ps1 b/Src/Private/Export-AbrDiagram.ps1
new file mode 100644
index 0000000..e7be722
--- /dev/null
+++ b/Src/Private/Export-AbrDiagram.ps1
@@ -0,0 +1,132 @@
+function Export-AbrDiagram {
+ <#
+ .SYNOPSIS
+ Function used to build the settings needed to call Export-Diagrammer (Diagrammer.Core)
+
+ .DESCRIPTION
+ The Export-AbrDiagram function build the settings needed to call Export-Diagrammer (Diagrammer.Core)
+ to export a diagram in PDF, PNG, SVG, or base64 formats using PSgraph.
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM
+ #>
+
+ # Don't remove this line (Don't touch it!)
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingCmdletAliases", "", Scope = "Function")]
+
+ [CmdletBinding()]
+ param (
+ $DiagramObject,
+ [string] $MainDiagramLabel = 'Change Me',
+ [Parameter(Mandatory = $true)]
+ [string] $FileName
+ )
+
+ begin {
+ Write-PScriboMessage -Message "EnableDiagrams set to $($Options.EnableDiagrams)."
+ }
+
+ process {
+ if ($Options.EnableDiagrams) {
+ Write-PScriboMessage -Message "Loading export diagram settings"
+
+ $RootPath = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
+ [System.IO.FileInfo]$IconPath = Join-Path $RootPath 'icons'
+
+ $DiagramParams = @{
+ 'FileName' = $FileName
+ 'OutputFolderPath' = $OutputFolderPath
+ 'MainDiagramLabel' = $MainDiagramLabel
+ 'MainDiagramLabelFontsize' = 28
+ 'MainDiagramLabelFontcolor' = '#565656'
+ 'MainDiagramLabelFontname' = 'Segoe UI Black'
+ 'IconPath' = $IconPath
+ 'ImagesObj' = $Images
+ 'LogoName' = 'AsBuiltReport_LOGO'
+ 'SignatureLogoName' = 'AsBuiltReport_Signature'
+ 'WaterMarkText' = $Options.DiagramWaterMark
+ 'Direction' = 'top-to-bottom'
+ }
+
+ if ($Options.DiagramTheme -eq 'Black') {
+ $DiagramParams.add('MainGraphBGColor', 'Black')
+ $DiagramParams.add('Edgecolor', 'White')
+ $DiagramParams.add('Fontcolor', 'White')
+ $DiagramParams.add('NodeFontcolor', 'White')
+ $DiagramParams.add('WaterMarkColor', 'White')
+ } elseif ($Options.DiagramTheme -eq 'Neon') {
+ $DiagramParams.add('MainGraphBGColor', 'grey14')
+ $DiagramParams.add('Edgecolor', 'gold2')
+ $DiagramParams.add('Fontcolor', 'gold2')
+ $DiagramParams.add('NodeFontcolor', 'gold2')
+ $DiagramParams.add('WaterMarkColor', '#FFD700')
+ } else {
+ $DiagramParams.add('WaterMarkColor', '#333333')
+ }
+
+ if ($Options.ExportDiagrams) {
+ if (-not $Options.ExportDiagramsFormat) {
+ $DiagramFormat = 'png'
+ } else {
+ $DiagramFormat = $Options.ExportDiagramsFormat
+ }
+ $DiagramParams.Add('Format', $DiagramFormat)
+ } else {
+ $DiagramParams.Add('Format', "base64")
+ }
+
+ if ($Options.EnableDiagramDebug) {
+
+ $DiagramParams.Add('DraftMode', $True)
+
+ }
+
+ if ($Options.EnableDiagramSignature) {
+ $DiagramParams.Add('Signature', $True)
+ $DiagramParams.Add('AuthorName', $Options.SignatureAuthorName)
+ $DiagramParams.Add('CompanyName', $Options.SignatureCompanyName)
+ }
+
+ if ($Options.ExportDiagrams) {
+ try {
+ Write-PScriboMessage -Message "Generating $MainDiagramLabel diagram"
+ $Graph = $DiagramObject
+ if ($Graph) {
+ Write-PScriboMessage -Message "Saving $MainDiagramLabel diagram"
+ $Diagram = New-Diagrammer @DiagramParams -InputObject $Graph
+ if ($Diagram) {
+ foreach ($OutputFormat in $DiagramFormat) {
+ Write-Information -MessageData "Saved '$($FileName).$($OutputFormat)' diagram to '$($OutputFolderPath)'." -InformationAction Continue
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning -Message "Unable to export the $MainDiagramLabel Diagram: $($_.Exception.Message)"
+ }
+ }
+ try {
+ $DiagramParams.Remove('Format')
+ $DiagramParams.Add('Format', "base64")
+
+ $Graph = $DiagramObject
+ $Diagram = New-Diagrammer @DiagramParams -InputObject $Graph
+ if ($Diagram) {
+ if ((Get-DiaImagePercent -GraphObj $Diagram).Width -gt 600) { $ImagePrty = 40 } else { $ImagePrty = 30 }
+ Section -Style Heading2 $MainDiagramLabel {
+ Image -Base64 $Diagram -Text "$MainDiagramLabel" -Percent $ImagePrty -Align Center
+ Paragraph "Image preview: Opens the image in a new tab to view it at full resolution." -Tabs 2
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning -Message "Unable to generate the $MainDiagramLabel Diagram: $($_.Exception.Message)"
+ }
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmAutoNetSetting.ps1 b/Src/Private/Get-AbrVmmAutoNetSetting.ps1
new file mode 100644
index 0000000..6f4e1b4
--- /dev/null
+++ b/Src/Private/Get-AbrVmmAutoNetSetting.ps1
@@ -0,0 +1,81 @@
+function Get-AbrVmmAutoNetSetting {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft VMM Auto Network information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Infrastructure InfoLevel set at $($InfoLevel.Infrastructure)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Infrastructure -gt 0) {
+ if ($Vmm) {
+ Write-PScriboMessage "Collecting VMM Auto Network information."
+ Section -Style Heading3 'AutoNetwork Settings' {
+ $VmmServerSettingsInfo = @()
+ foreach ($VmmServerSetting in $Vmm) {
+ $InObj = [Ordered]@{
+ 'Logical Network Creation Enabled' = $VMM.AutomaticLogicalNetworkCreationEnabled
+ 'Virtual Network Creation Enabled' = $VMM.AutomaticVirtualNetworkCreationEnabled
+ 'Logical Network Match' = $VMM.LogicalNetworkMatchOption
+ 'Backup Network Match' = $VMM.BackupLogicalNetworkMatchOption
+ }
+
+ $VmmServerSettingsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Infrastructure -ge 2) {
+ Paragraph "The following sections detail the configuration of the VMM Auto Network Settings."
+ foreach ($VmmServerSetting in $VmmServerSettingsInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($Vmm.FQDN)" {
+ $TableParams = @{
+ Name = "Auto Network Settings - $($Vmm.FQDN)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSetting | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the VMM Auto Network Settings."
+ BlankLine
+ $TableParams = @{
+ Name = "Auto Network Settings - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Logical Network Creation Enabled', 'Virtual Network Creation Enabled', 'Logical Network Match', 'Backup Network Match'
+ ColumnWidths = 25, 25, 25, 25
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSettingsInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmCluster.ps1 b/Src/Private/Get-AbrVmmCluster.ps1
new file mode 100644
index 0000000..459e1af
--- /dev/null
+++ b/Src/Private/Get-AbrVmmCluster.ps1
@@ -0,0 +1,80 @@
+function Get-AbrVmmCluster {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Clusters information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Clusters -gt 0) {
+ Write-PScriboMessage "Collecting VMM Cluster information."
+ if ($ScVmmClusters = Get-SCVMHostCluster) {
+ Section -Style Heading1 'Clusters' {
+ Paragraph "The following table summarises the configuration of the clusters."
+ BlankLine
+ Get-AbrVmmClusterSummary
+ Section -Style Heading3 'Clusters Configuration' {
+ foreach ($ScVmmCluster in ($ScVmmClusters | Where-Object { $_.VirtualizationPlatform -eq 'HyperV' })) {
+ try {
+ $script:ClusterTempPssSession = New-PSSession $ScVmmCluster.Name -Credential $Credential
+ $script:ClusterTempCimSession = New-CimSession $ScVmmCluster.Name -Credential $Credential
+ if ($Cluster = Invoke-Command -Session $script:ClusterTempPssSession { Get-Cluster }) {
+ Section -Style Heading4 $Cluster.Name {
+ # Cluster Server Configuration
+ Get-AbrVmmFOCluster
+ # Cluster Access Permission
+ Get-AbrVmmFOClusterPermission
+ # Cluster Nodes
+ Get-AbrVmmFOClusterNode
+ # Cluster Available Disks
+ Get-AbrVmmFOClusterAvailableDisk
+ # Cluster Fault Domain
+ Get-AbrVmmFOClusterFaultDomain
+ # Cluster Networks
+ Get-AbrVmmFOClusterNetwork
+ # Cluster Quorum
+ Get-AbrVmmFOClusterQuorum
+ #Cluster Resources
+ Get-AbrVmmFOClusterResource
+ #Cluster Shared Volume
+ Get-AbrVmmFOClusterSharedVolume
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ if ($ClusterTempPssSession) {
+ Remove-PSSession $ClusterTempPssSession
+ }
+ if ($ClusterTempCimSession) {
+ Remove-CimSession $ClusterTempCimSession
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmClusterSummary.ps1 b/Src/Private/Get-AbrVmmClusterSummary.ps1
new file mode 100644
index 0000000..3955235
--- /dev/null
+++ b/Src/Private/Get-AbrVmmClusterSummary.ps1
@@ -0,0 +1,58 @@
+function Get-AbrVmmClusterSummary {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Cluster Summary information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Clusters -gt 0) {
+ if ($ScVmmClusters = Get-SCVMHostCluster | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Cluster information."
+ $VmmClusterInfo = @()
+ foreach ($ScVmmCluster in $ScVmmClusters) {
+ $InObj = [Ordered]@{
+ 'Name' = $ScVmmCluster.Name
+ 'Host Group' = $ScVmmCluster.HostGroup
+ 'Cluster Nodes' = $ScVmmCluster.Nodes
+ }
+
+ $VmmClusterInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ $TableParams = @{
+ Name = "Cluster Summary - $($Vmm.FQDN)"
+ List = $false
+ ColumnWidths = 33, 33, 34
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmClusterInfo | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmDBSetting.ps1 b/Src/Private/Get-AbrVmmDBSetting.ps1
new file mode 100644
index 0000000..faa881a
--- /dev/null
+++ b/Src/Private/Get-AbrVmmDBSetting.ps1
@@ -0,0 +1,81 @@
+function Get-AbrVmmDBSetting {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft VMM Database information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Infrastructure InfoLevel set at $($InfoLevel.Infrastructure)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Infrastructure -gt 0) {
+ if ($Vmm) {
+ Write-PScriboMessage "Collecting VMM Database Settings information."
+ Section -Style Heading3 'Database Settings' {
+ $VmmServerSettingsInfo = @()
+ foreach ($VmmServerSetting in $Vmm) {
+ $InObj = [Ordered]@{
+ 'Server Name' = $VMM.DatabaseServerName
+ 'Instance Name' = $VMM.DatabaseInstanceName
+ 'DataBase Name' = $VMM.DatabaseName
+ 'Version' = $VMM.DatabaseVersion
+ }
+
+ $VmmServerSettingsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Infrastructure -ge 2) {
+ Paragraph "The following sections detail the configuration of the VMM Database Settings."
+ foreach ($VmmServerSetting in $VmmServerSettingsInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($Vmm.FQDN)" {
+ $TableParams = @{
+ Name = "Database Settings - $($Vmm.FQDN)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSetting | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the VMM Database Settings."
+ BlankLine
+ $TableParams = @{
+ Name = "Database Settings - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Server Name', 'Instance Name', 'DataBase Name', 'Version'
+ ColumnWidths = 30, 30, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSettingsInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOCluster.ps1 b/Src/Private/Get-AbrVmmFOCluster.ps1
new file mode 100644
index 0000000..042a4b9
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOCluster.ps1
@@ -0,0 +1,62 @@
+function Get-AbrVmmFOCluster {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster configuration
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Server information."
+ }
+
+ process {
+ try {
+ $Clusters = Invoke-Command -Session $ClusterTempPssSession { Get-Cluster | Select-Object -Property * }
+ if ($Clusters) {
+ $OutObj = @()
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $Clusters.Name
+ 'Domain' = $Clusters.Domain
+ 'Shared Volumes Root' = $Clusters.SharedVolumesRoot
+ 'Administrative Access Point' = $Clusters.AdministrativeAccessPoint
+ 'Description' = $Clusters.Description
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+
+ $TableParams = @{
+ Name = "Cluster Servers Settings - $($Clusters.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterAvailableDisk.ps1 b/Src/Private/Get-AbrVmmFOClusterAvailableDisk.ps1
new file mode 100644
index 0000000..125ff00
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterAvailableDisk.ps1
@@ -0,0 +1,64 @@
+function Get-AbrVmmFOClusterAvailableDisk {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Available Disk
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Clusters Available Disk information."
+ }
+
+ process {
+ try {
+ $ClusterAvailableDisks = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterAvailableDisk } | Sort-Object -Property Name
+ if ($ClusterAvailableDisks) {
+ Section -Style Heading3 "Available Disk" {
+ $OutObj = @()
+ foreach ($ClusterAvailableDisk in $ClusterAvailableDisks) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterAvailableDisk.Name
+ 'Number' = $ClusterAvailableDisk.Number
+ 'Size' = ConvertTo-FileSizeString $ClusterAvailableDisk.Size
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ $TableParams = @{
+ Name = "Available Disk - $($Cluster)"
+ List = $false
+ ColumnWidths = 40, 30, 30
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterFaultDomain.ps1 b/Src/Private/Get-AbrVmmFOClusterFaultDomain.ps1
new file mode 100644
index 0000000..766483a
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterFaultDomain.ps1
@@ -0,0 +1,74 @@
+function Get-AbrVmmFOClusterFaultDomain {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Fault Domain
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Clusters Fault Domain information."
+ }
+
+ process {
+ try {
+ $ClusterFaultDomains = Get-ClusterFaultDomain -CimSession $ClusterTempCimSession | Sort-Object -Property Name
+ if ($ClusterFaultDomains) {
+ Section -Style Heading3 "Fault Domain" {
+ $OutObj = @()
+ foreach ($ClusterFaultDomain in $ClusterFaultDomains) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterFaultDomain.Name
+ 'Type' = $ClusterFaultDomain.Type
+ 'Parent Name' = Switch ([string]::IsNullOrEmpty($ClusterFaultDomain.ParentName)) {
+ $true { "--" }
+ $false { $ClusterFaultDomain.ParentName }
+ default { 'Unknown' }
+ }
+ 'Children Names' = Switch ([string]::IsNullOrEmpty($ClusterFaultDomain.ChildrenNames)) {
+ $true { "--" }
+ $false { $ClusterFaultDomain.ChildrenNames }
+ default { 'Unknown' }
+ }
+ 'Location' = $ClusterFaultDomain.Location
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ $TableParams = @{
+ Name = "Fault Domain - $($Cluster)"
+ List = $false
+ ColumnWidths = 20, 20, 20, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterNetwork.ps1 b/Src/Private/Get-AbrVmmFOClusterNetwork.ps1
new file mode 100644
index 0000000..f8676c2
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterNetwork.ps1
@@ -0,0 +1,72 @@
+function Get-AbrVmmFOClusterNetwork {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Networks
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Networks information."
+ }
+
+ process {
+ try {
+ $ClusterNetworks = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterNetwork } | Sort-Object -Property Name
+ if ($ClusterNetworks) {
+ Section -Style Heading3 "Networks" {
+ $OutObj = @()
+ foreach ($ClusterNetwork in $ClusterNetworks) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterNetwork.Name
+ 'State' = $ClusterNetwork.State
+ 'Role' = $ClusterNetwork.Role
+ 'Address' = "$($ClusterNetwork.Address)/$($ClusterNetwork.AddressMask)"
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.'State' -ne 'UP' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ $TableParams = @{
+ Name = "Networks - $($Cluster)"
+ List = $false
+ ColumnWidths = 30, 15, 20, 35
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ # Cluster Network Interfaces
+ Get-AbrVmmFOClusterNetworkInterface
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterNetworkInterface.ps1 b/Src/Private/Get-AbrVmmFOClusterNetworkInterface.ps1
new file mode 100644
index 0000000..fbe3bd0
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterNetworkInterface.ps1
@@ -0,0 +1,70 @@
+function Get-AbrVmmFOClusterNetworkInterface {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Network Interfaces
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Network Interface information."
+ }
+
+ process {
+ try {
+ $ClusterNetworkInterfaces = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterNetworkInterface } | Sort-Object -Property Name
+ if ($ClusterNetworkInterfaces) {
+ Section -Style Heading3 "Interfaces" {
+ $OutObj = @()
+ foreach ($ClusterNetworkInterface in $ClusterNetworkInterfaces) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterNetworkInterface.Name
+ 'Node' = $ClusterNetworkInterface.Node
+ 'Network' = $ClusterNetworkInterface.Network
+ 'State' = $ClusterNetworkInterface.State
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.'State' -ne 'UP' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ $TableParams = @{
+ Name = "Interfaces - $($Cluster)"
+ List = $false
+ ColumnWidths = 30, 25, 30, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterNode.ps1 b/Src/Private/Get-AbrVmmFOClusterNode.ps1
new file mode 100644
index 0000000..052d054
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterNode.ps1
@@ -0,0 +1,91 @@
+function Get-AbrVmmFOClusterNode {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Nodes
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ }
+
+ process {
+ try {
+ $ClusterNodes = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterNode } | Sort-Object -Property Identity
+ if ($ClusterNodes) {
+ Write-PScriboMessage "Collecting Host Cluster Settings information."
+ Section -Style Heading3 'Nodes' {
+ $OutObj = @()
+ foreach ($ClusterNode in $ClusterNodes) {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterNode.Name
+ 'State' = $ClusterNode.State
+ 'Type' = $ClusterNode.Type
+ 'Cluster' = $ClusterNode.Cluster
+ 'Fault Domain' = $ClusterNode.FaultDomain
+ 'Node Weight' = $ClusterNode.NodeWeight
+ 'Model' = $ClusterNode.Model
+ 'Manufacturer' = $ClusterNode.Manufacturer
+ 'Serial Number' = $ClusterNode.SerialNumber
+ 'Status Information' = $ClusterNode.StatusInformation
+ 'Description' = $ClusterNode.Description
+
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ }
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.'State' -ne 'UP' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ if ($InfoLevel.Clusters -ge 2) {
+ Paragraph "The following sections detail the configuration of the Cluster Nodes."
+ foreach ($ClusterNode in $OutObj) {
+ Section -ExcludeFromTOC -Style NOTOCHeading4 "$($ClusterNode.Name)" {
+ $TableParams = @{
+ Name = "Node - $($ClusterNode.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $ClusterNode | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarizes the configuration of the Cluster Nodes."
+ BlankLine
+ $TableParams = @{
+ Name = "Nodes - $($Cluster)"
+ List = $false
+ Columns = 'Name', 'State', 'Type'
+ ColumnWidths = 40, 30, 30
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning "Cluster Nodes Section: $($_.Exception.Message)"
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterPermission.ps1 b/Src/Private/Get-AbrVmmFOClusterPermission.ps1
new file mode 100644
index 0000000..6aaa3b5
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterPermission.ps1
@@ -0,0 +1,64 @@
+function Get-AbrVmmFOClusterPermission {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Permissions
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Permissions Settings information."
+ }
+
+ process {
+ try {
+ $ClusterAccess = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterAccess } | Sort-Object -Property Identity
+ if ($ClusterAccess) {
+ Section -Style Heading3 "Access Permissions" {
+ $OutObj = @()
+ foreach ($Permission in $ClusterAccess) {
+ try {
+ $inObj = [ordered] @{
+ 'Identity' = $Permission.IdentityReference
+ 'Access Control Type' = $Permission.AccessControlType
+ 'Rights' = $Permission.ClusterRights
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ $TableParams = @{
+ Name = "Access Permission - $($Cluster)"
+ List = $false
+ ColumnWidths = 60, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterQuorum.ps1 b/Src/Private/Get-AbrVmmFOClusterQuorum.ps1
new file mode 100644
index 0000000..5b84b82
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterQuorum.ps1
@@ -0,0 +1,66 @@
+function Get-AbrVmmFOClusterQuorum {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Quorum
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Quorum information."
+ }
+
+ process {
+ try {
+ $ClusterQuorums = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterQuorum | Select-Object -Property * } | Sort-Object -Property Name
+ if ($ClusterQuorums) {
+ Section -Style Heading3 "Quorum" {
+ $OutObj = @()
+ foreach ($ClusterQuorum in $ClusterQuorums) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterQuorum.QuorumResource.Name
+ 'In State' = $ClusterQuorum.QuorumType
+ 'Status' = $ClusterQuorum.QuorumResource.State
+ 'Owner Node' = $ClusterQuorum.QuorumResource.OwnerNode
+ 'Resource Type' = $ClusterQuorum.QuorumResource.ResourceType
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ $TableParams = @{
+ Name = "Quorum - $($Cluster)"
+ List = $false
+ ColumnWidths = 20, 20, 20, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterResource.ps1 b/Src/Private/Get-AbrVmmFOClusterResource.ps1
new file mode 100644
index 0000000..82931b1
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterResource.ps1
@@ -0,0 +1,70 @@
+function Get-AbrVmmFOClusterResource {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Resource
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Resource information."
+ }
+
+ process {
+ try {
+ $ClusterResources = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterResource | Select-Object -Property * } | Sort-Object -Property Name
+ if ($ClusterResources) {
+ Section -Style Heading3 "Resource" {
+ $OutObj = @()
+ foreach ($ClusterResource in $ClusterResources) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterResource.Name
+ 'Owner Group' = $ClusterResource.OwnerGroup
+ 'Resource Type' = $ClusterResource.ResourceType
+ 'State' = $ClusterResource.State
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.'State' -notlike 'Online' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ $TableParams = @{
+ Name = "Resource - $($Cluster)"
+ List = $false
+ ColumnWidths = 25, 25, 35, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterSharedVolume.ps1 b/Src/Private/Get-AbrVmmFOClusterSharedVolume.ps1
new file mode 100644
index 0000000..6c4c139
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterSharedVolume.ps1
@@ -0,0 +1,100 @@
+function Get-AbrVmmFOClusterSharedVolume {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Shared Volume
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.5
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Shared Volume information."
+ }
+
+ process {
+ try {
+ # Todo: Add more properties if needed
+ $ClusterSharedVolumes = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterSharedVolume | Select-Object -Property * } | Sort-Object -Property Name
+ if ($ClusterSharedVolumes) {
+ Section -Style Heading3 "Cluster Shared Volume" {
+ $OutObj = @()
+ foreach ($ClusterSharedVolume in $ClusterSharedVolumes) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterSharedVolume.Name
+ 'Owner Node' = $ClusterSharedVolume.OwnerNode
+ 'Shared Volume' = switch ([string]::IsNullOrEmpty($ClusterSharedVolume.SharedVolumeInfo.FriendlyVolumeName)) {
+ $true { "Unknown" }
+ $false { $ClusterSharedVolume.SharedVolumeInfo.FriendlyVolumeName }
+ default { "--" }
+ }
+ 'File System Type' = $ClusterSharedVolume.SharedVolumeInfo.Partition.FileSystem
+ 'Volume Capacity(GB)' = [Math]::Round(($ClusterSharedVolume.SharedVolumeInfo.Partition.Size) / 1gb)
+ 'Free Capacity(GB)' = [Math]::Round(($ClusterSharedVolume.SharedVolumeInfo.Partition.FreeSpace) / 1gb)
+ 'State' = $ClusterSharedVolume.State
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.'State' -notlike 'Online' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ if ($InfoLevel.Clusters -ge 2) {
+ Paragraph "The following sections detail the configuration of the Cluster Shared Volume."
+ foreach ($ClusterSharedVolume in $OutObj) {
+ Section -ExcludeFromTOC -Style NOTOCHeading4 "$($ClusterSharedVolume.Name)" {
+ $TableParams = @{
+ Name = "Cluster Shared Volume - $($ClusterSharedVolume.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $ClusterSharedVolume | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarizes the configuration of the Cluster Shared Volume."
+ BlankLine
+ $TableParams = @{
+ Name = "Cluster Shared Volumes - $($Cluster)"
+ List = $false
+ Columns = 'Name', 'Owner Node', 'Shared Volume', 'State'
+ ColumnWidths = 25, 25, 35, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ #Cluster Shared Volume State
+ Get-AbrVmmFOClusterSharedVolumeState
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmFOClusterSharedVolumeState.ps1 b/Src/Private/Get-AbrVmmFOClusterSharedVolumeState.ps1
new file mode 100644
index 0000000..eb0392d
--- /dev/null
+++ b/Src/Private/Get-AbrVmmFOClusterSharedVolumeState.ps1
@@ -0,0 +1,70 @@
+function Get-AbrVmmFOClusterSharedVolumeState {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft Cluster Shared Volume State
+ .DESCRIPTION
+ Documents the configuration of Microsoft Windows Server in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.5.2
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.Windows
+ #>
+
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Clusters InfoLevel set at $($InfoLevel.Clusters)."
+ Write-PScriboMessage "Collecting Host Cluster Shared Volume State information."
+ }
+
+ process {
+ try {
+ $ClusterSharedVolumeStates = Invoke-Command -Session $ClusterTempPssSession { Get-ClusterSharedVolumeState | Select-Object -Property * } | Sort-Object -Property Name
+ if ($ClusterSharedVolumeStates) {
+ Section -Style Heading4 "Cluster Shared Volume State" {
+ $OutObj = @()
+ foreach ($ClusterSharedVolumeState in $ClusterSharedVolumeStates) {
+ try {
+ $inObj = [ordered] @{
+ 'Name' = $ClusterSharedVolumeState.Name
+ 'Node' = $ClusterSharedVolumeState.Node
+ 'State' = $ClusterSharedVolumeState.StateInfo
+ 'Volume Name' = $ClusterSharedVolumeState.VolumeFriendlyName
+ 'Volume Path' = $ClusterSharedVolumeState.VolumeName
+ }
+ $OutObj += [pscustomobject](ConvertTo-HashToYN $inObj)
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ if ($HealthCheck.Clusters) {
+ $OutObj | Where-Object { $_.State.Value -eq 'Unavailable' } | Set-Style -Style Warning -Property 'State'
+ }
+
+ $TableParams = @{
+ Name = "Cluster Shared Volume State - $($Cluster)"
+ List = $false
+ ColumnWidths = 20, 20, 20, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $OutObj | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmGuestOSProfile.ps1 b/Src/Private/Get-AbrVmmGuestOSProfile.ps1
new file mode 100644
index 0000000..1201aae
--- /dev/null
+++ b/Src/Private/Get-AbrVmmGuestOSProfile.ps1
@@ -0,0 +1,94 @@
+function Get-AbrVmmGuestOSProfile {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Guest OS Profile information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "LibraryTemplates InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ if ($GuestOSProfiles = Get-SCGuestOSProfile | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Guest OS Profiles information."
+ Section -Style Heading3 'Guest OS Profiles' {
+ $VmmGuestOSProfilesInfo = @()
+ foreach ($GuestOSProfile in $GuestOSProfiles) {
+ $InObj = [Ordered]@{
+ 'Name' = $GuestOSProfile.Name
+ 'Full Name' = $GuestOSProfile.FullName
+ 'Operating System' = $GuestOSProfile.OperatingSystem
+ 'Operating System Type' = $GuestOSProfile.OSType
+ 'Computer Name' = $GuestOSProfile.ComputerName
+ 'Product Key' = $GuestOSProfile.ProductKey
+ 'Join Workgroup' = $GuestOSProfile.JoinWorkgroup
+ 'Join Domain RunAs Account' = $GuestOSProfile.JoinDomainRunAsAccount
+ 'Join Domain' = $GuestOSProfile.JoinDomain
+ 'Admin Password RunAsAccount' = $GuestOSProfile.AdminPasswordRunAsAccount
+ 'Org Name' = $GuestOSProfile.OrgName
+ 'Domain Admin' = $GuestOSProfile.DomainAdmin
+ 'DNS Domain Name' = $GuestOSProfile.DNSDomainName
+ 'Sysprep Script' = $GuestOSProfile.SysprepScript
+ 'Domain Join Organizational Unit' = $GuestOSProfile.DomainJoinOrganizationalUnit
+ 'Server Features' = $GuestOSProfile.ServerFeatures.DisplayName
+ 'Description' = $GuestOSProfile.Description
+ }
+
+ $VmmGuestOSProfilesInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.LibraryTemplates -ge 2) {
+ Paragraph "The following sections detail the configuration of the guest os profiles."
+ foreach ($GuestOSProfile in $VmmGuestOSProfilesInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($GuestOSProfile.Name)" {
+ $TableParams = @{
+ Name = "Guest OS Profiles - $($GuestOSProfile.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $GuestOSProfile | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the guest os profiles."
+ BlankLine
+ $TableParams = @{
+ Name = "Guest OS Profiles - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Join Domain', 'Operating System Type', 'Server Features'
+ ColumnWidths = 25, 20, 20, 35
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmGuestOSProfilesInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmHardwareProfile.ps1 b/Src/Private/Get-AbrVmmHardwareProfile.ps1
new file mode 100644
index 0000000..6bf4610
--- /dev/null
+++ b/Src/Private/Get-AbrVmmHardwareProfile.ps1
@@ -0,0 +1,85 @@
+function Get-AbrVmmHardwareProfile {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Hardware Profile information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "LibraryTemplates InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ if ($HardwareProfiles = Get-SCHardwareProfile | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Hardware Profile information."
+ Section -Style Heading3 'Hardware Profiles' {
+ $VmmHardwareProfilesInfo = @()
+ foreach ($HardwareProfile in $HardwareProfiles) {
+ $InObj = [Ordered]@{
+ 'Name' = $HardwareProfile.Name
+ 'CPU Count' = $HardwareProfile.CPUCount
+ 'Memory MB' = $HardwareProfile.Memory
+ 'Secure Boot Enabled' = $HardwareProfile.SecureBootEnabled
+ 'Generation' = $HardwareProfile.Generation
+ 'Checkpoint Type' = $HardwareProfile.CheckpointType
+ 'Capability Profile' = $HardwareProfile.CapabilityProfile
+ 'Monitor Maximum Count' = $HardwareProfile.MonitorMaximumCount
+ }
+
+ $VmmHardwareProfilesInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.LibraryTemplates -ge 2) {
+ Paragraph "The following sections detail the configuration of the hardware profiles."
+ foreach ($HardwareProfile in $VmmHardwareProfilesInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($HardwareProfile.Name)" {
+ $TableParams = @{
+ Name = "Hardware Profiles - $($HardwareProfile.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $HardwareProfile | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the hardware profiles."
+ BlankLine
+ $TableParams = @{
+ Name = "Hardware Profiles - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'CPU Count', 'Memory MB', 'Generation'
+ ColumnWidths = 25, 25, 25, 25
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmHardwareProfilesInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmHost.ps1 b/Src/Private/Get-AbrVmmHost.ps1
new file mode 100644
index 0000000..f18a686
--- /dev/null
+++ b/Src/Private/Get-AbrVmmHost.ps1
@@ -0,0 +1,43 @@
+function Get-AbrVmmHost {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Hosts information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Hosts)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Hosts -gt 0) {
+ Write-PScriboMessage "Collecting VMM Host information."
+ if ($ScVmmHosts = Get-SCVMHost) {
+ Section -Style Heading1 'Hosts' {
+ Paragraph "The following table summarises the configuration of the hosts."
+ BlankLine
+ Get-AbrVmmHostSummary
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmHostSummary.ps1 b/Src/Private/Get-AbrVmmHostSummary.ps1
new file mode 100644
index 0000000..aec437c
--- /dev/null
+++ b/Src/Private/Get-AbrVmmHostSummary.ps1
@@ -0,0 +1,58 @@
+function Get-AbrVmmHostSummary {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Host Summary information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Hosts InfoLevel set at $($InfoLevel.Hosts)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Hosts -gt 0) {
+ if ($VMHosts = Get-SCVMHost -VMMServer $ConnectVmmServer | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Host information."
+ $VmmHostInfo = @()
+ foreach ($VMHost in $VMHosts) {
+ $InObj = [Ordered]@{
+ 'Name' = $VMHost.ComputerName
+ 'Host Group' = $VMHost.OperatingSystem
+ 'Cluster Nodes' = $VMHost.VMHostGroup
+ }
+
+ $VmmHostInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ $TableParams = @{
+ Name = "Host Summary - $($Vmm.FQDN)"
+ List = $false
+ ColumnWidths = 33, 33, 34
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmHostInfo | Table @TableParams
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmInfrastructure.ps1 b/Src/Private/Get-AbrVmmInfrastructure.ps1
new file mode 100644
index 0000000..9bafb51
--- /dev/null
+++ b/Src/Private/Get-AbrVmmInfrastructure.ps1
@@ -0,0 +1,45 @@
+function Get-AbrVmmInfrastructure {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft VMM Server information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Infrastructure InfoLevel set at $($InfoLevel.Infrastructure)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Infrastructure -gt 0) {
+ if ($Vmm) {
+ Write-PScriboMessage "Collecting VMM Server Settings information."
+ Section -Style Heading2 'Infrastructure' {
+ Get-AbrVmmServer
+ Get-AbrVmmDBSetting
+ Get-AbrVmmAutoNetSetting
+ Get-AbrVmmUpdateServer
+ Get-AbrVmmLibraryServer
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmInfrastructureDiagram.ps1 b/Src/Private/Get-AbrVmmInfrastructureDiagram.ps1
new file mode 100644
index 0000000..37161dc
--- /dev/null
+++ b/Src/Private/Get-AbrVmmInfrastructureDiagram.ps1
@@ -0,0 +1,95 @@
+function Get-AbrVmmInfrastructureDiagram {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to built VMM infrastructure diagram
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Generating Infrastructure Diagram for VMM."
+ # Used for DraftMode (Don't touch it!)
+ if ($Options.EnableDiagramDebug) {
+ $EdgeDebug = @{style = 'filled'; color = 'red' }
+ $SubGraphDebug = @{style = 'dashed'; color = 'red' }
+ $NodeDebug = @{color = 'black'; style = 'red'; shape = 'plain' }
+ $NodeDebugEdge = @{color = 'black'; style = 'red'; shape = 'plain' }
+ $IconDebug = $true
+ } else {
+ $EdgeDebug = @{style = 'invis'; color = 'red' }
+ $SubGraphDebug = @{style = 'invis'; color = 'gray' }
+ $NodeDebug = @{color = 'transparent'; style = 'transparent'; shape = 'point' }
+ $NodeDebugEdge = @{color = 'transparent'; style = 'transparent'; shape = 'none' }
+ $IconDebug = $false
+ }
+
+ # Used for setting diagram Theme (Can be change to fits your needs!)
+ if ($Options.DiagramTheme -eq 'Black') {
+ $Edgecolor = 'White'
+ $Fontcolor = 'White'
+ } elseif ($Options.DiagramTheme -eq 'Neon') {
+ $Edgecolor = 'gold2'
+ $Fontcolor = 'gold2'
+ } else {
+ $Edgecolor = '#71797E'
+ $Fontcolor = '#565656'
+ }
+ }
+
+ process {
+ try {
+ if ($VMM) {
+ $UpdateServer = Get-SCUpdateServer
+ $VMMServerAdditionalInfo = [pscustomobject][Ordered]@{
+ 'IP Address' = (Get-NetIPAddress -CimSession $VMMCimSession -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike "127.0.0.1" })[0].IPAddress
+ 'Server Port' = $VMM.Port
+ 'Version' = $VMM.ProductVersion
+ 'Role' = "VMM Server"
+
+ }
+ $VMMDBServerAdditionalInfo = [pscustomobject][Ordered]@{
+ 'Server' = $VMM.DatabaseServerName
+ 'Instance' = $VMM.DatabaseInstanceName
+ 'Server Port' = '1431'
+ 'Version' = $VMM.DatabaseVersion
+ }
+ $VMMUDServerAdditionalInfo = [pscustomobject][Ordered]@{
+ 'IP Address' = Get-NodeIP -Hostname $UpdateServer.Name
+ 'Server Port' = $UpdateServer.Port
+ 'Type' = $UpdateServer.ServerType
+ 'Role' = "Update Server"
+
+ }
+
+ Node VMMserver @{Label = Add-DiaNodeIcon -Name $VMM.FQDN.split(".")[0].ToUpper() -AditionalInfo $VMMServerAdditionalInfo -ImagesObj $Images -IconType "Server" -Align "Center" -IconDebug $IconDebug -FontSize 18; shape = 'plain'; fillColor = 'transparent'; fontsize = 14 }
+
+ Node DBServer @{Label = Add-DiaNodeIcon -Name $VMM.DatabaseName -AditionalInfo $VMMDBServerAdditionalInfo -ImagesObj $Images -IconType "DB_Server" -Align "Center" -IconDebug $IconDebug -FontSize 18; shape = 'plain'; fillColor = 'transparent'; fontsize = 14 }
+
+ Node UpdateServer @{Label = Add-DiaNodeIcon -Name $UpdateServer.Name.split(".")[0].ToUpper() -AditionalInfo $VMMUDServerAdditionalInfo -ImagesObj $Images -IconType "Server" -Align "Center" -IconDebug $IconDebug -FontSize 18; shape = 'plain'; fillColor = 'transparent'; fontsize = 14 }
+
+ Edge -From VMMserver -To DBServer -Attributes @{minlen = 2; label = "DB Connection 1431"; color = $Edgecolor; fontcolor = $Fontcolor; fontsize = 16; style = 'dashed'; penwidth = 2; arrowhead = 'normal'; arrowtail = 'none' }
+
+ Edge -From VMMserver -To UpdateServer -Attributes @{minlen = 2; color = $Edgecolor; fontcolor = $Fontcolor; fontsize = 16; style = 'dashed'; penwidth = 2; arrowhead = 'normal'; arrowtail = 'none' }
+
+ Rank VMMserver, DBServer
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
+ end {}
+
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmLibraryServer.ps1 b/Src/Private/Get-AbrVmmLibraryServer.ps1
new file mode 100644
index 0000000..0c12c7b
--- /dev/null
+++ b/Src/Private/Get-AbrVmmLibraryServer.ps1
@@ -0,0 +1,88 @@
+function Get-AbrVmmLibraryServer {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Library Servers information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "LibraryTemplates InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ if ($VMLibraries = Get-SCLibraryServer | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Library Servers information."
+ Section -Style Heading3 'Library Servers' {
+ $VmmLibraryServersInfo = @()
+ foreach ($VMLibrary in $VMLibraries) {
+ $InObj = [Ordered]@{
+ 'Name' = $VMLibrary.Name
+ 'FQDN' = $VMLibrary.FQDN
+ 'Status' = $VMLibrary.Status
+ 'Domain Name' = $VMLibrary.DomainName
+ 'Library Group' = $VMLibrary.LibraryGroup
+ 'Is Cluster Node?' = $VMLibrary.IsClusterNode
+ 'Is Virtual Cluster Name?' = $VMLibrary.IsVirtualClusterName
+ 'VM Networks' = ($VMLibrary.VMNetworks | ForEach-Object { $_.Name }) -join ', '
+ 'Is Unencrypted File Transfer Enabled?' = $VMLibrary.IsUnencryptedFileTransferEnabled
+ 'Library Server Management Credential' = $VMLibrary.LibraryServerManagementCredential.Name
+ 'Description' = $VMLibrary.Description
+ }
+
+ $VmmLibraryServersInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.LibraryTemplates -ge 2) {
+ Paragraph "The following sections detail the configuration of the library servers."
+ foreach ($LibraryServer in $VmmLibraryServersInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($LibraryServer.Name)" {
+ $TableParams = @{
+ Name = "Library Servers - $($LibraryServer.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $LibraryServer | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the library servers."
+ BlankLine
+ $TableParams = @{
+ Name = "Library Servers - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Description', 'Status'
+ ColumnWidths = 42, 42, 16
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmLibraryServersInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmLibraryShare.ps1 b/Src/Private/Get-AbrVmmLibraryShare.ps1
new file mode 100644
index 0000000..40cf6ff
--- /dev/null
+++ b/Src/Private/Get-AbrVmmLibraryShare.ps1
@@ -0,0 +1,82 @@
+function Get-AbrVmmLibraryShare {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Library Shares information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "LibraryTemplates InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ if ($LibraryShares = Get-SCLibraryShare | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Library Shares information."
+ Section -Style Heading3 'Library Shares' {
+ $VmmLibrarySharesInfo = @()
+ foreach ($LibraryShare in $LibraryShares) {
+ $InObj = [Ordered]@{
+ 'Name' = $LibraryShare.Name
+ 'Library Server' = $LibraryShare.LibraryServer
+ 'Path' = $LibraryShare.Path
+ 'Use Alternate DataStream?' = $LibraryShare.UseAlternateDataStream
+ 'Description' = $LibraryShare.Description
+ }
+
+ $VmmLibrarySharesInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.LibraryTemplates -ge 2) {
+ Paragraph "The following sections detail the configuration of the library shares."
+ foreach ($LibraryShare in $VmmLibrarySharesInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($LibraryShare.Name)" {
+ $TableParams = @{
+ Name = "Library Shares - $($LibraryShare.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $LibraryShare | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the library shares."
+ BlankLine
+ $TableParams = @{
+ Name = "Library Shares - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Library Server', 'Path', 'Use Alternate DataStream?'
+ ColumnWidths = 25, 30, 30, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmLibrarySharesInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmLibraryTemplate.ps1 b/Src/Private/Get-AbrVmmLibraryTemplate.ps1
new file mode 100644
index 0000000..18eb85e
--- /dev/null
+++ b/Src/Private/Get-AbrVmmLibraryTemplate.ps1
@@ -0,0 +1,43 @@
+function Get-AbrVmmLibraryTemplate {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Library and Templates information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ Write-PScriboMessage "Collecting VMM Library and Template information."
+ Section -Style Heading1 'Library and Templates' {
+ Paragraph 'The following section details the library and vm templates configured'
+ Get-AbrVmmLibraryShare
+ Get-AbrVmmVMTemplate
+ Get-AbrVmmGuestOSProfile
+ Get-AbrVmmHardwareProfile
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmLogicalNetwork.ps1 b/Src/Private/Get-AbrVmmLogicalNetwork.ps1
new file mode 100644
index 0000000..ec76ca4
--- /dev/null
+++ b/Src/Private/Get-AbrVmmLogicalNetwork.ps1
@@ -0,0 +1,84 @@
+function Get-AbrVmmLogicalNetwork {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Logical Network information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($LogicalNetworks = Get-SCLogicalNetworkDefinition | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Networking information."
+ Section -Style Heading2 'Logical Networks' {
+ $VmmLogicalNetworksInfo = @()
+ foreach ($LogicalNetwork in $LogicalNetworks) {
+ $InObj = [Ordered]@{
+ 'Name' = $LogicalNetwork.LogicalNetwork
+ 'ID' = $LogicalNetwork.ID
+ 'Isolation Type' = $LogicalNetwork.IsolationType
+ 'Host Groups' = $LogicalNetwork.HostGroups -join ', '
+ }
+
+ $VmmLogicalNetworksInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the logical networks."
+ foreach ($LogicalNetwork in $VmmLogicalNetworksInfo) {
+ Section -Style Heading3 "$($LogicalNetwork.Name)" {
+ $TableParams = @{
+ Name = "Logical Networks - $($LogicalNetwork.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $LogicalNetwork | Table @TableParams
+ Get-AbrVmmVlanSubnet -SubnetVLans ($LogicalNetworks | Where-Object { $_.ID -eq $LogicalNetwork.ID }).SubnetVLans
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the logical networks."
+ BlankLine
+ $TableParams = @{
+ Name = "Logical Networks - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Isolation Type', 'Host Groups'
+ ColumnWidths = 40, 30, 30
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmLogicalNetworksInfo | Table @TableParams
+ Get-AbrVmmVlanSubnet -SubnetVLans $LogicalNetworks.SubnetVLans
+
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmLogicalSwitch.ps1 b/Src/Private/Get-AbrVmmLogicalSwitch.ps1
new file mode 100644
index 0000000..9b767c4
--- /dev/null
+++ b/Src/Private/Get-AbrVmmLogicalSwitch.ps1
@@ -0,0 +1,83 @@
+function Get-AbrVmmLogicalSwitch {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Logical Switch information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($LogicalSwitches = Get-SCLogicalSwitch | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Logical Switches information."
+ Section -Style Heading3 'Logical Switches' {
+ $VmmLogicalSwitchesInfo = @()
+ foreach ($LogicalSwitch in $LogicalSwitches) {
+ $InObj = [Ordered]@{
+ 'Name' = $LogicalSwitch.Name
+ 'ID' = $LogicalSwitch.ID
+ 'Uplink Mode' = $LogicalSwitch.UplinkMode
+ 'Minimum Bandwidth Mode' = $LogicalSwitch.MinimumBandwidthMode
+ 'Enable SR-IOV' = $LogicalSwitch.EnableSriov
+ 'Description' = $LogicalSwitch.Description
+ }
+
+ $VmmLogicalSwitchesInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the logical switches."
+ foreach ($LogicalSwitch in $VmmLogicalSwitchesInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($LogicalSwitch.Name)" {
+ $TableParams = @{
+ Name = "Logical Switches - $($LogicalSwitch.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $LogicalSwitch | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the logical switches."
+ BlankLine
+ $TableParams = @{
+ Name = "Logical Switches - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Uplink Mode', 'Minimum Bandwidth Mode', 'Enable SR-IOV'
+ ColumnWidths = 25, 25, 25, 25
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmLogicalSwitchesInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmNetworkAdapterPortProfile.ps1 b/Src/Private/Get-AbrVmmNetworkAdapterPortProfile.ps1
new file mode 100644
index 0000000..330cd1c
--- /dev/null
+++ b/Src/Private/Get-AbrVmmNetworkAdapterPortProfile.ps1
@@ -0,0 +1,92 @@
+function Get-AbrVmmNetworkAdapterPortProfile {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Network Adapter Port Profiles information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($VirtualNetworkAdapterPortProfiles = Get-SCVirtualNetworkAdapterNativePortProfile | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Network Adapter Port Profiles information."
+ Section -Style Heading3 'Network Adapter Port Profiles' {
+ $VmmNetworkAdapterPortProfileInfo = @()
+ foreach ($VirtualNetworkAdapterPortProfile in $VirtualNetworkAdapterPortProfiles) {
+ $InObj = [Ordered]@{
+ 'Name' = $VirtualNetworkAdapterPortProfile.Name
+ 'Teaming' = $VirtualNetworkAdapterPortProfile.AllowTeaming
+ 'Mac Address Spoofing' = $VirtualNetworkAdapterPortProfile.AllowMacAddressSpoofing
+ 'Ieee Priority Tagging' = $VirtualNetworkAdapterPortProfile.AllowIeeePriorityTagging
+ 'DHCP Guard' = $VirtualNetworkAdapterPortProfile.EnableDHCPGuard
+ 'Guest IP Network Virtualization Updates' = $VirtualNetworkAdapterPortProfile.EnableGuestIPNetworkVirtualizationUpdates
+ 'Router Guard' = $VirtualNetworkAdapterPortProfile.EnableRouterGuard
+ 'Minimum Bandwidth Weight' = $VirtualNetworkAdapterPortProfile.MinimumBandwidthWeight
+ 'Minimum Bandwidth Absolute In Mbps' = $VirtualNetworkAdapterPortProfile.MinimumBandwidthAbsoluteInMbps
+ 'Maximum Bandwidth Absolute In Mbps' = $VirtualNetworkAdapterPortProfile.MaximumBandwidthAbsoluteInMbps
+ 'Enable Vmq' = $VirtualNetworkAdapterPortProfile.EnableVmq
+ 'Enable IPsec Offload' = $VirtualNetworkAdapterPortProfile.EnableIPsecOffload
+ 'Enable Iov' = $VirtualNetworkAdapterPortProfile.EnableIov
+ 'Enable Vrss' = $VirtualNetworkAdapterPortProfile.EnableVrss
+ 'Enable Rdma' = $VirtualNetworkAdapterPortProfile.EnableRdma
+ }
+
+ $VmmNetworkAdapterPortProfileInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the network adapter port profiles."
+ foreach ($VirtualNetworkAdapterPortProfile in $VmmNetworkAdapterPortProfileInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($VirtualNetworkAdapterPortProfile.Name)" {
+ $TableParams = @{
+ Name = "Network Adapter Port Profiles - $($VirtualNetworkAdapterPortProfile.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VirtualNetworkAdapterPortProfile | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the network adapter port profiles."
+ BlankLine
+ $TableParams = @{
+ Name = "Network Adapter Port Profiles - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Teaming', 'Mac Address Spoofing', 'DHCP Guard', 'Router Guard'
+ ColumnWidths = 20, 20, 20, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmNetworkAdapterPortProfileInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmNetworking.ps1 b/Src/Private/Get-AbrVmmNetworking.ps1
new file mode 100644
index 0000000..e73be13
--- /dev/null
+++ b/Src/Private/Get-AbrVmmNetworking.ps1
@@ -0,0 +1,45 @@
+function Get-AbrVmmNetworking {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Networking information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ Write-PScriboMessage "Collecting VMM Networking information."
+ Section -Style Heading1 'Networking' {
+ Paragraph 'The following section contains as built for Logical Networks, Logical Switches, Port Profiles and VM Networks'
+ Get-AbrVmmLogicalNetwork
+ Get-AbrVmmVmNetwork
+ Get-AbrVmmLogicalSwitch
+ Get-AbrVmmUplinkPortProfile
+ Get-AbrVmmNetworkAdapterPortProfile
+ Get-AbrVmmPortClassification
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmPortClassification.ps1 b/Src/Private/Get-AbrVmmPortClassification.ps1
new file mode 100644
index 0000000..2d2448f
--- /dev/null
+++ b/Src/Private/Get-AbrVmmPortClassification.ps1
@@ -0,0 +1,62 @@
+function Get-AbrVmmPortClassification {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Port Classification information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($PortClassifications = Get-SCPortClassification | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Port Classification information."
+ Section -Style Heading3 'Port Classifications' {
+ $VmmPortClassificationInfo = @()
+ foreach ($PortClassification in $PortClassifications) {
+ $InObj = [Ordered]@{
+ 'Name' = $PortClassification.Name
+ 'Description' = $PortClassification.Description
+ }
+
+ $VmmPortClassificationInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ Paragraph "The following table summarises the configuration of the port classification."
+ BlankLine
+ $TableParams = @{
+ Name = "Port Classification - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Description'
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmPortClassificationInfo | Sort-Object -Property Name | Table @TableParams
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmRequiredModule.ps1 b/Src/Private/Get-AbrVmmRequiredModule.ps1
new file mode 100644
index 0000000..b65d10b
--- /dev/null
+++ b/Src/Private/Get-AbrVmmRequiredModule.ps1
@@ -0,0 +1,75 @@
+function Get-AbrVmmRequiredModule {
+ <#
+ .SYNOPSIS
+ Function to check if the required version of VirtualMachineManager is installed
+ .DESCRIPTION
+ Documents the configuration of Veeam VMM in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.1.1
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VMM
+ #>
+ [CmdletBinding()]
+
+ param
+ (
+ [Parameter(Mandatory = $true, ValueFromPipeline = $false)]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $Name,
+
+ [Parameter(Mandatory = $true, ValueFromPipeline = $false)]
+ [ValidateNotNullOrEmpty()]
+ [String]
+ $Version
+ )
+ process {
+ #region: Start Load VirtualMachineManager Module
+ # Loading Module
+ # Make sure PSModulePath includes SCVMM Console
+ #Code taken from @vMarkus_K
+ if (Test-Path "C:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules" ) {
+ $MyModulePath = "C:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules"
+ $env:PSModulePath = $env:PSModulePath + "$([System.IO.Path]::PathSeparator)$MyModulePath"
+ } elseif (Test-Path "D:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules" ) {
+ $MyModulePath = "D:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules"
+ $env:PSModulePath = $env:PSModulePath + "$([System.IO.Path]::PathSeparator)$MyModulePath"
+ } elseif (Test-Path "E:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules" ) {
+ $MyModulePath = "E:\Program Files\Microsoft System Center\Virtual Machine Manager\bin\psModules"
+ $env:PSModulePath = $env:PSModulePath + "$([System.IO.Path]::PathSeparator)$MyModulePath"
+ }
+ if ($Modules = Get-Module -ListAvailable -Name VirtualMachineManager) {
+ try {
+ Write-PScriboMessage "Trying to import Microsoft SCVMM modules."
+ $Modules | Import-Module -WarningAction SilentlyContinue
+ } catch {
+ Write-PScriboMessage -IsWarning "Failed to load Microsoft SCVMM modules"
+ }
+ }
+ Write-PScriboMessage "Identifying Microsoft SCVMM module version."
+ if ($Module = Get-Module -ListAvailable -Name virtualmachinemanager) {
+ try {
+ $script:SCVmmVersion = $Module.Version.ToString()
+ Write-PScriboMessage "Using Microsoft SCVMM powershell module version $($SCVmmVersion)."
+ } catch {
+ Write-PScriboMessage -IsWarning "Failed to get Version from Module"
+ }
+ }
+ # Check if the required version of VMware PowerCLI is installed
+ $RequiredModule = Get-Module -ListAvailable -Name $Name
+ $ModuleVersion = "{0}.{1}" -f $RequiredModule.Version.Major, $RequiredModule.Version.Minor
+ if ($ModuleVersion -eq ".") {
+ throw "$Name $Version or higher is required to run the Microsoft SCVMM As Built Report. Install the Microsoft SCVMM console that provide the required modules."
+ }
+
+ if ($ModuleVersion -lt $Version) {
+ throw "$Name $Version or higher is required to run the Microsoft SCVMM As Built Report. Update the Microsoft SCVMM console that provide the required modules."
+ }
+ }
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmServer.ps1 b/Src/Private/Get-AbrVmmServer.ps1
new file mode 100644
index 0000000..99ef1f6
--- /dev/null
+++ b/Src/Private/Get-AbrVmmServer.ps1
@@ -0,0 +1,84 @@
+function Get-AbrVmmServer {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft VMM Server information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Infrastructure InfoLevel set at $($InfoLevel.Infrastructure)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Infrastructure -gt 0) {
+ if ($Vmm) {
+ Write-PScriboMessage "Collecting VMM Server Settings information."
+ Section -Style Heading2 'VMM Server' {
+ $VmmServerSettingsInfo = @()
+ foreach ($VmmServerSetting in $Vmm) {
+ $InObj = [Ordered]@{
+ 'Server FQDN' = $VmmServerSetting.FQDN
+ 'IP Address' = (Get-NetIPAddress -CimSession $VMMCimSession -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike "127.0.0.1" }).IPAddress
+ 'Product Version' = $VmmServerSetting.ProductVersion
+ 'Server Port' = $VmmServerSetting.Port
+ 'VM Connect Port' = $VmmServerSetting.VMConnectDefaultPort
+ 'VMM Service Account' = $VmmServerSetting.VMMServiceAccount
+ 'VMM High Availability' = $VmmServerSetting.IsHighlyAvailable
+ }
+
+ $VmmServerSettingsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Infrastructure -ge 2) {
+ Paragraph "The following sections detail the configuration of the VMM Server Settings."
+ foreach ($VmmServerSetting in $VmmServerSettingsInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($VmmServerSetting.'Server FQDN')" {
+ $TableParams = @{
+ Name = "VMM Server Settings - $($VmmServerSetting.'Server FQDN')"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSetting | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the VMM Server Settings."
+ BlankLine
+ $TableParams = @{
+ Name = "VMM Server Settings - $($VmmServerSetting.FQDN)"
+ List = $false
+ Columns = 'Server FQDN', 'IP Address', 'Product Version', 'Server Port'
+ ColumnWidths = 45, 20, 20, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmServerSettingsInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmServerConnection.ps1 b/Src/Private/Get-AbrVmmServerConnection.ps1
new file mode 100644
index 0000000..a3da55c
--- /dev/null
+++ b/Src/Private/Get-AbrVmmServerConnection.ps1
@@ -0,0 +1,39 @@
+function Get-AbrVmmServerConnection {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to establish connection to Microsoft SCVMM Server.
+ .DESCRIPTION
+ Documents the configuration of Microsoft SCVMM in Word/HTML/Text formats using PScribo.
+ .NOTES
+ Version: 0.1.1
+ Author: Jonathan Colon
+ Twitter: @jcolonfzenpr
+ Github: rebelinux
+ Credits: Iain Brighton (@iainbrighton) - PScribo module
+
+ .LINK
+ https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM
+ #>
+ [CmdletBinding()]
+ param (
+
+ )
+
+ begin {
+ Write-PScriboMessage "Establishing initial connection to VMM Server: $($System)."
+ }
+
+ process {
+ Write-PScriboMessage "Looking for VMM existing server connection."
+ $script:ConnectVmmServer = Get-SCVMMServer -ComputerName $Server -Credential $Credential -TCPPort $Options.VmmServerPort
+ if ($ConnectVmmServer) {
+ Write-PScriboMessage "Successfully connected to $($System):$($Options.VmmServerPort) Vmm Server."
+ $script:VMM = $ConnectVmmServer
+ $script:VMMCimSession = New-CimSession -ComputerName ($VMM.FQDN) -Credential $Credential
+ } else {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ throw "Failed to connect to Vmm Server Host $($System):$($Options.VmmServerPort) with username $($Credential.USERNAME)"
+ }
+ }
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmUpdateServer.ps1 b/Src/Private/Get-AbrVmmUpdateServer.ps1
new file mode 100644
index 0000000..7cdbac1
--- /dev/null
+++ b/Src/Private/Get-AbrVmmUpdateServer.ps1
@@ -0,0 +1,84 @@
+function Get-AbrVmmUpdateServer {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Update Servers information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Infrastructure InfoLevel set at $($InfoLevel.Infrastructure)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Infrastructure -gt 0) {
+ if ($VMMUpdateServers = Get-SCUpdateServer | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Update Servers information."
+ Section -Style Heading3 'Update Servers' {
+ $VmmUpdateServersInfo = @()
+ foreach ($VMMUpdateServer in $VMMUpdateServers) {
+ $InObj = [Ordered]@{
+ 'Name' = $VMMUpdateServer.Name
+ 'Port' = $VMMUpdateServer.Port
+ 'Is Connection Secure' = $VMMUpdateServer.IsConnectionSecure
+ 'Server Type' = $VMMUpdateServer.ServerType
+ 'Version' = $VMMUpdateServer.Version
+ 'Synchronization Type' = $VMMUpdateServer.SynchronizationType
+ 'UsesProxy' = $VMMUpdateServer.UsesProxy
+ }
+
+ $VmmUpdateServersInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Infrastructure -ge 2) {
+ Paragraph "The following sections detail the configuration of the update server."
+ foreach ($VMMUpdateServer in $VmmUpdateServersInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($VMMUpdateServer.Name)" {
+ $TableParams = @{
+ Name = "Update Servers - $($VMMUpdateServer.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VMMUpdateServer | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the update servers."
+ BlankLine
+ $TableParams = @{
+ Name = "Update Servers - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Port', 'Is Connection Secure', 'Server Type'
+ ColumnWidths = 45, 15, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmUpdateServersInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmUplinkPortProfile.ps1 b/Src/Private/Get-AbrVmmUplinkPortProfile.ps1
new file mode 100644
index 0000000..19e39e5
--- /dev/null
+++ b/Src/Private/Get-AbrVmmUplinkPortProfile.ps1
@@ -0,0 +1,83 @@
+function Get-AbrVmmUplinkPortProfile {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM Uplink Port Profile information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($UplinkPortProfiles = Get-SCNativeUplinkPortProfile | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM Uplink Port Profile information."
+ Section -Style Heading3 'Uplink Port Profiles' {
+ $VmmUplinkPortProfileInfo = @()
+ foreach ($UplinkPortProfile in $UplinkPortProfiles) {
+ $InObj = [Ordered]@{
+ 'Name' = $UplinkPortProfile.Name
+ 'Team Mode' = $UplinkPortProfile.LBFOTeamMode
+ 'Load Balance' = $UplinkPortProfile.LBFOLoadBalancingAlgorithm
+ 'Enabled Network Virtualization' = $UplinkPortProfile.EnableNetworkVirtualization
+ 'Logical Network Definitions' = $UplinkPortProfile.LogicalNetworkDefinitions -join ', '
+ 'Description' = $UplinkPortProfile.Description
+ }
+
+ $VmmUplinkPortProfileInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the uplink port profile."
+ foreach ($UplinkPortProfile in $VmmUplinkPortProfileInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($UplinkPortProfile.Name)" {
+ $TableParams = @{
+ Name = "Uplink Port Profile - $($UplinkPortProfile.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $UplinkPortProfile | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the uplink port profile."
+ BlankLine
+ $TableParams = @{
+ Name = "Uplink Port Profile - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Team Mode', 'Load Balance', 'Enabled Network Virtualization'
+ ColumnWidths = 25, 25, 25, 25
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmUplinkPortProfileInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmVMTemplate.ps1 b/Src/Private/Get-AbrVmmVMTemplate.ps1
new file mode 100644
index 0000000..2aebfba
--- /dev/null
+++ b/Src/Private/Get-AbrVmmVMTemplate.ps1
@@ -0,0 +1,100 @@
+function Get-AbrVmmVMTemplate {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM VM Templates information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "LibraryTemplates InfoLevel set at $($InfoLevel.LibraryTemplates)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.LibraryTemplates -gt 0) {
+ if ($VMTemplates = Get-SCVMTemplate | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM VM Templates information."
+ Section -Style Heading3 'VM Templates' {
+ $VmmVMTemplatesInfo = @()
+ foreach ($VMTemplate in $VMTemplates) {
+ $InObj = [Ordered]@{
+ 'Name' = $VMTemplate.Name
+ 'Operating System' = $VMTemplate.OperatingSystem
+ 'CPU Count' = $VMTemplate.CPUCount
+ 'Product Key' = $VMTemplate.ProductKey
+ 'Memory (MB)' = $VMTemplate.Memory
+ 'JoinWorkgroup' = $VMTemplate.JoinWorkgroup
+ 'OrgName' = $VMTemplate.OrgName
+ 'DomainAdmin' = $VMTemplate.DomainAdmin
+ 'ComputerName' = $VMTemplate.ComputerName
+ 'FullName' = $VMTemplate.FullName
+ 'DNSDomainName' = $VMTemplate.DNSDomainName
+ 'SysprepScript' = $VMTemplate.SysprepScript
+ 'DynamicMemoryEnabled' = $VMTemplate.DynamicMemoryEnabled
+ 'VirtualVideoAdapterEnabled' = $VMTemplate.VirtualVideoAdapterEnabled
+ 'MonitorMaximumCount' = $VMTemplate.MonitorMaximumCount
+ 'MonitorResolutionMaximum' = $VMTemplate.MonitorResolutionMaximum
+ 'UseHardwareAssistedVirtualization' = $VMTemplate.UseHardwareAssistedVirtualization
+ 'Tags' = ($VMTemplate.Tags -join ', ')
+ 'CapabilityProfile' = $VMTemplate.CapabilityProfile
+ 'VirtualizationPlatform' = $VMTemplate.VirtualizationPlatform
+ 'DomainJoinOrganizationalUnit' = $VMTemplate.DomainJoinOrganizationalUnit
+ 'Generation' = $VMTemplate.Generation
+ 'Description' = $VMTemplate.Description
+ }
+
+ $VmmVMTemplatesInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.LibraryTemplates -ge 2) {
+ Paragraph "The following sections detail the configuration of the vm templates."
+ foreach ($VMTemplate in $VmmVMTemplatesInfo) {
+ Section -Style NOTOCHeading4 -ExcludeFromTOC "$($VMTemplate.Name)" {
+ $TableParams = @{
+ Name = "VM Templates - $($VMTemplate.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VMTemplate | Table @TableParams
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the vm templates."
+ BlankLine
+ $TableParams = @{
+ Name = "VM Templates - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Operating System', 'CPU Count', 'Memory (MB)', 'Generation'
+ ColumnWidths = 27, 28, 15, 15, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmVMTemplatesInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmVlanSubnet.ps1 b/Src/Private/Get-AbrVmmVlanSubnet.ps1
new file mode 100644
index 0000000..582a9d6
--- /dev/null
+++ b/Src/Private/Get-AbrVmmVlanSubnet.ps1
@@ -0,0 +1,82 @@
+function Get-AbrVmmVlanSubnet {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM VLANs and Subnets information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory)]
+ $SubnetVLans
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($SubnetVLans) {
+ Write-PScriboMessage "Collecting VMM VLANs and Subnets information."
+ Section -Style Heading2 'Subnets & VLANs' {
+ $VmmVlansSubnetsInfo = @()
+ foreach ($VlansSubnets in ($SubnetVLans | Sort-Object -Property Name)) {
+ $InObj = [Ordered]@{
+ 'Name' = $VlansSubnets.Subnet
+ 'VLAN ID' = $VlansSubnets.VLanID
+ 'Secondary VLan ID' = $VlansSubnets.SecondaryVLanID -join ', '
+ 'Supports DHCP' = $VlansSubnets.SupportsDHCP
+ 'Is Assigned To VM Subnet?' = $VlansSubnets.IsAssignedToVMSubnet
+ 'Enabled' = $VlansSubnets.IsVLanEnabled
+ }
+
+ $VmmVlansSubnetsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ foreach ($VlansSubnets in $VmmVlansSubnetsInfo) {
+ Section -Style NOTOCHeading6 -ExcludeFromTOC "$($VlansSubnets.Name)" {
+ $TableParams = @{
+ Name = "Subnets & VLANs - $($VlansSubnets.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VlansSubnets | Table @TableParams
+ }
+ }
+ } else {
+ $TableParams = @{
+ Name = "Subnets & VLANs - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'VLAN ID'
+ ColumnWidths = 50, 50
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmVlansSubnetsInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmVmNetwork.ps1 b/Src/Private/Get-AbrVmmVmNetwork.ps1
new file mode 100644
index 0000000..1072d70
--- /dev/null
+++ b/Src/Private/Get-AbrVmmVmNetwork.ps1
@@ -0,0 +1,86 @@
+function Get-AbrVmmVmNetwork {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM VM Network information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($VMNetworks = Get-SCVMNetwork | Sort-Object -Property Name) {
+ Write-PScriboMessage "Collecting VMM VM Networks information."
+ Section -Style Heading3 'VM Networks' {
+ $VmmVMNetworksInfo = @()
+ foreach ($VMNetwork in $VMNetworks) {
+ $InObj = [Ordered]@{
+ 'Name' = $VMNetwork.Name
+ 'ID' = $VMNetwork.ID
+ 'Logical Network' = $VMNetwork.LogicalNetwork
+ 'VM Subnets' = $VMNetwork.VMSubnet.Name -join ', '
+ 'Isolation Type' = $VMNetwork.IsolationType
+ 'Enabled' = $VMNetwork.Enabled
+ 'Is Assigned?' = $VMNetwork.IsAssigned
+ 'Description' = $VMNetwork.Description
+ }
+
+ $VmmVMNetworksInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the vm networks."
+ foreach ($VMNetwork in $VmmVMNetworksInfo) {
+ Section -Style Heading4 "$($VMNetwork.Name)" {
+ $TableParams = @{
+ Name = "VM Networks - $($VMNetwork.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VMNetwork | Table @TableParams
+ Get-AbrVmmVmSubnet -VMSubnet ($VMNetworks | Where-Object { $_.ID -eq $VMNetwork.ID }).VMSubnet
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the vm networks."
+ BlankLine
+ $TableParams = @{
+ Name = "VM Networks - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'Logical Network', 'VM Subnets', 'Isolation Type', 'Enabled'
+ ColumnWidths = 20, 20, 20, 25, 15
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmVMNetworksInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmVmSubnet.ps1 b/Src/Private/Get-AbrVmmVmSubnet.ps1
new file mode 100644
index 0000000..597d08b
--- /dev/null
+++ b/Src/Private/Get-AbrVmmVmSubnet.ps1
@@ -0,0 +1,85 @@
+function Get-AbrVmmVmSubnet {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM VM Subnets information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory)]
+ $VMSubnet
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($VMSubnet) {
+ Write-PScriboMessage "Collecting VMM VM Subnets information."
+ Section -Style Heading5 'VM Subnets' {
+ $VmmVlansSubnetsInfo = @()
+ foreach ($VlansSubnets in ($VMSubnet | Sort-Object -Property Name)) {
+ $InObj = [Ordered]@{
+ 'Name' = $VlansSubnets.Name
+ 'ID' = $VlansSubnets.ID
+ 'VM Network' = $VlansSubnets.VMNetwork
+ 'Encrypted' = $VlansSubnets.EncryptionEnabled
+ 'Allows Intra Port Communication' = $VlansSubnets.AllowsIntraPortCommunication
+ }
+
+ $VmmVlansSubnetsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+
+ if ($InfoLevel.Networking -ge 2) {
+ Paragraph "The following sections detail the configuration of the vm subnets."
+ foreach ($VlansSubnets in $VmmVlansSubnetsInfo) {
+ Section -Style Heading6 "$($VlansSubnets.Name)" {
+ $TableParams = @{
+ Name = "VM Subnets - $($VlansSubnets.Name)"
+ List = $true
+ ColumnWidths = 40, 60
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VlansSubnets | Table @TableParams
+ Get-AbrVmmVmVlanSubnet -Name $VlansSubnets.Name -SubnetVLans ($VMSubnet | Where-Object { $_.ID -eq $VlansSubnets.ID }).SubnetVLans
+ }
+ }
+ } else {
+ Paragraph "The following table summarises the configuration of the vm subnets."
+ BlankLine
+ $TableParams = @{
+ Name = "VM Subnets - $($Vmm.FQDN)"
+ List = $false
+ Columns = 'Name', 'VM Network', 'Encrypted', 'Allows Intra Port Communication'
+ ColumnWidths = 25, 25, 25, 25
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmVlansSubnetsInfo | Table @TableParams
+ }
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/Get-AbrVmmVmVlanSubnet.ps1 b/Src/Private/Get-AbrVmmVmVlanSubnet.ps1
new file mode 100644
index 0000000..682b9f8
--- /dev/null
+++ b/Src/Private/Get-AbrVmmVmVlanSubnet.ps1
@@ -0,0 +1,65 @@
+function Get-AbrVmmVmVlanSubnet {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to retrieve Microsoft SCVMM VM VLANs and Subnets information
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: AsBuiltReport
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ param (
+ [Parameter(Mandatory)]
+ $SubnetVLans,
+ [string] $Name
+ )
+
+ begin {
+ Write-PScriboMessage "Networking InfoLevel set at $($InfoLevel.Networking)."
+ }
+
+ process {
+ try {
+ if ($InfoLevel.Networking -gt 0) {
+ if ($SubnetVLans) {
+ Write-PScriboMessage "Collecting VMM VM VLANs and Subnets information."
+ Section -Style NOTOCHeading5 -ExcludeFromTOC 'Subnets & VLANs' {
+ $VmmVlansSubnetsInfo = @()
+ foreach ($VlansSubnets in ($SubnetVLans | Sort-Object -Property Name)) {
+ $InObj = [Ordered]@{
+ 'Name' = $VlansSubnets.Subnet
+ 'VLAN ID' = $VlansSubnets.VLanID
+ 'Supports DHCP' = $VlansSubnets.SupportsDHCP
+ 'Is Assigned To VM Subnet?' = $VlansSubnets.IsAssignedToVMSubnet
+ 'Enabled' = $VlansSubnets.IsVLanEnabled
+ }
+
+ $VmmVlansSubnetsInfo += [pscustomobject](ConvertTo-HashToYN $InObj)
+ }
+ BlankLine
+ $TableParams = @{
+ Name = "Subnets & VLANs - $($Name)"
+ List = $false
+ ColumnWidths = 20, 20, 20, 20, 20
+ }
+ if ($Report.ShowTableCaptions) {
+ $TableParams['Caption'] = "- $($TableParams.Name)"
+ }
+ $VmmVlansSubnetsInfo | Table @TableParams
+ }
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $($_.Exception.Message)
+ }
+ }
+
+ end {}
+}
\ No newline at end of file
diff --git a/Src/Private/SharedUtilsFunctions.ps1 b/Src/Private/SharedUtilsFunctions.ps1
new file mode 100644
index 0000000..5bce849
--- /dev/null
+++ b/Src/Private/SharedUtilsFunctions.ps1
@@ -0,0 +1,512 @@
+function ConvertTo-TextYN {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to convert true or false automatically to Yes or No.
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.3.0
+ Author: LEE DAILEY
+
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ [OutputType([String])]
+ param (
+ [Parameter (
+ Position = 0,
+ Mandatory)]
+ [AllowEmptyString()]
+ [string] $TEXT
+ )
+
+ switch ($TEXT) {
+ "" { "--"; break }
+ " " { "--"; break }
+ $Null { "--"; break }
+ "True" { "Yes"; break }
+ "False" { "No"; break }
+ default { $TEXT }
+ }
+} # end
+
+
+function ConvertTo-FileSizeString {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to convert bytes automatically to GB or TB based on size.
+ .DESCRIPTION
+ .NOTES
+ Version: 0.1.0
+ Author: Jonathan Colon
+ .EXAMPLE
+ .LINK
+ #>
+ [CmdletBinding()]
+ [OutputType([String])]
+ param
+ (
+ [Parameter (
+ Position = 0,
+ Mandatory)]
+ [int64] $Size,
+ [Parameter(
+ Position = 1,
+ Mandatory = $false,
+ HelpMessage = 'Please provide the source space unit'
+ )]
+ [ValidateSet('MB', 'GB', 'TB', 'PB')]
+ [string] $SourceSpaceUnit,
+ [Parameter(
+ Position = 2,
+ Mandatory = $false,
+ HelpMessage = 'Please provide the space unit to output'
+ )]
+ [ValidateSet('MB', 'GB', 'TB', 'PB')]
+ [string] $TargetSpaceUnit,
+ [Parameter(
+ Position = 3,
+ Mandatory = $false,
+ HelpMessage = 'Please provide the value to round the storage unit'
+ )]
+ [int] $RoundUnits = 0
+ )
+
+ if ($SourceSpaceUnit) {
+ return "$([math]::Round(($Size * $("1" + $SourceSpaceUnit) / $("1" + $TargetSpaceUnit)), $RoundUnits)) $TargetSpaceUnit"
+ } else {
+ $Unit = switch ($Size) {
+ { $Size -gt 1PB } { 'PB' ; break }
+ { $Size -gt 1TB } { 'TB' ; break }
+ { $Size -gt 1GB } { 'GB' ; break }
+ { $Size -gt 1Mb } { 'MB' ; break }
+ Default { 'KB' }
+ }
+ return "$([math]::Round(($Size / $("1" + $Unit)), $RoundUnits)) $Unit"
+ }
+} # end
+function Convert-Size {
+ [cmdletbinding()]
+ param(
+ [validateset("Bytes", "KB", "MB", "GB", "TB")]
+ [string]$From,
+ [validateset("Bytes", "KB", "MB", "GB", "TB")]
+ [string]$To,
+ [Parameter(Mandatory = $true)]
+ [double]$Value,
+ [int]$Precision = 4
+ )
+ switch ($From) {
+ "Bytes" { $value = $Value }
+ "KB" { $value = $Value * 1024 }
+ "MB" { $value = $Value * 1024 * 1024 }
+ "GB" { $value = $Value * 1024 * 1024 * 1024 }
+ "TB" { $value = $Value * 1024 * 1024 * 1024 * 1024 }
+ }
+
+ switch ($To) {
+ "Bytes" { return $value }
+ "KB" { $Value = $Value / 1KB }
+ "MB" { $Value = $Value / 1MB }
+ "GB" { $Value = $Value / 1GB }
+ "TB" { $Value = $Value / 1TB }
+
+ }
+
+ return [Math]::Round($value, $Precision, [MidPointRounding]::AwayFromZero)
+}
+
+function Get-PieChart {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to generate PScriboChart pie charts.
+ .DESCRIPTION
+ .NOTES
+ Version: 0.1.0
+ Author: Jonathan Colon
+ .EXAMPLE
+ .LINK
+ #>
+ [CmdletBinding()]
+ [OutputType([System.String])]
+ param
+ (
+ [Parameter (
+ Position = 0,
+ Mandatory)]
+ [System.Array]
+ $SampleData,
+ [String]
+ $ChartName,
+ [String]
+ $XField,
+ [String]
+ $YField,
+ [String]
+ $ChartLegendName,
+ [String]
+ $ChartLegendAlignment = 'Center',
+ [String]
+ $ChartTitleName = ' ',
+ [String]
+ $ChartTitleText = ' ',
+ [int]
+ $Width = 600,
+ [int]
+ $Height = 400,
+ [Switch]
+ $Status,
+ [bool]
+ $ReversePalette = $false
+ )
+
+ $StatusCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#DFF0D0')
+ [System.Drawing.ColorTranslator]::FromHtml('#FFF4C7')
+ [System.Drawing.ColorTranslator]::FromHtml('#FEDDD7')
+ [System.Drawing.ColorTranslator]::FromHtml('#878787')
+ )
+
+ $AbrCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#d5e2ff')
+ [System.Drawing.ColorTranslator]::FromHtml('#bbc9e9')
+ [System.Drawing.ColorTranslator]::FromHtml('#a2b1d3')
+ [System.Drawing.ColorTranslator]::FromHtml('#8999bd')
+ [System.Drawing.ColorTranslator]::FromHtml('#7082a8')
+ [System.Drawing.ColorTranslator]::FromHtml('#586c93')
+ [System.Drawing.ColorTranslator]::FromHtml('#40567f')
+ [System.Drawing.ColorTranslator]::FromHtml('#27416b')
+ [System.Drawing.ColorTranslator]::FromHtml('#072e58')
+ )
+
+ $VeeamCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#ddf6ed')
+ [System.Drawing.ColorTranslator]::FromHtml('#c3e2d7')
+ [System.Drawing.ColorTranslator]::FromHtml('#aacec2')
+ [System.Drawing.ColorTranslator]::FromHtml('#90bbad')
+ [System.Drawing.ColorTranslator]::FromHtml('#77a898')
+ [System.Drawing.ColorTranslator]::FromHtml('#5e9584')
+ [System.Drawing.ColorTranslator]::FromHtml('#458370')
+ [System.Drawing.ColorTranslator]::FromHtml('#2a715d')
+ [System.Drawing.ColorTranslator]::FromHtml('#005f4b')
+ )
+
+ if ($Options.ReportStyle -eq "Veeam") {
+ $BorderColor = 'DarkGreen'
+ } else {
+ $BorderColor = 'DarkBlue'
+ }
+
+ $exampleChart = New-Chart -Name $ChartName -Width $Width -Height $Height -BorderStyle Dash -BorderWidth 1 -BorderColor $BorderColor
+
+ $addChartAreaParams = @{
+ Chart = $exampleChart
+ Name = 'exampleChartArea'
+ AxisXInterval = 1
+ }
+ $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru
+
+ if ($Status) {
+ $CustomPalette = $StatusCustomPalette
+ } elseif ($Options.ReportStyle -eq 'Veeam') {
+ $CustomPalette = $VeeamCustomPalette
+
+ } else {
+ $CustomPalette = $AbrCustomPalette
+ }
+
+ $addChartSeriesParams = @{
+ Chart = $exampleChart
+ ChartArea = $exampleChartArea
+ Name = 'exampleChartSeries'
+ XField = $XField
+ YField = $YField
+ CustomPalette = $CustomPalette
+ ColorPerDataPoint = $true
+ ReversePalette = $ReversePalette
+ }
+
+ $sampleData | Add-PieChartSeries @addChartSeriesParams
+
+ $addChartLegendParams = @{
+ Chart = $exampleChart
+ Name = $ChartLegendName
+ TitleAlignment = $ChartLegendAlignment
+ }
+ Add-ChartLegend @addChartLegendParams
+
+ $addChartTitleParams = @{
+ Chart = $exampleChart
+ ChartArea = $exampleChartArea
+ Name = $ChartTitleName
+ Text = $ChartTitleText
+ Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Segoe Ui', '12', [System.Drawing.FontStyle]::Bold)
+ }
+ Add-ChartTitle @addChartTitleParams
+
+ $TempPath = Resolve-Path ([System.IO.Path]::GetTempPath())
+
+ $ChartImage = Export-Chart -Chart $exampleChart -Path $TempPath.Path -Format "PNG" -PassThru
+
+ $Base64Image = [convert]::ToBase64String((Get-Content $ChartImage -Encoding byte))
+
+ Remove-Item -Path $ChartImage.FullName
+
+ return $Base64Image
+
+} # end
+
+function Get-ColumnChart {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to generate PScriboChart column charts.
+ .DESCRIPTION
+ .NOTES
+ Version: 0.1.0
+ Author: Jonathan Colon
+ .EXAMPLE
+ .LINK
+ #>
+ [CmdletBinding()]
+ [OutputType([System.String])]
+ param
+ (
+ [Parameter (
+ Position = 0,
+ Mandatory)]
+ [System.Array]
+ $SampleData,
+ [String]
+ $ChartName,
+ [String]
+ $AxisXTitle,
+ [String]
+ $AxisYTitle,
+ [String]
+ $XField,
+ [String]
+ $YField,
+ [String]
+ $ChartAreaName,
+ [String]
+ $ChartTitleName = ' ',
+ [String]
+ $ChartTitleText = ' ',
+ [int]
+ $Width = 600,
+ [int]
+ $Height = 400,
+ [Switch]
+ $Status,
+ [bool]
+ $ReversePalette = $false
+ )
+
+ $StatusCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#DFF0D0')
+ [System.Drawing.ColorTranslator]::FromHtml('#FFF4C7')
+ [System.Drawing.ColorTranslator]::FromHtml('#FEDDD7')
+ [System.Drawing.ColorTranslator]::FromHtml('#878787')
+ )
+
+ $AbrCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#d5e2ff')
+ [System.Drawing.ColorTranslator]::FromHtml('#bbc9e9')
+ [System.Drawing.ColorTranslator]::FromHtml('#a2b1d3')
+ [System.Drawing.ColorTranslator]::FromHtml('#8999bd')
+ [System.Drawing.ColorTranslator]::FromHtml('#7082a8')
+ [System.Drawing.ColorTranslator]::FromHtml('#586c93')
+ [System.Drawing.ColorTranslator]::FromHtml('#40567f')
+ [System.Drawing.ColorTranslator]::FromHtml('#27416b')
+ [System.Drawing.ColorTranslator]::FromHtml('#072e58')
+ )
+
+ $VeeamCustomPalette = @(
+ [System.Drawing.ColorTranslator]::FromHtml('#ddf6ed')
+ [System.Drawing.ColorTranslator]::FromHtml('#c3e2d7')
+ [System.Drawing.ColorTranslator]::FromHtml('#aacec2')
+ [System.Drawing.ColorTranslator]::FromHtml('#90bbad')
+ [System.Drawing.ColorTranslator]::FromHtml('#77a898')
+ [System.Drawing.ColorTranslator]::FromHtml('#5e9584')
+ [System.Drawing.ColorTranslator]::FromHtml('#458370')
+ [System.Drawing.ColorTranslator]::FromHtml('#2a715d')
+ [System.Drawing.ColorTranslator]::FromHtml('#005f4b')
+ )
+
+ if ($Options.ReportStyle -eq "Veeam") {
+ $BorderColor = 'DarkGreen'
+ } else {
+ $BorderColor = 'DarkBlue'
+ }
+
+ $exampleChart = New-Chart -Name $ChartName -Width $Width -Height $Height -BorderStyle Dash -BorderWidth 1 -BorderColor $BorderColor
+
+ $addChartAreaParams = @{
+ Chart = $exampleChart
+ Name = $ChartAreaName
+ AxisXTitle = $AxisXTitle
+ AxisYTitle = $AxisYTitle
+ NoAxisXMajorGridLines = $true
+ NoAxisYMajorGridLines = $true
+ AxisXInterval = 1
+ }
+ $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru
+
+ if ($Status) {
+ $CustomPalette = $StatusCustomPalette
+ } elseif ($Options.ReportStyle -eq 'Veeam') {
+ $CustomPalette = $VeeamCustomPalette
+
+ } else {
+ $CustomPalette = $AbrCustomPalette
+ }
+
+ $addChartSeriesParams = @{
+ Chart = $exampleChart
+ ChartArea = $exampleChartArea
+ Name = 'exampleChartSeries'
+ XField = $XField
+ YField = $YField
+ CustomPalette = $CustomPalette
+ ColorPerDataPoint = $true
+ ReversePalette = $ReversePalette
+ }
+
+ $sampleData | Add-ColumnChartSeries @addChartSeriesParams
+
+ $addChartTitleParams = @{
+ Chart = $exampleChart
+ ChartArea = $exampleChartArea
+ Name = $ChartTitleName
+ Text = $ChartTitleText
+ Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Segoe Ui', '12', [System.Drawing.FontStyle]::Bold)
+ }
+ Add-ChartTitle @addChartTitleParams
+
+ $TempPath = Resolve-Path ([System.IO.Path]::GetTempPath())
+
+ $ChartImage = Export-Chart -Chart $exampleChart -Path $TempPath.Path -Format "PNG" -PassThru
+
+ if ($PassThru) {
+ Write-Output -InputObject $chartFileItem
+ }
+
+ $Base64Image = [convert]::ToBase64String((Get-Content $ChartImage -Encoding byte))
+
+ Remove-Item -Path $ChartImage.FullName
+
+ return $Base64Image
+
+} # end
+
+function Get-WindowsTimePeriod {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to generate time period table.
+ .DESCRIPTION
+ .NOTES
+ Version: 0.1.0
+ Author: Jonathan Colon
+ .EXAMPLE
+ .LINK
+ #>
+ [CmdletBinding()]
+ param
+ (
+ [Parameter (
+ Position = 0,
+ Mandatory)]
+ [System.Array]
+ $InputTimePeriod
+ )
+
+ $OutObj = @()
+ $Hours24 = [ordered]@{
+ 0 = 12
+ 1 = 1
+ 2 = 2
+ 3 = 3
+ 4 = 4
+ 5 = 5
+ 6 = 6
+ 7 = 7
+ 8 = 8
+ 9 = 9
+ 10 = 10
+ 11 = 11
+ 12 = 12
+ 13 = 1
+ 14 = 2
+ 15 = 3
+ 16 = 4
+ 17 = 5
+ 18 = 6
+ 19 = 7
+ 20 = 8
+ 21 = 9
+ 22 = 10
+ 23 = 11
+ }
+ $ScheduleTimePeriod = $InputTimePeriod -split '(.{48})' | Where-Object { $_ }
+
+ foreach ($OBJ in $Hours24.GetEnumerator()) {
+
+ $inObj = [ordered] @{
+ 'H' = $OBJ.Value
+ 'Sun' = $ScheduleTimePeriod[0].Split(',')[$OBJ.Key]
+ 'Mon' = $ScheduleTimePeriod[1].Split(',')[$OBJ.Key]
+ 'Tue' = $ScheduleTimePeriod[2].Split(',')[$OBJ.Key]
+ 'Wed' = $ScheduleTimePeriod[3].Split(',')[$OBJ.Key]
+ 'Thu' = $ScheduleTimePeriod[4].Split(',')[$OBJ.Key]
+ 'Fri' = $ScheduleTimePeriod[5].Split(',')[$OBJ.Key]
+ 'Sat' = $ScheduleTimePeriod[6].Split(',')[$OBJ.Key]
+ }
+ $OutObj += $inobj
+ }
+
+ return $OutObj
+
+} # end
+
+# Variable translating Icon to Image Path ($IconPath)
+$script:Images = @{
+}
+
+function ConvertTo-HashToYN {
+ <#
+ .SYNOPSIS
+ Used by As Built Report to convert array content true or false automatically to Yes or No.
+ .DESCRIPTION
+
+ .NOTES
+ Version: 0.2.0
+ Author: Jonathan Colon
+
+ .EXAMPLE
+
+ .LINK
+
+ #>
+ [CmdletBinding()]
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
+ param (
+ [Parameter (Position = 0, Mandatory)]
+ [AllowEmptyString()]
+ [System.Collections.Specialized.OrderedDictionary] $TEXT
+ )
+
+ $result = [ordered] @{}
+ foreach ($i in $TEXT.GetEnumerator()) {
+ try {
+ $result.add($i.Key, (ConvertTo-TextYN $i.Value))
+ } catch {
+ $result.add($i.Key, ($i.Value))
+ }
+ }
+ if ($result) {
+ return $result
+ } else { return $TEXT }
+} # end
\ No newline at end of file
diff --git a/Src/Public/Invoke-AsBuiltReport.Microsoft.SCVMM.ps1 b/Src/Public/Invoke-AsBuiltReport.Microsoft.SCVMM.ps1
index 52bb047..f022637 100644
--- a/Src/Public/Invoke-AsBuiltReport.Microsoft.SCVMM.ps1
+++ b/Src/Public/Invoke-AsBuiltReport.Microsoft.SCVMM.ps1
@@ -5,22 +5,65 @@ function Invoke-AsBuiltReport.Microsoft.SCVMM {
.DESCRIPTION
Documents the configuration of Microsoft SCVMM in Word/HTML/Text formats using PScribo.
.NOTES
- Version: 0.1.0
- Author: Andrew Ramsay
- Twitter:
- Github:
+ Version: 0.1.1
+ Author: AsBuiltReport Organization
+ Twitter: @AsBuiltReport
+ Github: https://github.com/AsBuiltReport
Credits: Iain Brighton (@iainbrighton) - PScribo module
.LINK
https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM
#>
- # Do not remove or add to these parameters
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Scope = "Function")]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "", Scope = "Function")]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope = "Function")]
+ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope = "Function")]
+
+ # Do not remove or add to these parameters
param (
[String[]] $Target,
[PSCredential] $Credential
)
+ #Requires -Version 5.1
+ #Requires -PSEdition Desktop
+ #Requires -RunAsAdministrator
+
+ if ($psISE) {
+ Write-Error -Message "You cannot run this script inside the PowerShell ISE. Please execute it from the PowerShell Command Window."
+ break
+ }
+
+ Get-AbrVmmRequiredModule -Name 'VirtualMachineManager' -Version '1.0'
+
+ Write-Host "- Please refer to the AsBuiltReport.Microsoft.SCVMM github website for more detailed information about this project."
+ Write-Host "- Do not forget to update your report configuration file after each new version release."
+ Write-Host "- Documentation: https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM"
+ Write-Host "- Issues or bug reporting: https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.SCVMM/issues"
+ Write-Host "- This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates."
+
+
+ # Check the version of the dependency modules
+ $ModuleArray = @('AsBuiltReport.Microsoft.SCVMM', 'Diagrammer.Core')
+
+ foreach ($Module in $ModuleArray) {
+ try {
+ $InstalledVersion = Get-Module -ListAvailable -Name $Module -ErrorAction SilentlyContinue | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version
+
+ if ($InstalledVersion) {
+ Write-Host "- $Module module v$($InstalledVersion.ToString()) is currently installed."
+ $LatestVersion = Find-Module -Name $Module -Repository PSGallery -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version
+ if ($InstalledVersion -lt $LatestVersion) {
+ Write-Host " - $Module module v$($LatestVersion.ToString()) is available." -ForegroundColor Red
+ Write-Host " - Run 'Update-Module -Name $Module -Force' to install the latest version." -ForegroundColor Red
+ }
+ }
+ } catch {
+ Write-PScriboMessage -IsWarning $_.Exception.Message
+ }
+ }
+
# Import Report Configuration
$Report = $ReportConfig.Report
$InfoLevel = $ReportConfig.InfoLevel
@@ -29,844 +72,39 @@ function Invoke-AsBuiltReport.Microsoft.SCVMM {
# Used to set values to TitleCase where required
$TextInfo = (Get-Culture).TextInfo
- # Update/rename the $VmmServer variable and build out your code within the ForEach loop. The ForEach loop enables AsBuiltReport to generate an as built configuration against multiple defined targets.
-
#region foreach loop
foreach ($Server in $Target) {
- $ConnectVmmServer = Get-SCVMMServer -ComputerName $Server -Credential $Credential
- Write-Verbose "`VMM Server [$($ConnectVmmServer.name)] connection status is [$($ConnectVmmServer.IsConnected)]"
- Section -Style Heading1 'Virtual Machine Manager Server' {
- $VMM = $ConnectVmmServer
- $vmmCim = New-CimSession -ComputerName ($VMM.FQDN) -Credential $Credential
- $VMMFQDN = $VMM.FQDN
+ # Establish initial connection to VMM server
+ Get-AbrVmmServerConnection
- Paragraph "The following section details the configuration of SCVMM server $VMMFQDN."
-
- Section -Style Heading2 $VMMFQDN {
- $VMMServerSettingsReport = [PSCustomObject]@{
- 'Server FQDN' = $VMMFQDN
- 'IP Address' = (Get-NetIPAddress -CimSession $vmmCim -AddressFamily IPv4 | Where-Object {$_.IPAddress -notlike "127.0.0.1"}).IPAddress
- 'Product Version' = $VMM.ProductVersion
- 'Server Port' = $VMM.Port
- 'VM Connect Port' = $VMM.VMConnectDefaultPort
- 'VMM Service Account' = $VMM.VMMServiceAccount
- 'VMM High Availability' = $VMM.IsHighlyAvailable
- }
- $TableParams = @{
- Name = 'VMM Server Settings'
- List = $true
- ColumnWidths = 50,50
- }
- $VMMServerSettingsReport | Table $TableParams
- }
- Section -Style Heading3 'VMM Database Settings' {
- $VMMDBSettingsReport = [PSCustomObject]@{
- 'DB Server Name' = $VMM.DatabaseServerName
- 'DB Instance Name' = $VMM.DatabaseInstanceName
- 'DB Name' = $VMM.DatabaseName
- 'DB Version' = $VMM.DatabaseVersion
- }
- $VMMDBSettingsReport | Table -Name 'VMM DB Settings' -List -ColumnWidths 50,50
- }
- Section -Style Heading3 'VMM AutoNetwork Settings' {
- $VmmAutoNetworkSettingsReport = [PSCustomObject]@{
- 'Logical Network Creation Enabled' = $VMM.AutomaticLogicalNetworkCreationEnabled
- 'Virtual Network Creation Enabled' = $VMM.AutomaticVirtualNetworkCreationEnabled
- 'Logical Network Match' = $VMM.LogicalNetworkMatchOption
- 'Backup Network Match' = $VMM.BackupLogicalNetworkMatchOption
- }
- $VMMAutoNetworkSettingsReport | Table -Name 'VMM Server Settings' -List -ColumnWidths 50,50
- }
+ # Variable translating Icon to Image Path ($IconPath)
+ $script:Images = @{
+ "AsBuiltReport_LOGO" = "AsBuiltReport_Logo.png"
+ "AsBuiltReport_Signature" = "AsBuiltReport_Signature.png"
+ "Abr_LOGO_Footer" = "AsBuiltReport_Signature.png"
+ "Microsoft_Logo" = "Microsoft_Logo.png"
+ "Server" = "server.png"
+ "DB_Server" = "DB_Server.png"
}
- Section -Style Heading1 'VMM Networking' {
- Paragraph 'The following section contains as built for Logical Networks, Logical Switches, Port Profiles and VM Networks'
- Section -Style Heading2 'Logical Networks' {
- $LogicalNetworks = Get-SCLogicalNetworkDefinition
- Paragraph 'The summary for logical networks is as follws'
- $LogicalNetworks | Select-Object Name,IsolationType | Table -Name 'Logical Network Summary'
- foreach($network in $LogicalNetworks){
- Section -Style Heading3 $network.Name {
- $network | Select-Object Name,IsolationType,@{L="HostGroups";E={$_.HostGroups -Join ","}}| Table -Name $network.Name
- }
- Section -Style Heading3 'Vlans and Subnets' {
- $network.SubnetVLans | Select-Object VLanID,Subnet | Table -Name ($network.Name + "VLANs")
- }
- }
- }
- Section -Style Heading2 'VM Networks' {
- Paragraph 'The following section details VM Networks'
- BlankLine
- $VMNetworks = Get-SCVMNetwork
- $VMNetworkReport = @()
- ForEach($VMNetwork in $VMNetworks) {
- $TempVMNetworkReport = [PSCustomObject]@{
- 'Name' = $VMNetwork.Name
- 'Logical Network' = $VMNetwork.LogicalNetwork
- 'VLAN' = $VMNetwork.VMSubnet.SubnetVLans.VLanID
- 'Subnet' = $VMNetwork.VMSubnet.SubnetVLans.Subnet
- 'Isolation Type' = $VMNetwork.IsolationType
- }
- $VMNetworkReport += $TempVMNetworkReport
- }
- $VMNetworkReport | Table -Name 'VM Networks'
- }
- Section -Style Heading2 'Logical Switches'{
- Paragraph 'The following section contains as-built for Logical Switches'
- $LogicalSwitches = Get-SCLogicalSwitch
- if($LogicalSwitches){
- $LogicalSwitchesReport = @()
- ForEach($TempPssSessionwitch in $LogicalSwitches){
- $TempLogicalSwitchesReport = [PSCustomObject]@{
- 'Name' = $TempPssSessionwitch.Name
- 'Uplink Mode' = $TempPssSessionwitch.UplinkMode
- 'Minimum Bandwidth Mode' = $TempPssSessionwitch.MinimumMandwidthMode
- }
- $LogicalSwitchesReport += $TempLogicalSwitchesReport
- }
- $LogicalSwitchesReport | Table -Name 'LogicalSwitches'
- }
- }
- Section -Style Heading2 'Uplink Port Profiles'{
- Paragraph 'The following section contains as-built for Uplink Port Profiles'
- $UplinkPortProfile = Get-SCNativeUplinkPortProfile
- if($UplinkPortProfle){
- $UplinkReport = $UplinkPortProfile | Select-Object Name, `
- @{L='Team Mode'; E={$_.LBFOTeamMode}}, `
- @{L='Load Balance'; E={$_LBFOLoadBalancingAlgorithm}}
- $UplinkReport | Table -Name 'Uplink Port Profiles'
- }
- }
- Section -Style Heading2 'Network Adapter Port Profiles' {
- Paragraph 'The following section details Virtual Network Adapter Port Profiles'
- $VirtualNetworkAdapterPortProfiles = Get-SCVirtualNetworkAdapterNativePortProfile
- if($VirtualNetworkAdapterPortProfiles){
- foreach($adapter in $VirtualNetworkAdapterPortProfiles){
- Section -Style Heading3 ($adapter.Name) {
- Paragraph ($adapter.Description)
- $AdapterReport = [PSCustomObject]@{
- 'Teaming' = $adapter.AllowTeaming
- 'Mac Address Spoofing' = $adapter.AllowMacAddressSpoofing
- 'Ieee Priority Tagging' = $adapter.AllowIeeePriorityTagging
- 'DHCP Guard' = $adapter.EnableDHCPGuard
- 'Guest IP Network Virtualization Updates' = $adapter.EnableGuestIPNetworkVirtualizationUpdates
- 'Router Guard' = $adapter.EnableRouterGuard
- 'Minimum Bandwidth Weight' = $adapter.MinimumBandwidthWeight
- 'Minimum Bandwidth Absolute In Mbps' = $adapter.MinimumBandwidthAbsoluteInMbps
- 'Maximum Bandwidth Absolute In Mbps' = $adapter.MaximumBandwidthAbsoluteInMbps
- 'Enable Vmq' = $adapter.EnableVmq
- 'Enable IPsec Offload' = $adapter.EnableIPsecOffload
- 'Enable Iov' = $adapter.EnableIov
- 'Enable Vrss' = $adapter.EnableVrss
- 'Enable Rdma' = $adapter.EnableRdma
- }
- $AdapterReport | Table -Name ($adapter.'Name') -List -ColumnWidths 50,50
- }
- }
- }
- }
- Section -Style Heading2 'Port Classifications' {
- Paragraph 'The following section details Port Classifications Configured'
- $PortClassifications = Get-SCPortClassification
- $PortClassifications | Select-Object Name, Description | Table -Name 'Port Classifications'
- }
- }
- Section -Style Heading1 'VMM Library and Templates'{
- Paragraph 'The following section details the Library and VM Templates configured'
- Section -Style Heading2 'VMM Library Servers'{
- Paragraph 'The following table is a summary of the VMM Library servers deployed'
- $VMLibrary = Get-SCLibraryServer
- $VMLibrary | Select-Object ComputerName,Description,Status | Table -Name 'VMM Library Servers'
- }
- Section -Style Heading2 'VMM Library Shares'{
- Paragraph 'The following table details the Library Shares Configured'
- $VMLibraryShares = Get-SCLibraryShare
- $VMLibraryShares | Select-Object Name,Description,LibraryServer | Table -Name 'VMM Library Shares'
- }
- Section -Style Heading2 'VMM Templates'{
- Paragraph 'The following table is a summary of VM Templates Deployed'
- $VMTemplates = Get-SCVMTemplate
- if($VMTemplates){
- $VMTemplates | Select-Object Name,OperatingSystem,Description | Table -Name 'VMM Templates' -ColumnWidths 20,20,60
- }
- }
- Section -Style Heading2 'Guest OS Profiles'{
- Paragraph 'The following table is a summary of the Guest OS Profiles Deployed'
- $GuestOSProfiles = Get-SCGuestOsProfile
- $GuestOSProfiles | Select-Object Name,JoinDomain,OSTYpe | Table -Name 'Guest OS Profiles'
- }
- Section -Style Heading2 'Hardware Profiles'{
- Paragraph 'The following table is a summary of deployed Hardware Profiles'
- $HardwareProfiles = Get-SCHardwareProfile
- if($HardwareProfiles){
- $HardwareProfiles | Select-Object Name,CPUCount,Memory,IsHighlyAvailable,SecureBootEnabled | Table -Name 'Hardware Profiles'
- }
- }
- }
- Section -Style Heading1 'Clusters' {
- Paragraph 'The following section details Hyper-V Clusters'
- $ScVmmClusters = Get-SCVMHostCluster
- #$Clusters = Get-Cluster -Name $TempPssSessioncVmmClusters.Name
- Paragraph 'The following table is the summary of the clusters managed by SCVMM'
- $ClusterSummaryReport = @()
- ForEach($ScVmmCluster in $ScVmmClusters){
- $TempReport = [PSCustomObject]@{
- 'Cluster Name' = $ScVmmCluster.Name
- 'Cluster IP' = $ScVmmCluster.IPAddresses -Join ","
- 'Host Group' = $ScVmmCluster.HostGroup
- 'Cluster Nodes' = $ScVmmCluster.Nodes -Join ","
- }
- $ClusterSummaryReport += $TempReport
- }
- $ClusterSummaryReport | Table -Name 'Cluster Summary' -ColumnWidths 20,10,30,40
- Section -Style Heading2 'Cluster Details' {
- ForEach($ScVmmCluster in $ScVmmClusters){
- $Cluster = Get-Cluster -Name $ScVmmCluster.Name
- Section -Style Heading3 $Cluster.Name {
- #region Cluster Settings
- Section -Style Heading4 'Cluster Settings' {
- $ClusterSettingsTable = [PSCustomObject] @{
- 'Add Evict Delay' = $Cluster.AddEvictDelay
- 'Administrative Access Point' = $Cluster.AdministrativeAccessPoint
- 'Auto Assign Node Site' = $Cluster.AutoAssignNodeSite
- 'Auto Balancer Mode' = $Cluster.AutoBalancerMode
- 'Auto Balancer Level' = $Cluster.AutoBalancerLevel
- 'Backup In Progress' = $Cluster.BackupInProgress
- 'Block Cache Size' = $Cluster.BlockCacheSize
- 'Cluster Service Hang Timeout' = $Cluster.ClusSvcHangTimeout
- 'Cluster Service Regroup Stage Timeout' = $Cluster.ClusSvcRegroupStageTimeout
- 'Cluster Service Regroup Tick In Milliseconds' = $Cluster.ClusSvcRegroupTickInMilliseconds
- 'Cluster Enforced AntiAffinity' = $Cluster.ClusterEnforcedAntiAffinity
- 'Cluster Functional Level' = $Cluster.ClusterFunctionalLevel
- 'Cluster Upgrade Version' = $Cluster.ClusterUpgradeVersion
- 'Cluster Group Wait Delay' = $Cluster.ClusterGroupWaitDelay
- 'Cluster Log Level' = $Cluster.ClusterLogLevel
- 'Cluster Log Size' = $Cluster.ClusterLogSize
- 'Cross Site Delay' = $Cluster.CrossSiteDelay
- 'Cross Site Threshold' = $Cluster.CrossSiteThreshold
- 'Cross Subnet Delay' = $Cluster.CCrossSubnetDelay
- 'Cross Subnet Threshold' = $Cluster.CrossSubnetThreshold
- 'Csv Balancer' = $Cluster.CsvBalancer
- 'Database Read Write Mode' = $Cluster.DatabaseReadWriteMode
- 'Default Network Role' = $Cluster.DefaultNetworkRole
- 'Description' = $Cluster.Description
- 'Domain' = $Cluster.Domain
- 'Drain On Shutdown' = $Cluster.DrainOnShutdown
- 'Dump Policy' = $Cluster.DumpPolicy
- 'Dynamic Quorum' = $Cluster.DynamicQuorum
- 'Enable Shared Volumes' = $Cluster.EnableSharedVolumes
- 'Fix Quorum' = $Cluster.FixQuorum
- 'Group Dependency Timeout' = $Cluster.GroupDependencyTimeout
- 'Hang Recovery Action' = $Cluster.HangRecoveryAction
- 'Ignore Persistent State On Startup' = $Cluster.IgnorePersistentStateOnStartup
- 'Log Resource Controls' = $Cluster.LogResourceControls
- 'Lower Quorum Priority Node Id' = $Cluster.LowerQuorumPriorityNodeId
- 'Message Buffer Length' = $Cluster.MessageBufferLength
- 'Minimum Never Preempt Priority' = $Cluster.MinimumNeverPreemptPriority
- 'Minimum Preemptor Priority' = $Cluster.MinimumPreemptorPriority
- 'Name' = $Cluster.Name
- 'Net ft IPSec Enabled' = $Cluster.NetftIPSecEnabled
- 'Placement Options' = $Cluster.PlacementOptions
- 'Plumb All Cross Subnet Routes' = $Cluster.PlumbAllCrossSubnetRoutes
- 'Preferred Site' = $Cluster.PreferredSite
- 'Prevent Quorum' = $Cluster.PreventQuorum
- 'Quarantine Duration' = $Cluster.QuarantineDuration
- 'Quarantine Threshold' = $Cluster.QuarantineThreshold
- 'Quorum Arbitration Time Max' = $Cluster.QuorumArbitrationTimeMax
- 'Recent Events Reset Time' = $Cluster.RecentEventsResetTime
- 'Request Reply Timeout' = $Cluster.RequestReplyTimeout
- 'Resiliency Default Period' = $Cluster.ResiliencyDefaultPeriod
- 'Resiliency Level' = $Cluster.ResiliencyLevel
- 'Route History Length' = $Cluster.RouteHistoryLength
- 'Same Subnet Delay' = $Cluster.SameSubnetDelay
- 'Same Subnet Threshold' = $Cluster.SameSubnetThreshold
- 'Security Level' = $Cluster.SecurityLevel
- 'Shared Volume Compatible Filters' = $Cluster.SharedVolumeCompatibleFilters
- 'Shared Volume Incompatible Filters' = $Cluster.SharedVolumeIncompatibleFilters
- 'Shared Volume Security Descriptor' = $Cluster.SharedVolumeSecurityDescriptor
- 'Shared Volumes Root' = $Cluster.SharedVolumesRoot
- 'Shared Volume VssWriter Operation Timeout' = $Cluster.SharedVolumeVssWriterOperationTimeout
- 'Shutdown Timeout In Minutes' = $Cluster.ShutdownTimeoutInMinutes
- 'Use Client Access Networks For Shared Volumes' = $Cluster.UseClientAccessNetworksForSharedVolumes
- 'Witness Database Write Timeout' = $Cluster.WitnessDatabaseWriteTimeout
- 'Witness Dynamic Weight' = $Cluster.WitnessDynamicWeight
- 'Witness Restart Interval' = $Cluster.WitnessRestartInterval
- }
- $ClusterSettingsTable | Table -Name 'Cluster Settings' -List -ColumnWidths 50,50
- }
- #end region Cluster Settings
- #Cluster Nodes
- Section -Style Heading4 'Cluster Nodes' {
- Paragraph 'The following Nodes are members of the cluster'
- $ClusterNodes = $Cluster | Get-ClusterNode
- $ClusterNodeReport = @()
- foreach($ClusterNode in $ClusterNodes){
- $Temp = [PSCustomObject] @{
- 'Name' = $ClusterNode.Name
- 'Status Information' = $ClusterNode.StatusInformation
- 'Node Weight' = $ClusterNode.NodeWeight
- 'Model' = $ClusterNode.Model
- 'Manufacturer' = $ClusterNode.Manufacturer
- 'Serial Number' = $ClusterNode.SerialNumber
- }
- $ClusterNodeReport += $Temp
- }
- $ClusterNodeReport | Table -Name 'Cluster Nodes'
- }
- #Cluster Quorum
- Section -Style Heading4 'Cluster Quorum' {
- Paragraph 'The following Cluster Quorum Settings are applied'
- $ClusterQuorum = $Cluster | Get-ClusterQuorum
- $QuorumReport = [PSCustomObject] @{
- 'Name' = $ClusterQuorum.QuorumResource.Name
- 'State' = $ClusterQuorum.QuorumResource.State
- 'Owner Node' = $ClusterQuorum.QuorumResource.OwnerNode
- 'ResourceType' = $ClusterQuorum.QuorumResource.ResourceType
- }
- $QuorumReport | Table -Name 'Cluster Quorum Settings' -List -ColumnWidths 50,50
- }
- #Cluster Networks
- Section -Style Heading4 'Cluster Networks'{
- Paragraph 'The following Cluster Networks are configured'
- $ClusterNetworks = $Cluster | Get-ClusterNetwork
- $ClusterNetworkReport = @()
- foreach($ClusterNetwork in $ClusterNetworks){
- $TempClusterNetwork = [PSCustomObject]@{
- 'Name' = $ClusterNetwork.Name
- 'Description' = $ClusterNetwork.Description
- 'Role' = $ClusterNetwork.Role
- 'Network Address' = $ClusterNetwork.Address
- 'State' = $ClusterNetwork.State
- }
- $ClusterNetworkReport += $TempClusterNetwork
- }
- $ClusterNetworkReport | Table -Name 'Cluster Networks'
- #Cluster Network Interfaces
- Section -Style Heading5 'Cluster Network Interfaces'{
- Paragraph 'The following table details the network interfaces nodes use in the cluster'
- $ClusterNetworkInterfaces = $Cluster | Get-ClusterNetworkInterface
- $ClusterInterfaceReport = @()
- foreach($Interface in $ClusterNetworkInterfaces){
- $TempInterfaceReport = [PSCustomObject]@{
- 'Node' = $Interface.Node
- 'Address' = $Interface.Address
- 'Network' = $Interface.Network
- 'Interface Name' = $Interface.Name
- }
- $ClusterInterfaceReport += $TempInterfaceReport
- }
- $ClusterInterfaceReport | Table -Name 'Cluster Interfaces'
- }
- }
- #Cluster Storage
- Section -Style Heading4 'Cluster Shared Volumes'{
- Paragraph 'The following Cluster Shared Volumes are Configure'
- $ClusterVolumes = $Cluster | Get-ClusterSharedVolume
- if($ClusterVolumes){
- $ClusterVolumeReport = @()
- foreach($ClusterVolume in $ClusterVolumes){
- $TempClusterVolume = [PSCustomObject] @{
- 'Name' = $ClusterVolume.Name
- 'State' = $ClusterVolume.State
- 'File System Type' = $ClusterVolume.SharedVolumeInfo.Partition.FileSystem
- 'Volume Capacity(GB)' = [Math]::Round(($ClusterVolume.SharedVolumeInfo.Partition.Size)/1gb)
- 'Free Fapacity(GB)' = [Math]::Round(($ClusterVolume.SharedVolumeInfo.Partition.FreeSpace)/1gb)
- }
- $ClusterVolumeReport += $TempClusterVolume
- }
- $ClusterVolumeReport | Table -Name 'Cluster Volumes'
- }
- }
- #Cluster Hyper-V Replica Broker
- }
- }
- }
- }
- Section -Style Heading1 'Hyper-V Hosts'{
- Paragraph 'The following table details the Hyper-V hosts'
- $VMHosts = Get-SCVMHost -VMMServer $ConnectVmmServer | Sort-Object Name
- $VMHostSummary = $VMHosts | Select-Object ComputerName,OperatingSystem,VMHostGroup
- $VMHostSummary | Table -Name 'VM Host Summary'
- #Host Summary
- ForEach($VMHost in $VMHosts){
- #Create Remote Sessions
- $TempPssSession = New-PSSession $VMHost.Name -Credential $Credential
- $TempCimSession = New-CimSession $VMHost.Name -Credential $Credential
- #Get Server Data using WinRM
- $HostInfo = Invoke-Command -Session $TempPssSession {Get-ComputerInfo}
- $HostCPU = Get-CimInstance -CimSession $TempCimSession -ClassName Win32_Processor
- $HostComputer = Get-CimInstance -CimSession $TempCimSession -ClassName Win32_ComputerSystem
- $HostBIOS = Get-CimInstance -CimSession $TempCimSession -ClassName Win32_Bios
- $HostLicense = Get-CimInstance -CimSession $TempCimSession -query 'Select * from SoftwareLicensingProduct'| Where-Object {$_.LicenseStatus -eq 1}
- $HotFixes = Get-CimInstance -CimSession $TempCimSession -ClassName Win32_QuickFixEngineering
- Section -Style Heading2 ($VMHost.Name){
- #Host Hardware
- Section -Style Heading3 'Host Hardware Settings'{
- Paragraph 'The following section details hardware settings for the host'
- $HostHardware = [PSCustomObject] @{
- 'Manufacturer' = $HostComputer.Manufacturer
- 'Model' = $HostComputer.Model
- 'Product ID' = $HostComputer.SystemSKUNumber
- 'Serial Number' = $HostBIOS.SerialNumber
- 'BIOS Version' = $HostBIOS.Version
- 'Processor Manufacturer' = $HostCPU[0].Manufacturer
- 'Processor Model' = $HostCPU[0].Name
- 'Number of Processors' = $HostCPU.Length
- 'Number of CPU Cores' = $HostCPU[0].NumberOfCores
- 'Number of Logical Cores' = $HostCPU[0].NumberOfLogicalProcessors
- 'Physical Memory (GB)' = [Math]::Round($HostComputer.TotalPhysicalMemory/1Gb)
- }
- $HostHardware | Table -Name 'Host Hardware Specifications' -List -ColumnWidths 50,50
- }
- #Host OS
- Section -Style Heading3 'Host OS' {
- Paragraph 'The following settings details host OS Settings'
- Section -Style Heading4 'OS Configuration'{
- Paragraph 'The following section details hos OS configuration'
- $HostOSReport = [PSCustomObject] @{
- 'Windows Product Name' = $HostInfo.WindowsProductName
- 'Windows Version' = $HostInfo.WindowsCurrentVersion
- 'Windows Build Number' = $HostInfo.OsVersion
- 'Windows Install Type' = $HostInfo.WindowsInstallationType
- 'AD Domain' = $HostInfo.CsDomain
- 'Windows Installation Date' = $HostInfo.OsInstallDate
- 'Time Zone' = $HostInfo.TimeZone
- 'License Type' = $HostLicense.ProductKeyChannel
- 'Partial Product Key' = $HostLicense.PartialProductKey
- }
- $HostOSReport | Table -Name 'Host OS Settings' -List -ColumnWidths 50,50
- }
- Section -Style Heading4 'Host Hotfixes'{
- Paragraph 'The following table details the OS Hotfixes installed'
- $HotFixReport = @()
- Foreach($HotFix in $HotFixes){
- $TempHotFix = [PSCustomObject] @{
- 'Hotfix ID' = $HotFix.HotFixID
- 'Description' = $HotFix.Description
- 'Installation Date' = $HotFix.InstalledOn
- }
- $HotFixReport += $TempHotFix
- }
- $HotFixReport | Table -Name 'HostFixes Installed' -ColumnWidths 10,70,20
- }
- Section -Style Heading4 'Host Drivers'{
- Paragraph 'The following section details host drivers'
- Invoke-Command -Session $TempPssSession {Import-Module DISM}
- $HostDriversList = Invoke-Command -Session $TempPssSession {Get-WindowsDriver -Online}
- $HostDriverReport = @()
- ForEach($HostDriver in $HostDriversList){
- $TempDriver = [PSCustomObject] @{
- 'Class Description' = $HostDriver.ClassDescription
- 'Provider Name' = $HostDriver.ProviderName
- 'Driver Version' = $HostDriver.Version
- 'Version Date' = $HostDriver.Date
- }
- $HostDriverReport += $TempDriver
- }
- $HostDriverReport | Table -Name 'Host Drivers' -ColumnWidths 30,30,20,20
- }
- #Host Roles and Features
- Section -Style Heading4 'Roles and Features' {
- Paragraph 'The following settings details host roles and features installed'
- $HostRolesAndFeatures = Get-WindowsFeature -ComputerName $VMHost.Name -Credential $Credential | Where-Object {$_.Installed -eq $True}
- [array]$HostRolesAndFeaturesReport = @()
- ForEach($HostRoleAndFeature in $HostRolesAndFeatures){
- $TempHostRolesAndFeaturesReport = [PSCustomObject] @{
- 'Feature Name' = $HostRoleAndFeature.DisplayName
- 'Feature Type' = $HostRoleAndFeature.FeatureType
- 'Description' = $HostRoleAndFeature.Description
- }
- $HostRolesAndFeaturesReport += $TempHostRolesAndFeaturesReport
- }
- $HostRolesAndFeaturesReport | Table -Name 'Roles and Features' -ColumnWidths 20,10,70
- }
- #Host 3rd Party Applications
- Section -Style Heading4 'Installed Applications' {
- Paragraph 'The following settings details applications listed in Add/Remove Programs'
- [array]$AddRemove = @()
- $AddRemove += Invoke-Command -Session $TempPssSession {Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*}
- $AddRemove += Invoke-Command -Session $TempPssSession {Get-ItemProperty HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*}
- [array]$AddRemoveReport = @()
- ForEach($App in $AddRemove){
- $TempAddRemoveReport = [PSCustomObject]@{
- 'Application Name' = $App.DisplayName
- 'Publisher' = $App.Publisher
- 'Version' = $App.Version
- 'Install Date' = $App.InstallDate
- }
- $AddRemoveReport += $TempAddRemoveReport
- }
- $AddRemoveReport | Where-Object {$_.'Application Name' -notlike $null} | Sort-Object 'Application Name' | Table -Name 'Installed Applications'
- }
- }
- #Local Users and Groups
- Section -Style Heading3 'Local Users and Groups'{
- Paragraph 'The following section details local users and groups configured'
- Section -Style Heading4 'Local Users'{
- Paragraph 'The following table details local users'
- $LocalUsers = Invoke-Command -Session $TempPssSession {Get-LocalUser}
- $LocalUsersReport = @()
- ForEach($LocalUser in $LocalUsers){
- $TempLocalUsersReport = [PSCustomObject]@{
- 'User Name' = $LocalUser.Name
- 'Description' = $LocalUser.Description
- 'Account Enabled' = $LocalUser.Enabled
- 'Last Logon Date' = $LocalUser.LastLogon
- }
- $LocalUsersReport += $TempLocalUsersReport
- }
- $LocalUsersReport | Table -Name 'Local Users' -ColumnWidths 20,40,10,30
- }
- Section -Style Heading4 'Local Groups'{
- Paragraph 'The following table details local groups configured'
- $LocalGroups = Invoke-Command -Session $TempPssSession {Get-LocalGroup}
- $LocalGroupsReport = @()
- ForEach($LocalGroup in $LocalGroups){
- $TempLocalGroupsReport = [PSCustomObject]@{
- 'Group Name' = $LocalGroup.Name
- 'Description' = $LocalGroup.Description
- }
- $LocalGroupsReport += $TempLocalGroupsReport
- }
- $LocalGroupsReport | Table -Name 'Local Group Summary'
- }
- Section -Style Heading4 'Local Administrators'{
- Paragraph 'The following table lists Local Administrators'
- $LocalAdmins = Invoke-Command -Session $TempPssSession {Get-LocalGroupMember -Name 'Administrators'}
- $LocalAdminsReport = @()
- ForEach($LocalAdmin in $LocalAdmins){
- $TempLocalAdminsReport = [PSCustomObject]@{
- 'Account Name' = $LocalAdmin.Name
- 'Account Type' = $LocalAdmin.ObjectClass
- 'Account Source' = $LocalAdmin.PrincipalSource
- }
- $LocalAdminsReport += $TempLocalAdminsReport
- }
- $LocalAdminsReport | Table -Name 'Local Administrators'
- }
- }
- #Host Firewall
- Section -Style Heading3 'Windows Firewall'{
- Paragraph 'The Following table is a the Windowss Firewall Summary'
- $NetFirewallProfile = Get-NetFirewallProfile -CimSession $TempCimSession
- $NetFirewallProfileReport = @()
- Foreach($FirewallProfile in $NetFireWallProfile){
- $TempNetFirewallProfileReport = [PSCustomObject]@{
- 'Profile' = $FirewallProfile.Name
- 'Profile Enabled' = $FirewallProfile.Enabled
- 'Inbound Action' = $FirewallProfile.DefaultInboundAction
- 'Outbound Action' = $FirewallProfile.DefaultOutboundAction
- }
- $NetFirewallProfileReport += $TempNetFirewallProfileReport
- }
- $NetFirewallProfileReport | Table -Name 'Windows Firewall Profiles'
- }
- #Host Networking
- Section -Style Heading3 'Host Networking'{
- Paragraph 'The following section details Host Network Configuration'
- Section -Style Heading4 'Network Adapters'{
- Paragraph 'The Following table details host network adapters'
- $HostAdapters = Invoke-Command -Session $TempPssSession {Get-NetAdapter}
- $HostAdaptersReport = @()
- ForEach($HostAdapter in $HostAdapters){
- $TempHostAdaptersReport = [PSCustomObject]@{
- 'Adapter Name' = $HostAdapter.Name
- 'Adapter Description' = $HostAdapter.InterfaceDescription
- 'Mac Address' = $HostAdapter.MacAddress
- 'Link Speed' = $HostAdapter.LinkSpeed
- }
- $HostAdaptersReport += $TempHostAdaptersReport
- }
- $HostAdaptersReport | Table -Name 'Network Adapters' -ColumnWidths 20,40,20,20
- }
- Section -Style Heading4 'IP Addresses'{
- Paragraph 'The following table details IP Addresses assigned to hosts'
- $NetIPs = Invoke-Command -Session $TempPssSession {Get-NetIPConfiguration | Where-Object -FilterScript {($_.NetAdapter.Status -Eq "Up")}}
- $NetIpsReport = @()
- ForEach($NetIp in $NetIps){
- $TempNetIpsReport = [PSCustomObject]@{
- 'Interface Name' = $NetIp.InterfaceAlias
- 'Interface Description' = $NetIp.InterfaceDescription
- 'IPv4 Addresses' = $NetIp.IPv4Address -Join ","
- 'Subnet Mask' = $NetIp.IPv4Address[0].PrefixLength
- 'IPv4 Gateway' = $NetIp.IPv4DefaultGateway.NextHop
- }
- $NetIpsReport += $TempNetIpsReport
- }
- $NetIpsReport | Table -Name 'Net IP Addresses'
- }
- Section -Style Heading4 'DNS Client'{
- Paragraph 'The following table details the DNS Seach Domains'
- $DnsClient = Invoke-Command -Session $TempPssSession {Get-DnsClientGlobalSetting}
- $DnsClientReport = [PSCustomObject]@{
- 'DNS Suffix' = $DnsClient.SuffixSearchList -Join ","
- }
- $DnsClientReport | Table -Name "DNS Seach Domain"
- }
- Section -Style Heading4 'DNS Servers'{
- Paragraph 'The following table details the DNS Server Addresses Configured'
- $DnsServers = Invoke-Command -Session $TempPssSession {Get-DnsClientServerAddress -AddressFamily IPv4 | `
- Where-Object {$_.ServerAddresses -notlike $null -and $_.InterfaceAlias -notlike "*isatap*"}}
- $DnsServerReport = @()
- ForEach($DnsServer in $DnsServers){
- $TempDnsServerReport = [PSCustomObject]@{
- 'Interface' = $DnsServer.InterfaceAlias
- 'Server Address' = $DnsServer.ServerAddresses -Join ","
- }
- $DnsServerReport += $TempDnsServerReport
- }
- $DnsServerReport | Table -Name 'DNS Server Addresses' -ColumnWidths 40,60
- }
- $NetworkTeamCheck = Invoke-Command -Session $TempPssSession {Get-NetLbfoTeam}
- if($NetworkTeamCheck){
- Section -Style Heading4 'Network Team Interfaces'{
- Paragraph 'The following table details Network Team Interfaces'
- $NetTeams = Invoke-Command -Session $TempPssSession {Get-NetLbfoTeam}
- $NetTeamReport = @()
- ForEach($NetTeam in $NetTeams){
- $TempNetTeamReport = [PSCustomObject]@{
- 'Team Name' = $NetTeam.Name
- 'Team Mode' = $NetTeam.tm
- 'Load Balancing' = $NetTeam.lba
- 'Network Adapters' = $NetTeam.Members -Join ","
- }
- $NetTeamReport += $TempNetTeamReport
- }
- $NetTeamReport | Table -Name 'Network Team Interfaces'
- }
- }
- Section -Style Heading4 'Network Adapter MTU'{
- Paragraph 'The following table lists Network Adapter MTU settings'
- $NetMtus = Invoke-Command -Session $TempPssSession {Get-NetAdapterAdvancedProperty | Where-Object {$_.DisplayName -eq 'Jumbo Packet'}}
- $NetMtuReport = @()
- ForEach($NetMtu in $NetMtus){
- $TempNetMtuReport = [PSCustomObject]@{
- 'Adapter Name' = $NetMtu.Name
- 'MTU Size' = $NetMtu.DisplayValue
- }
- $NetMtuReport += $TempNetMtuReport
- }
- $NetMtuReport | Table -Name 'Network Adapter MTU' -ColumnWidths 50,50
- }
- }
- #Host Storage
- Section -Style Heading3 'Host Storage'{
- Paragraph 'The following section details the storage configuration of the host'
- #Local Disks
- Section -Style Heading4 'Local Disks'{
- Paragraph 'The following table details physical disks installed in the host'
- $HostDisks = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-Disk | Where-Object -FilterScript {$_.BusType -Eq "RAID" -or $_.BusType -eq "File Backed Virtual" -or $_.BusType -eq "SATA" -or $_.BusType -eq "USB"}}
- $LocalDiskReport = @()
- ForEach($Disk in $HostDisks){
- $TempLocalDiskReport = [PSCustomObject]@{
- 'Disk Number' = $Disk.Number
- 'Model' = $Disk.Model
- 'Serial Number' = $Disk.SerialNumber
- 'Partition Style' = $Disk.PartitionStyle
- 'Disk Size(GB)' = [Math]::Round($Disk.Size/1Gb)
- }
- $LocalDiskReport += $TempLocalDiskReport
- }
- $LocalDiskReport | Sort-Object -Property 'Disk Number' | Table -Name 'Local Disks'
- }
- #SAN Disks
- $SanDisks = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-Disk | Where-Object {$_.BusType -Eq "iSCSI"}}
- if($SanDisks){
- Section -Style Heading4 'SAN Disks'{
- Paragraph 'The following section details SAN disks connected to the host'
- $SanDiskReport = @()
- ForEach($Disk in $SanDisks){
- $TempSanDiskReport = [PSCustomObject]@{
- 'Disk Number' = $Disk.Number
- 'Model' = $Disk.Model
- 'Serial Number' = $Disk.SerialNumber
- 'Partition Style' = $Disk.PartitionStyle
- 'Disk Size(GB)' = [Math]::Round($Disk.Size/1Gb)
- }
- $SanDiskReport += $TempSanDiskReport
- }
- $SanDiskReport | Sort-Object -Property 'Disk Number' | Table -Name 'Local Disks'
- }
- }
- #Local Volumes
- Section -Style Heading4 'Host Volumes'{
- Paragraph 'The following section details local volumes on the host'
- $HostVolumes = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-Volume}
- $HostVolumeReport = @()
- ForEach($HostVolume in $HostVolumes){
- $TempHostVolumeReport = [PSCustomObject]@{
- 'Drive Letter' = $HostVolume.DriveLetter
- 'File System Label' = $HostVolume.FileSystemLabel
- 'File System' = $HostVolume.FileSystem
- 'Size (GB)' = [Math]::Round($HostVolume.Size/1gb)
- 'Free Space(GB)' = [Math]::Round($HostVolume.SizeRemaining/1gb)
- }
- $HostVolumeReport += $TempHostVolumeReport
- }
- $HostVolumeReport | Sort-Object 'Drive Letter' | Table -Name 'Host Volumes'
- }
- #iSCSI Configuration
- $iSCSICheck = Invoke-Command -Session $TempPssSession {Get-Service -Name 'MSiSCSI'}
- if($iSCSICheck.Status -eq 'Running'){
- Section -Style Heading4 'Host iSCSI Settings'{
- Paragraph 'The following section details the iSCSI configuration for the host'
- $HostInitiator = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-InitiatorPort}
- Paragraph 'The following table details the hosts iSCI IQN'
- $HostInitiator | Select-Object NodeAddress | Table -Name 'Host IQN'
- Section -Style Heading5 'iSCSI Target Server'{
- Paragraph 'The following table details iSCSI Target Server details'
- $HostIscsiTargetServer = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-IscsiTargetPortal}
- $HostIscsiTargetServer | Select-Object TargetPortalAddress,TargetPortalPortNumber | Table -Name 'iSCSI Target Servers' -ColumnWidths 50,50
- }
- Section -Style Heading5 'iSCIS Target Volumes'{
- Paragraph 'The following table details iSCSI target volumes'
- $HostIscsiTargetVolumes = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-IscsiTarget}
- $HostIscsiTargetVolumeReport = @()
- ForEach($HostIscsiTargetVolume in $HostIscsiTargetVolumes){
- $TempHostIscsiTargetVolumeReport = [PSCustomObject]@{
- 'Node Address' = $HostIscsiTargetVolume.NodeAddress
- 'Node Connected' = $HostIscsiTargetVolume.IsConnected
- }
- $HostIscsiTargetVolumeReport += $TempHostIscsiTargetVolumeReport
- }
- $HostIscsiTargetVolumeReport | Table -Name 'iSCSI Target Volumes' -ColumnWidths 80,20
- }
- Section -Style Heading5 'iSCSI Connections'{
- Paragraph 'The following table details iSCSI Connections'
- $HostIscsiConnections = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-IscsiConnection}
- $HostIscsiConnections | Select-Object ConnectionIdentifier,InitiatorAddress,TargetAddress | Table -Name 'iSCSI Connections'
- }
- }
- }
- #MPIO Configuration
- $MPIOInstalledCheck = Invoke-Command -Session $TempPssSession {Get-WindowsFeature | Where-Object {$_.Name -like "Multipath*"}}
- if($MPIOInstalledCheck.InstallState -eq "Installed"){
- Section -Style Heading4 'Host MPIO Settings'{
- Paragraph 'The following section details host MPIO Settings'
- [string]$MpioLoadBalance = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-MSDSMGlobalDefaultLoadBalancePolicy}
- Paragraph "The default load balancing policy is: $MpioLoadBalance"
- Section -Style Heading5 'Multipath I/O AutoClaim'{
- Paragraph 'The Following table details the BUS types MPIO will automatically claim for'
- $MpioAutoClaim = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-MSDSMAutomaticClaimSettings | Select-Object -ExpandProperty Keys}
- $MpioAutoClaimReport = @()
- foreach($key in $MpioAutoClaim){
- $Temp = "" | Select-Object BusType,State
- $Temp.BusType = $key
- $Temp.State = 'Enabled'
- $MpioAutoClaimReport += $Temp
- }
- $MpioAutoClaimReport | Table -Name 'Multipath I/O Auto Claim Settings'
- }
- Section -Style Heading5 'MPIO Detected Hardware'{
- Paragraph 'The following table details the hardware detected and claimed by MPIO'
- $MpioAvailableHw = Invoke-Command -Session $TempPssSession -ScriptBlock {Get-MPIOAvailableHw}
- $MpioAvailableHw | Select-Object VendorId,ProductId,BusType,IsMultipathed | Table -Name 'MPIO Available Hardware'
- }
- }
- }
- }
- #HyperV Configuration
- $HyperVInstalledCheck = Invoke-Command -Session $TempPssSession { Get-WindowsFeature | Where-Object { $_.Name -like "*Hyper-V*" } }
- if ($HyperVInstalledCheck.InstallState -eq "Installed") {
- Section -Style Heading4 "Hyper-V Configuration Settings" {
- Paragraph 'The following table details the Hyper-V Server Settings'
- $VmHost = Invoke-Command -Session $TempPssSession { Get-VMHost }
- $VmHostReport = [PSCustomObject]@{
- 'Logical Processor Count' = $VmHost.LogicalProcessorCount
- 'Memory Capacity (GB)' = [Math]::Round($VmHost.MemoryCapacity / 1gb)
- 'VM Default Path' = $VmHost.VirtualMachinePath
- 'VM Disk Default Path' = $VmHost.VirtualHardDiskPath
- 'Supported VM Versions' = $VmHost.SupportedVmVersions -Join ","
- 'Numa Spannning Enabled' = $VmHost.NumaSpanningEnabled
- 'Iov Support' = $VmHost.IovSupport
- 'VM Migrations Enabled' = $VmHost.VirtualMachineMigrationEnabled
- 'Allow any network for Migrations' = $VmHost.UseAnyNetworkForMigrations
- 'VM Migration Authentication Type' = $VmHost.VirtualMachineMigrationAuthenticationType
- 'Max Concurrent Storage Migrations' = $VmHost.MaximumStorageMigrations
- 'Max Concurrent VM Migrations' = $VmHost.MaximumStorageMigrations
- }
- $VmHostReport | Table -Name 'Hyper-V Host Settings' -List -ColumnWidths 50, 50
- Section -Style Heading5 "Hyper-V NUMA Boundaries" {
- Paragraph 'The following table details the NUMA nodes on the host'
- $VmHostNumaNodes = Get-VMHostNumaNode -CimSession $TempCimSession
- [array]$VmHostNumaReport = @()
- foreach ($Node in $VmHostNumaNodes) {
- $TempVmHostNumaReport = [PSCustomObject]@{
- 'Numa Node Id' = $Node.NodeId
- 'Memory Available(GB)' = ($Node.MemoryAvailable)/1024
- 'Memory Total(GB)' = ($Node.MemoryTotal)/1024
- }
- $VmHostNumaReport += $TempVmHostNumaReport
- }
- $VmHostNumaReport | Table -Name 'Host NUMA Nodes'
- }
- Section -Style Heading5 "Hyper-V MAC Pool settings" {
- 'The following table details the Hyper-V MAC Pool'
- $VmHostMacPool = [PSCustomObject]@{
- 'Mac Address Minimum' = $VmHost.MacAddressMinimum
- 'Mac Address Maximum' = $VmHost.MacAddressMaximum
- }
- $VmHostMacPool | Table -Name 'MAC Address Pool' -ColumnWidths 50, 50
- }
- Section -Style Heading5 "Hyper-V Management OS Adapters" {
- Paragraph 'The following table details the Management OS Virtual Adapters created on Virtual Switches'
- $VmOsAdapters = Get-VMNetworkAdapter -CimSession $TempCimSession -ManagementOS
- $VmOsAdapterReport = @()
- Foreach ($VmOsAdapter in $VmOsAdapters) {
- $AdapterVlan = Get-VMNetworkAdapterVlan -CimSession $TempCimSession -ManagementOS -VMNetworkAdapterName $VmOsAdapter.Name
- $TempVmOsAdapterReport = [PSCustomObject]@{
- 'Name' = $VmOsAdapter.Name
- 'Switch Name' = $VmOsAdapter.SwitchName
- 'Mac Address' = $VmOsAdapter.MacAddress
- 'IPv4 Address' = $VmOsAdapter.IPAddresses -Join ","
- 'Adapter Mode' = $AdapterVlan.OperationMode
- 'Vlan ID' = $AdapterVlan.AccessVlanId
- }
- $VmOsAdapterReport += $TempVmOsAdapterReport
- }
- $VmOsAdapterReport | Table -Name 'VM Management OS Adapters'
- }
- Section -Style Heading5 "Hyper-V vSwitch Settings" {
- Paragraph 'The following table details the Hyper-V vSwitches configured'
- $VmSwitches = Invoke-Command -Session $TempPssSession { Get-VMSwitch }
- $VmSwitchesReport = @()
- ForEach ($VmSwitch in $VmSwitches) {
- $TempVmSwitchesReport = [PSCustomObject]@{
- 'Switch Name' = $VmSwitch.Name
- 'Switch Type' = $VmSwitch.SwitchType
- 'Embedded Team' = $VmSwitch.EmbeddedTeamingEnabled
- 'Interface Description' = $VmSwitch.NetAdapterInterfaceDescription
- }
- $VmSwitchesReport += $TempVmSwitchesReport
- }
- $VmSwitchesReport | Table -Name 'Virtual Switch Summary' -ColumnWidths 40, 10, 10, 40
- Foreach ($VmSwitch in $VmSwitches) {
- Section -Style Heading6 ($VmSwitch.Name) {
- Paragraph 'The following table details the Hyper-V vSwitch'
- $VmSwitchReport = [PSCustomObject]@{
- 'Switch Name' = $VmSwitch.Name
- 'Switch Type' = $VmSwitch.SwitchType
- 'Switch Embedded Teaming Status' = $VmSwitch.EmbeddedTeamingEnabled
- 'Bandwidth Reservation Mode' = $VmSwitch.BandwidthReservationMode
- 'Bandwidth Reservation Percentage' = $VmSwitch.Percentage
- 'Management OS Allowed' = $VmSwitch.AllowManagementOS
- 'Physical Adapters' = $VmSwitch.NetAdapterInterfaceDescriptions -Join ","
- 'IOV Support' = $VmSwitch.IovSupport
- 'IOV Support Reasons' = $VmSwitch.IovSupportReasons
- 'Available VM Queues' = $VmSwitch.AvailableVMQueues
- 'Packet Direct Enabled' = $VmSwitch.PacketDirectinUse
- }
- $VmSwitchReport | Table -Name 'VM Switch Details' -List -ColumnWidths 50, 50
- }
- }
- }
- }
- }
- }
+ $script:ColumnSize = $Options.DiagramColumnSize
+
+ Write-Verbose "`VMM Server [$($VMM.name)] connection status is [$($VMM.IsConnected)]"
+ Section -Style Heading1 $($VMM.FQDN) {
+ Paragraph "The following section details the configuration of SCVMM server $($VMM.FQDN)."
+
+ $VMMDiagram = Get-AbrVmmInfrastructureDiagram
+ if ($VMMDiagram) {
+ Export-AbrDiagram -DiagramObject $VMMDiagram -MainDiagramLabel "Infrastructure Diagram" -FileName "AsBuiltReport.Microsoft.SCVMM.Infrastructure"
+ } else {
+ Write-PScriboMessage -IsWarning "Unable to generate the Infrastructure Diagram."
}
- Remove-PSSession $TempPssSession
- Remove-CimSession $TempCimSession
- }
- }
- #endregion foreach loop
+ Get-AbrVmmInfrastructure
+ Get-AbrVmmNetworking
+ Get-AbrVmmLibraryTemplate
+ Get-AbrVmmCluster
+ Get-AbrVmmHost
+ }
+ }
+ #endregion foreach loop
}
diff --git a/Todo.md b/Todo.md
new file mode 100644
index 0000000..1e6a224
--- /dev/null
+++ b/Todo.md
@@ -0,0 +1,10 @@
+[x] Add Update Server
+[] Add PXE Server
+[] Add vCenter Server
+[] Add Network Service
+[] Add configuration settings
+ [] Get-SCRunAsAccount
+ [] Get-SCUserRole
+[] Add Cloud (Get-SCCloud)
+[] Update ReadMe file
+[] Add HostGroup (Get-SCVMHostGroup)
\ No newline at end of file
diff --git a/icons/AsBuiltReport_Logo.png b/icons/AsBuiltReport_Logo.png
new file mode 100644
index 0000000..ff8a542
Binary files /dev/null and b/icons/AsBuiltReport_Logo.png differ
diff --git a/icons/AsBuiltReport_Signature.png b/icons/AsBuiltReport_Signature.png
new file mode 100644
index 0000000..000cde6
Binary files /dev/null and b/icons/AsBuiltReport_Signature.png differ
diff --git a/icons/DB_Server.png b/icons/DB_Server.png
new file mode 100644
index 0000000..315e904
Binary files /dev/null and b/icons/DB_Server.png differ
diff --git a/icons/Microsoft_Logo.png b/icons/Microsoft_Logo.png
new file mode 100644
index 0000000..e263d99
Binary files /dev/null and b/icons/Microsoft_Logo.png differ
diff --git a/icons/no_icon.png b/icons/no_icon.png
new file mode 100644
index 0000000..c5b0563
Binary files /dev/null and b/icons/no_icon.png differ
diff --git a/icons/server.png b/icons/server.png
new file mode 100644
index 0000000..40b8e58
Binary files /dev/null and b/icons/server.png differ