diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..b735373 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..066b2d9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..b6b1e17 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,34 @@ + + +## Description + + +## Related Issue + + + + + +## Motivation and Context + + +## How Has This Been Tested? + + + + +## Screenshots (if appropriate): + +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Checklist: + + +- [ ] My code follows the code style of this project. +- [ ] My change requires a change to the documentation. +- [ ] I have updated the documentation accordingly. +- [ ] I have read the [**CONTRIBUTING**](/CONTRIBUTING.md) document. diff --git a/.github/workflows/PSScriptAnalyzer.yml b/.github/workflows/PSScriptAnalyzer.yml new file mode 100644 index 0000000..fe69d8f --- /dev/null +++ b/.github/workflows/PSScriptAnalyzer.yml @@ -0,0 +1,17 @@ +name: PSScriptAnalyzer +on: [push, pull_request] +jobs: + lint: + name: Run PSScriptAnalyzer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: lint + uses: devblackops/github-action-psscriptanalyzer@master + with: + sendComment: true + failOnErrors: true + failOnWarnings: false + failOnInfos: false + repoToken: ${{ secrets.GITHUB_TOKEN }} + settingsPath: .github/workflows/PSScriptAnalyzerSettings.psd1 \ No newline at end of file diff --git a/.github/workflows/PSScriptAnalyzerSettings.psd1 b/.github/workflows/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 0000000..c053761 --- /dev/null +++ b/.github/workflows/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,8 @@ +@{ + ExcludeRules = @( + 'PSUseToExportFieldsInManifest', + 'PSReviewUnusedParameter', + 'PSUseDeclaredVarsMoreThanAssignments', + 'PSAvoidGlobalVars' + ) +} \ No newline at end of file diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml new file mode 100644 index 0000000..aec620e --- /dev/null +++ b/.github/workflows/Release.yml @@ -0,0 +1,23 @@ +name: Publish PowerShell Module + +on: + release: + types: [published] + +jobs: + publish-to-gallery: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - 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: Publish module to PowerShell Gallery + shell: pwsh + run: | + Publish-Module -Path ./ -NuGetApiKey ${{ secrets.PSGALLERY_API_KEY }} -Verbose diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c133455 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,25 @@ +{ + "powershell.codeFormatting.preset": "Custom", + "powershell.codeFormatting.useCorrectCasing": true, + "powershell.codeFormatting.autoCorrectAliases": true, + "powershell.codeFormatting.whitespaceBeforeOpenBrace": true, + "powershell.codeFormatting.whitespaceBeforeOpenParen": true, + "powershell.codeFormatting.whitespaceAroundOperator": true, + "powershell.codeFormatting.whitespaceAfterSeparator": true, + "powershell.codeFormatting.addWhitespaceAroundPipe": true, + "powershell.codeFormatting.ignoreOneLineBlock": true, + "powershell.codeFormatting.newLineAfterCloseBrace": false, + "powershell.codeFormatting.newLineAfterOpenBrace": true, + "powershell.codeFormatting.openBraceOnSameLine": true, + "powershell.codeFormatting.alignPropertyValuePairs": false, + "powershell.codeFolding.enable": true, + "powershell.scriptAnalysis.enable": true, + "powershell.scriptAnalysis.settingsPath": ".github/workflows/PSScriptAnalyzerSettings.psd1", + "editor.tabSize": 4, + "editor.insertSpaces": true, + "editor.detectIndentation": false, + "editor.rulers": [ + 115 + ], + "files.trimTrailingWhitespace": true +} \ No newline at end of file diff --git a/AsBuiltReport.Microsoft.AD.Style.ps1 b/AsBuiltReport.Microsoft.AD.Style.ps1 new file mode 100644 index 0000000..40b8ab1 --- /dev/null +++ b/AsBuiltReport.Microsoft.AD.Style.ps1 @@ -0,0 +1,106 @@ +# Microsoft AD Default Document Style + +# Configure document options +DocumentOption -EnableSectionNumbering -PageSize A4 -DefaultFont 'Arial' -MarginLeftAndRight 71 -MarginTopAndBottom 71 -Orientation $Orientation + +# Configure Heading and Font Styles +Style -Name 'Title' -Size 24 -Color '737373' -Align Center +Style -Name 'Title 2' -Size 18 -Color '00A4EF' -Align Center +Style -Name 'Title 3' -Size 12 -Color '00A4EF' -Align Left +Style -Name 'Heading 1' -Size 16 -Color '00A4EF' +Style -Name 'Heading 2' -Size 14 -Color '00A4EF' +Style -Name 'Heading 3' -Size 12 -Color '00A4EF' +Style -Name 'Heading 4' -Size 11 -Color '00A4EF' +Style -Name 'Heading 5' -Size 10 -Color '00A4EF' +Style -Name 'Normal' -Size 10 -Color '565656' -Default +Style -Name 'Caption' -Size 10 -Color '565656' -Italic -Align Center +Style -Name 'Header' -Size 10 -Color '565656' -Align Center +Style -Name 'Footer' -Size 10 -Color '565656' -Align Center +Style -Name 'TOC' -Size 16 -Color '00A4EF' +Style -Name 'TableDefaultHeading' -Size 10 -Color 'FAFAFA' -BackgroundColor '00A4EF' +Style -Name 'TableDefaultRow' -Size 10 -Color '565656' +Style -Name 'Critical' -Size 10 -BackgroundColor 'F25022' +Style -Name 'Warning' -Size 10 -BackgroundColor 'FFB900' +Style -Name 'Info' -Size 10 -BackgroundColor '00A4EF' +Style -Name 'OK' -Size 10 -BackgroundColor '7FBA00' + +# Configure Table Styles +$TableDefaultProperties = @{ + Id = 'TableDefault' + HeaderStyle = 'TableDefaultHeading' + RowStyle = 'TableDefaultRow' + BorderColor = '00A4EF' + Align = 'Left' + CaptionStyle = 'Caption' + CaptionLocation = 'Below' + BorderWidth = 0.25 + PaddingTop = 1 + PaddingBottom = 1.5 + PaddingLeft = 2 + PaddingRight = 2 +} + +TableStyle @TableDefaultProperties -Default +TableStyle -Id 'Borderless' -HeaderStyle Normal -RowStyle Normal -BorderWidth 0 + +# Microsoft AD Cover Page Layout +# Header & Footer +if ($ReportConfig.Report.ShowHeaderFooter) { + Header -Default { + Paragraph -Style Header "$($ReportConfig.Report.Name) - v$($ReportConfig.Report.Version)" + } + + Footer -Default { + Paragraph -Style Footer 'Page ' + } +} + +# Set position of report titles and information based on page orientation +if (!($ReportConfig.Report.ShowCoverPageImage)) { + $LineCount = 5 +} +if ($Orientation -eq 'Portrait') { + BlankLine -Count 11 + $LineCount = 32 + $LineCount +} else { + BlankLine -Count 7 + $LineCount = 15 + $LineCount +} + +# Microsoft Logo Image +if ($ReportConfig.Report.ShowCoverPageImage) { + # Always check the vendor's branding guidelines to ensure the use of their company logo is allowed. + # Convert a vendor's logo image to Base64 using https://base64.guru/converter/encode/image/jpg. + # Specify Base64 code using the `Base64` parameter below. Size image accordingly using the `Percent` parameter. Align image to center. + <# + Try { + # Image -Text 'Microsoft Logo' -Align 'Center' -Percent 5 -Base64 "" + } Catch { + Write-PScriboMessage -Message ".NET Core is required for cover page image support. Please install .NET Core or disable 'ShowCoverPageImage' in the report JSON configuration file." + } + #> +} + +# Add Report Name +Paragraph -Style Title $ReportConfig.Report.Name + +if ($AsBuiltConfig.Company.FullName) { + # Add Company Name if specified + BlankLine -Count 2 + Paragraph -Style Title2 $AsBuiltConfig.Company.FullName + BlankLine -Count $LineCount +} else { + BlankLine -Count ($LineCount + 1) +} +Table -Name 'Cover Page' -List -Style Borderless -Width 0 -Hashtable ([Ordered] @{ + 'Author:' = $AsBuiltConfig.Report.Author + 'Date:' = (Get-Date).ToLongDateString() + 'Version:' = $ReportConfig.Report.Version + }) +PageBreak + +if ($ReportConfig.Report.ShowTableOfContents) { + # Add Table of Contents + TOC -Name 'Table of Contents' + PageBreak +} diff --git a/AsBuiltReport.Microsoft.AD.json b/AsBuiltReport.Microsoft.AD.json new file mode 100644 index 0000000..5f6cbe6 --- /dev/null +++ b/AsBuiltReport.Microsoft.AD.json @@ -0,0 +1,38 @@ +{ + "Report": { + "Name": "Microsoft AD As Built Report", + "Version": "1.0", + "Status": "Released", + "ShowCoverPageImage": true, + "ShowTableOfContents": true, + "ShowHeaderFooter": true, + "ShowTableCaptions": true + }, + "Options": { + + }, + "InfoLevel": { + "_comment_": "0 = Disabled, 1 = Enabled", + "Forest": 1, + "Domain": 1, + "Site": 1, + "DHCP": 1, + "DNS": 1, + "CA": 1 + }, + "HealthCheck": { + "Domain": { + "GMSA": true + }, + "DomainController": { + "Diagnostic": true, + "Services": true + }, + "Site": { + "Replication": true + }, + "DNS": { + "Aging": true + } + } +} diff --git a/AsBuiltReport.Microsoft.AD.psd1 b/AsBuiltReport.Microsoft.AD.psd1 new file mode 100644 index 0000000..be60c21 --- /dev/null +++ b/AsBuiltReport.Microsoft.AD.psd1 @@ -0,0 +1,137 @@ +# +# Module manifest for module 'AsBuiltReport.Microsoft.AD' +# +# Generated by: Jonathan Colon +# +# Generated on: 10/09/2021 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'AsBuiltReport.Microsoft.AD.psm1' + +# Version number of this module. +ModuleVersion = '0.2.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = '0a3e1c04-13b8-418f-89bc-a5a18da07394' + +# Author of this module +Author = 'Jonathan Colon' + +# Company or vendor of this module +# CompanyName = 'Unknown' + +# Copyright statement for this module +Copyright = '(c) 2021 Jonathan Colon. 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 AD.' + +# 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 = '' + +# 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 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 = '' + +# Modules that must be imported into the global environment prior to importing this module +RequiredModules = @( + @{ + ModuleName = 'AsBuiltReport.Core'; + ModuleVersion = '1.1.0' + }, + @{ + ModuleName = 'ActiveDirectory'; + ModuleVersion = '1.0' + }, + @{ + ModuleName = 'PSPKI'; + ModuleVersion = '3.7.2' + } +) + +# 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 = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# 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.AD') + +# 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 = '*' + +# Variables to export from this module +# VariablesToExport = '*' + +# 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 = '*' + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# 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', 'AD', 'Active-Directory', 'Documentation', 'PScribo', 'PSEdition_Desktop', 'PSEdition_Core', 'Windows', 'MacOS', 'Linux' + + # A URL to the license for this module. + LicenseUri = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.AD/master/LICENSE' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.AD' + + # A URL to an icon representing this module. + IconUri = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport/master/AsBuiltReport.png' + + # ReleaseNotes of this module + ReleaseNotes = 'https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.AD/master/CHANGELOG.md' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} + + diff --git a/AsBuiltReport.Microsoft.AD.psm1 b/AsBuiltReport.Microsoft.AD.psm1 new file mode 100644 index 0000000..e22b0dc --- /dev/null +++ b/AsBuiltReport.Microsoft.AD.psm1 @@ -0,0 +1,14 @@ +# Get public and private function definition files and dot source them +$Public = @(Get-ChildItem -Path $PSScriptRoot\Src\Public\*.ps1 -ErrorAction SilentlyContinue) +$Private = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\*.ps1 -ErrorAction SilentlyContinue) + +foreach ($Module in @($Public + $Private)) { + try { + . $Module.FullName + } catch { + Write-Error -Message "Failed to import function $($Module.FullName): $_" + } +} + +Export-ModuleMember -Function $Public.BaseName +Export-ModuleMember -Function $Private.BaseName \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e1c9037 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,51 @@ +# :arrows_counterclockwise: Microsoft AD As Built Report Changelog + +## [0.2.0] - 2021-09-10 + +### Added + +- Added Active Directory DNS summary information + - Added DNS Forwarder summary information + - Added Added DNS Recursion configuration information + - Added Added DNS RRL configuration information + - Added Added DNS Zone Reverse Lookup configuration information + - Added Added DNS Zone Scavenging/Aging configuration information + - Added Added DNS Zone Delegation configuration information + - Added more health checks + +### Changed + +- Improved per Domain configuration information +- Improved per Domain Controller configuration information +- Introduced the ability to use a shared PSsession +- Merged the functions used within the reports into a single file (SharedUtilsFunctions) + +### Fixed + +- Enhanced the logic of detecting a unavailable Domain or DC. +- Enhanced verbose/degug logging +- Added more try/catch code to improve error diagnostic + +## [0.1.0] - 2021-08-10 + +### Added + +- Added Active Directory Forest summary information + - Added Forest Optional Features Summary + - Added Domain Site summary information + - Added Domain Site Link summary information +- Added Active Directory Domain summary Infomation + - Added Object Count summary Information + - Added Default Domain Password Policy Summary Information + - Added Group Managed Service Accounts (GMSA) Summary Information + - Added Flexible Single Master Operations (FSMO) Information + - Added Trust Summary information +- Added Domain Controller Information + - Added Domain Controller Hardware Summary + - Added Domain Controller NTDS Summary + - Added Domain Controller Time Source Summary + - Added Domain Controller Infrastructure Services Status + - Added Site Replication Summary + - Added Site Replication Failure Summary + - Added Group Policy Objects Summary + - Added Organizational Unit summary diff --git a/README.md b/README.md new file mode 100644 index 0000000..549273c --- /dev/null +++ b/README.md @@ -0,0 +1,182 @@ + +

+ + +

+

+ + + + + + +

+

+ + + + + + +

+

+ + +

+ + +# Microsoft AD As Built Report + +Microsoft AD As Built Report is a PowerShell module which works in conjunction with [AsBuiltReport.Core](https://github.com/AsBuiltReport/AsBuiltReport.Core). + +[AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport) is an open-sourced community project which utilises PowerShell to produce as-built documentation in multiple document formats for multiple vendors and technologies. + +Please refer to the AsBuiltReport [website](https://www.asbuiltreport.com) for more detailed information about this project. + +# :beginner: Getting Started + +Below are the instructions on how to install, configure and generate a Microsoft AD As Built report. + +## :floppy_disk: Supported Versions + +The Microsoft AD As Built Report supports the following Active Directory versions; + +- 2008, 2008 R2, 2012, 2016, 2019 + +### 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 or PowerShell 7, and the following PowerShell modules are required for generating a Microsoft AD As Built report. + +- [AsBuiltReport.Microsoft.AD Module](https://www.powershellgallery.com/packages/AsBuiltReport.Microsoft.AD/) +- [ActiveDirectory Module](https://docs.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2019-ps) +- [PSPKI Module](https://www.powershellgallery.com/packages/PSPKI/3.7.2) +- [GroupPolicy Module](https://docs.microsoft.com/en-us/powershell/module/grouppolicy/?view=windowsserver2019-ps) + +### Linux & macOS + +This report does not support Linux or Mac due to the fact that the ActiveDirectory/GroupPolicy modules are dependent on the .NET Framework. Until Microsoft migrates these modules to native PowerShell Core, only PowerShell >= (5.x, 7) will be supported on Windows. + +### :closed_lock_with_key: Required Privileges + +A Microsoft AD As Built Report can be generated with Active Directory Enterprise Forest level privileges. Due to the limitations of the WinRM protocol, a domain-joined machine is needed, also it is required to use the FQDN of the DC instead of its IP address. +[Reference](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting?view=powershell-7.1#how-to-use-an-ip-address-in-a-remote-command) + +## :package: Module Installation + +### PowerShell v5.x running on a Domain Controller server + +```powershell +Install-Module AsBuiltReport.Microsoft.AD +Install-Module PSPKI +Install-WindowsFeature RSAT-AD-PowerShell +Install-WindowsFeature GPMC +``` + +### PowerShell v5.x running on Windows 10 client computer + +```powershell +Install-Module AsBuiltReport.Microsoft.AD +Install-Module PSPKI +Add-WindowsCapability -online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' +Add-WindowsCapability -online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0' +``` + +### 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.AD#wrench-system-requirements) also. + +1. Download the code package / [latest release](https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.AD/releases/latest) zip from GitHub +2. Extract the zip file +3. Copy the folder `AsBuiltReport.Microsoft.AD` 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.AD -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 AD As Built Report utilises a JSON file to allow configuration of report information, options, detail and healthchecks. + +A Microsoft AD report configuration file can be generated by executing the following command; + +```powershell +New-AsBuiltReportConfig -Report Microsoft.AD -FolderPath -Filename +``` + +Executing this command will copy the default Microsoft AD 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 AD report information. + +| Sub-Schema | Setting | Default | Description | +|---------------------|--------------|--------------------------------|--------------------------------------------------------------| +| Name | User defined | Microsoft AD 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 | + +### Options + +The **Options** schema allows certain options within the report to be toggled on or off. + +### InfoLevel + +The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set. + +There are 2 levels (0-1) 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 | + +### Healthcheck + +The **Healthcheck** schema is used to toggle health checks on or off. + +## :computer: Examples + +There are a few examples listed below on running the AsBuiltReport script against a Microsoft Active Directory Domain Controller target. Refer to the `README.md` file in the main AsBuiltReport project repository for more examples. + +```powershell + +# Generate a Microsoft Active Directory As Built Report for Domain Controller Server 'admin-dc-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.AD -Target 'admin-dc-01v.contoso.local' -Username 'administrator@contoso.local' -Password 'P@ssw0rd' -Format Html,Word -OutputFolderPath 'C:\Users\Jon\Documents' -Timestamp + +# Generate a Microsoft Active Directory As Built Report for Domain Controller Server 'admin-dc-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.AD -Target 'admin-dc-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.AD.json' -Verbose + +# Generate a Microsoft Active Directory As Built Report for Domain Controller Server 'admin-dc-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.AD -Target 'admin-dc-01v.contoso.local' -Credential $Creds -Format Html,Text -OutputFolderPath 'C:\Users\Jon\Documents' -EnableHealthCheck + +# Generate a Microsoft Active Directory As Built Report for Domain Controller Server 'admin-dc-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.AD -Target 'admin-dc-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 Linux/Mac support until Microsoft migrates the ActiveDirectory/GroupPolicy modules to PowerShell Core. diff --git a/Samples/Sample Microsoft AD As Built Report.html b/Samples/Sample Microsoft AD As Built Report.html new file mode 100644 index 0000000..0621e0e --- /dev/null +++ b/Samples/Sample Microsoft AD As Built Report.html @@ -0,0 +1,720 @@ + + +Microsoft AD As Built Report + +
+ +











Microsoft AD As Built Report


Zen PR Solutions





































+ + + +
Author:Jonathan Colon
Date:Tuesday, September 21, 2021
Version:0.2.0
+
+
+
Microsoft AD As Built Report - v0.2.0

Table of Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1Report for Active Directory Forest ZENPR.LOCAL
1.1   Forest Information.
1.1.1      Optional Features Summary
1.1.2      Domain Site Summary
1.1.3      Site Links Summary
1.2   Active Directory Information for domain ZENPR.LOCAL
1.2.1      Domain Object Count Summary
1.2.2      Default Domain Password Policy Summary
1.2.3      Group Managed Service Accounts (GMSA) Summary
1.2.4      Flexible Single Master Operations (FSMO) Information
1.2.5      Trust Summary
1.2.6      Domain Controller Information
1.2.6.1         Domain Controller Hardware Summary
1.2.6.2         Domain Controller NTDS Summary
1.2.6.2.1            Domain Controller Time Source Summary
1.2.6.3         DCDiag Information
1.2.6.4         Domain Controller Infrastructure Services Status of SERVER-DC-01V
1.2.6.5         Domain Controller Infrastructure Services Status of CAYEY-DC-01V
1.2.6.6         Site Replication Summary
1.2.6.7         Site Replication Failure Summary
1.2.6.8         Group Policy Objects Summary for domain ZENPR
1.2.6.9         Organizational Unit summary for domain ZENPR
1.3   Active Directory Information for domain ACAD.ZENPR.LOCAL
1.3.1      Domain Object Count Summary
1.3.2      Default Domain Password Policy Summary
1.3.3      Group Managed Service Accounts (GMSA) Summary
1.3.4      Flexible Single Master Operations (FSMO) Information
1.3.5      Trust Summary
1.3.6      Domain Controller Information
1.3.6.1         Domain Controller Hardware Summary
1.3.6.2         Domain Controller NTDS Summary
1.3.6.2.1            Domain Controller Time Source Summary
1.3.6.3         DCDiag Information
1.3.6.4         Domain Controller Infrastructure Services Status of ACADE-DC-01V
1.3.6.5         Site Replication Summary
1.3.6.6         Group Policy Objects Summary for domain ACAD
1.3.6.7         Organizational Unit summary for domain ACAD
1.4   Domain Name System Information for domain ZENPR.LOCAL
1.4.1      Infrastructure Summary
1.4.1.1         Response Rate Limiting (RRL) Summary
1.4.1.2         Scavenging Summary
1.4.1.3         Forwarder Summary
1.4.1.4         Zone Scope Recursion Summary
1.5   Domain Name System Information for domain ACAD.ZENPR.LOCAL
1.5.1      Infrastructure Summary
1.5.1.1         Response Rate Limiting (RRL) Summary
1.5.1.2         Scavenging Summary
1.5.1.3         Forwarder Summary
1.5.1.4         Zone Scope Recursion Summary
1.6   Domain Name System Zone Configuration of ACADE-DC-01V
1.6.1      Reverse Lookup Zone Configuration of ACADE-DC-01V
1.6.2      Zone Scope Aging properties of ACADE-DC-01V
+

+
Microsoft AD As Built Report - v0.2.0

1 Report for Active Directory Forest ZENPR.LOCAL

The following section provides a summary of the Active Directory Infrastructure configuration for ZENPR.LOCAL.

1.1 Forest Information.

+ + + + + + + + + + +
Forest Namezenpr.local
Forest Functional LevelWindows2016Forest
Schema VersionObjectVersion 88; PSComputerName=acade-dc-01v.acad.zenpr.local; RunspaceId=4e7fcc4f-b977-49e4-9293-28d66954c15f; PSShowComputerName=True, Correspond to
Domainsacad.zenpr.local; zenpr.local
Global CatalogsServer-DC-01V.zenpr.local; acade-dc-01v.acad.zenpr.local
Application PartitionsDC=DomainDnsZones,DC=acad,DC=zenpr,DC=local
DC=ForestDnsZones,DC=zenpr,DC=local
DC=DomainDnsZones,DC=zenpr,DC=local
PartitionsContainerCN=Partitions,CN=Configuration,DC=zenpr,DC=local
SPN Suffixes 
UPN Suffixes 
+
Table 1 - AD Forest Summary Information - ZENPR.LOCAL

+

1.1.1 Optional Features Summary

The following section provides a summary of the enabled Optional Features.

+ + + +
NameRequired Forest ModeForest
Recycle Bin FeatureWindows2008R2ForestZENPR.LOCAL
Privileged Access Management FeatureWindows2016ForestZENPR.LOCAL
+
Table 2 - Active Directory Enabled Optional Features Information - ZENPR.LOCAL

+

1.1.2 Domain Site Summary

The following section provides a summary of the Active Directory Sites on.

+ + + + +
Site NameDescriptionCreation DateSubnets
Zenpr-HQSite of San Juan, PR HQMon, 11 Jun 2018 00:59:59 GMT10.9.1.0/24
192.168.0.0/16
Cayey-BranchSite of Cayey, PR BranchSat, 04 Sep 2021 00:35:15 GMT10.10.0.0/16
ACAD Sun, 05 Sep 2021 16:13:51 GMT172.23.0.0/16
+
Table 3 - AD Domain Controller Summary Information - ZENPR.LOCAL

+

1.1.3 Site Links Summary

The following section provides a summary of the Active Directory Site Link information.

+ + + +
Site Link NameCostReplication FrequencyTransport ProtocolSites
Zenpr-to-All10015 minIPACAD
Cayey-Branch
Zenpr-HQ
ZENPR-to-ACAD10015 minIPACAD
Zenpr-HQ
+
Table 4 - Site Links Information - ZENPR.LOCAL

+

1.2 Active Directory Information for domain ZENPR.LOCAL

The following section provides a summary of the AD Domain Information.

+ + + + + + + + + + + + + + + + +
Domain Namezenpr
NetBIOS NameZENPR
Domain SIDS-1-5-21-2867495315-1194516362-180967319
Domain Functional LevelWindows2016Domain
Domains 
Forestzenpr.local
Parent Domain 
Replica Directory ServersServer-DC-01V.zenpr.local
cayey-dc-01v.zenpr.local
Child Domainsacad.zenpr.local
Computers ContainerCN=Computers,DC=zenpr,DC=local
Distinguished NameDC=zenpr,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=zenpr,DC=local
Systems ContainerCN=System,DC=zenpr,DC=local
Users ContainerCN=Users,DC=zenpr,DC=local
ReadOnly Replica Directory Servers 
+
Table 5 - AD Domain Summary Information - ZENPR.LOCAL

+

1.2.1 Domain Object Count Summary

The following section provides a summary of the Active Directory Object Count on ZENPR.LOCAL.

+ + +
Domain NameComputer CountUsers CountGroup Count
zenpr.local8924107
+
Table 6 - Active Directory Object Count Information - ZENPR.LOCAL

+

1.2.2 Default Domain Password Policy Summary

The following section provides a summary of the Default Domain Password Policy on ZENPR.LOCAL.

+ + + + + + + + + + + + +
Domain Namezenpr.local
Complexity EnabledYes
Distinguished NameDC=zenpr,DC=local
Lockout Duration00 days 00 hours 30 minutes 00 seconds
Lockout Threshold0
Lockout Observation Window00 days 00 hours 30 minutes 00 seconds
Max Password Age42 days 00 hours 00 minutes 00 seconds
Min Password Age01 days 00 hours 00 minutes 00 seconds
Min Password Length7
Password History Count24
Reversible Encryption EnabledNo
+
Table 7 - Default Domain Password Policy Information - ZENPR.LOCAL

+

1.2.3 Group Managed Service Accounts (GMSA) Summary

The following section provides a summary of the Group Managed Service Accounts on ZENPR.LOCAL.

+ + + + + + + + + + + + + + +
NameSQLServer
SamAccountNameSQLServer$
Created09/27/2020 14:14:22
EnabledYes
DNS Host NameSQL-Cluster
Host ComputersCN=SQL-CLUSTER-02V,OU=Member Servers,DC=zenpr,DC=local
CN=SQL-CLUSTER-01V,OU=Member Servers,DC=zenpr,DC=local
Retrieve Managed PasswordCN=SQL-CLUSTER-01V,OU=Member Servers,DC=zenpr,DC=local
CN=SQL-CLUSTER-02V,OU=Member Servers,DC=zenpr,DC=local
Primary GroupCN=Domain Computers,CN=Users,DC=zenpr,DC=local
Last Logon Date09/27/2020 14:41:08
Locked OutNo
Logon Count3
Password ExpiredNo
Password Last Set09/27/2020 14:14:22
+
+
+ + + + + + + + + + + + + + +
Nameadfsgmsa
SamAccountNameadfsgmsa$
Created10/07/2020 18:36:16
EnabledYes
DNS Host NameADFS.zenpr.local
Host Computers 
Retrieve Managed PasswordCN=SERVER-ADFS-01V,OU=Member Servers,DC=zenpr,DC=local
CN=SERVER-ADFS-02V,OU=Member Servers,DC=zenpr,DC=local
Primary GroupCN=Domain Computers,CN=Users,DC=zenpr,DC=local
Last Logon Date10/07/2020 18:36:17
Locked OutNo
Logon Count40
Password ExpiredNo
Password Last Set10/07/2020 18:36:16
+
+

1.2.4 Flexible Single Master Operations (FSMO) Information

The following section provides a summary of the Active Directory FSMO for Domain ZENPR.LOCAL.

+ + + + + + +
Infrastructure Master ServerServer-DC-01V.zenpr.local
RID Master ServerServer-DC-01V.zenpr.local
PDC Emulator NameServer-DC-01V.zenpr.local
Domain Naming Master ServerServer-DC-01V.zenpr.local
Schema Master ServerServer-DC-01V.zenpr.local
+
Table 8 - FSMO Server Information - zenpr.local

+

1.2.5 Trust Summary

The following section provides a summary of Active Directory Trust information on ZENPR.LOCAL.

+ + + + + + + + + + + + +
Nameacad.zenpr.local
Distinguished NameCN=acad.zenpr.local,CN=System,DC=zenpr,DC=local
SourceDC=zenpr,DC=local
Targetacad.zenpr.local
DirectionBiDirectional
IntraForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
Trust TypeUplevel
Uplevel OnlyNo
+
Table 9 - Active Directory Trusts Information - ZENPR.LOCAL

+

1.2.6 Domain Controller Information

The following section provides a summary of the Active Directory Domain Controller.

+ + + +
DC NameDomain NameSiteGlobal CatalogRead OnlyIP Address
SERVER-DC-01Vzenpr.localZenpr-HQYesNo192.168.5.1
CAYEY-DC-01Vzenpr.localCayey-BranchNoNo10.10.33.1
+
Table 10 - AD Domain Controller Summary Information - ZENPR.LOCAL

+

1.2.6.1 Domain Controller Hardware Summary

The following section provides a summary of the Domain Controller Hardware for ZENPR.LOCAL.

+ + + + + + + + + +
NameServer-DC-01V
WindowsProductNameWindows Server 2019 Standard Evaluation
ManufacturerVMware, Inc.
CsModelVMware7,1
Bios TypeUefi
CPU Socket1
CPU Cores2
Total RAM4.00 GB
+
+
+ + + + + + + + + +
Namecayey-dc-01v
WindowsProductNameWindows Server 2019 Standard Evaluation
ManufacturerVMware, Inc.
CsModelVMware7,1
Bios TypeUefi
CPU Socket1
CPU Cores2
Total RAM4.00 GB
+
+

1.2.6.2 Domain Controller NTDS Summary

The following section provides a summary of the Domain Controller NTDS file size on ZENPR.LOCAL.

+ + + +
NameDSA Database FileSize
Server-DC-01V.zenpr.localC:\Windows\NTDS\ntds.dit54.00 MB
cayey-dc-01v.zenpr.localC:\Windows\NTDS\ntds.dit38.00 MB
+
Table 11 - Domain Controller NTDS Database File Usage Information - ZENPR.LOCAL

+
1.2.6.2.1 Domain Controller Time Source Summary
The following section provides a summary of the Domain Controller Time Source configuration on ZENPR.LOCAL.

+ + + +
NameTime ServerType
Server-DC-01V.zenpr.local0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org,8MANUAL (NTP)
cayey-dc-01v.zenpr.localDomain HierarchyDOMHIER
+
Table 12 - Domain Controller Time Source Configuration - ZENPR.LOCAL

+

1.2.6.3 DCDiag Information

The following section provides a summary of the Active Directory DC Diagnostic.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
DC NameTest NameResult
Server-DC-01V.zenpr.localConnectivitypassed
Server-DC-01V.zenpr.localAdvertisingpassed
Server-DC-01V.zenpr.localFrsEventpassed
Server-DC-01V.zenpr.localDFSREventfailed
Server-DC-01V.zenpr.localSysVolCheckpassed
Server-DC-01V.zenpr.localKccEventpassed
Server-DC-01V.zenpr.localKnowsOfRoleHolderspassed
Server-DC-01V.zenpr.localMachineAccountpassed
Server-DC-01V.zenpr.localNCSecDescpassed
Server-DC-01V.zenpr.localNetLogonspassed
Server-DC-01V.zenpr.localObjectsReplicatedpassed
Server-DC-01V.zenpr.localReplicationspassed
Server-DC-01V.zenpr.localRidManagerpassed
Server-DC-01V.zenpr.localServicespassed
Server-DC-01V.zenpr.localSystemLogpassed
Server-DC-01V.zenpr.localVerifyReferencespassed
Server-DC-01V.zenpr.localCheckSDRefDompassed
Server-DC-01V.zenpr.localCheckSDRefDompassed
Server-DC-01V.zenpr.localCheckSDRefDompassed
Server-DC-01V.zenpr.localCrossRefValidationpassed
Server-DC-01V.zenpr.localCheckSDRefDompassed
Server-DC-01V.zenpr.localCrossRefValidationpassed
Server-DC-01V.zenpr.localCheckSDRefDompassed
Server-DC-01V.zenpr.localCrossRefValidationpassed
Server-DC-01V.zenpr.localLocatorCheckpassed
Server-DC-01V.zenpr.localIntersitepassed
+
Table 13 - AD Domain Controller DCDiag Information - ZENPR.LOCAL

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
DC NameTest NameResult
cayey-dc-01v.zenpr.localConnectivitypassed
cayey-dc-01v.zenpr.localAdvertisingpassed
cayey-dc-01v.zenpr.localFrsEventpassed
cayey-dc-01v.zenpr.localDFSREventpassed
cayey-dc-01v.zenpr.localSysVolCheckpassed
cayey-dc-01v.zenpr.localKccEventpassed
cayey-dc-01v.zenpr.localKnowsOfRoleHolderspassed
cayey-dc-01v.zenpr.localMachineAccountpassed
cayey-dc-01v.zenpr.localNCSecDescpassed
cayey-dc-01v.zenpr.localNetLogonspassed
cayey-dc-01v.zenpr.localObjectsReplicatedpassed
cayey-dc-01v.zenpr.localReplicationspassed
cayey-dc-01v.zenpr.localRidManagerpassed
cayey-dc-01v.zenpr.localServicespassed
cayey-dc-01v.zenpr.localSystemLogpassed
cayey-dc-01v.zenpr.localVerifyReferencespassed
cayey-dc-01v.zenpr.localCheckSDRefDompassed
cayey-dc-01v.zenpr.localCheckSDRefDompassed
cayey-dc-01v.zenpr.localCheckSDRefDompassed
cayey-dc-01v.zenpr.localCrossRefValidationpassed
cayey-dc-01v.zenpr.localCheckSDRefDompassed
cayey-dc-01v.zenpr.localCrossRefValidationpassed
cayey-dc-01v.zenpr.localCheckSDRefDompassed
cayey-dc-01v.zenpr.localCrossRefValidationpassed
cayey-dc-01v.zenpr.localLocatorCheckpassed
cayey-dc-01v.zenpr.localIntersitepassed
+
Table 14 - AD Domain Controller DCDiag Information - ZENPR.LOCAL

+

1.2.6.4 Domain Controller Infrastructure Services Status of SERVER-DC-01V

The following section provides a summary of the Domain Controller Infrastructure services status.

+ + + + + + + + +
Display NameShort NameStatus
DNS ServerDNSRunning
DFS ReplicationDFSRRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Active Directory Domain ServicesNTDSRunning
Windows TimeW32TimeRunning
+
Table 15 - Domain Controller Infrastructure Services Status Information.

+

1.2.6.5 Domain Controller Infrastructure Services Status of CAYEY-DC-01V

The following section provides a summary of the Domain Controller Infrastructure services status.

+ + + + + + + + +
Display NameShort NameStatus
DNS ServerDNSRunning
DFS ReplicationDFSRRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Active Directory Domain ServicesNTDSRunning
Windows TimeW32TimeRunning
+
Table 16 - Domain Controller Infrastructure Services Status Information.

+

1.2.6.6 Site Replication Summary

The following section provides a summary of the Active Directory Site Replication information.

+ + + + + + + + + + + +
DC NameServer-DC-01V.zenpr.local
GUIDd5a28ae4-ee92-47a4-872e-e4115bc8d1a5
Description 
Replicate From Directory ServerCN=NTDS Settings,CN=ACADE-DC-01V,CN=Servers,CN=ACAD,CN=Sites,CN=Configuration,DC=zenpr,DC=local
Replicate To Directory ServerServer-DC-01V.zenpr.local
Replicated Naming ContextsDC=DomainDnsZones,DC=zenpr,DC=local
DC=ForestDnsZones,DC=zenpr,DC=local
CN=Schema,CN=Configuration,DC=zenpr,DC=local
CN=Configuration,DC=zenpr,DC=local
DC=zenpr,DC=local
Transport ProtocolIP
AutoGeneratedYes
EnabledYes
CreatedSun, 05 Sep 2021 16:24:39 GMT
+
+
+ + + + + + + + + + + +
DC Namecayey-dc-01v.zenpr.local
GUID9b7cbbe0-7c6f-4add-af4a-7b581a7bf5ca
Description 
Replicate From Directory ServerCN=NTDS Settings,CN=SERVER-DC-01V,CN=Servers,CN=Zenpr-HQ,CN=Sites,CN=Configuration,DC=zenpr,DC=local
Replicate To Directory Servercayey-dc-01v.zenpr.local
Replicated Naming ContextsDC=DomainDnsZones,DC=zenpr,DC=local
DC=ForestDnsZones,DC=zenpr,DC=local
CN=Schema,CN=Configuration,DC=zenpr,DC=local
CN=Configuration,DC=zenpr,DC=local
DC=zenpr,DC=local
Transport ProtocolIP
AutoGeneratedYes
EnabledYes
CreatedSat, 04 Sep 2021 01:35:40 GMT
+
+

1.2.6.7 Site Replication Failure Summary

The following section provides a summary of the Active Directory Site Replication Failure information.

+ + + + + + + +
Server NameServer-DC-01V.zenpr.local
PartnerCN=NTDS Settings,CN=ACADE-DC-01V,CN=Servers,CN=ACAD,CN=Sites,CN=Configuration,DC=zenpr,DC=local
Last Error1256
Failure TypeLink
Failure Count0
First Failure TimeTue, 21 Sep 2021 03:53:34 GMT
+
+
+ + + + + + + +
Server NameServer-DC-01V.zenpr.local
PartnerCN=NTDS Settings,CN=CAYEY-DC-01V,CN=Servers,CN=Cayey-Branch,CN=Sites,CN=Configuration,DC=zenpr,DC=local
Last Error1256
Failure TypeLink
Failure Count0
First Failure TimeTue, 21 Sep 2021 04:10:54 GMT
+
+

1.2.6.8 Group Policy Objects Summary for domain ZENPR

The following section provides a summary of the Group Policy Objects.

+ + + + + + + + + + + + + + +
Display NameGpoStatusCreatedModified
Assign-ApplicationsAll Settings Enabled03/10/202103/10/2021
Certificate AutoEnrollmentUser Settings Disabled01/25/202006/30/2021
Default Domain PolicyAll Settings Enabled06/10/201809/15/2020
VEEAM_Disable_FirewallAll Settings Enabled12/13/201909/08/2020
Default Domain Controllers PolicyAll Settings Enabled06/10/201811/01/2020
ProfileUnityAll Settings Enabled06/08/202009/13/2021
VEEAM_Local_AdministratorsAll Settings Enabled12/13/201909/08/2020
WSUS - Domain PolicyUser Settings Disabled02/23/202003/10/2021
SCEP ConfigurationAll Settings Enabled09/14/202010/04/2020
Horizon-DEMAll Settings Enabled03/01/202009/08/2020
Linux-Settings-GPOAll Settings Enabled05/22/202105/22/2021
SCCM - Restricted Group and General SettingsAll Settings Enabled09/12/202009/12/2020
LAPS ConfigurationAll Settings Enabled11/01/202011/01/2020
+
Table 17 - Group Policy Objects Information.

+

1.2.6.9 Organizational Unit summary for domain ZENPR

The following section provides a summary of Active Directory OU information on ZENPR.LOCAL.

+ + + + + + + + + + + + + + + + + + + + + +
NameDistinguished NameLinked GPO
Domain ControllersOU=Domain Controllers,DC=zenpr,DC=localDefault Domain Controllers Policy
Member ServersOU=Member Servers,DC=zenpr,DC=local 
Configuration ManagerOU=Configuration Manager,DC=zenpr,DC=localSCEP Configuration, SCCM - Restricted Group and General Settings
EMC NAS serversOU=EMC NAS servers,DC=zenpr,DC=local 
ComputersOU=Computers,OU=EMC NAS servers,DC=zenpr,DC=local 
VEEAM ServersOU=VEEAM Servers,DC=zenpr,DC=localVEEAM_Disable_Firewall, VEEAM_Local_Administrators
VEEAM WorkStationsOU=VEEAM WorkStations,DC=zenpr,DC=localVEEAM_Local_Administrators, VEEAM_Disable_Firewall
VDI-ComputersOU=VDI-Computers,DC=zenpr,DC=localHorizon-DEM
Fortinet EMSOU=Fortinet EMS,DC=zenpr,DC=local 
ProfileUnity VDIOU=ProfileUnity VDI,DC=zenpr,DC=localVEEAM_Local_Administrators, VEEAM_Disable_Firewall
ServersOU=Servers,OU=ProfileUnity VDI,DC=zenpr,DC=local 
ComputersOU=Computers,OU=ProfileUnity VDI,DC=zenpr,DC=localProfileUnity
Configuration Manager ComputersOU=Configuration Manager Computers,DC=zenpr,DC=localLAPS Configuration, SCEP Configuration
MarketingOU=Marketing,OU=VDI-Computers,DC=zenpr,DC=local 
SalesOU=Sales,OU=VDI-Computers,DC=zenpr,DC=local 
HROU=HR,OU=VDI-Computers,DC=zenpr,DC=local 
FinancesOU=Finances,OU=VDI-Computers,DC=zenpr,DC=local 
Admins PCOU=Admins PC,DC=zenpr,DC=local 
-OU=-,DC=zenpr,DC=local 
LinuxMachinesOU=LinuxMachines,DC=zenpr,DC=localLinux-Settings-GPO
+
Table 18 - Active Directory Organizational Unit Information - ZENPR.LOCAL

+

1.3 Active Directory Information for domain ACAD.ZENPR.LOCAL

The following section provides a summary of the AD Domain Information.

+ + + + + + + + + + + + + + + + +
Domain Nameacad
NetBIOS NameACAD
Domain SIDS-1-5-21-370360276-377477351-3184454278
Domain Functional LevelWindows2016Domain
Domains 
Forestzenpr.local
Parent Domainzenpr.local
Replica Directory Serversacade-dc-01v.acad.zenpr.local
Child Domains 
Computers ContainerCN=Computers,DC=acad,DC=zenpr,DC=local
Distinguished NameDC=acad,DC=zenpr,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=acad,DC=zenpr,DC=local
Systems ContainerCN=System,DC=acad,DC=zenpr,DC=local
Users ContainerCN=Users,DC=acad,DC=zenpr,DC=local
ReadOnly Replica Directory Servers 
+
Table 19 - AD Domain Summary Information - ACAD.ZENPR.LOCAL

+

1.3.1 Domain Object Count Summary

The following section provides a summary of the Active Directory Object Count on ACAD.ZENPR.LOCAL.

+ + +
Domain NameComputer CountUsers CountGroup Count
acad.zenpr.local1444
+
Table 20 - Active Directory Object Count Information - ACAD.ZENPR.LOCAL

+

1.3.2 Default Domain Password Policy Summary

The following section provides a summary of the Default Domain Password Policy on ACAD.ZENPR.LOCAL.

+ + + + + + + + + + + + +
Domain Nameacad.zenpr.local
Complexity EnabledYes
Distinguished NameDC=acad,DC=zenpr,DC=local
Lockout Duration00 days 00 hours 30 minutes 00 seconds
Lockout Threshold0
Lockout Observation Window00 days 00 hours 30 minutes 00 seconds
Max Password Age42 days 00 hours 00 minutes 00 seconds
Min Password Age01 days 00 hours 00 minutes 00 seconds
Min Password Length7
Password History Count24
Reversible Encryption EnabledNo
+
Table 21 - Default Domain Password Policy Information - ACAD.ZENPR.LOCAL

+

1.3.3 Group Managed Service Accounts (GMSA) Summary

The following section provides a summary of the Group Managed Service Accounts on ACAD.ZENPR.LOCAL.

+ + + + + + + + + + + + + + +
NameSQLServer
SamAccountNameSQLServer$
Created09/27/2020 14:14:22
EnabledYes
DNS Host NameSQL-Cluster
Host ComputersCN=SQL-CLUSTER-02V,OU=Member Servers,DC=zenpr,DC=local
CN=SQL-CLUSTER-01V,OU=Member Servers,DC=zenpr,DC=local
Retrieve Managed PasswordCN=SQL-CLUSTER-01V,OU=Member Servers,DC=zenpr,DC=local
CN=SQL-CLUSTER-02V,OU=Member Servers,DC=zenpr,DC=local
Primary GroupCN=Domain Computers,CN=Users,DC=zenpr,DC=local
Last Logon Date09/27/2020 14:41:08
Locked OutNo
Logon Count3
Password ExpiredNo
Password Last Set09/27/2020 14:14:22
+
+
+ + + + + + + + + + + + + + +
Nameadfsgmsa
SamAccountNameadfsgmsa$
Created10/07/2020 18:36:16
EnabledYes
DNS Host NameADFS.zenpr.local
Host Computers 
Retrieve Managed PasswordCN=SERVER-ADFS-01V,OU=Member Servers,DC=zenpr,DC=local
CN=SERVER-ADFS-02V,OU=Member Servers,DC=zenpr,DC=local
Primary GroupCN=Domain Computers,CN=Users,DC=zenpr,DC=local
Last Logon Date10/07/2020 18:36:17
Locked OutNo
Logon Count40
Password ExpiredNo
Password Last Set10/07/2020 18:36:16
+
+

1.3.4 Flexible Single Master Operations (FSMO) Information

The following section provides a summary of the Active Directory FSMO for Domain ACAD.ZENPR.LOCAL.

+ + + + + + +
Infrastructure Master Serveracade-dc-01v.acad.zenpr.local
RID Master Serveracade-dc-01v.acad.zenpr.local
PDC Emulator Nameacade-dc-01v.acad.zenpr.local
Domain Naming Master ServerServer-DC-01V.zenpr.local
Schema Master ServerServer-DC-01V.zenpr.local
+
Table 22 - FSMO Server Information - acad.zenpr.local

+

1.3.5 Trust Summary

The following section provides a summary of Active Directory Trust information on ACAD.ZENPR.LOCAL.

+ + + + + + + + + + + + +
Namezenpr.local
Distinguished NameCN=zenpr.local,CN=System,DC=acad,DC=zenpr,DC=local
SourceDC=acad,DC=zenpr,DC=local
Targetzenpr.local
DirectionBiDirectional
IntraForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
Trust TypeUplevel
Uplevel OnlyNo
+
Table 23 - Active Directory Trusts Information - ACAD.ZENPR.LOCAL

+

1.3.6 Domain Controller Information

The following section provides a summary of the Active Directory Domain Controller.

+ + +
DC NameDomain NameSiteGlobal CatalogRead OnlyIP Address
ACADE-DC-01Vacad.zenpr.localACADYesNo172.23.4.1
+
Table 24 - AD Domain Controller Summary Information - ACAD.ZENPR.LOCAL

+

1.3.6.1 Domain Controller Hardware Summary

The following section provides a summary of the Domain Controller Hardware for ACAD.ZENPR.LOCAL.

+ + + + + + + + + +
Nameacade-dc-01v
WindowsProductNameWindows Server 2019 Standard Evaluation
ManufacturerVMware, Inc.
CsModelVMware7,1
Bios TypeUefi
CPU Socket1
CPU Cores2
Total RAM4.00 GB
+
Table 25 - AD Domain Controller Hardware Information - ACAD.ZENPR.LOCAL

+

1.3.6.2 Domain Controller NTDS Summary

The following section provides a summary of the Domain Controller NTDS file size on ACAD.ZENPR.LOCAL.

+ + +
NameDSA Database FileSize
acade-dc-01v.acad.zenpr.localC:\Windows\NTDS\ntds.dit36.00 MB
+
Table 26 - Domain Controller NTDS Database File Usage Information - ACAD.ZENPR.LOCAL

+
1.3.6.2.1 Domain Controller Time Source Summary
The following section provides a summary of the Domain Controller Time Source configuration on ACAD.ZENPR.LOCAL.

+ + +
NameTime ServerType
acade-dc-01v.acad.zenpr.localDomain HierarchyDOMHIER
+
Table 27 - Domain Controller Time Source Configuration - ACAD.ZENPR.LOCAL

+

1.3.6.3 DCDiag Information

The following section provides a summary of the Active Directory DC Diagnostic.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
DC NameTest NameResult
acade-dc-01v.acad.zenpr.localConnectivitypassed
acade-dc-01v.acad.zenpr.localAdvertisingpassed
acade-dc-01v.acad.zenpr.localFrsEventpassed
acade-dc-01v.acad.zenpr.localDFSREventfailed
acade-dc-01v.acad.zenpr.localSysVolCheckpassed
acade-dc-01v.acad.zenpr.localKccEventpassed
acade-dc-01v.acad.zenpr.localKnowsOfRoleHolderspassed
acade-dc-01v.acad.zenpr.localMachineAccountpassed
acade-dc-01v.acad.zenpr.localNCSecDescpassed
acade-dc-01v.acad.zenpr.localNetLogonspassed
acade-dc-01v.acad.zenpr.localObjectsReplicatedpassed
acade-dc-01v.acad.zenpr.localReplicationspassed
acade-dc-01v.acad.zenpr.localRidManagerpassed
acade-dc-01v.acad.zenpr.localServicespassed
acade-dc-01v.acad.zenpr.localSystemLogfailed
acade-dc-01v.acad.zenpr.localVerifyReferencespassed
acade-dc-01v.acad.zenpr.localCheckSDRefDompassed
acade-dc-01v.acad.zenpr.localCheckSDRefDompassed
acade-dc-01v.acad.zenpr.localCrossRefValidationpassed
acade-dc-01v.acad.zenpr.localCheckSDRefDompassed
acade-dc-01v.acad.zenpr.localCheckSDRefDompassed
acade-dc-01v.acad.zenpr.localCrossRefValidationpassed
acade-dc-01v.acad.zenpr.localCheckSDRefDompassed
acade-dc-01v.acad.zenpr.localCrossRefValidationpassed
acade-dc-01v.acad.zenpr.localLocatorCheckpassed
acade-dc-01v.acad.zenpr.localIntersitepassed
+
Table 28 - AD Domain Controller DCDiag Information - ACAD.ZENPR.LOCAL

+

1.3.6.4 Domain Controller Infrastructure Services Status of ACADE-DC-01V

The following section provides a summary of the Domain Controller Infrastructure services status.

+ + + + + + + + +
Display NameShort NameStatus
DNS ServerDNSRunning
DFS ReplicationDFSRRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Active Directory Domain ServicesNTDSRunning
Windows TimeW32TimeRunning
+
Table 29 - Domain Controller Infrastructure Services Status Information.

+

1.3.6.5 Site Replication Summary

The following section provides a summary of the Active Directory Site Replication information.

+ + + + + + + + + + + +
DC Nameacade-dc-01v.acad.zenpr.local
GUID739a49db-275b-4d09-81c8-ab9e5f393977
Description 
Replicate From Directory ServerCN=NTDS Settings,CN=SERVER-DC-01V,CN=Servers,CN=Zenpr-HQ,CN=Sites,CN=Configuration,DC=zenpr,DC=local
Replicate To Directory Serveracade-dc-01v.acad.zenpr.local
Replicated Naming ContextsDC=DomainDnsZones,DC=acad,DC=zenpr,DC=local
DC=acad,DC=zenpr,DC=local
DC=ForestDnsZones,DC=zenpr,DC=local
CN=Schema,CN=Configuration,DC=zenpr,DC=local
CN=Configuration,DC=zenpr,DC=local
Transport ProtocolIP
AutoGeneratedYes
EnabledYes
CreatedSun, 05 Sep 2021 16:26:31 GMT
+
Table 30 - Site Replication Information - ACAD.ZENPR.LOCAL

+

1.3.6.6 Group Policy Objects Summary for domain ACAD

The following section provides a summary of the Group Policy Objects.

+ + + +
Display NameGpoStatusCreatedModified
Default Domain PolicyAll Settings Enabled09/05/202109/05/2021
Default Domain Controllers PolicyAll Settings Enabled09/05/202109/05/2021
+
Table 31 - Group Policy Objects Information.

+

1.3.6.7 Organizational Unit summary for domain ACAD

The following section provides a summary of Active Directory OU information on ACAD.ZENPR.LOCAL.

+ + + + + +
NameDistinguished NameLinked GPO
Domain ControllersOU=Domain Controllers,DC=acad,DC=zenpr,DC=localDefault Domain Controllers Policy
Member ServersOU=Member Servers,DC=acad,DC=zenpr,DC=local 
Acad ComputersOU=Acad Computers,DC=acad,DC=zenpr,DC=local 
SCCM ComputersOU=SCCM Computers,OU=Acad Computers,DC=acad,DC=zenpr,DC=local 
+
Table 32 - Active Directory Organizational Unit Information - ACAD.ZENPR.LOCAL

+

1.4 Domain Name System Information for domain ZENPR.LOCAL

The following section provides a summary of the Domain Name System Information.

1.4.1 Infrastructure Summary

The following section provides a summary of the Domain Name System Infrastructure configuration.

+ + + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
SERVER-DC-01V17763YesNoNo192.168.5.1
CAYEY-DC-01V17763YesNoNofe80::b5fd:f35b:d81d:dfcd
10.10.33.1
+
Table 33 - Domain Name System Infrastructure Setting Information.

+

1.4.1.1 Response Rate Limiting (RRL) Summary

The following section provides a summary of the Domain Name System Response Rate Limiting configuration.

+ + + +
DC NameStatusResponses Per SecErrors Per SecWindow In SecLeak RateTruncate Rate
SERVER-DC-01VDisable55532
CAYEY-DC-01VDisable55532
+
Table 34 - Domain Name System Response Rate Limiting configuration.

+

1.4.1.2 Scavenging Summary

The following section provides a summary of the Domain Name System Scavenging configuration.

+ + + +
DC NameNoRefresh IntervalRefresh IntervalScavenging IntervalLast Scavenge TimeScavenging State
SERVER-DC-01V7.00:00:007.00:00:007.00:00:00 Enabled
CAYEY-DC-01V7.00:00:007.00:00:0000:00:00 Disabled
+
Table 35 - Domain Name System Scavenging configuration.

+

1.4.1.3 Forwarder Summary

The following section provides a summary of the Domain Name System Forwarder configuration.

+ + + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
SERVER-DC-01V192.168.1.2
192.168.1.1
3/sYesYes
CAYEY-DC-01V192.168.5.1
192.168.1.1
3/sYesYes
+
Table 36 - Domain Name System Infrastructure Forwarder configuration.

+

1.4.1.4 Zone Scope Recursion Summary

The following section provides a summary of the Domain Name System Zone Scope Recursion configuration.

+ + + +
DC NameZone NameForwarderUse Recursion
SERVER-DC-01VRoot192.168.1.2
192.168.1.1
Yes
CAYEY-DC-01VRoot192.168.5.1
192.168.1.1
Yes
+
Table 37 - Domain Name System Zone Scope Recursion configuration.

+

1.5 Domain Name System Information for domain ACAD.ZENPR.LOCAL

The following section provides a summary of the Domain Name System Information.

1.5.1 Infrastructure Summary

The following section provides a summary of the Domain Name System Infrastructure configuration.

+ + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
ACADE-DC-01V17763YesNoNo172.23.4.1
+
Table 41 - Domain Name System Infrastructure Setting Information.

+

1.5.1.1 Response Rate Limiting (RRL) Summary

The following section provides a summary of the Domain Name System Response Rate Limiting configuration.

+ + +
DC NameStatusResponses Per SecErrors Per SecWindow In SecLeak RateTruncate Rate
ACADE-DC-01VDisable55532
+
Table 42 - Domain Name System Response Rate Limiting configuration.

+

1.5.1.2 Scavenging Summary

The following section provides a summary of the Domain Name System Scavenging configuration.

+ + +
DC NameNoRefresh IntervalRefresh IntervalScavenging IntervalLast Scavenge TimeScavenging State
ACADE-DC-01V7.00:00:007.00:00:0000:00:00 Disabled
+
Table 43 - Domain Name System Scavenging configuration.

+

1.5.1.3 Forwarder Summary

The following section provides a summary of the Domain Name System Forwarder configuration.

+ + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
ACADE-DC-01V192.168.5.13/sYesYes
+
Table 44 - Domain Name System Infrastructure Forwarder configuration.

+

1.5.1.4 Zone Scope Recursion Summary

The following section provides a summary of the Domain Name System Zone Scope Recursion configuration.

+ + +
DC NameZone NameForwarderUse Recursion
ACADE-DC-01VRoot192.168.5.1Yes
+
Table 45 - Domain Name System Zone Scope Recursion configuration.

+

1.6 Domain Name System Zone Configuration of ACADE-DC-01V

The following section provides a summary of the Domain Name System Zone Configuration information.

+ + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.zenpr.localPrimaryForestSecureYesNoNo
acad.zenpr.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
+
Table 46 - Domain Name System Zone Information.

+

1.6.1 Reverse Lookup Zone Configuration of ACADE-DC-01V

The following section provides a summary of the Domain Name System Reverse Lookup Zone Configuration information.

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
0.in-addr.arpaPrimaryNoneNoneNoNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
+
Table 47 - Domain Name System Zone Information.

+

1.6.2 Zone Scope Aging properties of ACADE-DC-01V

The following section provides a summary of the Domain Name System Zone Aging properties information.

+ + + + +
Zone NameAging EnabledRefresh IntervalNoRefresh IntervalAvailable For Scavenge
_msdcs.zenpr.localYes7.00:00:007.00:00:00Sun, 12 Sep 2021 23:00:00 GMT
acad.zenpr.localNo7.00:00:007.00:00:00 
TrustAnchorsYes7.00:00:007.00:00:00Thu, 07 Jan 2021 16:00:00 GMT
+
Table 48 - Domain Name System Zone Aging properties Information.

+
+

diff --git a/Src/Private/Get-AbrADDCDiag.ps1 b/Src/Private/Get-AbrADDCDiag.ps1 new file mode 100644 index 0000000..1d4288c --- /dev/null +++ b/Src/Private/Get-AbrADDCDiag.ps1 @@ -0,0 +1,68 @@ +function Get-AbrADDCDiag { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Sites information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + [string] + $DC, + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory DCDiag information for domain $Domain." + } + + process { + $OutObj = @() + if ($DC) { + try { + Write-PscriboMessage "Discovering Active Directory DCDiag information for DC $DC." + $DCDIAG = Invoke-DcDiag -DomainController $DC + Write-PscriboMessage "Discovered Active Directory DCDiag information for DC $DC." + foreach ($Result in $DCDIAG) { + Write-PscriboMessage "Collecting Active Directory DCDiag test '$($Result.TestName)' for DC $DC." + $inObj = [ordered] @{ + 'DC Name' = $DC + 'Test Name' = $Result.TestName + 'Result' = $Result.TestResult + } + $OutObj += [pscustomobject]$inobj + } + $TableParams = @{ + Name = "AD Domain Controller DCDiag Information - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 35, 35, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PScriboMessage -IsDebug $_.Exception.Message + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADDNSInfrastructure.ps1 b/Src/Private/Get-AbrADDNSInfrastructure.ps1 new file mode 100644 index 0000000..aaf62ce --- /dev/null +++ b/Src/Private/Get-AbrADDNSInfrastructure.ps1 @@ -0,0 +1,247 @@ +function Get-AbrADDNSInfrastructure { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Name System Infrastructure information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory Domain Name System Infrastructure information for $Domain" + } + + process { + Section -Style Heading4 "Infrastructure Summary" { + Paragraph "The following section provides a summary of the Domain Name System Infrastructure configuration." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + if ($DCs) {Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller on $Domain"} + foreach ($DC in $DCs) { + Write-PscriboMessage "Collecting Domain Name System Infrastructure information on '$($DC)'." + try { + $DNSSetting = Invoke-Command -Session $Session {Get-DnsServerSetting -ComputerName $using:DC} + $inObj = [ordered] @{ + 'DC Name' = $($DNSSetting.ComputerName.ToString().ToUpper().Split(".")[0]) + 'Build Number' = $DNSSetting.BuildNumber + 'IPv6' = ConvertTo-TextYN $DNSSetting.EnableIPv6 + 'DnsSec' = ConvertTo-TextYN $DNSSetting.EnableDnsSec + 'ReadOnly DC' = ConvertTo-TextYN $DNSSetting.IsReadOnlyDC + 'Listening IP' = $DNSSetting.ListeningIPAddress + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Name System Infrastructure Setting Information." + List = $false + ColumnWidths = 30, 10, 9, 10, 11, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + Section -Style Heading5 "Response Rate Limiting (RRL) Summary" { + Paragraph "The following section provides a summary of the Domain Name System Response Rate Limiting configuration." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + if ($DCs) {Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller on $Domain"} + foreach ($DC in $DCs) { + Write-PscriboMessage "Collecting Domain Name System Infrastructure information on '$($DC)'." + try { + $DNSSetting = Invoke-Command -Session $Session {Get-DnsServerResponseRateLimiting -ComputerName $using:DC} + $inObj = [ordered] @{ + 'DC Name' = $($DC.ToString().ToUpper().Split(".")[0]) + 'Status' = $DNSSetting.Mode + 'Responses Per Sec' = $DNSSetting.ResponsesPerSec + 'Errors Per Sec' = $DNSSetting.ErrorsPerSec + 'Window In Sec' = $DNSSetting.WindowInSec + 'Leak Rate' = $DNSSetting.LeakRate + 'Truncate Rate' = $DNSSetting.TruncateRate + + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Name System Response Rate Limiting configuration." + List = $false + ColumnWidths = 30, 10, 12, 12, 12, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Section -Style Heading5 "Scavenging Summary" { + Paragraph "The following section provides a summary of the Domain Name System Scavenging configuration." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + if ($DCs) {Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller on $Domain"} + foreach ($DC in $DCs) { + Write-PscriboMessage "Collecting Domain Name System Infrastructure information on '$($DC)'." + try { + $DNSSetting = Invoke-Command -Session $Session {Get-DnsServerScavenging -ComputerName $using:DC} + $inObj = [ordered] @{ + 'DC Name' = $($DC.ToString().ToUpper().Split(".")[0]) + 'NoRefresh Interval' = $DNSSetting.NoRefreshInterval + 'Refresh Interval' = $DNSSetting.RefreshInterval + 'Scavenging Interval' = $DNSSetting.ScavengingInterval + 'Last Scavenge Time' = Switch ($DNSSetting.LastScavengeTime) { + !$Null {$DNSSetting.LastScavengeTime.ToString("MM/dd/yyyy")} + default {$DNSSetting.LastScavengeTime} + + } + 'Scavenging State' = Switch ($DNSSetting.ScavengingState) { + "True" {"Enabled"} + "False" {"Disabled"} + default {$DNSSetting.ScavengingState} + } + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Name System Scavenging configuration." + List = $false + ColumnWidths = 25, 15, 15, 15, 15, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Section -Style Heading5 "Forwarder Summary" { + Paragraph "The following section provides a summary of the Domain Name System Forwarder configuration." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + if ($DCs) {Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller on $Domain"} + foreach ($DC in $DCs) { + Write-PscriboMessage "Collecting Domain Name System Infrastructure information on '$($DC)'." + try { + $DNSSetting = Invoke-Command -Session $Session {Get-DnsServerForwarder -ComputerName $using:DC} + $Recursion = Invoke-Command -Session $Session {Get-DnsServerRecursion -ComputerName $using:DC | Select-Object -ExpandProperty Enable} + $inObj = [ordered] @{ + 'DC Name' = $($DC.ToString().ToUpper().Split(".")[0]) + 'IP Address' = $DNSSetting.IPAddress + 'Timeout' = "$($DNSSetting.Timeout)/s" + 'Use Root Hint' = ConvertTo-TextYN $DNSSetting.UseRootHint + 'Use Recursion' = ConvertTo-TextYN $Recursion + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Name System Infrastructure Forwarder configuration." + List = $false + ColumnWidths = 35, 15, 15, 15, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Section -Style Heading5 "Zone Scope Recursion Summary" { + Paragraph "The following section provides a summary of the Domain Name System Zone Scope Recursion configuration." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + if ($DCs) {Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller on $Domain"} + foreach ($DC in $DCs) { + Write-PscriboMessage "Collecting Domain Name System Infrastructure information on '$($DC)'." + try { + $DNSSetting = Invoke-Command -Session $Session {Get-DnsServerRecursionScope -ComputerName $using:DC} + $inObj = [ordered] @{ + 'DC Name' = $($DC.ToString().ToUpper().Split(".")[0]) + 'Zone Name' = Switch ($DNSSetting.Name) { + "." {"Root"} + default {$DNSSetting.Name} + } + 'Forwarder' = $DNSSetting.Forwarder + 'Use Recursion' = ConvertTo-TextYN $DNSSetting.EnableRecursion + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Name System Zone Scope Recursion configuration." + List = $false + ColumnWidths = 35, 25, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADDNSZone.ps1 b/Src/Private/Get-AbrADDNSZone.ps1 new file mode 100644 index 0000000..e1bddb7 --- /dev/null +++ b/Src/Private/Get-AbrADDNSZone.ps1 @@ -0,0 +1,200 @@ +function Get-AbrADDNSZone { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Name System Zone information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + [PSCredential] + $Cred, + [string] + $DC + ) + + begin { + Write-PscriboMessage "Discovering Actve Directory Domain Name System Zone information on $Domain." + } + + process { + Section -Style Heading4 "Domain Name System Zone Configuration of $($DC.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Domain Name System Zone Configuration information." + BlankLine + $OutObj = @() + if ($DC) { + try { + Write-PscriboMessage "Discovered Actve Directory Domain Controller: $DC. (Domain Name System Zone)" + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $DNSSetting = Invoke-Command -Session $DCPssSession {Get-DnsServerZone | Where-Object {$_.IsReverseLookupZone -like "False"}} + foreach ($Zones in $DNSSetting) { + Write-PscriboMessage "Collecting Actve Directory DNS Zone: '$($Zones.ZoneName)' on $DC" + $inObj = [ordered] @{ + 'Zone Name' = $Zones.ZoneName + 'Zone Type' = $Zones.ZoneType + 'Replication Scope' = $Zones.ReplicationScope + 'Dynamic Update' = $Zones.DynamicUpdate + 'DS Integrated' = ConvertTo-TextYN $Zones.IsDsIntegrated + 'Read Only' = ConvertTo-TextYN $Zones.IsReadOnly + 'Signed' = ConvertTo-TextYN $Zones.IsSigned + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + + $TableParams = @{ + Name = "Domain Name System Zone Information." + List = $false + ColumnWidths = 25, 15, 12, 12, 12, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + try { + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + Write-PscriboMessage "Discovered Actve Directory Domain Controller: $DC. (Domain Name System Zone)" + $DNSSetting = Invoke-Command -Session $DCPssSession {Get-DnsServerZone | Where-Object {$_.IsReverseLookupZone -like "False" -and $_.ReplicationScope -eq "Domain"} | Select-Object -ExpandProperty ZoneName } + $Zones = Invoke-Command -Session $DCPssSession {Get-DnsServerZoneDelegation -Name $using:DNSSetting} + if ($Zones) { + Section -Style Heading5 "Zone Delegation of $($DC.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Domain Name System Zone Delegation information." + BlankLine + $OutObj = @() + if ($DC -and $DNSSetting -and $Zones) { + if ($Zones) { + foreach ($Delegations in $Zones) { + if ($Delegations) { + Write-PscriboMessage "Collecting Actve Directory DNS Zone: '$($Delegations.ZoneName)' on $DC" + $inObj = [ordered] @{ + 'Zone Name' = $Delegations.ZoneName + 'Child Zone' = $Delegations.ChildZoneName + 'Name Server' = $Delegations.NameServer.RecordData.NameServer + 'IP Address' = $Delegations.IPaddress.RecordData.IPv4Address.IPAddressToString + } + $OutObj += [pscustomobject]$inobj + } + } + } + + $TableParams = @{ + Name = "Domain Name System Zone Delegation Information." + List = $false + ColumnWidths = 25, 25, 32, 18 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + Section -Style Heading5 "Reverse Lookup Zone Configuration of $($DC.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Domain Name System Reverse Lookup Zone Configuration information." + BlankLine + $OutObj = @() + if ($DC) { + try { + Write-PscriboMessage "Discovered Actve Directory Domain Controller: $DC (Domain Name System Zone)" + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $DNSSetting = Invoke-Command -Session $DCPssSession {Get-DnsServerZone | Where-Object {$_.IsReverseLookupZone -like "True"}} + foreach ($Zones in $DNSSetting) { + Write-PscriboMessage "Collecting Actve Directory DNS Zone: '$($Zones.ZoneName)' on $DC" + $inObj = [ordered] @{ + 'Zone Name' = $Zones.ZoneName + 'Zone Type' = $Zones.ZoneType + 'Replication Scope' = $Zones.ReplicationScope + 'Dynamic Update' = $Zones.DynamicUpdate + 'DS Integrated' = ConvertTo-TextYN $Zones.IsDsIntegrated + 'Read Only' = ConvertTo-TextYN $Zones.IsReadOnly + 'Signed' = ConvertTo-TextYN $Zones.IsSigned + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + + $TableParams = @{ + Name = "Domain Name System Zone Information." + List = $false + ColumnWidths = 25, 15, 12, 12, 12, 12, 12 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Section -Style Heading5 "Zone Scope Aging properties of $($DC.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Domain Name System Zone Aging properties information." + BlankLine + $OutObj = @() + try { + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + Write-PscriboMessage "Discovered Actve Directory Domain Controller: $DC. (Domain Name System Zone)" + $DNSSetting = Invoke-Command -Session $DCPssSession {Get-DnsServerZone | Where-Object {$_.IsReverseLookupZone -like "False"} | Select-Object -ExpandProperty ZoneName } + $Zones = Invoke-Command -Session $DCPssSession {Get-DnsServerZoneAging -Name $using:DNSSetting} + foreach ($Settings in $Zones) { + Write-PscriboMessage "Collecting Actve Directory DNS Zone: '$($Settings.ZoneName)' on $DC" + $inObj = [ordered] @{ + 'Zone Name' = $Settings.ZoneName + 'Aging Enabled' = ConvertTo-TextYN $Settings.AgingEnabled + 'Refresh Interval' = $Settings.RefreshInterval + 'NoRefresh Interval' = $Settings.NoRefreshInterval + 'Available For Scavenge' = if ($Settings.AvailForScavengeTime) {($Settings.AvailForScavengeTime).ToUniversalTime().toString("r")} + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + + if ($HealthCheck.DNS.Aging) { + $OutObj | Where-Object { $_.'Aging Enabled' -ne 'Yes'} | Set-Style -Style Warning -Property 'Aging Enabled' + } + + $TableParams = @{ + Name = "Domain Name System Zone Aging properties Information." + List = $false + ColumnWidths = 25, 10, 15, 15, 35 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADDomain.ps1 b/Src/Private/Get-AbrADDomain.ps1 new file mode 100644 index 0000000..fcf0286 --- /dev/null +++ b/Src/Private/Get-AbrADDomain.ps1 @@ -0,0 +1,212 @@ +function Get-AbrADDomain { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain information from Domain Controller + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Discovering AD Domain information on forest $Forestinfo." + } + + process { + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + try { + $DomainInfo = Invoke-Command -Session $Session {Get-ADDomain $using:Item -ErrorAction Stop} + Write-PscriboMessage "Discovered Active Directory Domain information of domain $Domain." + if ($DomainInfo) { + Write-PscriboMessage "Collectin Domain information of '$($DomainInfo.Name)'." + $inObj = [ordered] @{ + 'Domain Name' = $DomainInfo.Name + 'NetBIOS Name' = $DomainInfo.NetBIOSName + 'Domain SID' = $DomainInfo.DomainSID + 'Domain Functional Level' = $DomainInfo.DomainMode + 'Domains' = $DomainInfo.Domains + 'Forest' = $DomainInfo.Forest + 'Parent Domain' = $DomainInfo.ParentDomain + 'Replica Directory Servers' = $DomainInfo.ReplicaDirectoryServers + 'Child Domains' = $DomainInfo.ChildDomains + 'Computers Container' = $DomainInfo.ComputersContainer + 'Distinguished Name' = $DomainInfo.DistinguishedName + 'Domain Controllers Container' = $DomainInfo.DomainControllersContainer + 'Systems Container' = $DomainInfo.SystemsContainer + 'Users Container' = $DomainInfo.UsersContainer + 'ReadOnly Replica Directory Servers' = $DomainInfo.ReadOnlyReplicaDirectoryServers + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Item" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + + $TableParams = @{ + Name = "AD Domain Summary Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + if ($OutObj) {$OutObj | Table @TableParams} + } + } + Section -Style Heading5 'Domain Object Count Summary' { + Paragraph "The following section provides a summary of the Active Directory Object Count on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Collecting the Active Directory Object Count of domain $Item." + try { + $GlobalCatalog = "$(Invoke-Command -Session $Session {Get-ADDomainController -Discover -Service GlobalCatalog | Select-Object -ExpandProperty HostName}):3268" + $Computers = Invoke-Command -Session $Session {(Get-ADComputer -Filter * -Server $using:GlobalCatalog -Searchbase (Get-ADDomain -Identity $using:Item).distinguishedName) | Measure-Object} + #$Servers = (Get-ADComputer -LDAPFilter "(&(objectClass=Computer)(operatingSystem=*Windows server*))" -Server "$($GlobalCatalog.name):3268" -Searchbase (Get-ADDomain -Identity $Item).distinguishedName) | Measure-Object + $Users = Invoke-Command -Session $Session {(Get-ADUser -filter * -Server $using:GlobalCatalog -Searchbase (Get-ADDomain -Identity $using:Item).distinguishedName) | Measure-Object} + $Group = Invoke-Command -Session $Session {(Get-ADGroup -filter * -Server $using:GlobalCatalog -Searchbase (Get-ADDomain -Identity $using:Item).distinguishedName) | Measure-Object} + $inObj = [ordered] @{ + 'Domain Name' = $Item + 'Computer Count' = $Computers.Count + #'Servers Count' = $Servers.Count + 'Users Count' = $Users.Count + 'Group Count' = $Group.Count + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Item" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Active Directory Object Count Information - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 40, 20, 20, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + if ($OutObj) {$OutObj | Table @TableParams} + } + } + Section -Style Heading5 'Default Domain Password Policy Summary' { + Paragraph "The following section provides a summary of the Default Domain Password Policy on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Collecting the Active Directory Default Domain Password Policy of domain $Item." + try { + $PasswordPolicy = Invoke-Command -Session $Session {Get-ADDefaultDomainPasswordPolicy -Identity $using:Item} + $inObj = [ordered] @{ + 'Domain Name' = $Item + 'Complexity Enabled' = ConvertTo-TextYN $PasswordPolicy.ComplexityEnabled + 'Distinguished Name' = $PasswordPolicy.DistinguishedName + 'Lockout Duration' = $PasswordPolicy.LockoutDuration.toString("dd' days 'hh' hours 'mm' minutes 'ss' seconds'") + 'Lockout Threshold' = $PasswordPolicy.LockoutThreshold + 'Lockout Observation Window' = $PasswordPolicy.LockoutObservationWindow.toString("dd' days 'hh' hours 'mm' minutes 'ss' seconds'") + 'Max Password Age' = $PasswordPolicy.MaxPasswordAge.toString("dd' days 'hh' hours 'mm' minutes 'ss' seconds'") + 'Min Password Age' = $PasswordPolicy.MinPasswordAge.toString("dd' days 'hh' hours 'mm' minutes 'ss' seconds'") + 'Min Password Length' = $PasswordPolicy.MinPasswordLength + 'Password History Count' = $PasswordPolicy.PasswordHistoryCount + 'Reversible Encryption Enabled' = ConvertTo-TextYN $PasswordPolicy.ReversibleEncryptionEnabled + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Item" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Default Domain Password Policy Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + if ($OutObj) {$OutObj | Table @TableParams} + } + } + Section -Style Heading5 'Group Managed Service Accounts (GMSA) Summary' { + Paragraph "The following section provides a summary of the Group Managed Service Accounts on $($Domain.ToString().ToUpper())." + BlankLine + $Domain = "pharmax.local" + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PScriboMessage "Collecting the Active Directory Group Managed Service Accounts for $Item." + try { + $DC = Invoke-Command -Session $TempPssSession {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers | Select-Object -First 1} + Write-PScriboMessage "Collecting the Active Directory Group Managed Service Accounts from DC $DC." + $GMSA = Invoke-Command -Session $TempPssSession {Get-ADServiceAccount -Filter * -Server $using:DC -Properties *} + foreach ($Account in $GMSA) { + $inObj = [ordered] @{ + 'Name' = $Account.Name + 'SamAccountName' = $Account.SamAccountName + 'Created' = $Account.Created + 'Enabled' = ConvertTo-TextYN $Account.Enabled + 'DNS Host Name' = $Account.DNSHostName + 'Host Computers' = $Account.HostComputers + 'Retrieve Managed Password' = $Account.PrincipalsAllowedToRetrieveManagedPassword + 'Primary Group' = $Account.PrimaryGroup + 'Last Logon Date' = $Account.LastLogonDate + 'Locked Out' = ConvertTo-TextYN $Account.LockedOut + 'Logon Count' = $Account.logonCount + 'Password Expired' = ConvertTo-TextYN $Account.PasswordExpired + 'Password Last Set' = $Account.PasswordLastSet + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Item" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + + if ($HealthCheck.Domain.GMSA) { + $OutObj | Where-Object { $_.'Enabled' -notlike 'Yes'} | Set-Style -Style Warning -Property 'Enabled' + } + + $TableParams = @{ + Name = "Group Managed Service Accounts Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + if ($OutObj) {$OutObj | Table @TableParams} + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADDomainController.ps1 b/Src/Private/Get-AbrADDomainController.ps1 new file mode 100644 index 0000000..01cbdb2 --- /dev/null +++ b/Src/Private/Get-AbrADDomainController.ps1 @@ -0,0 +1,219 @@ +function Get-AbrADDomainController { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Controller information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session, + [PSCredential] + $Cred + ) + + begin { + Write-PscriboMessage "Collecting AD Domain Controller information." + } + + process { + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Discovering Active Directory Domain Controller information in $Domain." + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + foreach ($DC in $DCs) { + Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller in domain $Domain." + try { + Write-PscriboMessage "Collecting AD Domain Controller Summary information of $DC." + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $DCInfo = Invoke-Command -Session $DCPssSession {Get-ADDomainController -Identity $using:DC} + $inObj = [ordered] @{ + 'DC Name' = ($DCInfo.Name).ToString().ToUpper() + 'Domain Name' = $DCInfo.Domain + 'Site' = $DCInfo.Site + 'Global Catalog' = ConvertTo-TextYN $DCInfo.IsGlobalCatalog + 'Read Only' = ConvertTo-TextYN $DCInfo.IsReadOnly + 'IP Address' = $DCInfo.IPv4Address + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "AD Domain Controller Summary Information - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 25, 25, 15, 10, 10, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + Write-PscriboMessage "Collecting AD Domain Controller Hardware information for domain $Domain" + Section -Style Heading5 'Domain Controller Hardware Summary' { + Paragraph "The following section provides a summary of the Domain Controller Hardware for $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Discovering Active Directory Domain Controller information in $Domain." + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller in domain $Domain." + foreach ($DC in $DCs) { + try { + Write-PscriboMessage "Collecting AD Domain Controller Hardware information for $DC." + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $HW = Invoke-Command -Session $DCPssSession -ScriptBlock { Get-ComputerInfo } + if ($HW) { + $inObj = [ordered] @{ + 'Name' = $HW.CsDNSHostName + 'WindowsProductName' = $HW.WindowsProductName + 'Manufacturer' = $HW.CsManufacturer + 'CsModel' = $HW.CsModel + 'Bios Type' = $HW.BiosFirmwareType + 'CPU Socket' = $HW.CsNumberOfProcessors + 'CPU Cores' = $HW.CsNumberOfLogicalProcessors + 'Total RAM' = ConvertTo-FileSizeString $HW.CsTotalPhysicalMemory + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "AD Domain Controller Hardware Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Write-PscriboMessage "Collecting AD Domain Controller NTDS information." + Section -Style Heading5 'Domain Controller NTDS Summary' { + Paragraph "The following section provides a summary of the Domain Controller NTDS file size on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Discovering Active Directory Domain Controller information in $Domain." + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller in domain $Domain." + foreach ($DC in $DCs) { + try { + Write-PscriboMessage "Collecting AD Domain Controller NTDS information for $DC." + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $NTDS = Invoke-Command -Session $DCPssSession -ScriptBlock {Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\NTDS\Parameters | Select-Object -ExpandProperty 'DSA Database File'} + $size = Invoke-Command -Session $DCPssSession -ScriptBlock {(Get-ItemProperty -Path $using:NTDS).Length} + if ( $NTDS -and $size ) { + $inObj = [ordered] @{ + 'Name' = $DC + 'DSA Database File' = $NTDS + 'Size' = ConvertTo-FileSizeString $size + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Controller NTDS Database File Usage Information - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 40, 40, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + Write-PscriboMessage "Collecting AD Domain Controller Time Source information." + Section -Style Heading5 'Domain Controller Time Source Summary' { + Paragraph "The following section provides a summary of the Domain Controller Time Source configuration on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + foreach ($Item in $Domain) { + Write-PscriboMessage "Discovering Active Directory Domain Controller information in $Domain." + $DCs = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + Write-PscriboMessage "Discovered '$(($DCs | Measure-Object).Count)' Active Directory Domain Controller in domain $Domain." + foreach ($DC in $DCs) { + try { + Write-PscriboMessage "Collecting AD Domain Controller Time Source information for $DC." + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $NtpServer = Invoke-Command -Session $DCPssSession -ScriptBlock {Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\W32Time\Parameters | Select-Object -ExpandProperty 'NtpServer'} + $SourceType = Invoke-Command -Session $DCPssSession -ScriptBlock {Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\W32Time\Parameters | Select-Object -ExpandProperty 'Type'} + + if ( $NtpServer -and $SourceType ) { + $inObj = [ordered] @{ + 'Name' = $DC + 'Time Server' = Switch ($NtpServer) { + 'time.windows.com,0x8' {"Domain Hierarchy"} + 'time.windows.com' {"Domain Hierarchy"} + '0x8' {"Domain Hierarchy"} + default {$NtpServer} + } + 'Type' = Switch ($SourceType) { + 'NTP' {"MANUAL (NTP)"} + 'NT5DS' {"DOMHIER"} + default {$SourceType} + } + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + } + + $TableParams = @{ + Name = "Domain Controller Time Source Configuration - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 40, 40, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADFSMO.ps1 b/Src/Private/Get-AbrADFSMO.ps1 new file mode 100644 index 0000000..2a9aa2b --- /dev/null +++ b/Src/Private/Get-AbrADFSMO.ps1 @@ -0,0 +1,69 @@ +function Get-AbrADFSMO { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Flexible Single Master Operations information from Domain Controller + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory FSMO information of domain $ForestInfo." + } + + process { + Section -Style Heading4 'Flexible Single Master Operations (FSMO) Information' { + Paragraph "The following section provides a summary of the Active Directory FSMO for Domain $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + try { + $DomainData = Invoke-Command -Session $Session {Get-ADDomain $using:Domain | Select-Object InfrastructureMaster, RIDMaster, PDCEmulator} + $ForestData = Invoke-Command -Session $Session {Get-ADForest $using:Domain | Select-Object DomainNamingMaster, SchemaMaster} + Write-PscriboMessage "Discovered Active Directory FSMO information of domain $Domain." + $inObj = [ordered] @{ + 'Infrastructure Master Server' = $DomainData.InfrastructureMaster + 'RID Master Server' = $DomainData.RIDMaster + 'PDC Emulator Name' = $DomainData.PDCEmulator + 'Domain Naming Master Server' = $ForestData.DomainNamingMaster + 'Schema Master Server' = $ForestData.SchemaMaster + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Could not connect to domain $Domain" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + + $TableParams = @{ + Name = "FSMO Server Information - $($Domain)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADForest.ps1 b/Src/Private/Get-AbrADForest.ps1 new file mode 100644 index 0000000..1f8b257 --- /dev/null +++ b/Src/Private/Get-AbrADForest.ps1 @@ -0,0 +1,105 @@ +function Get-AbrADForest { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD information from Domain Controller + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory forest information." + } + + process { + $Data = Invoke-Command -Session $Session {Get-ADForest} + $ForestInfo = $Data.RootDomain.toUpper() + Write-PscriboMessage "Discovered Active Directory information of forest $ForestInfo." + $ADVersion = Invoke-Command -Session $Session {Get-ADObject (Get-ADRootDSE).schemaNamingContext -property objectVersion | Select-Object objectVersion} + $ADnumber = $ADVersion -replace "@{objectVersion=","" -replace "}","" + If ($ADnumber -eq '88') {$server = 'Windows Server 2019'} + ElseIf ($ADnumber -eq '87') {$server = 'Windows Server 2016'} + ElseIf ($ADnumber -eq '69') {$server = 'Windows Server 2012 R2'} + ElseIf ($ADnumber -eq '56') {$server = 'Windows Server 2012'} + ElseIf ($ADnumber -eq '47') {$server = 'Windows Server 2008 R2'} + ElseIf ($ADnumber -eq '44') {$server = 'Windows Server 2008'} + ElseIf ($ADnumber -eq '31') {$server = 'Windows Server 2003 R2'} + ElseIf ($ADnumber -eq '30') {$server = 'Windows Server 2003'} + $OutObj = @() + if ($Data) { + Write-PscriboMessage "Collecting Active Directory information of forest $ForestInfo." + foreach ($Item in $Data) { + $inObj = [ordered] @{ + 'Forest Name' = $Item.RootDomain + 'Forest Functional Level' = $Item.ForestMode + 'Schema Version' = "ObjectVersion $ADnumber, Correspond to $server" + 'Domains' = $Item.Domains -join '; ' + 'Global Catalogs' = $Item.GlobalCatalogs -join '; ' + 'Application Partitions' = $Item.ApplicationPartitions + 'PartitionsContainer' = [string]$Item.PartitionsContainer + 'SPN Suffixes' = $Item.SPNSuffixes + 'UPN Suffixes' = $Item.UPNSuffixes + } + $OutObj += [pscustomobject]$inobj + } + + $TableParams = @{ + Name = "AD Forest Summary Information - $($ForestInfo)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + Section -Style Heading5 'Optional Features Summary' { + Paragraph "The following section provides a summary of the enabled Optional Features." + BlankLine + Write-PscriboMessage "Discovering Optional Features enabled on forest $ForestInfo." + $Data = Invoke-Command -Session $Session {Get-ADOptionalFeature -Filter *} + $OutObj = @() + if ($Data) { + Write-PscriboMessage "Discovered Optional Features enabled on forest $ForestInfo." + foreach ($Item in $Data) { + Write-PscriboMessage "Collecting Optional Features '$($Item.Name)'" + $Forest = Invoke-Command -Session $Session {Get-ADForest} + $inObj = [ordered] @{ + 'Name' = $Item.Name + 'Required Forest Mode' = $Item.RequiredForestMode + 'Forest' = $Forest.RootDomain.toUpper() + } + $OutObj += [pscustomobject]$inobj + } + + $TableParams = @{ + Name = "Active Directory Enabled Optional Features Information - $($ForestInfo)" + List = $false + ColumnWidths = 40, 30, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADGPO.ps1 b/Src/Private/Get-AbrADGPO.ps1 new file mode 100644 index 0000000..4ee1db4 --- /dev/null +++ b/Src/Private/Get-AbrADGPO.ps1 @@ -0,0 +1,70 @@ +function Get-AbrADGPO { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft Active Directory Group Policy Objects information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory Group Policy Objects information for $($Domain.ToString().ToUpper())." + } + + process { + Section -Style Heading5 "Group Policy Objects Summary for domain $($Domain.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Group Policy Objects." + BlankLine + $OutObj = @() + if ($Domain) { + try { + $GPOs = Invoke-Command -Session $Session -ScriptBlock {Get-GPO -Domain $using:Domain -All} + Write-PscriboMessage "Discovered Active Directory Group Policy Objects information on $Domain. (Group Policy Objects)" + foreach ($GPO in $GPOs) { + Write-PscriboMessage "Collecting Active Directory Group Policy Objects '$($GPO.DisplayName)'. (Group Policy Objects)" + $inObj = [ordered] @{ + 'Display Name' = $GPO.DisplayName + 'GpoStatus' = ($GPO.GpoStatus -creplace '([A-Z\W_]|\d+)(? + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $DC, + [pscredential] + $Cred + ) + + begin { + Write-PscriboMessage "Discovering Active Directory DC Infrastructure Services information of $DC." + } + + process { + Write-PscriboMessage "Discovering AD Domain Controller Time Source information for $DC." + try { + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $Available = Invoke-Command -Session $DCPssSession -ScriptBlock {Get-Service "W32Time" | Select-Object DisplayName, Name, Status} + if ($Available) { + Write-PscriboMessage "Discovered Active Directory DC Infrastructure Services information of $DC." + Section -Style Heading5 "Domain Controller Infrastructure Services Status of $($DC.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of the Domain Controller Infrastructure services status." + BlankLine + $OutObj = @() + if ($DC) { + $Services = @('DNS','DFS Replication','Intersite Messaging','Kerberos Key Distribution Center','NetLogon','Active Directory Domain Services','W32Time') + foreach ($Service in $Services) { + $Status = Invoke-Command -Session $DCPssSession -ScriptBlock {Get-Service $using:Service | Select-Object DisplayName, Name, Status} + Write-PscriboMessage "Collecting Domain Controller '$($Status.DisplayName)' Services status on $DC." + $inObj = [ordered] @{ + 'Display Name' = $Status.DisplayName + 'Short Name' = $Status.Name + 'Status' = $Status.Status + } + $OutObj += [pscustomobject]$inobj + } + + if ($HealthCheck.DomainController.Services) { + $OutObj | Where-Object { $_.'Status' -notlike 'Running'} | Set-Style -Style Warning -Property 'Status' + } + + $TableParams = @{ + Name = "Domain Controller Infrastructure Services Status Information." + List = $false + ColumnWidths = 40, 40, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PScriboMessage -IsDebug $_.Exception.Message + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADOU.ps1 b/Src/Private/Get-AbrADOU.ps1 new file mode 100644 index 0000000..1733ac7 --- /dev/null +++ b/Src/Private/Get-AbrADOU.ps1 @@ -0,0 +1,77 @@ +function Get-AbrADOU { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Organizational Unit information + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory Organizational Unit information on domain $Domain" + } + + process { + Section -Style Heading5 "Organizational Unit summary for domain $($Domain.ToString().ToUpper().Split(".")[0])" { + Paragraph "The following section provides a summary of Active Directory OU information on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + try { + $DC = Invoke-Command -Session $Session -ScriptBlock {Get-ADDomainController -Discover -Domain $using:Domain | Select-Object -ExpandProperty HostName} + Write-PscriboMessage "Discovered Active Directory Organizational Unit information on DC $DC. (Organizational Unit)" + $OUs = Invoke-Command -Session $Session -ScriptBlock {Get-ADOrganizationalUnit -Server $using:DC -Searchbase (Get-ADDomain -Identity $using:Domain).distinguishedName -Filter *} + foreach ($OU in $OUs) { + Write-PscriboMessage "Collecting information of Active Directory Organizational Unit $OU. (Organizational Unit)" + $GPOArray = @() + [array]$GPOs = $OU.LinkedGroupPolicyObjects + foreach ($Object in $GPOs) { + $GP = Get-GPO -Guid $Object.Split(",")[0].Split("=")[1] + Write-PscriboMessage "Collecting linked GPO: '$($GP.DisplayName)' on Organizational Unit $OU. (Organizational Unit)" + $GPOArray += $GP.DisplayName + } + $inObj = [ordered] @{ + 'Name' = $OU.Name + 'Distinguished Name' = $OU.DistinguishedName + 'Linked GPO' = $GPOArray -join ", " + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to DC: $DC (Group Policy Objects)" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + $TableParams = @{ + Name = "Active Directory Organizational Unit Information - $($Domain.ToString().ToUpper())" + List = $false + ColumnWidths = 25, 40, 35 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADSite.ps1 b/Src/Private/Get-AbrADSite.ps1 new file mode 100644 index 0000000..620a090 --- /dev/null +++ b/Src/Private/Get-AbrADSite.ps1 @@ -0,0 +1,120 @@ +function Get-AbrADSite { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Sites information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + $Session + ) + + begin { + Write-PscriboMessage "Discovering Active Directory Sites information of forest $ForestInfo" + } + + process { + Section -Style Heading3 'Domain Site Summary' { + Paragraph "The following section provides a summary of the Active Directory Sites on." + BlankLine + $Data = Invoke-Command -Session $Session {Get-ADReplicationSite -Filter * -Properties *} + $OutObj = @() + if ($Data) { + Write-PscriboMessage "Discovered Active Directory Sites information of forest $ForestInfo" + foreach ($Item in $Data) { + try { + Write-PscriboMessage "Collecting '$($Item.Name)' Site" + $SubnetArray = @() + $Subnets = $Item.Subnets + foreach ($Object in $Subnets) { + $SubnetName = Invoke-Command -Session $Session {Get-ADReplicationSubnet $using:Object} + $SubnetArray += $SubnetName.Name + } + $inObj = [ordered] @{ + 'Site Name' = $Item.Name + 'Description' = $Item.Description + 'Creation Date' = ($Item.createTimeStamp).ToUniversalTime().toString("r") + 'Subnets' = $SubnetArray + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Unable to retreive Forest: $ForestInfo information." + Write-PScriboMessage -IsDebug $_.Exception.Message + continue + } + } + + $TableParams = @{ + Name = "AD Domain Controller Summary Information - $($ForestInfo)" + List = $false + ColumnWidths = 25, 30, 25, 20 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Section -Style Heading4 'Site Links Summary' { + Paragraph "The following section provides a summary of the Active Directory Site Link information." + BlankLine + $Data = Invoke-Command -Session $Session {Get-ADReplicationSiteLink -Filter * -Properties *} + $OutObj = @() + if ($Data) { + Write-PscriboMessage "Discovered Active Directory Sites Link information of forest $ForestInfo" + foreach ($Item in $Data) { + try { + Write-PscriboMessage "Collecting '$($Item.Name)' Site Link" + $SiteArray = @() + $Sites = $Item.siteList + foreach ($Object in $Sites) { + $SiteName = Invoke-Command -Session $Session {Get-ADReplicationSite -Identity $using:Object} + $SiteArray += $SiteName.Name + } + $inObj = [ordered] @{ + 'Site Link Name' = $Item.Name + 'Cost' = $Item.Cost + 'Replication Frequency' = "$($Item.ReplicationFrequencyInMinutes) min" + 'Transport Protocol' = $Item.InterSiteTransportProtocol + 'Sites' = $SiteArray + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning "Error: Unable to retreive Forest: $ForestInfo information." + Write-PScriboMessage -IsDebug $_.Exception.Message + continue + } + } + + $TableParams = @{ + Name = "Site Links Information - $($ForestInfo)" + List = $false + ColumnWidths = 30, 15, 15, 15, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADSiteReplication.ps1 b/Src/Private/Get-AbrADSiteReplication.ps1 new file mode 100644 index 0000000..60f9397 --- /dev/null +++ b/Src/Private/Get-AbrADSiteReplication.ps1 @@ -0,0 +1,133 @@ +function Get-AbrADSiteReplication { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Domain Sites Replication information. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session + ) + + begin { + Write-PscriboMessage "Collecting AD Domain Sites Replication information." + } + + process { + Write-PscriboMessage "Collecting AD Domain Sites Replication Summary. (Sites Replication)" + Section -Style Heading4 'Site Replication Summary' { + Paragraph "The following section provides a summary of the Active Directory Site Replication information." + BlankLine + $OutObj = @() + if ($Domain) { + Write-PscriboMessage "Discovering Active Directory Sites Replication information on $Domain. (Sites Replication)" + foreach ($Item in $Domain) { + try { + # TODO Why is this working? only God knows! (Investigate) + $DCs = Invoke-Command -Session $Session -ScriptBlock {Get-ADDomain -Identity $using:Item | Select-Object -ExpandProperty ReplicaDirectoryServers} + foreach ($DC in $DCs) { + $Replication = Invoke-Command -Session $Session -ScriptBlock {Get-ADReplicationConnection -Server $using:DC -Properties *} + if ($Replication) {Write-PscriboMessage "Collecting Active Directory Sites Replication information on $DC. (Sites Replication)"} + foreach ($Repl in $Replication) { + $inObj = [ordered] @{ + 'DC Name' = $DC + 'GUID' = $Repl.ObjectGUID + 'Description' = $Repl.Description + 'Replicate From Directory Server' = $Repl.ReplicateFromDirectoryServer + 'Replicate To Directory Server' = $DC + 'Replicated Naming Contexts' = $Repl.ReplicatedNamingContexts + 'Transport Protocol' = $Repl.InterSiteTransportProtocol + 'AutoGenerated' = ConvertTo-TextYN $Repl.AutoGenerated + 'Enabled' = ConvertTo-TextYN $Repl.enabledConnection + 'Created' = ($Repl.Created).ToUniversalTime().toString("r") + } + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to DC $DC (Sites Replication)" + Write-PscriboMessage -IsDebug $_.Exception.Message + + } + } + + if ($HealthCheck.Site.Replication) { + $OutObj | Where-Object { $_.'Enabled' -ne 'Yes'} | Set-Style -Style Warning -Property 'Enabled' + } + + $TableParams = @{ + Name = "Site Replication Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + Write-PscriboMessage "Discovering Active Directory Sites Replication Failure on $Domain. (Sites Replication Failure)" + if (($HealthCheck.Site.Replication) -and (Invoke-Command -Session $Session -ScriptBlock {Get-ADReplicationFailure -Target $using:Domain -Scope Domain})) { + Section -Style Heading4 'Site Replication Failure Summary' { + Paragraph "The following section provides a summary of the Active Directory Site Replication Failure information." + BlankLine + $OutObj = @() + foreach ($Item in $Domain) { + try { + Write-PscriboMessage "Discovered Active Directory Sites Replication Failure on $Item. (Sites Replication Failure)" + $Failures = Invoke-Command -Session $Session -ScriptBlock {Get-ADReplicationFailure -Target $using:Domain -Scope Domain} + foreach ($Fails in $Failures) { + Write-PscriboMessage "Collecting Active Directory Sites Replication Failure on '$($Fails.Server)'. (Sites Replication Failure)" + $inObj = [ordered] @{ + 'Server Name' = $Fails.Server + 'Partner' = $Fails.Partner + 'Last Error' = $Fails.LastError + 'Failure Type' = $Fails.FailureType + 'Failure Count' = $Fails.FailureCount + 'First Failure Time' = ($Fails.FirstFailureTime).ToUniversalTime().toString("r") + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to Domain $Domian (Sites Replication Failure)" + Write-PscriboMessage -IsDebug $_.Exception.Message + } + } + + if ($HealthCheck.Site.Replication) { + $OutObj | Where-Object {$NULL -notlike $_.'Last Error'} | Set-Style -Style Warning -Property 'Last Error', 'Failure Type', 'Failure Count', 'First Failure Time' + } + + $TableParams = @{ + Name = "Site Replication Failure Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + } + + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrADTrust.ps1 b/Src/Private/Get-AbrADTrust.ps1 new file mode 100644 index 0000000..72221ba --- /dev/null +++ b/Src/Private/Get-AbrADTrust.ps1 @@ -0,0 +1,83 @@ +function Get-AbrADTrust { + <# + .SYNOPSIS + Used by As Built Report to retrieve Microsoft AD Trust from Domain Controller + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + param ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $Domain, + $Session, + [PSCredential] + $Cred + ) + + begin { + Write-PscriboMessage "Collecting AD Trust information of $($Domain.ToString().ToUpper())." + } + + process { + Section -Style Heading5 'Trust Summary' { + Paragraph "The following section provides a summary of Active Directory Trust information on $($Domain.ToString().ToUpper())." + BlankLine + $OutObj = @() + if ($Domain) { + try { + $DC = Invoke-Command -Session $Session {Get-ADDomain -Identity $using:Domain | Select-Object -ExpandProperty ReplicaDirectoryServers | Select-Object -First 1} + Write-PScriboMessage "Discovered '$(($DC | Measure-Object).Count)' Active Directory Domain Controller in domain $Domain." + $DCPssSession = New-PSSession $DC -Credential $Cred -Authentication Default + $Trusts = Invoke-Command -Session $DCPssSession {Get-ADTrust -Filter *} + if ($Trusts) {Write-PScriboMessage "Discovered created trusts in domain $Domain"} + foreach ($Trust in $Trusts) { + Write-PscriboMessage "Collecting Active Directory Domain Trust information from $($Trust.Name)" + $inObj = [ordered] @{ + 'Name' = $Trust.Name + 'Distinguished Name' = $Trust.DistinguishedName + 'Source' = $Trust.Source + 'Target' = $Trust.Target + 'Direction' = $Trust.Direction + 'IntraForest' = ConvertTo-TextYN $Trust.IntraForest + 'Selective Authentication' = ConvertTo-TextYN $Trust.SelectiveAuthentication + 'SID Filtering Forest Aware' = ConvertTo-TextYN $Trust.SIDFilteringForestAware + 'SID Filtering Quarantined' = ConvertTo-TextYN $Trust.SIDFilteringQuarantined + 'Trust Type' = $Trust.TrustType + 'Uplevel Only' = ConvertTo-TextYN $Trust.UplevelOnly + } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation." + Write-PScriboMessage -IsDebug $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Active Directory Trusts Information - $($Domain.ToString().ToUpper())" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + + 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..bb4a941 --- /dev/null +++ b/Src/Private/SharedUtilsFunctions.ps1 @@ -0,0 +1,108 @@ +function ConvertTo-TextYN { + <# + .SYNOPSIS + Used by As Built Report to convert true or false automatically to Yes or No. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: LEE DAILEY + + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + [OutputType([String])] + Param + ( + [Parameter ( + Position = 0, + Mandatory)] + [string] + $TEXT + ) + + switch ($TEXT) + { + "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.2.0 + Author: LEE DAILEY + + .EXAMPLE + + .LINK + + #> + [CmdletBinding()] + [OutputType([String])] + Param + ( + [Parameter ( + Position = 0, + Mandatory)] + [int64] + $Size + ) + + switch ($Size) + { + {$_ -gt 1TB} + {[string]::Format("{0:0.00} TB", $Size / 1TB); break} + {$_ -gt 1GB} + {[string]::Format("{0:0.00} GB", $Size / 1GB); break} + {$_ -gt 1MB} + {[string]::Format("{0:0.00} MB", $Size / 1MB); break} + {$_ -gt 1KB} + {[string]::Format("{0:0.00} KB", $Size / 1KB); break} + {$_ -gt 0} + {[string]::Format("{0} B", $Size); break} + {$_ -eq 0} + {"0 KB"; break} + default + {"0 KB"} + } + } # end >> function Format-FileSize + function Invoke-DcDiag { + <# + .SYNOPSIS + Used by As Built Report to get the dcdiag tests for a Domain Controller. + .DESCRIPTION + + .NOTES + Version: 0.2.0 + Author: Adam Bertram + + .EXAMPLE + + .LINK + + #> + param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string]$DomainController + ) + $result = Invoke-Command -Session $TempPssSession {dcdiag /s:$using:DomainController} + $result | select-string -pattern '\. (.*) \b(passed|failed)\b test (.*)' | ForEach-Object { + $obj = @{ + TestName = $_.Matches.Groups[3].Value + TestResult = $_.Matches.Groups[2].Value + Entity = $_.Matches.Groups[1].Value + } + [pscustomobject]$obj + } + } \ No newline at end of file diff --git a/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 b/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 new file mode 100644 index 0000000..e871503 --- /dev/null +++ b/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 @@ -0,0 +1,154 @@ +function Invoke-AsBuiltReport.Microsoft.AD { + <# + .SYNOPSIS + PowerShell script to document the configuration of Microsoft AD in Word/HTML/Text formats + .DESCRIPTION + Documents the configuration of Microsoft AD in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.2.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Microsoft.AD + #> + + # Do not remove or add to these parameters + param ( + [String[]] $Target, + [PSCredential] $Credential + ) + + # Import Report Configuration + $Report = $ReportConfig.Report + $InfoLevel = $ReportConfig.InfoLevel + $Options = $ReportConfig.Options + + # Used to set values to TitleCase where required + $TextInfo = (Get-Culture).TextInfo + + # Update/rename the $System 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 + #---------------------------------------------------------------------------------------------# + # Connection Section # + #---------------------------------------------------------------------------------------------# + foreach ($System in $Target) { + Try { + Write-PScriboMessage "Connecting to Domain Controller Server '$System'." + $TempPssSession = New-PSSession $System -Credential $Credential -Authentication Default + $ADSystem = Invoke-Command -Session $TempPssSession { Get-ADForest -ErrorAction Stop} + } Catch { + Write-Verbose "Unable to connect to the Domain Controller: $System" + throw + } + $global:ForestInfo = $ADSystem.RootDomain.toUpper() + #---------------------------------------------------------------------------------------------# + # Forest Section # + #---------------------------------------------------------------------------------------------# + Section -Style Heading1 "Report for Active Directory Forest $($ForestInfo.toUpper())" { + Paragraph "The following section provides a summary of the Active Directory Infrastructure configuration for $($ForestInfo)." + BlankLine + Write-PScriboMessage "Forest InfoLevel set at $($InfoLevel.Forest)." + if ($InfoLevel.Forest -gt 0) { + try { + Section -Style Heading2 "Forest Information." { + Get-AbrADForest -Session $TempPssSession + Get-AbrADSite -Session $TempPssSession + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Unable to retreive Forest: $ForestInfo information." + Write-PScriboMessage -IsDebug $_.Exception.Message + continue + } + } + #---------------------------------------------------------------------------------------------# + # Domain Section # + #---------------------------------------------------------------------------------------------# + if ($InfoLevel.Domain -gt 0) { + foreach ($Domain in (Invoke-Command -Session $TempPssSession {Get-ADForest | Select-Object -ExpandProperty Domains | Sort-Object -Descending})) { + try { + if (Invoke-Command -Session $TempPssSession {Get-ADDomain -Identity $using:Domain}) { + Section -Style Heading3 "Active Directory Information for domain $($Domain.ToString().ToUpper())" { + Paragraph "The following section provides a summary of the AD Domain Information." + BlankLine + Get-AbrADDomain -Domain $Domain -Session $TempPssSession + Get-AbrADFSMO -Domain $Domain -Session $TempPssSession + Get-AbrADTrust -Domain $Domain -Session $TempPssSession -Cred $Credential + Section -Style Heading4 'Domain Controller Information' { + Paragraph "The following section provides a summary of the Active Directory Domain Controller." + BlankLine + Get-AbrADDomainController -Domain $Domain -Session $TempPssSession -Cred $Credential + if ($HealthCheck.DomainController.Diagnostic) { + try { + Section -Style Heading4 'DCDiag Information' { + Paragraph "The following section provides a summary of the Active Directory DC Diagnostic." + BlankLine + $DCs = Invoke-Command -Session $TempPssSession {Get-ADDomain -Identity $using:Domain | Select-Object -ExpandProperty ReplicaDirectoryServers} + foreach ($DC in $DCs){ + Get-AbrADDCDiag -Domain $Domain -Session $TempPssSession -DC $DC + } + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation. ('DCDiag Information)" + Write-PScriboMessage -IsDebug $_.Exception.Message + continue + } + } + try { + $DCs = Invoke-Command -Session $TempPssSession {Get-ADDomain -Identity $using:Domain | Select-Object -ExpandProperty ReplicaDirectoryServers} + foreach ($DC in $DCs){ + Get-AbrADInfrastructureService -DC $DC -Cred $Credential + } + } + catch { + Write-PscriboMessage -IsWarning "Error: Connecting to remote server $DC failed: WinRM cannot complete the operation. (ADInfrastructureService)" + Write-PScriboMessage -IsDebug $_.Exception.Message + continue + } + Get-AbrADSiteReplication -Domain $Domain -Session $TempPssSession + Get-AbrADGPO -Domain $Domain -Session $TempPssSession + Get-AbrADOU -Domain $Domain -Session $TempPssSession + } + } + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Domain" + Write-PscriboMessage -IsDebug $_.Exception.Message + continue + } + } + } + #---------------------------------------------------------------------------------------------# + # DNS Section # + #---------------------------------------------------------------------------------------------# + if ($InfoLevel.DNS -gt 0) { + foreach ($Domain in ( Invoke-Command -Session $TempPssSession {Get-ADForest | Select-Object -ExpandProperty Domains | Sort-Object -Descending})) { + try { + if (Invoke-Command -Session $TempPssSession {Get-ADDomain $using:Domain -ErrorAction Stop}) { + Section -Style Heading3 "Domain Name System Information for domain $($Domain.ToString().ToUpper())" { + Paragraph "The following section provides a summary of the Domain Name System Information." + BlankLine + Get-AbrADDNSInfrastructure -Domain $Domain -Session $TempPssSession + } + } + $DCs = Invoke-Command -Session $TempPssSession {Get-ADDomain $using:Domain | Select-Object -ExpandProperty ReplicaDirectoryServers} + foreach ($DC in $DCs){ + Get-AbrADDNSZone -Domain $Domain -DC $DC -Cred $Credential + } + } + catch { + Write-PscriboMessage -IsWarning "WARNING: Could not connect to domain $Domain" + Write-PscriboMessage -IsDebug $_.Exception.Message + continue + } + } + } + }#endregion AD Section + }#endregion foreach loop +} \ No newline at end of file