From c0fc6cda438da890a70176d293349ea2ede5d698 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 3 Apr 2026 20:47:15 -0400 Subject: [PATCH 01/18] Update print statement from 'Hello' to 'Goodbye' --- README.md | 3418 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 3172 insertions(+), 246 deletions(-) diff --git a/README.md b/README.md index 6df76a2..fdb418e 100644 --- a/README.md +++ b/README.md @@ -1,251 +1,3177 @@ - -

- - -

-

- - - - - - -

-

- - - - - - -

-

- - -

- + + +Microsoft Active Directory As Built Report + +
-> [!WARNING] -> This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages—including lost profits, business interruptions, or financial losses arising from the use of this report or its recommendations. +











+AsBuiltReport Logo +
+
Microsoft Active Directory As Built Report

Zen PR Solutions






















+ + + +
Author:As Built Report
Date:Thursday, April 2, 2026
Version:1.0
+
+
+
Microsoft Active Directory As Built Report - v1.0

Table of Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1PHARMAX.LOCAL Active Directory Forest
1.1   Forest Configuration
1.1.1      Forest Diagram
1.1.2      Certificate Authority
1.1.3      Certificate Authority Diagram
1.1.4      Optional Features
1.2   AD Sites & Replication
1.2.1      Replication
1.2.1.1         Replication Diagram
1.2.1.2         Sites
1.2.1.3         Site Subnets
1.2.1.4         Site Topology Diagram
1.2.1.5         Inter-Site Transports
1.2.1.5.1            IP
1.2.1.5.1.1               Site Links
1.2.1.5.1.2               Site Link Bridges
1.2.1.6         Sysvol Replication
1.3   Infrastructure Services
1.3.1      Exchange Infrastructure
1.3.2      SCCM Infrastructure
1.3.3      DHCP Infrastructure
2AD Domain Configuration
2.1   PHARMAX.LOCAL
2.1.1      FSMO Roles
2.1.2      Domain and Trusts
2.1.2.1         Domain and Trusts Diagram
2.1.3      Directory Objects
2.1.3.1         User Objects
2.1.3.2         Group Objects
2.1.3.2.1            Privileged Groups (Built-in)
2.1.3.2.2            Empty Groups (Non-Default)
2.1.3.2.3            Circular Group Membership
2.1.3.2.4            Pre-Windows 2000 Compatible Access Group Membership
2.1.3.3         Computer Objects
2.1.3.3.1            Status of Computer Accounts
2.1.3.3.2            Operating Systems Count
2.1.4      Account Policies
2.1.4.1         Default Domain Password Policy
2.1.4.2         Fined Grained Password Policies
2.1.4.3         Microsoft LAPS
2.1.4.4         gMSA Identities
2.1.4.5         Foreign Security Principals
2.1.5      Domain Controllers
2.1.5.1         Configuration
2.1.5.1.1            CAGUAS-DC-01V
2.1.5.1.2            CAROLINA-DC-01V
2.1.5.1.3            CAYEY-DC-01V
2.1.5.1.4            NAGUABO-DC-01V
2.1.5.1.5            PONCE-DC-01V
2.1.5.1.6            SERVER-DC-01V
2.1.5.2         DNS IP Configuration
2.1.5.3         NTDS Information
2.1.5.4         Time Source Information
2.1.5.5         SRV Records Status
2.1.5.6         File Shares
2.1.5.7         Installed Software
2.1.5.8         Missing Windows Updates
2.1.5.9         Roles
2.1.5.10         Infrastructure Services
2.1.6      Replication
2.1.6.1         Replication Connection
2.1.6.2         Replication Status
2.1.7      Group Policy
2.1.7.1         Group Policy Objects
2.1.7.1.1            GPO Inventory
2.1.7.1.2            GPO Settings
2.1.7.1.3            GPO Health
2.1.8      Organizational Units
2.1.9      Active Directory Hardening
2.1.10      Health Checks
2.2   ACAD.PHARMAX.LOCAL
2.2.1      FSMO Roles
2.2.2      Domain and Trusts
2.2.2.1         Domain and Trusts Diagram
2.2.3      Directory Objects
2.2.3.1         User Objects
2.2.3.2         Group Objects
2.2.3.2.1            Privileged Groups (Built-in)
2.2.3.2.2            Privileged Group (Non-Default)
2.2.3.2.3            Empty Groups (Non-Default)
2.2.3.2.4            Circular Group Membership
2.2.3.2.5            Pre-Windows 2000 Compatible Access Group Membership
2.2.3.3         Computer Objects
2.2.3.3.1            Status of Computer Accounts
2.2.3.3.2            Operating Systems Count
2.2.4      Account Policies
2.2.4.1         Default Domain Password Policy
2.2.4.2         Fined Grained Password Policies
2.2.4.3         gMSA Identities
2.2.4.4         Foreign Security Principals
2.2.5      Domain Controllers
2.2.5.1         Configuration
2.2.5.1.1            ACADE-DC-01V
2.2.5.2         DNS IP Configuration
2.2.5.3         NTDS Information
2.2.5.4         Time Source Information
2.2.5.5         SRV Records Status
2.2.5.6         File Shares
2.2.5.7         Installed Software
2.2.5.8         Missing Windows Updates
2.2.5.9         Roles
2.2.5.10         Infrastructure Services
2.2.6      Replication
2.2.6.1         Replication Connection
2.2.6.2         Replication Status
2.2.7      Group Policy
2.2.7.1         Group Policy Objects
2.2.7.1.1            GPO Inventory
2.2.7.1.2            GPO Settings
2.2.7.1.3            GPO Health
2.2.8      Organizational Units
2.2.9      Active Directory Hardening
2.2.10      Health Checks
3DNS Configuration
3.1   PHARMAX.LOCAL
3.1.1      Infrastructure Summary
3.1.1.1         Forwarder Options
3.1.2      CAGUAS-DC-01V DNS Zones
3.1.2.1         Reverse Lookup Zone
3.1.2.2         Conditional Forwarder
3.1.3      CAROLINA-DC-01V DNS Zones
3.1.3.1         Reverse Lookup Zone
3.1.3.2         Conditional Forwarder
3.1.4      CAYEY-DC-01V DNS Zones
3.1.4.1         Reverse Lookup Zone
3.1.4.2         Conditional Forwarder
3.1.5      NAGUABO-DC-01V DNS Zones
3.1.5.1         Reverse Lookup Zone
3.1.5.2         Conditional Forwarder
3.1.6      PONCE-DC-01V DNS Zones
3.1.6.1         Reverse Lookup Zone
3.1.6.2         Conditional Forwarder
3.1.7      SERVER-DC-01V DNS Zones
3.1.7.1         Reverse Lookup Zone
3.1.7.2         Conditional Forwarder
3.2   ACAD.PHARMAX.LOCAL
3.2.1      Infrastructure Summary
3.2.1.1         Forwarder Options
3.2.2      ACADE-DC-01V DNS Zones
3.2.2.1         Reverse Lookup Zone
3.2.2.2         Conditional Forwarder
+

+
Microsoft Active Directory As Built Report - v1.0

DISCLAIMER

This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages-including lost profits, business interruptions, or financial losses-arising from the use of this report or its recommendations.

+
Microsoft Active Directory As Built Report - v1.0

Report Brief

This report brief provides a high-level summary of the Active Directory environment, including infrastructure topology, domain configuration, and the scope of this document.

+ + + + + + +
Company NameZen PR Solutions
ContactJonathan Colon
Email Addressjcolonf@zenprsolutions.com
Target ForestPHARMAX.LOCAL
Generated On2026-04-02 20:03:53
+
Table 1 - Report Overview - PHARMAX.LOCAL

+
+ + + + + + + + +
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Root Domainpharmax.local
Total Domains2
Total Sites8
Global Catalog Servers8
UPN Suffixes2
+
Table 2 - Forest Summary - PHARMAX.LOCAL

+
+ + + +
Domain NameDomain Functional LevelDomain ControllersPDC Emulator
pharmax.localWindows2016Domain7Server-DC-01V.pharmax.local
acad.pharmax.localWindows2016Domain1acade-dc-01v.acad.pharmax.local
+
Table 3 - Domain Summary - PHARMAX.LOCAL

+
+ + + + +
SectionDetail Level
ForestEnabled (Advanced Summary)
DomainEnabled (Advanced Summary)
DNSEnabled (Summary)
+
Table 4 - Report Scope - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1 PHARMAX.LOCAL Active Directory Forest

This section provides a detailed overview of the Active Directory infrastructure and configuration for the PHARMAX.LOCAL forest.

1.1 Forest Configuration

The following section provides a detailed overview of the Active Directory Forest infrastructure and configuration.

+ + + + + + + + + + + + + + + +
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Schema VersionObjectVersion 91, Correspond to Windows Server 2025
Tombstone Lifetime (days)180
Domainsacad.pharmax.local; pharmax.local
Global CatalogsServer-DC-01V.pharmax.local; acade-dc-01v.acad.pharmax.local; Server-DC-02V.pharmax.local; Caguas-DC-01V.pharmax.local; Carolina-DC-01V.pharmax.local; Ponce-DC-01V.pharmax.local; Naguabo-DC-01V.pharmax.local; Cayey-Dc-01V.pharmax.local
Domains Count2
Global Catalogs Count8
Sites Count8
Application PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local DC=DomainDnsZones,DC=pharmax,DC=local
Partitions ContainerCN=Partitions,CN=Configuration,DC=pharmax,DC=local
SPN Suffixes--
UPN Suffixespharmax, acad
Anonymous Access (dsHeuristics)Disabled
+
Table 5 - Forest Summary - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.1 Forest Diagram

+Forest Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

1.1.2 Certificate Authority

The following section provides an overview of the Public Key Infrastructure (PKI) configuration deployed within the Active Directory environment.

Certificate Authority Root(s)

+ + + +
NameDistinguished Name
pharmax-SERVER-DC-01V-CACN=pharmax-SERVER-DC-01V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
pharmax-SERVER-DC-02V-CACN=pharmax-SERVER-DC-02V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
+
Table 6 - Certificate Authority Root(s) - PHARMAX.LOCAL

+

Certificate Authority Issuer(s)

+ + + + +
NameDNS Name
acad-ACADE-DC-01V-CAacade-dc-01v.acad.pharmax.local
pharmax-CAYEY-DC-01V-CAcayey-dc-01v.pharmax.local
pharmax-SERVER-DC-01V-CAServer-DC-01V.pharmax.local
+
Table 7 - Certificate Authority Issuer(s) - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.3 Certificate Authority Diagram

+Certificate Authority Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

1.1.4 Optional Features

+ + + + +
NameRequired Forest ModeEnabled
Database 32k Pages FeatureWindows2025ForestNo
Privileged Access Management FeatureWindows2016ForestNo
Recycle Bin FeatureWindows2008R2ForestYes
+
Table 8 - Optional Features - PHARMAX.LOCAL

+

1.2 AD Sites & Replication

The following section provides an overview of the Active Directory site topology, site links, replication connections, and inter-site transport configuration.

1.2.1 Replication

Replication is the process by which Active Directory objects are transferred and synchronized between domain controllers within the domain and forest, ensuring consistency across the infrastructure.

The following section provides detailed information about Active Directory replication and its associated relationships.

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.1 Replication Diagram

+Replication Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.2 Sites

+ + + + + + + + + +
Site NameDescriptionSubnetsDomain Controllers
ACAD-- (1)172.23.4.0/24ACADE-DC-01V
Caguas-- (1)172.23.7.0/24CAGUAS-DC-01V
Carolina-- (1)172.23.9.0/24CAROLINA-DC-01V
CayeySite of Cayey, PR Branch10.10.30.0/24CAYEY-DC-01V
Dead-Site-- (1)No subnet assigned (2)No DC assigned (3)
Naguabo-- (1)10.10.31.0/24NAGUABO-DC-01V
Ponce-- (1)10.10.32.0/24PONCE-DC-01V
SanJuanSite of San Juan, PR HQ192.168.5.0/24
192.168.7.0/24
SERVER-DC-01V
SERVER-DC-02V
+
Table 9 - Sites - PHARMAX.LOCAL

+
Health Check:
    +
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. +
  3. Ensure Sites have an associated subnet. If subnets are not associated with AD Sites, users might choose a remote domain controller for authentication, which could result in excessive use of remote domain controllers.
  4. +
  5. It is important to ensure that each site has at least one assigned domain controller. Missing domain controllers can lead to authentication delays and potential service disruptions for users in the site.
  6. +
-#### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates. +

Connection Objects

+ + + + + + + + + + + + + + + + + + + + + +
NameFrom ServerTo ServerFrom Site
<automatically generated>ACADE-DC-01VSERVER-DC-01VACAD
<automatically generated>CAGUAS-DC-01VSERVER-DC-01VCaguas
<automatically generated>CAROLINA-DC-01VSERVER-DC-01VCarolina
<automatically generated>CAYEY-DC-01VSERVER-DC-01VCayey
<automatically generated>NAGUABO-DC-01VSERVER-DC-01VNaguabo
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-01VPonce
<automatically generated>SERVER-DC-01VNAGUABO-DC-01VSanJuan
<automatically generated>SERVER-DC-02VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAROLINA-DC-01VSanJuan
<automatically generated>SERVER-DC-01VPONCE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VACADE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAYEY-DC-01VSanJuan
<automatically generated>SERVER-DC-02VSERVER-DC-01VSanJuan
<automatically generated>SERVER-DC-01VSERVER-DC-02VSanJuan
<automatically generated>SERVER-DC-02VCAYEY-DC-01VSanJuan
+
Table 10 - Connection Objects - PHARMAX.LOCAL

+

1.2.1.3 Site Subnets

+ + + + + + + + + +
SubnetDescriptionSites
10.10.30.0/24-- (1)Cayey
10.10.31.0/24-- (1)Naguabo
10.10.32.0/24-- (1)Ponce
172.23.4.0/24-- (1)ACAD
172.23.7.0/24-- (1)Caguas
172.23.9.0/24-- (1)Carolina
192.168.5.0/24-- (1)SanJuan
192.168.7.0/24-- (1)SanJuan
+
Table 11 - Site Subnets - PHARMAX.LOCAL

+
Health Check:
    +
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. +
-# Microsoft AD As Built Report +

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.4 Site Topology Diagram

+Site Topology Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.5 Inter-Site Transports

Site links in Active Directory represent the inter-site connectivity and method used to transfer replication traffic. There are two transport protocols that can be used for replication via site links. The default protocol used in site link is IP, and it performs synchronous replication between available domain controllers. The SMTP method can be used when the link between sites is not reliable.

+ + + +
NameBridge All Site LinksIgnore Schedules
IPYesNo
SMTPYesYes
+
Table 12 - Inter-Site Transports - PHARMAX.LOCAL

+
1.2.1.5.1 IP
1.2.1.5.1.1 Site Links
+ + + + + + + + + +
Site Link NamePharmax-to-Naguabo
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesNaguabo; SanJuan
Protected From Accidental DeletionNo
Description--
+
Table 13 - Site Links - Pharmax-to-Naguabo

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

+ + + + + + + + + +
Site Link NamePharmax-to-Cayey
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCayey; SanJuan
Protected From Accidental DeletionNo
Description--
+
Table 14 - Site Links - Pharmax-to-Cayey

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

+ + + + + + + + + +
Site Link NamePharmax-to-Carolina
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCarolina; SanJuan
Protected From Accidental DeletionNo
Description--
+
Table 15 - Site Links - Pharmax-to-Carolina

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

+ + + + + + + + + +
Site Link NamePharmax-to-Caguas
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCaguas; SanJuan
Protected From Accidental DeletionNo
Description--
+
Table 16 - Site Links - Pharmax-to-Caguas

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

+ + + + + + + + + +
Site Link NamePharmax-to-Ponce
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesPonce; SanJuan
Protected From Accidental DeletionNo
Description--
+
Table 17 - Site Links - Pharmax-to-Ponce

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

+ + + + + + + + + +
Site Link NamePHARMAX-to-ACAD
Cost100
Replication Frequency90 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesACAD; SanJuan
Protected From Accidental DeletionYes
Description--
+
Table 18 - Site Links - PHARMAX-to-ACAD

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

1.2.1.5.1.2 Site Link Bridges
+ + + + + + +
Site Link Bridges NameSite-Bridge
Transport ProtocolIP
Site LinksPHARMAX-to-ACAD
Protected From Accidental DeletionNo
Description--
+
Table 19 - Site Link Bridges - Site-Bridge

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Link Bridges in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

1.2.1.6 Sysvol Replication

+ + + + + + + + + +
DC NameReplication StatusDomain
acade-dc-01vNormalacad.pharmax.local
Server-DC-01VNormalpharmax.local
Server-DC-02VUnknownpharmax.local
Caguas-DC-01VNormalpharmax.local
Carolina-DC-01VNormalpharmax.local
Ponce-DC-01VNormalpharmax.local
Naguabo-DC-01VNormalpharmax.local
Cayey-Dc-01VNormalpharmax.local
+
Table 20 - Sysvol Replication - PHARMAX.LOCAL

+
Health Check:

Best Practice: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

1.3 Infrastructure Services

The following section provides an overview of infrastructure services registered in Active Directory, including Exchange, MECM/SCCM, and DHCP server information.

1.3.1 Exchange Infrastructure

The following section provides an overview of the Microsoft Exchange Server infrastructure registered in Active Directory, including server names, roles, and version information.

EX16-SERVER-01V

+ + + + + +
NameEX16-SERVER-01V
DNS Nameex16-server-01v.pharmax.local
Server RolesUM, CAS, MBX, HUB
VersionVersion 15.1 (Build 32507.6)
+
Table 21 - Exchange Infrastructure - EX16-SERVER-01V

+

1.3.2 SCCM Infrastructure

The following section provides a summary of the Microsoft Endpoint Configuration Manager (MECM/SCCM) infrastructure registered in Active Directory, including site codes, management points, and version details.

SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

+ + + + + +
NameSMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL
Management PointSCCM-PRI-01V.PHARMAX.LOCAL
Site CodePMX
Version9012
+
Table 22 - SCCM Infrastructure - SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

+

1.3.3 DHCP Infrastructure

The following section provides an overview of the DHCP servers registered in Active Directory.

+ + + + + + + +
Server NameIs Domain Controller?
acad-dhcp-01v.acad.pharmax.localNo
acade-dc-01v.acad.pharmax.localYes
cayey-dc-01v.pharmax.localYes
cayey-dc-01v.pharmax.local +CNF:aa5dd995-2945-449c-8538-37ee3aa289eaNo
dc-uia-01v.uia.localNo
server-dc-01v.pharmax.localYes
+
Table 23 - DHCP Infrastructure - PHARMAX.LOCAL

+

2 AD Domain Configuration

The following table provides a detailed breakdown of the Active Directory domain configuration attributes.

2.1 PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

+ + + + + + + + + + + + + + + + + + + + + + +
Domain Namepharmax
NetBIOS NamePHARMAX
Domain SIDS-1-5-21-2867495315-1194516362-180967319
Domain Functional LevelWindows2016Domain
Domains--
Forestpharmax.local
Parent Domain--
Replica Directory ServersServer-DC-01V.pharmax.local Server-DC-02V.pharmax.local Caguas-DC-01V.pharmax.local Carolina-DC-01V.pharmax.local Ponce-DC-01V.pharmax.local Naguabo-DC-01V.pharmax.local Cayey-Dc-01V.pharmax.local
Child Domainsacad.pharmax.local
Domain Pathpharmax.local/
Computers ContainerCN=Computers,DC=pharmax,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=pharmax,DC=local
Systems ContainerCN=System,DC=pharmax,DC=local
Users ContainerCN=Users,DC=pharmax,DC=local
Deleted Objects ContainerCN=Deleted Objects,DC=pharmax,DC=local
Foreign Security Principals ContainerCN=ForeignSecurityPrincipals,DC=pharmax,DC=local
Lost And Found ContainerCN=LostAndFound,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available360600 / 1073381223 (1% Issued)
+
Table 24 - Domain Summary - PHARMAX.LOCAL

+

2.1.1 FSMO Roles

+ + + + + + +
Infrastructure MasterServer-DC-01V.pharmax.local
PDC Emulator NameServer-DC-01V.pharmax.local
RID MasterServer-DC-01V.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
+
Table 25 - FSMO Roles - pharmax.local

+
Health Check:

Best Practice: The infrastructure master role in the domain PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.1.2 Domain and Trusts

acad.pharmax.local Trust Details

+ + + + + + + + + + + + + + + + +
Nameacad.pharmax.local
Pathpharmax.local/System/acad.pharmax.local
Sourcepharmax
Targetacad.pharmax.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 26 - Trust - acad.pharmax.local

+

lab.local Trust Details

+ + + + + + + + + + + + + + + + +
Namelab.local
Pathpharmax.local/System/lab.local
Sourcepharmax
Targetlab.local
Trust TypeUplevel
Trust AttributesForest Trust
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 27 - Trust - lab.local

+

uia.local Trust Details

+ + + + + + + + + + + + + + + + +
Nameuia.local
Pathpharmax.local/System/uia.local
Sourcepharmax
Targetuia.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 28 - Trust - uia.local

+

b12.local Trust Details

+ + + + + + + + + + + + + + + + +
Nameb12.local
Pathpharmax.local/System/b12.local
Sourcepharmax
Targetb12.local
Trust TypeUplevel
Trust AttributesForest Trust
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 29 - Trust - b12.local

+
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

+
Microsoft Active Directory As Built Report - v1.0

2.1.2.1 Domain and Trusts Diagram

+Domain and Trusts Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

2.1.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.1.3.1 User Objects

Users

+User Objects - Diagram +
+
+ + + + +
Users8559
Privileged Users8
Foreign Security Principals7
+
Table 30 - User - PHARMAX.LOCAL

+

Status of Users Accounts

+Status of Users Accounts - Diagram +
+
+ + + + + + + + + + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users8559100130.158559100
Cannot Change Password130.1500130.15
Password Never Expires330.3920.02330.39
Must Change Password at Logon120.14120.14120.14
Password Age (> 180 days)852199.56100.12852199.56
SmartcardLogonRequired000000
SidHistory000000
Never Logged in853799.74130.15853799.74
Dormant (> 90 days)855599.95130.15855599.95
Password Not Required70.0830.0470.08
Account Expired10.010010.01
Account Lockout000000
+
Table 31 - Status of Users Accounts - PHARMAX.LOCAL

+

2.1.3.2 Group Objects

Groups Categories

+Groups Categories - Diagram +
+
+ + + +
Security Groups94
Distribution Groups3
+
Table 32 - Groups Categories - PHARMAX.LOCAL

+

Groups Scopes

+Groups Scopes - Diagram +
+
+ + + + +
Domain Locals46
Globals26
Universal25
+
Table 33 - Groups Scopes - PHARMAX.LOCAL

+
2.1.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (4 Members)

+ + + + + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
jocolon (USER)12/22/2043**YesYes
scvmm-admin (USER)*9/4/2025**YesYes
veeam_admin (USER)*11/22/2025**YesYes
+
Table 34 - Domain Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Enterprise Admins (1 Members)

+ + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
+
Table 35 - Enterprise Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

Unless an account is performing specific tasks that require those highly elevated permissions, every account should be removed from the Enterprise Admins (EA) group. A side benefit of having an empty Enterprise Admins group is that it adds just enough friction to ensure that enterprise-wide changes requiring Enterprise Admin rights are done purposefully and methodically.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

Administrators (3 Members)

+ + + + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
Domain Admins (GROUP)------
svc_SCCM_ClientPush (USER)*9/14/2020**YesYes
+
Table 36 - Administrators - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Schema Admins (2 Members)

+ + + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
1227935471SA (USER)--NoYes
Administrator (USER)12/10/2053**YesYes
+
Table 37 - Schema Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

The Schema Admins group is a privileged group in a forest root domain. Members of the Schema Admins group can make changes to the schema, which is the framework for the Active Directory forest. Changes to the schema are not frequently required. This group only contains the Built-in Administrator account by default. Additional accounts must only be added when changes to the schema are necessary and then must be removed.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.
2.1.3.2.2 Empty Groups (Non-Default)
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Group NameGroup SID
ADSyncBrowseS-1-5-21-2867495315-1194516362-180967319-351274
ADSyncOperatorsS-1-5-21-2867495315-1194516362-180967319-351273
ADSyncPasswordSetS-1-5-21-2867495315-1194516362-180967319-351275
BitLocker Admin UsersS-1-5-21-2867495315-1194516362-180967319-2627
BitLocker Reporting UsersS-1-5-21-2867495315-1194516362-180967319-2626
Compliance ManagementS-1-5-21-2867495315-1194516362-180967319-351235
Delegated SetupS-1-5-21-2867495315-1194516362-180967319-351233
Discovery ManagementS-1-5-21-2867495315-1194516362-180967319-351231
Exchange Trusted SubsystemS-1-5-21-2867495315-1194516362-180967319-351239
ExchangeLegacyInteropS-1-5-21-2867495315-1194516362-180967319-351242
External Trust AccountsS-1-5-21-2867495315-1194516362-180967319-529
FIN-SEC-DATAS-1-5-21-2867495315-1194516362-180967319-351248
Forest Trust AccountsS-1-5-21-2867495315-1194516362-180967319-528
Help DeskS-1-5-21-2867495315-1194516362-180967319-351229
HR-IT-DATAS-1-5-21-2867495315-1194516362-180967319-351247
Hygiene ManagementS-1-5-21-2867495315-1194516362-180967319-351234
Public Folder ManagementS-1-5-21-2867495315-1194516362-180967319-351227
Recipient ManagementS-1-5-21-2867495315-1194516362-180967319-351225
Records ManagementS-1-5-21-2867495315-1194516362-180967319-351230
Sec-IT-DATAS-1-5-21-2867495315-1194516362-180967319-351246
Security AdministratorS-1-5-21-2867495315-1194516362-180967319-351237
Security ReaderS-1-5-21-2867495315-1194516362-180967319-351236
Server ManagementS-1-5-21-2867495315-1194516362-180967319-351232
UM ManagementS-1-5-21-2867495315-1194516362-180967319-351228
UN-GroupS-1-5-21-2867495315-1194516362-180967319-351221
View-Only Organization ManagementS-1-5-21-2867495315-1194516362-180967319-351226
Windows Admin Center CredSSPS-1-5-21-2867495315-1194516362-180967319-351298
WSUS AdministratorsS-1-5-21-2867495315-1194516362-180967319-1200
WSUS ReportersS-1-5-21-2867495315-1194516362-180967319-1201
+
Table 38 - Empty Groups - PHARMAX.LOCAL

+
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.1.3.2.3 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

+ + + +
Parent Group NameChild Group Name
AD - SRM Admin GroupESX Admins
ESX AdminsAD - SRM Admin Group
+
Table 39 - Circular Group Membership - PHARMAX.LOCAL

+
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.1.3.2.4 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

+ + + + +
NameDistinguished Name
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=pharmax,DC=local
SERVER-DC-01V (COMPUTER)CN=SERVER-DC-01V,OU=Domain Controllers,DC=pharmax,DC=local
SERVER-DC-02V (COMPUTER)CN=SERVER-DC-02V,OU=Domain Controllers,DC=pharmax,DC=local
+
Table 40 - Pre-Windows 2000 Compatible Access - PHARMAX.LOCAL

+
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.1.3.3 Computer Objects

Computers

+Computer Objects - Diagram +
+
+ + + +
Computers3102
Servers96
+
Table 41 - Computers - PHARMAX.LOCAL

+
2.1.3.3.1 Status of Computer Accounts
+Status of Computer Accounts - Diagram +
+
+ + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers308199.32210.683102100
Dormant (> 90 days)305898.58210.68307999.26
Password Age (> 30 days)307098.97210.68309199.65
SidHistory000000
+
Table 42 - Status of Computer Accounts - PHARMAX.LOCAL

+
2.1.3.3.2 Operating Systems Count
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operating SystemCount
CentOS1
Data Domain OS1
EMC File Server1
NetApp Release 9.15.11
NetApp Release 9.17.12
NetApp Release 9.18.11
NetApp Release 9.18.1RC11
NetApp Release 9.5P61
NetApp Release 9.81
NetApp Release 9.9.1P12
No OS Specified2963
OneFS1
pc-linux-gnu2
redhat-linux-gnu2
unknown2
Windows 10 Enterprise2
Windows 10 Enterprise Evaluation18
Windows 11 Enterprise LTSC3
Windows Server 20031
Windows Server 2012 R2 Standard Evaluation1
Windows Server 2016 Standard Evaluation11
Windows Server 2019 Standard1
Windows Server 2019 Standard Evaluation40
Windows Server 2022 Datacenter13
Windows Server 2022 Datacenter Evaluation15
Windows Server 2025 Datacenter12
Windows Server 2025 Standard1
Windows Vista1
Windows XP1
+
Table 43 - - PHARMAX.LOCAL

+
Health Check:

Security Best Practice: Operating systems that are no longer supported for security updates are not maintained or updated to address vulnerabilities, leaving them open to potential attack. Organizations must transition to a supported operating system to ensure continued support and to improve the organization's security posture.

2.1.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.1.4.1 Default Domain Password Policy

+ + + + + + + + + + + +
Password Must Meet Complexity RequirementsYes
Pathpharmax.local/
Lockout Duration30 minutes
Lockout Threshold5
Lockout Observation Window30 minutes
Maximum Password Age42 days
Minimum Password Age01 days
Minimum Password Length7
Enforce Password History24
Store Password using Reversible EncryptionNo
+
Table 44 - Default Domain Password Policy - PHARMAX.LOCAL

+

2.1.4.2 Fined Grained Password Policies

Administrators

+ + + + + + + + + + + + + + + +
NameAdministrators
Domain NameDC=pharmax,DC=local
Complexity EnabledYes
Pathpharmax.local/System/Password Settings Container/Administrators
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age05 days
Min Password Length12
Password History Count90
Reversible Encryption EnabledNo
Precedence1
Applies Tohorizon-ic, dbuser, jocolon
+
Table 45 - Name - Administrators

+

Test

+ + + + + + + + + + + + + + + +
NameTest
Domain NameDC=pharmax,DC=local
Complexity EnabledYes
Pathpharmax.local/System/Password Settings Container/Test
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age01 days
Min Password Length7
Password History Count23
Reversible Encryption EnabledNo
Precedence1
Applies Tovmuserro
+
Table 46 - Name - Test

+

2.1.4.3 Microsoft LAPS

+ + + + + +
NameLocal Administrator Password Solution
Domain NameDC=pharmax,DC=local
EnabledYes
Distinguished NameCN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=pharmax,DC=local
+
Table 47 - Microsoft LAPS - PHARMAX.LOCAL

+

2.1.4.4 gMSA Identities

SQLServer

+ + + + + + + + + + + + + + +
NameSQLServer
SamAccountNameSQLServer$
Created9/27/2020
EnabledYes
DNS Host NameSQL-Cluster
Host ComputersSQL-CLUSTER-02V, SQL-CLUSTER-01V
Retrieve Managed PasswordSQL-CLUSTER-01V, SQL-CLUSTER-02V
Primary GroupDomain Computers
Last Logon Date*9/27/2020
Locked OutNo
Logon Count3
Password ExpiredNo
Password Last Set9/27/2020
+
Table 48 - gMSA - SQLServer

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

adfsgmsa

+ + + + + + + + + + + + + + +
Nameadfsgmsa
SamAccountNameadfsgmsa$
Created10/7/2020
EnabledYes
DNS Host NameADFS.pharmax.local
Host Computers**--
Retrieve Managed PasswordSERVER-ADFS-01V, SERVER-ADFS-02V
Primary GroupDomain Computers
Last Logon Date*10/7/2020
Locked OutNo
Logon Count40
Password ExpiredNo
Password Last Set10/7/2020
+
Table 49 - gMSA - adfsgmsa

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ITFarm1

+ + + + + + + + + + + + + + +
NameITFarm1
SamAccountNameITFarm1$
Created7/13/2023
EnabledYes
DNS Host NameITFarm1.pharmax.local
Host Computers**--
Retrieve Managed Password***--
Primary GroupDomain Computers
Last Logon Date*--
Locked OutNo
Logon Count0
Password ExpiredNo
Password Last Set7/13/2023
+
Table 50 - gMSA - ITFarm1

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ADSyncMSAda440

+ + + + + + + + + + + + + + +
NameADSyncMSAda440
SamAccountNameADSyncMSAda440$
Created4/21/2025
EnabledYes
DNS Host Name--
Host ComputersSERVER-DC-01V
Retrieve Managed Password***--
Primary GroupDomain Computers
Last Logon Date4/2/2026
Locked OutNo
Logon Count381
Password ExpiredNo
Password Last Set3/28/2026
+
Table 51 - gMSA - ADSyncMSAda440

+
Health Check:

Security Best Practice:

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.1.4.5 Foreign Security Principals

+ + + + + + + + +
NamePrincipal Name
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
NT AUTHORITY\Authenticated UsersCertificate Service DCOM Access
Users
Pre-Windows 2000 Compatible Access
NT AUTHORITY\INTERACTIVEUsers
NT AUTHORITY\IUSR--
----
--Backup Operators
--Backup Operators
+
Table 52 - Foreign Security Principals - PHARMAX.LOCAL

+

2.1.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

+ + + + + + + + +
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
CAGUAS-DC-01VOnlineCaguasYesNo172.23.7.1
CAROLINA-DC-01VOnlineCarolinaYesNo172.23.9.1
CAYEY-DC-01VOnlineCayeyYesNo10.10.30.1
NAGUABO-DC-01VOnlineNaguaboYesNo10.10.31.1
PONCE-DC-01VOnlinePonceYesNo10.10.32.1
SERVER-DC-01VOnlineSanJuanYesNo192.168.5.1
SERVER-DC-02VOffline--------
+
Table 53 - Domain Controller in Domain - PHARMAX.LOCAL

+
+Domain Controller Object - Chart +
+
+ + + +
Domain Controller7
Global Catalog7
+
Table 54 - Domain Controller Counts - PHARMAX.LOCAL

+

2.1.5.1 Configuration

2.1.5.1.1 CAGUAS-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameCaguas-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCaguas
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351303
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 55 - General Information - CAGUAS-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 56 - Partitions - CAGUAS-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses172.23.7.1
IPv6 Addressesfe80::75c9:eaa3:559a:23de%12
LDAP Port389
LDAPS Port636
+
Table 57 - Networking Settings - CAGUAS-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameCAGUAS-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:10
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 58 - Hardware Inventory - CAGUAS-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.2 CAROLINA-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameCarolina-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCarolina
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351304
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 59 - General Information - CAROLINA-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 60 - Partitions - CAROLINA-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses172.23.9.1
IPv6 Addressesfe80::586:15a2:ab35:2609%12
LDAP Port389
LDAPS Port636
+
Table 61 - Networking Settings - CAROLINA-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameCAROLINA-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 62 - Hardware Inventory - CAROLINA-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.3 CAYEY-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameCayey-Dc-01V.pharmax.local
Domain Namepharmax.local
SiteCayey
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351300
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 63 - General Information - CAYEY-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 64 - Partitions - CAYEY-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses10.10.30.1
IPv6 Addressesfe80::74a3:277d:e262:218b%11
LDAP Port389
LDAPS Port636
+
Table 65 - Networking Settings - CAYEY-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameCAYEY-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 12:51:56
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 66 - Hardware Inventory - CAYEY-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.4 NAGUABO-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameNaguabo-DC-01V.pharmax.local
Domain Namepharmax.local
SiteNaguabo
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351301
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 67 - General Information - NAGUABO-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 68 - Partitions - NAGUABO-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses10.10.31.1
IPv6 Addressesfe80::efb6:c739:603c:1121%12
LDAP Port389
LDAPS Port636
+
Table 69 - Networking Settings - NAGUABO-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameNAGUABO-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 13:50:08
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 70 - Hardware Inventory - NAGUABO-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.5 PONCE-DC-01V

General Information

+ + + + + + + + + + + + +
DC NamePonce-DC-01V.pharmax.local
Domain Namepharmax.local
SitePonce
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351302
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 71 - General Information - PONCE-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 72 - Partitions - PONCE-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses10.10.32.1
IPv6 Addressesfe80::de92:566e:cf5c:a051%11
LDAP Port389
LDAPS Port636
+
Table 73 - Networking Settings - PONCE-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NamePONCE-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 14:26:27
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 74 - Hardware Inventory - PONCE-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.6 SERVER-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameServer-DC-01V.pharmax.local
Domain Namepharmax.local
SiteSanJuan
Global CatalogYes
Read OnlyNo
Operation Master RolesSchemaMaster, DomainNamingMaster, PDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-1602
Operating SystemWindows Server 2025 Standard
SMB1 StatusEnabled
DescriptionPrueba
+
Table 75 - General Information - SERVER-DC-01V

+
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 76 - Partitions - SERVER-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses192.168.7.1, 192.168.5.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
+
Table 77 - Networking Settings - SERVER-DC-01V

+
Health Check:

Best Practice: On Domain Controllers with more than one NIC where each NIC is connected to a separate network, there is a possibility that the Host A DNS registration can occur for unwanted NICs. Avoid registering unwanted NICs in DNS on a multihomed domain controller.

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameSERVER-DC-01V
Windows Product NameWindows Server 2025 Standard
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date11/17/2025 14:04:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyMY832
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors2
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 78 - Hardware Inventory - SERVER-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.1.5.2 DNS IP Configuration

+ + + + + + + + + +
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
CAGUAS-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
CAROLINA-DC-01VEthernet0192.168.5.1127.0.0.1----
CAYEY-DC-01VEthernet0192.168.5.1127.0.0.1----
NAGUABO-DC-01VEthernet0192.168.5.1127.0.0.1----
PONCE-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
SERVER-DC-01VEthernet3192.168.5.1127.0.0.1----
SERVER-DC-01VEthernet0192.168.5.1127.0.0.1----
SERVER-DC-02V----------
+
Table 79 - DNS IP Configuration - PHARMAX.LOCAL

+
Health Check:


Best Practices: DNS configuration on the network adapter should not include the Domain Controller's own IP address as the first entry.

Corrective Actions: Network interfaces must be configured with DNS servers that can resolve names in the forest root domain. The following DNS server did not respond to the query for the forest root domain PHARMAX.LOCAL: 192.168.5.5, 192.168.5.5

2.1.5.3 NTDS Information

+ + + + + + + + +
DC NameDatabase FileDatabase SizeLog PathSysVol Path
CAGUAS-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAROLINA-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAYEY-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
NAGUABO-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
PONCE-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
SERVER-DC-01VC:\Windows\NTDS\ntds.dit290 MBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
SERVER-DC-02V--------
+
Table 80 - NTDS Database File Usage - PHARMAX.LOCAL

+

2.1.5.4 Time Source Information

+ + + + + + + + +
NameTime ServerType
CAGUAS-DC-01VDomain HierarchyDOMHIER
CAROLINA-DC-01VDomain HierarchyDOMHIER
CAYEY-DC-01VDomain HierarchyDOMHIER
NAGUABO-DC-01VDomain HierarchyDOMHIER
PONCE-DC-01VDomain HierarchyDOMHIER
SERVER-DC-01V192.168.5.254 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
SERVER-DC-02V----
+
Table 81 - Time Source Configuration - PHARMAX.LOCAL

+

2.1.5.5 SRV Records Status

+ + + + + + + + +
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
CAGUAS-DC-01VOKOKNon PDCOKOK
CAROLINA-DC-01VOKOKNon PDCOKOK
CAYEY-DC-01VOKOKNon PDCOKOK
NAGUABO-DC-01VOKOKNon PDCOKOK
PONCE-DC-01VOKOKNon PDCFailOK
SERVER-DC-01VOKOKOKOKOK
SERVER-DC-02V----------
+
Table 82 - SRV Records Status - PHARMAX.LOCAL

+
Health Check:

Best Practice: The SRV record is a Domain Name System (DNS) resource record. It is used to identify computers hosting specific services. SRV resource records are used to locate domain controllers for Active Directory. These records are essential for the proper functioning of Active Directory as they allow clients to locate domain controllers and other critical services within the network. Ensuring that these records are correctly configured and available is crucial for maintaining the health and accessibility of the Active Directory environment.

2.1.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

SERVER-DC-01V

+ + + + + +
NamePathDescription
UpdateServicesPackagesE:\wsus\UpdateServicesPackagesA network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
VcenterBackupF:\VcenterBackup--
VeeamConfBackupF:\VeeamConfBackup--
WsusContentE:\wsus\WsusContentA network share to be used by Local Publishing to place published content on this WSUS system.
+
Table 83 - File Shares - SERVER-DC-01V

+
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.1.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the PHARMAX.LOCAL domain.

SERVER-DC-01V

+ + + + + + + + + +
NamePublisherInstall Date
Dell Data Domain DDBoost SDKVeeam Software Group GmbH20260317
HPE StoreOnce Catalyst SDKVeeam Software Group GmbH20260317
OpenSSL v3.0.0 FIPSVeeam Software Group GmbH20251119
Veeam Agent for Microsoft WindowsVeeam Software Group GmbH20260317
Veeam Backup TransportVeeam Software Group GmbH20260326
Veeam Backup VSS IntegrationVeeam Software Group GmbH20260317
Veeam Guest Interaction Proxy ServiceVeeam Software Group GmbH20260317
Veeam Installer ServiceVeeam Software Group GmbH--
+
Table 84 - Installed Software - SERVER-DC-01V

+
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.1.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the PHARMAX.LOCAL domain.

CAROLINA-DC-01V

+ + +
KB ArticleName
KB50787402026-03 Cumulative Update for Microsoft server operating system version 24H2 for x64-based Systems (KB5078740) (26100.32522)
+
Table 85 - Missing Windows Updates - CAROLINA-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

PONCE-DC-01V

+ + +
KB ArticleName
KB50661312025-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Microsoft server operating system version 24H2 for x64 (KB5066131)
+
Table 86 - Missing Windows Updates - PONCE-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

SERVER-DC-01V

+ + +
KB ArticleName
KBSystem.__ComObjectMicrosoft Edge-WebView2 Runtime Version 146 Update for x64 based Editions (Build 146.0.3856.97)
+
Table 87 - Missing Windows Updates - SERVER-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.1.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in pharmax.local.

CAGUAS-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 88 - Roles - CAGUAS-DC-01V

+

CAROLINA-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 89 - Roles - CAROLINA-DC-01V

+

CAYEY-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 90 - Roles - CAYEY-DC-01V

+

NAGUABO-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 91 - Roles - NAGUABO-DC-01V

+

PONCE-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 92 - Roles - PONCE-DC-01V

+

SERVER-DC-01V

+ + + + + + + + +
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
Windows Server Update Services (1)RoleWindows Server Update Services allows network administrators to specify the Microsoft updates that should be installed, create separate groups of computers for different sets of updates, and get reports on the compliance levels of the computers and the updates that must be installed.
+
Table 93 - Roles - SERVER-DC-01V

+
Health Check:

Best Practices:
    +
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
  2. +
-Microsoft AD As Built Report is a PowerShell module which works in conjunction with [AsBuiltReport.Core](https://github.com/AsBuiltReport/AsBuiltReport.Core). +

2.1.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

CAGUAS-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 94 - Infrastructure Services Status - CAGUAS-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAROLINA-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 95 - Infrastructure Services Status - CAROLINA-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAYEY-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 96 - Infrastructure Services Status - CAYEY-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

NAGUABO-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 97 - Infrastructure Services Status - NAGUABO-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

PONCE-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 98 - Infrastructure Services Status - PONCE-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

SERVER-DC-01V

+ + + + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 99 - Infrastructure Services Status - SERVER-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.1.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.1.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: CAGUAS-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID0fc69a2f-27db-46d0-9d77-fe1e6aa11bbb
Description--
From ServerSERVER-DC-01V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
+
Table 100 - Replication Connection - CAGUAS-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: CAGUAS-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID3e145ba6-3e78-4f99-994b-8eff197b1b4e
Description--
From ServerSERVER-DC-02V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:31:02 GMT
+
Table 101 - Replication Connection - CAGUAS-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: CAROLINA-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID6c379734-f95a-4498-ad32-d001c4c29a89
Description--
From ServerSERVER-DC-01V
To ServerCAROLINA-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:13 GMT
+
Table 102 - Replication Connection - CAROLINA-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: CAYEY-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDbd8d4d25-a9f8-480d-a56a-49c9c5ac62f3
Description--
From ServerSERVER-DC-02V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
+
Table 103 - Replication Connection - CAYEY-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: CAYEY-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDec5a6456-5ced-473f-a313-8af9daefdbfb
Description--
From ServerSERVER-DC-01V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
+
Table 104 - Replication Connection - CAYEY-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: NAGUABO-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDbc36599a-0876-4b1b-9ca7-4e7a5df10cc7
Description--
From ServerSERVER-DC-01V
To ServerNAGUABO-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:33 GMT
+
Table 105 - Replication Connection - NAGUABO-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: PONCE-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID79c509ba-15f9-4204-82d1-856a4cbf222f
Description--
From ServerSERVER-DC-01V
To ServerPONCE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
+
Table 106 - Replication Connection - PONCE-DC-01V

+

Site: ACAD: From: ACADE-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteACAD
GUID6488a593-7cd5-4823-ad44-4d1439b0ac92
Description--
From ServerACADE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 03:22:52 GMT
+
Table 107 - Replication Connection - SERVER-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID8a3b236b-e90b-49ff-9a47-b032b6003318
Description--
From ServerSERVER-DC-02V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport Protocol--
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:21:56 GMT
+
Table 108 - Replication Connection - SERVER-DC-01V

+

Site: Naguabo: From: NAGUABO-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteNaguabo
GUID30240e89-7df7-4985-ad8f-ec5aac00c0a6
Description--
From ServerNAGUABO-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 109 - Replication Connection - SERVER-DC-01V

+

Site: Carolina: From: CAROLINA-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCarolina
GUID021a795d-328f-41aa-a82e-96d947a05b01
Description--
From ServerCAROLINA-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 110 - Replication Connection - SERVER-DC-01V

+

Site: Cayey: From: CAYEY-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCayey
GUIDaaf66f39-f9a6-45bc-bc7b-7c3d0ff77976
Description--
From ServerCAYEY-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 111 - Replication Connection - SERVER-DC-01V

+

Site: Caguas: From: CAGUAS-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCaguas
GUIDf7d2a8e7-04bf-418e-8710-afa13de520f8
Description--
From ServerCAGUAS-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
+
Table 112 - Replication Connection - SERVER-DC-01V

+

Site: Ponce: From: PONCE-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SitePonce
GUIDf311cacf-16b7-4c8f-a9f6-a93ba30f7fed
Description--
From ServerPONCE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
+
Table 113 - Replication Connection - SERVER-DC-01V

+

2.1.6.2 Replication Status

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:37:54000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 20:11:56000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:51:57000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:44:26000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:45:1812562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:4312562026-04-02 19:53:3791
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-14 13:59:2217222026-04-02 19:55:01150
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:1712562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:42:0217222026-04-02 19:54:1991
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:46:1517222026-04-02 19:53:3791
+
Table 114 - Replication Status - PHARMAX

+
Health Check:

Best Practices: Replication failures can lead to object inconsistencies, stale credentials, Group Policy application failures, and authentication issues across the environment. Investigate and resolve any replication errors promptly using tools such as repadmin /showrepl or the Active Directory Replication Status Tool to prevent further divergence between domain controllers.

2.1.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.1.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the PHARMAX.LOCAL domain.

2.1.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Security Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID04e1aad5-f19b-4d0b-af25-b4ed4f52048f
Created04/26/2024
Modified11/21/2025
OwnerPHARMAX\Domain Admins
Computer Version18 (AD), 18 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 115 - GPO - Security Policy

+

Deleted GPO in Sysvol

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID09e68095-8cfc-4174-81ed-afb52597dd7f
Created06/20/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 116 - GPO - Deleted GPO in Sysvol

+
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Assign-Applications

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID2168b63b-4bd0-4627-99a8-835aea402534
Created03/10/2021
Modified04/13/2025
OwnerPHARMAX\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security Filteringjocolon
Authenticated Users
Linked Targetpharmax.local/LinuxMachines
DescriptionThis is a bad description example
+
Table 117 - GPO - Assign-Applications

+

Certificate AutoEnrollment

+ + + + + + + + + + + + +
GPO StatusUser Settings Disabled
GUID27fa05c8-7c50-4994-9f95-29c4aa3971ed
Created01/25/2020
Modified06/30/2021
OwnerPHARMAX\Domain Admins
Computer Version28 (AD), 28 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 118 - GPO - Certificate AutoEnrollment

+

Default Domain Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created06/10/2018
Modified03/07/2025
OwnerPHARMAX\Domain Admins
Computer Version114 (AD), 114 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 119 - GPO - Default Domain Policy

+

Restricted-Group

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID45497a0f-b3e2-42c0-8a43-992086110bb8
Created02/12/2025
Modified02/13/2025
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Admins PC
Description--
+
Table 120 - GPO - Restricted-Group

+

VEEAM_Disable_Firewall

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID4b2e42eb-2100-4a94-b4b0-7822e30634f6
Created12/13/2019
Modified09/08/2020
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
+
Table 121 - GPO - VEEAM_Disable_Firewall

+

SET - KMS Server

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID502c4398-dc59-49ee-b567-47656f08e09e
Created08/31/2022
Modified08/25/2024
OwnerPHARMAX\Domain Admins
Computer Version10 (AD), 10 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 122 - GPO - SET - KMS Server

+

Default Domain Controllers Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created06/10/2018
Modified11/17/2025
OwnerPHARMAX\Domain Admins
Computer Version26 (AD), 26 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Domain Controllers
Description--
+
Table 123 - GPO - Default Domain Controllers Policy

+

ProfileUnity

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID8f11a3fa-3b68-476d-99fc-32064f696ebe
Created06/08/2020
Modified10/05/2021
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/ProfileUnity VDI/Computers
Description--
+
Table 124 - GPO - ProfileUnity

+

VEEAM_Local_Administrators

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID96cb9511-a88c-45ab-b10c-05b0441b1057
Created12/13/2019
Modified11/29/2024
OwnerPHARMAX\Domain Admins
Computer Version27 (AD), 27 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
+
Table 125 - GPO - VEEAM_Local_Administrators

+

WSUS - Domain Policy

+ + + + + + + + + + + + +
GPO StatusUser Settings Disabled
GUIDa9ec1b8c-3520-4e19-b11c-babb27c6da1a
Created02/23/2020
Modified04/15/2025
OwnerPHARMAX\Domain Admins
Computer Version30 (AD), 30 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 126 - GPO - WSUS - Domain Policy

+

SCEP Configuration

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDd6187a9f-118c-4ee7-a18f-6889a0a657f4
Created09/14/2020
Modified10/04/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
pharmax.local/Configuration Manager Computers
Description--
+
Table 127 - GPO - SCEP Configuration

+

Dead Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Disabled
GUIDe360fece-8631-4749-b1a4-e55d0e48aa5e
Created10/05/2021
Modified06/19/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI FilterByUser
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 128 - GPO - Dead Policy

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

No Security Filtering Applied

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDecbc276e-0e38-42f5-b6e0-6c133b08203c
Created06/18/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringNo Security Filtering
Linked Target--
Description--
+
Table 129 - GPO - No Security Filtering Applied

+
Health Check:

Corrective Actions: Identify 'No Security Filtering' Group Policy Objects (GPOs) that are not linked to any security groups or users. Determine which of these GPOs should be deleted to reduce clutter and improve manageability in Active Directory.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Horizon-DEM

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDf33e9036-4496-4323-9d5a-3011dfd8f1f7
Created03/01/2020
Modified09/15/2025
OwnerPHARMAX\Domain Admins
Computer Version24 (AD), 24 (SYSVOL)
User Version18 (AD), 18 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VDI-Computers
pharmax.local/Admin
Description--
+
Table 130 - GPO - Horizon-DEM

+

Linux-Settings-GPO

+ + + + + + + + + + + + +
GPO StatusAll Settings Disabled
GUIDf46abddd-4ae2-457d-b933-849b164fb3f8
Created05/22/2021
Modified02/04/2022
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version6 (AD), 6 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/LinuxMachines
Description--
+
Table 131 - GPO - Linux-Settings-GPO

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

SCCM - Restricted Group and General Settings

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDfc8443e6-43cb-4ea4-9862-47b19813596b
Created09/12/2020
Modified09/12/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
Description--
+
Table 132 - GPO - SCCM - Restricted Group and General Settings

+

LAPS Configuration

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDfe43b055-4f61-4fa1-b387-0fc3e2b5915e
Created11/01/2020
Modified11/01/2020
OwnerPHARMAX\Domain Admins
Computer Version15 (AD), 15 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager Computers
Description--
+
Table 133 - GPO - LAPS Configuration

+
2.1.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

+ + + + + +
NameByIP
AuthorAdministrator@pharmax.local
Query1;3;10;78;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where TotalPhysicalMemory >= 1073741824

;
DescriptionFilter by IP
+
Table 134 - WMI Filter - ByIP

+
+ + + + + +
NameByUser
AuthorAdministrator@pharmax.local
Query1;3;10;81;WQL;root\CIMv2;Select * from Win32_OperatingSystem where Version like "10.%" and ProductType="1";
DescriptionUser Filter
+
Table 135 - WMI Filter - ByUser

+

Central Store Repository

+ + +
DomainConfiguredCentral Store Path
PHARMAXYes\\pharmax.local\SYSVOL\pharmax.local\Policies\PolicyDefinitions
+
Table 136 - GPO Central Store - PHARMAX.LOCAL

+

Logon/Logoff Script

+ + + + + +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
Horizon-DEMAll Settings EnabledLogoffC:\Program Files\Immidio\Flex Profiles\FlexEngine.exe
No Security Filtering AppliedAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
ProfileUnityAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
+
Table 137 - GPO with Logon/Logoff Script - PHARMAX.LOCAL

+

Startup/Shutdown Script

+ + + + +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
No Security Filtering AppliedAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
ProfileUnityAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
+
Table 138 - GPO with Startup/Shutdown Script - PHARMAX.LOCAL

+
2.1.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

+ + + + +
GPO NameCreatedModifiedComputer EnabledUser Enabled
Dead Policy2021-10-052023-06-20NoNo
Deleted GPO in Sysvol2023-06-202023-06-20YesYes
No Security Filtering Applied2023-06-192023-06-20YesYes
+
Table 139 - Unlinked GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

+ + + +
GPO NameCreatedModifiedDescription
Deleted GPO in Sysvol2023-06-202023-06-20--
Linux-Settings-GPO2021-05-232022-02-04--
+
Table 140 - Empty GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

+ + + + + + +
GPO NameTarget
Certificate AutoEnrollmentpharmax.local/
SET - KMS Serverpharmax.local/
LAPS Configurationpharmax.local/Configuration Manager Computers
Linux-Settings-GPOpharmax.local/LinuxMachines
VEEAM_Local_Administratorspharmax.local/VEEAM Servers
+
Table 141 - Enforced GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

+ + + + + + + +
NameUnknown
GuidA8DF92D3-BDAF-479E-8C0C-9D78AAE058E4
AD DN DatabaseMissing
AD DN PathCN={A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4},CN=Policies,CN=System,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4} (Valid)
+
Table 142 - Orphaned GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

+ + + + + + + +
NameDeleted GPO in Sysvol
Guid09E68095-8CFC-4174-81ED-AFB52597DD7F
AD DN DatabaseValid
AD DN PathCN={09E68095-8CFC-4174-81ED-AFB52597DD7F},CN=Policies,CN=System,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{09E68095-8CFC-4174-81ED-AFB52597DD7F} (Missing)
+
Table 143 - Orphaned GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.1.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameLinked GPOProtected
AdminHorizon-DEMYes
Admins PCRestricted-GroupYes
Configuration ManagerSCEP Configuration, SCCM - Restricted Group and General SettingsYes
Configuration Manager ComputersLAPS Configuration, SCEP ConfigurationYes
Domain ControllersDefault Domain Controllers PolicyNo
EMC NAS servers--No
EMC NAS servers/Computers--No
LinuxMachinesAssign-Applications, Linux-Settings-GPOYes
Member Servers--Yes
Microsoft Exchange Security Groups--No
People--Yes
ProfileUnity VDIVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
ProfileUnity VDI/ComputersProfileUnityYes
ProfileUnity VDI/Servers--Yes
Tier 2--Yes
Tier 2/FIN--No
Tier 2/FIN/Devices--Yes
Tier 2/FIN/Groups--Yes
Tier 2/FIN/ServiceAccounts--Yes
Tier 2/FIN/Test--Yes
Tier 2/HRE--No
Tier 2/HRE/Devices--Yes
Tier 2/HRE/Groups--Yes
Tier 2/HRE/ServiceAccounts--Yes
Tier 2/HRE/Test--Yes
Tier 2/OGC--No
Tier 2/OGC/Devices--Yes
Tier 2/OGC/Groups--Yes
Tier 2/OGC/ServiceAccounts--Yes
Tier 2/OGC/Test--Yes
VDI-ComputersHorizon-DEMYes
VDI-Computers/Finances--Yes
VDI-Computers/HR--Yes
VDI-Computers/Marketing--Yes
VDI-Computers/Sales--Yes
VEEAM ServersVEEAM_Disable_Firewall, VEEAM_Local_AdministratorsYes
VEEAM WorkStationsVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
+
Table 144 - Organizational Unit - PHARMAX.LOCAL

+
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

+ + + + +
OU NameContainer TypeInheritance BlockedPath
adminOUYespharmax.local/Admin
linuxmachinesOUYespharmax.local/LinuxMachines
veeam workstationsOUYespharmax.local/VEEAM WorkStations
+
Table 145 - Blocked Inheritance GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.1.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

+ + + + + + +
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
+
Table 146 - Active Directory Hardening - PHARMAX.LOCAL

+
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.1.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the PHARMAX.LOCAL domain.

+ + + + + + +
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=DomainDnsZones,DC=pharmax,DC=local2025:08:30215
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
DC=pharmax,DC=local2025:08:30215
+
Table 147 - Naming Context Last Backup - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain PHARMAX.LOCAL.

+ + + + + + + + +
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
Caguas-DC-01VNormal1919Yes0
Carolina-DC-01VNormal1919Yes0
Cayey-Dc-01VNormal1919Yes0
Naguabo-DC-01VNormal1919Yes0
Ponce-DC-01VNormal1919Yes0
Server-DC-01VNormal1919Yes0
Server-DC-02VOffline0000
+
Table 148 - Sysvol Replication Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

Sysvol Content Status

The following section provides the SYSVOL health status for domain PHARMAX.LOCAL.

+ + + + + + + + + + + + + + + + + + +
ExtensionFile CountSize
.aas30.09 MB
.adm40.05 MB
.adml497079.15 MB
.admx2363.98 MB
.cmd10.00 MB
.cmt10.00 MB
.cmtx80.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.inf120.01 MB
.INI200.01 MB
.msi3150.78 MB
.pol160.04 MB
.ps120.02 MB
.xml50.01 MB
.zip5143.60 MB
+
Table 149 - Sysvol Content Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain PHARMAX.LOCAL.

+ + + + + + + + + + + + + +
ExtensionFile CountSize
.adm10.01 MB
.adml10.03 MB
.admx10.02 MB
.cmd10.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.ini10.01 MB
.msi3150.78 MB
.ps120.02 MB
.xml10.00 MB
.zip5143.60 MB
+
Table 150 - Netlogon Content Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain PHARMAX.LOCAL.

+User Account Security Assessment - Diagram +
+
+ + + + + + + + + + + +
Total8559
Enabled8546
Disabled13
Enabled Inactive1
Reversible Encryption Password1
Password Not Required7
Password Never Expires33
Kerberos DES1
Does Not Require Pre Auth0
SID History0
+
Table 151 - User Account Security Assessment - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain PHARMAX.LOCAL.

+ + + + + + + + + +
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
krbtgt6/10/2018--No** Yes
Administrator6/10/201812/10/2053* Yes** Yes
jocolon11/30/202112/22/2043* Yes** Yes
veeam_admin12/13/201911/22/2025No** Yes
svc_SCCM_ClientPush9/12/20209/14/2020No** Yes
1227935471SA5/28/2023--No** Yes
GERARDO_RICE5/29/2023--No** Yes
scvmm-admin9/4/20259/4/2025No** Yes
+
Table 152 - Privileged Users Assessment - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

+ + + + + +
UsernameCreatedPassword Last SetLast Logon Date
veeam_admin12/13/201912/13/201911/22/2025
svc_SCCM_ClientPush9/12/20209/12/20209/14/2020
1227935471SA5/28/20235/28/2023--
GERARDO_RICE5/29/20235/29/2023--
+
Table 153 - Inactive Privileged Accounts - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain PHARMAX.LOCAL.

+ + + + + + + + + + +
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
vcenterYes12/13/201912/13/2019CIFS/ACAD-DNS-01V
svc_SCCM_ClientPushYes9/12/20209/14/2020CIFS/VEEAM-HV-01
krbtgtNo6/10/2018--CIFS/VEEAM-VBR-01V kadmin/changepw
srmrecadminYes10/25/2021--ftp/VEEAM-EM
jocolonYes11/30/202112/22/2043HTTP/example.com
horizon-icYes9/14/202510/20/2025https/GOOWLPT1000001
** GERARDO_RICEYes5/29/2023--POP3/SECWVIR1000255
** AdministratorYes6/10/201812/10/2053SCVMM/SCVMM-SVR-01V SCVMM/SCVMM-SVR-01V.pharmax.local VeeamCdpSvc/VEEAM-VBR VeeamCdpSvc/VEEAM-VBR.pharmax.local VeeamCloudConnectSvc/VEEAM-VBR VeeamCloudConnectSvc/VEEAM-VBR.pharmax.local VeeamBackupSvc/VEEAM-VBR VeeamBackupSvc/VEEAM-VBR.pharmax.local VeeamCatalogSvc/VEEAM-VBR VeeamCatalogSvc/VEEAM-VBR.pharmax.local VeeamEnterpriseManagerSvc/VEEAM-EM VeeamEnterpriseManagerSvc/VEEAM-EM.pharmax.local VeeamCatalogSvc/VEEAM-EM VeeamCatalogSvc/VEEAM-EM.pharmax.local
veeam_adminYes12/13/201911/22/2025VeeamCdpSvc/VEEAM-DRO-01V VeeamCdpSvc/VEEAM-DRO-01V.pharmax.local VeeamCloudConnectSvc/VEEAM-DRO-01V VeeamCloudConnectSvc/VEEAM-DRO-01V.pharmax.local VeeamBackupSvc/VEEAM-DRO-01V VeeamBackupSvc/VEEAM-DRO-01V.pharmax.local VeeamCatalogSvc/VEEAM-DRO-01V VeeamCatalogSvc/VEEAM-DRO-01V.pharmax.local
+
Table 154 - Service Accounts Assessment (Kerberoastable) - PHARMAX.LOCAL

+
Health Check:

Security Best Practice: ** Attackers are most interested in Service Accounts that are members of highly privileged groups like Domain Admins. A quick way to check for this is to enumerate all user accounts with the attribute AdminCount equal to 1. This means an attacker may just ask Active Directory for all user accounts with an SPN and with AdminCount=1. Ensure that there are no privileged accounts that have SPNs assigned to them.

Unconstrained Kerberos Delegation

The following section identifies systems configured with unconstrained Kerberos delegation, which represents a significant security risk in the domain PHARMAX.LOCAL.

+ + +
NameDistinguished Name
HV-SERVER-01VCN=HV-SERVER-01V,OU=Member Servers,DC=pharmax,DC=local
+
Table 155 - Unconstrained Kerberos Delegation - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there are no instances of unconstrained Kerberos delegation in Active Directory, as it poses a security risk by allowing any service to impersonate users.

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain PHARMAX.LOCAL.

+ + + + + +
Namekrbtgt
Created06/10/2018 21:00:49
Password Last Set06/10/2018 21:00:49
Distinguished NameCN=krbtgt,CN=Users,DC=pharmax,DC=local
+
Table 156 - KRBTGT Account Audit - PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain PHARMAX.LOCAL.

+ + + + + + +
NameAdministrator
Created06/10/2018 21:00:05
Password Last Set06/10/2018 04:01:50
Last Logon Date12/10/2053 19:01:07
Distinguished NameCN=Administrator,CN=Users,DC=pharmax,DC=local
+
Table 157 - Administrator Account Audit - PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

Duplicate Objects

The following section details duplicate objects detected in the domain PHARMAX.LOCAL. These objects may indicate replication issues or administrative errors that require attention.

+ + +
NameCreatedChangedConflict Changed
SCCM-DP-01V-Remote-Installation-Services CNF:0b206bf4-6c39-47b2-bd69-3694aa657d762020:09:132020:09:132020:09:13
+
Table 158 - Duplicate Object - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there are no duplicate objects in Active Directory. Duplicate objects can cause various issues such as authentication problems, replication conflicts, and administrative overhead. It is recommended to regularly audit and clean up any duplicate objects to maintain a healthy and efficient Active Directory environment.

2.2 ACAD.PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

+ + + + + + + + + + + + + + + + + + + + + + +
Domain Nameacad
NetBIOS NameACAD
Domain SIDS-1-5-21-370360276-377477351-3184454278
Domain Functional LevelWindows2016Domain
Domains--
Forestpharmax.local
Parent Domainpharmax.local
Replica Directory Serversacade-dc-01v.acad.pharmax.local
Child Domains--
Domain Pathacad.pharmax.local/
Computers ContainerCN=Computers,DC=acad,DC=pharmax,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=acad,DC=pharmax,DC=local
Systems ContainerCN=System,DC=acad,DC=pharmax,DC=local
Users ContainerCN=Users,DC=acad,DC=pharmax,DC=local
Deleted Objects ContainerCN=Deleted Objects,DC=acad,DC=pharmax,DC=local
Foreign Security Principals ContainerCN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
Lost And Found ContainerCN=LostAndFound,DC=acad,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=acad,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available2100 / 1073739723 (1% Issued)
+
Table 159 - Domain Summary - ACAD.PHARMAX.LOCAL

+

2.2.1 FSMO Roles

+ + + + + + +
Infrastructure Masteracade-dc-01v.acad.pharmax.local
PDC Emulator Nameacade-dc-01v.acad.pharmax.local
RID Masteracade-dc-01v.acad.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
+
Table 160 - FSMO Roles - acad.pharmax.local

+
Health Check:

Best Practice: The infrastructure master role in the domain ACAD.PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.2.2 Domain and Trusts

pharmax.local Trust Details

+ + + + + + + + + + + + + + + + +
Namepharmax.local
Pathacad.pharmax.local/System/pharmax.local
Sourceacad
Targetpharmax.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 161 - Trust - pharmax.local

+

lab.local Trust Details

+ + + + + + + + + + + + + + + + +
Namelab.local
Pathacad.pharmax.local/System/lab.local
Sourceacad
Targetlab.local
Trust TypeUplevel
Trust AttributesQuarantined Domain (External)
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 162 - Trust - lab.local

+

pharam.local Trust Details

+ + + + + + + + + + + + + + + + +
Namepharam.local
Pathacad.pharmax.local/System/pharam.local
Sourceacad
Targetpharam.local
Trust TypeUplevel
Trust Attributes20
Trust DirectionOutbound (Trusted domain)
Intra ForestNo
Selective AuthenticationYes
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 163 - Trust - pharam.local

+
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

+
Microsoft Active Directory As Built Report - v1.0

2.2.2.1 Domain and Trusts Diagram

+Domain and Trusts Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

2.2.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.2.3.1 User Objects

Users

+User Objects - Diagram +
+
+ + + + +
Users7
Privileged Users4
Foreign Security Principals4
+
Table 164 - User - ACAD.PHARMAX.LOCAL

+

Status of Users Accounts

+Status of Users Accounts - Diagram +
+
+ + + + + + + + + + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users7100342.867100
Cannot Change Password000000
Password Never Expires228.57228.57228.57
Must Change Password at Logon114.29114.29114.29
Password Age (> 180 days)114.29114.29114.29
SmartcardLogonRequired000000
SidHistory000000
Never Logged in685.71342.86685.71
Dormant (> 90 days)685.71342.86685.71
Password Not Required457.14114.29457.14
Account Expired000000
Account Lockout000000
+
Table 165 - Status of Users Accounts - ACAD.PHARMAX.LOCAL

+

2.2.3.2 Group Objects

Groups Categories

+Groups Categories - Diagram +
+
+ + + +
Security Groups48
Distribution Groups0
+
Table 166 - Groups Categories - ACAD.PHARMAX.LOCAL

+

Groups Scopes

+Groups Scopes - Diagram +
+
+ + + + +
Domain Locals34
Globals14
Universal0
+
Table 167 - Groups Scopes - ACAD.PHARMAX.LOCAL

+
2.2.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (2 Members)

+ + + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
SCCM-GMSA (GROUP)------
+
Table 168 - Domain Admins - ACAD.PHARMAX.LOCAL

+

Key Admins (1 Members)

+ + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
SCCM-GMSA (GROUP)------
+
Table 169 - Key Admins - ACAD.PHARMAX.LOCAL

+

Backup Operators (1 Members)

+ + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
+
Table 170 - Backup Operators - ACAD.PHARMAX.LOCAL

+
2.2.3.2.2 Privileged Group (Non-Default)
The following section provides a summary of privileged groups with the AdminCount attribute set to 1 (excluding default groups).

+ + + +
Group NameGroup SID
PruebaS-1-5-21-370360276-377477351-3184454278-1114
SCCM-GMSAS-1-5-21-370360276-377477351-3184454278-1104
+
Table 171 - - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Regularly validate and remove unneeded privileged group members in Active Directory. Ensuring that only necessary accounts have privileged access helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation. Regular audits and reviews of group memberships can help identify and mitigate potential security risks.
2.2.3.2.3 Empty Groups (Non-Default)
+ + +
Group NameGroup SID
EmptyGrouptestS-1-5-21-370360276-377477351-3184454278-1117
+
Table 172 - Empty Groups - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.2.3.2.4 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

+ + + + + +
Parent Group NameChild Group Name
Key AdminsSCCM-GMSA
PruebaSCCM-GMSA
SCCM-GMSAKey Admins
SCCM-GMSAPrueba
+
Table 173 - Circular Group Membership - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.2.3.2.5 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

+ + + +
NameDistinguished Name
ACADE-DC-01V (COMPUTER)CN=ACADE-DC-01V,OU=Domain Controllers,DC=acad,DC=pharmax,DC=local
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
+
Table 174 - Pre-Windows 2000 Compatible Access - ACAD.PHARMAX.LOCAL

+
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.2.3.3 Computer Objects

Computers

+Computer Objects - Diagram +
+
+ + + +
Computers5
Servers4
+
Table 175 - Computers - ACAD.PHARMAX.LOCAL

+
2.2.3.3.1 Status of Computer Accounts
+Status of Computer Accounts - Diagram +
+
+ + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers5100005100
Dormant (> 90 days)48000480
Password Age (> 30 days)48000480
SidHistory000000
+
Table 176 - Status of Computer Accounts - ACAD.PHARMAX.LOCAL

+
2.2.3.3.2 Operating Systems Count
+ + + + + +
Operating SystemCount
No OS Specified1
Windows Server 2019 Standard2
Windows Server 2019 Standard Evaluation1
Windows Server 2022 Datacenter Evaluation1
+
Table 177 - - ACAD.PHARMAX.LOCAL

+

2.2.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.2.4.1 Default Domain Password Policy

+ + + + + + + + + + + +
Password Must Meet Complexity RequirementsYes
Pathacad.pharmax.local/
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Maximum Password Age42 days
Minimum Password Age01 days
Minimum Password Length7
Enforce Password History24
Store Password using Reversible EncryptionNo
+
Table 178 - Default Domain Password Policy - ACAD.PHARMAX.LOCAL

+

2.2.4.2 Fined Grained Password Policies

ACADTest

+ + + + + + + + + + + + + + + +
NameACADTest
Domain NameDC=acad,DC=pharmax,DC=local
Complexity EnabledYes
Pathacad.pharmax.local/System/Password Settings Container/ACADTest
Lockout Duration30 minutes
Lockout Threshold5
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age01 days
Min Password Length14
Password History Count24
Reversible Encryption EnabledNo
Precedence1
Applies To--
+
Table 179 - Name - ACADTest

+

2.2.4.3 gMSA Identities

SCCMMSA

+ + + + + + + + + + + + + + +
NameSCCMMSA
SamAccountNameSCCMMSA$
Created9/11/2021
EnabledYes
DNS Host Nameacad.pharmax.local
Host Computers**--
Retrieve Managed PasswordSCCM-GMSA
Primary GroupDomain Computers
Last Logon Date*--
Locked OutNo
Logon Count0
Password ExpiredNo
Password Last Set9/11/2021
+
Table 180 - gMSA - SCCMMSA

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.2.4.4 Foreign Security Principals

+ + + + + +
NamePrincipal Name
NT AUTHORITY\INTERACTIVEUsers
NT AUTHORITY\Authenticated UsersPre-Windows 2000 Compatible Access
Certificate Service DCOM Access
Users
NT AUTHORITY\IUSR--
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
+
Table 181 - Foreign Security Principals - ACAD.PHARMAX.LOCAL

+

2.2.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

+ + +
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
ACADE-DC-01VOnlineACADYesNo172.23.4.1
+
Table 182 - Domain Controller in Domain - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: All domains should have at least two functioning domain controllers for redundancy. In the event of a failure on the domain's only domain controller, users will not be able to log in to the domain or access domain resources. This ensures high availability and fault tolerance within the domain infrastructure.

+Domain Controller Object - Chart +
+
+ + + +
Domain Controller1
Global Catalog1
+
Table 183 - Domain Controller Counts - ACAD.PHARMAX.LOCAL

+

2.2.5.1 Configuration

2.2.5.1.1 ACADE-DC-01V

General Information

+ + + + + + + + + + + + +
DC Nameacade-dc-01v.acad.pharmax.local
Domain Nameacad.pharmax.local
SiteACAD
Global CatalogYes
Read OnlyNo
Operation Master RolesPDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-370360276-377477351-3184454278-1000
Operating SystemWindows Server 2019 Standard
SMB1 StatusEnabled
DescriptionACAD PDC Server
+
Table 184 - General Information - ACADE-DC-01V

+
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

+ + + +
Default PartitionDC=acad,DC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
+
Table 185 - Partitions - ACADE-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses172.23.4.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
+
Table 186 - Networking Settings - ACADE-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameACADE-DC-01V
Windows Product NameWindows Server 2019 Standard
Windows Build Number10.0.17763
AD Domainacad.pharmax.local
Windows Installation Date09/05/2021 10:35:50
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyJ464C
ManufacturerVMware, Inc.
ModelVMware7,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 187 - Hardware Inventory - ACADE-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.2.5.2 DNS IP Configuration

+ + +
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
ACADE-DC-01VEthernet0192.168.5.1127.0.0.1172.23.4.1127.0.0.1
+
Table 188 - DNS IP Configuration - ACAD.PHARMAX.LOCAL

+

2.2.5.3 NTDS Information

+ + +
DC NameDatabase FileDatabase SizeLog PathSysVol Path
ACADE-DC-01VC:\Windows\NTDS\ntds.dit1 GBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
+
Table 189 - NTDS Database File Usage - ACAD.PHARMAX.LOCAL

+

2.2.5.4 Time Source Information

+ + +
NameTime ServerType
ACADE-DC-01V0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
+
Table 190 - Time Source Configuration - ACAD.PHARMAX.LOCAL

+

2.2.5.5 SRV Records Status

+ + +
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
ACADE-DC-01VOKOKOKOKOK
+
Table 191 - SRV Records Status - ACAD.PHARMAX.LOCAL

+

2.2.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

ACADE-DC-01V

+ + +
NamePathDescription
CertEnrollC:\Windows\system32\CertSrv\CertEnrollActive Directory Certificate Services share
+
Table 192 - File Shares - ACADE-DC-01V

+
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.2.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

+ + + +
NamePublisherInstall Date
7-Zip 22.01 (x64)Igor Pavlov--
DiskMax 7.22KoshyJohn.com06/08/2024
+
Table 193 - Installed Software - ACADE-DC-01V

+
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.2.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

+ + +
KB ArticleName
KB50787522026-03 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5078752)
+
Table 194 - Missing Windows Updates - ACADE-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.2.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in acad.pharmax.local.

ACADE-DC-01V

+ + + + + + + +
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
+
Table 195 - Roles - ACADE-DC-01V

+
Health Check:

Best Practices:
    +
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
  2. +
-[AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport) is an open-sourced community project which utilizes PowerShell to produce as-built documentation in multiple document formats for multiple vendors and technologies. - -Please refer to the AsBuiltReport [website](https://www.asbuiltreport.com) for more detailed information about this project. - -# :books: Sample Reports - -## Sample Report - Default Style with EnableHealthCheck - -Sample Microsoft AD As Built report HTML file: [Sample Microsoft AD As-Built Report.html](https://htmlpreview.github.io/?https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.AD/dev/Samples/Sample%20Microsoft%20AD%20As%20Built%20Report.html) - -# :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; - -- 2012, 2016, 2019, 2022 & 2025 - -### PowerShell - -This report is compatible with the following PowerShell versions; - - -| Windows PowerShell 5.1 | PowerShell 7 | -| :--------------------: | :----------------: | -| :x: | :white_check_mark: | - -## :wrench: System Requirements - -PowerShell 7.4+, and the following PowerShell modules are required for generating a Microsoft AD As Built report. - -- [AsBuiltReport.Core Module](https://github.com/AsBuiltReport/AsBuiltReport.Core) -- [AsBuiltReport.Chart Module](https://github.com/AsBuiltReport/AsBuiltReport.Chart) -- [AsBuiltReport.Diagram Module](https://github.com/AsBuiltReport/AsBuiltReport.Diagram) -- [AsBuiltReport.Microsoft.AD Module](https://www.powershellgallery.com/packages/AsBuiltReport.Microsoft.AD/) -- [PScribo Module](https://github.com/iainbrighton/PScribo) -- [PSGraph Module](https://github.com/KevinMarquette/PSGraph) -- [ActiveDirectory Module](https://docs.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2019-ps) -- [ADCSAdministration Module](https://learn.microsoft.com/en-us/powershell/module/adcsadministration/?view=windowsserver2019-ps) -- [GroupPolicy Module](https://docs.microsoft.com/en-us/powershell/module/grouppolicy/?view=windowsserver2019-ps) -- [DnsServer Module](https://docs.microsoft.com/en-us/powershell/module/dnsserver/?view=windowsserver2019-ps) - -### Linux & macOS - -This report is not supported on Linux or macOS because the ActiveDirectory and GroupPolicy modules depend on the .NET Framework. These modules are Windows-only until Microsoft migrates them to PowerShell Core. Therefore, only PowerShell 7.4+ on Windows is supported for generating this report. - -### :closed_lock_with_key: Required Privileges - -A Microsoft AD As Built Report can be generated with Active Directory Enterprise Forest level privileges. Since this report relies extensively on the WinRM component, you should make sure that it is enabled and configured. [Reference](https://docs.microsoft.com/en-us/windows/win32/winrm/installation-and-configuration-for-windows-remote-management) - -Due to a limitation of the WinRM component, a domain-joined machine is needed, also it is required to use the FQDN of the DC instead of it's 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 -Name PSGraph -Install-Module -Name AsBuiltReport.Chart -Install-Module -Name AsBuiltReport.Diagram -Install-Module -Name AsBuiltReport.Microsoft.AD -Install-WindowsFeature -Name RSAT-AD-PowerShell -Install-WindowsFeature -Name RSAT-ADCS,RSAT-ADCS-mgmt -Install-WindowsFeature -Name RSAT-DNS-Server -Install-WindowsFeature -Name GPMC -``` - -### PowerShell v5.x running on Windows 10 client computer - -```powershell -Install-Module -Name PSGraph -Install-Module -Name AsBuiltReport.Chart -Install-Module -Name AsBuiltReport.Diagram -Install-Module -Name AsBuiltReport.Microsoft.AD -Add-WindowsCapability -online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' -Add-WindowsCapability -Online -Name 'Rsat.CertificateServices.Tools~~~~0.0.1.0' -Add-WindowsCapability -online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0' -Add-WindowsCapability –online –Name 'Rsat.Dns.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. - -| Sub-Schema | Setting | Default | Description | -| ----------------------- | ------------------ | --------- | -------------------------------------------------------------------------------- | -| DCStatusPingCount | int | 2 | Set the count value for the cmdlet Test-Connection (Increase if network is slow) | -| DiagramTheme | string | White | Set the diagram theme (Black/White/Neon) | -| DiagramType | true / false | true | Toggle to enable/disable the export of individual diagram diagrams | -| DiagramWaterMark | string | empty | Set the diagram watermark | -| EnableDiagrams | true / false | false | Toggle to enable/disable infrastructure diagrams | -| EnableDiagramsDebug | true / false | false | Toggle to enable/disable diagram debug option | -| EnableDiagramSignature | true / false | false | Toggle to enable/disable diagram signature (bottom right corner) | -| EnableHardwareInventory | true / false | false | Toggle to enable/disable hardware information | -| ExportDiagrams | true / false | true | Toggle to enable/disable diagram export option | -| ExportDiagramsFormat | string array | pdf | Set the format used to export the infrastructure diagram (dot, png, pdf, svg) | -| Exclude.DCs | array List | Empty | Allow to filter on AD Domain Controller Server FQDN. | -| Exclude.Domains | array List | Empty | Allow to filter on AD Domain FQDN | -| Include.DCs | array List | Empty | Allow only a list of Active Directory Domain FQDN to document. | -| Include.Domains | array List | Empty | Allow only a list of Active Directory Domain Controller FQDN to document. | -| JobsTimeOut | int | 900 | Allow to set the timeout (in seconds) for remote jobs execution | -| PSDefaultAuthentication | Negotiate/Kerberos | Negotiate | Allow to set the value of the PSRemoting authentication method. | -| | | | For Workgroup authentication Negotiate value is required. | -| ShowDefinitionInfo | true/false | False | Toggle to enable/disable Microsoft AD term explanations | -| SignatureAuthorName | string | empty | Set the signature author name | -| SignatureCompanyName | string | empty | Set the signature company name | -| WinRMFallbackToNoSSL | bool | True | Allow to fallback to WINRM without SSL | -| WinRMPort | int | 5985 | Allow to set tcp port for WinRM | -| WinRMSSL | bool | True | Allow to enable SSL for WINRM connection | -| WinRMSSLPort | int | 5986 | Allow to set tcp port for WinRM over SSL | - - -### InfoLevel - -The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set. - -There are 4 levels (0-3) of detail granularity for each section as follows; - -| Setting | InfoLevel | Description | -| :-----: | ------------ | --------------------------------------------------------------------------------------------------- | -| 0 | Disabled | Does not collect or display any information | -| 1 | Enabled | Provides summarized information for a collection of objects | -| 2 | Adv Summary | Provides condensed, detailed information for a collection of objects | -| 3 | Detailed | Provides detailed information for individual objects | -| 4 | Adv Detailed | Provides detailed information for individual objects, as well as information for associated objects | - - -The table below outlines the default and maximum **InfoLevel** settings for each section. - -| Sub-Schema | Default Setting | Maximum Setting | -| ---------- | :-------------: | :-------------: | -| Forest | 2 | 1 | -| Domain | 2 | 4 | -| DNS | 1 | 2 | - -### 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 -- **PSWriteWord Module Conflict**: PScribo and the EvotecIT "PSWriteWord" project use conflicting cmdlets. The PSWriteWord module must be uninstalled before generating reports. -- **WinRM Dependency**: This report relies heavily on remote connections via WinRM. A Windows 10 client is recommended as a jumpbox for optimal connectivity. -- **DNS Service Requirements**: To extract DNS service configuration, install PowerShell management modules on servers hosting DNS services (RSAT-DNS-Server and RSAT-AD-PowerShell). -- **DNS Cohosting Assumption**: The report assumes DNS Server service runs on the same server as the Domain Controller. -- **Windows Server 2012/2012 R2 Compatibility**: Hexadecimal character errors may occur when running against older Windows Server versions. +

2.2.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

ACADE-DC-01V

+ + + + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 196 - Infrastructure Services Status - ACADE-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.2.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.2.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: ACADE-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDca680ef0-acf8-4b96-a041-241cc754b87a
Description--
From ServerSERVER-DC-01V
To ServerACADE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 04:17:40 GMT
+
Table 197 - Replication Connection - ACADE-DC-01V

+

2.2.6.2 Replication Status

+ + + + + +
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:06:43000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:36:39000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:44:26000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:13:46000
+
Table 198 - Replication Status - ACAD

+

2.2.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.2.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the ACAD.PHARMAX.LOCAL domain.

2.2.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Empty Policy ACAD

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID053a8be2-fc5e-46de-8dde-4c5047ccd151
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI FilterFilter
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
acad.pharmax.local
Description--
+
Table 199 - GPO - Empty Policy ACAD

+

Default Domain Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created09/05/2021
Modified03/07/2025
OwnerACAD\Domain Admins
Computer Version13 (AD), 13 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local
Description--
+
Table 200 - GPO - Default Domain Policy

+

Unlinked Policy ACAD

+ + + + + + + + + + + + +
GPO StatusAll Settings Disabled
GUID40a5cbba-ed3f-460d-9de1-22d2541b7643
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Enterprise Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 201 - GPO - Unlinked Policy ACAD

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

ACAD - Deleted GPO in Sysvol

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID696c8f4b-54a9-4456-ae3f-bc52b40c5c33
Created06/21/2023
Modified06/21/2023
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 202 - GPO - ACAD - Deleted GPO in Sysvol

+
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Default Domain Controllers Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created09/05/2021
Modified03/03/2026
OwnerACAD\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Domain Controllers
Description--
+
Table 203 - GPO - Default Domain Controllers Policy

+

ACAD Certificate AutoEnrollment

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDbe6237b7-b1d4-47e3-a8e5-7f6ec1b38d57
Created09/22/2021
Modified09/22/2021
OwnerPHARMAX\Enterprise Admins
Computer Version2 (AD), 2 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local
Description--
+
Table 204 - GPO - ACAD Certificate AutoEnrollment

+

Logon Script

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDfd32ee4c-ac02-4de5-ae91-1316f4f86bf5
Created10/07/2021
Modified10/07/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version2 (AD), 2 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
Description--
+
Table 205 - GPO - Logon Script

+
2.2.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

+ + + + + +
NameFilter
AuthorAdministrator@pharmax.local
Query1;3;13;62;WQL;root\Hardware;select * from Win32_OperatingSystem where Version like "6.%"
;
Description--
+
Table 206 - WMI Filter - Filter

+

Central Store Repository

+ + +
DomainConfiguredCentral Store Path
ACADNo\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\PolicyDefinitions
+
Table 207 - GPO Central Store - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practices: The Group Policy Central Store is a central location to store all the Group Policy template files (ADMX/ADML files). This eliminates the need for administrators to load and open Group Policy template files on each system used to manage Group Policy. Ensure the Central Store is deployed to a centralized GPO repository to streamline management and ensure consistency across the environment.

Logon/Logoff Script

+ + +
GPO NameGPO StatusTypeScript
Logon ScriptAll Settings EnabledLogon\\acad.pharmax.local\NETLOGON\enroll.exe
+
Table 208 - GPO with Logon/Logoff Script - ACAD.PHARMAX.LOCAL

+
2.2.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

+ + + +
GPO NameCreatedModifiedComputer EnabledUser Enabled
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21YesYes
Unlinked Policy ACAD2021-10-062021-10-06NoNo
+
Table 209 - Unlinked GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

+ + + +
GPO NameCreatedModifiedDescription
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21--
Empty Policy ACAD2021-10-062021-10-06--
+
Table 210 - Empty GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

+ + + + + +
GPO NameTarget
ACAD Certificate AutoEnrollmentacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/Acad Computers/SCCM Computers
Logon Scriptacad.pharmax.local/Acad Computers/SCCM Computers
+
Table 211 - Enforced GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

+ + + + + + + +
NameUnknown
Guid2E8D7948-6F28-4872-B97C-CA2CB971C9AE
AD DN DatabaseMissing
AD DN PathCN={2E8D7948-6F28-4872-B97C-CA2CB971C9AE},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{2E8D7948-6F28-4872-B97C-CA2CB971C9AE} (Valid)
+
Table 212 - Orphaned GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

+ + + + + + + +
NameACAD - Deleted GPO in Sysvol
Guid696C8F4B-54A9-4456-AE3F-BC52B40C5C33
AD DN DatabaseValid
AD DN PathCN={696C8F4B-54A9-4456-AE3F-BC52B40C5C33},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{696C8F4B-54A9-4456-AE3F-BC52B40C5C33} (Missing)
+
Table 213 - Orphaned GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.2.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

+ + + + + +
NameLinked GPOProtected
Acad Computers--Yes
Acad Computers/SCCM ComputersLogon Script, Empty Policy ACADYes
Domain ControllersDefault Domain Controllers PolicyNo
Member Servers--No
+
Table 214 - Organizational Unit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

+ + +
OU NameContainer TypeInheritance BlockedPath
sccm computersOUYesacad.pharmax.local/Acad Computers/SCCM Computers
+
Table 215 - Blocked Inheritance GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.2.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

+ + + + + + +
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
+
Table 216 - Active Directory Hardening - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.2.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the ACAD.PHARMAX.LOCAL domain.

+ + + + + + +
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=acad,DC=pharmax,DC=local2021:09:051670
DC=DomainDnsZones,DC=acad,DC=pharmax,DC=local2021:09:051670
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
+
Table 217 - Naming Context Last Backup - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain ACAD.PHARMAX.LOCAL.

+ + +
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
acade-dc-01vNormal77Yes0
+
Table 218 - Sysvol Replication Status - ACAD.PHARMAX.LOCAL

+

Sysvol Content Status

The following section provides the SYSVOL health status for domain ACAD.PHARMAX.LOCAL.

+ + + + + + + + + + +
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.cmtx10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.inf30.01 MB
.INI70.00 MB
.pol30.01 MB
.ps120.02 MB
+
Table 219 - Sysvol Content Status - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain ACAD.PHARMAX.LOCAL.

+ + + + + + +
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.ps120.02 MB
+
Table 220 - Netlogon Content Status - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain ACAD.PHARMAX.LOCAL.

+User Account Security Assessment - Diagram +
+
+ + + + + + + + + + + +
Total7
Enabled4
Disabled3
Enabled Inactive1
Reversible Encryption Password0
Password Not Required4
Password Never Expires2
Kerberos DES0
Does Not Require Pre Auth0
SID History0
+
Table 221 - User Account Security Assessment - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain ACAD.PHARMAX.LOCAL.

+ + + + + +
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
grouptest7/21/2023--* YesNo
Administrator3/19/20263/19/2026No** Yes
Guest----No** Yes
krbtgt9/5/2021--No** Yes
+
Table 222 - Privileged Users Assessment - ACAD.PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain ACAD.PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

+ + + +
UsernameCreatedPassword Last SetLast Logon Date
grouptest7/21/20237/21/2023--
Guest9/5/2021----
+
Table 223 - Inactive Privileged Accounts - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain ACAD.PHARMAX.LOCAL.

+ + +
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
krbtgtNo9/5/2021--kadmin/changepw
+
Table 224 - Service Accounts Assessment (Kerberoastable) - ACAD.PHARMAX.LOCAL

+
Health Check:

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain ACAD.PHARMAX.LOCAL.

+ + + + + +
Namekrbtgt
Created09/05/2021 12:25:21
Password Last Set09/05/2021 12:25:21
Distinguished NameCN=krbtgt,CN=Users,DC=acad,DC=pharmax,DC=local
+
Table 225 - KRBTGT Account Audit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain ACAD.PHARMAX.LOCAL.

+ + + + + + +
NameAdministrator
Created09/05/2021 12:24:39
Password Last Set03/19/2026 21:42:01
Last Logon Date03/19/2026 21:42:01
Distinguished NameCN=Administrator,CN=Users,DC=acad,DC=pharmax,DC=local
+
Table 226 - Administrator Account Audit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

3 DNS Configuration

The following section provides a detailed overview of the DNS infrastructure configuration and settings within the Active Directory environment.

3.1 PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.1.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

+ + + + + + + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
CAGUAS-DC-01V26100YesYesNofe80::75c9:eaa3:559a:23de
172.23.7.1
CAROLINA-DC-01V26100YesYesNo172.23.9.1
CAYEY-DC-01V26100YesYesNofe80::74a3:277d:e262:218b
10.10.30.1
NAGUABO-DC-01V26100YesYesNofe80::efb6:c739:603c:1121
10.10.31.1
PONCE-DC-01V26100YesYesNofe80::de92:566e:cf5c:a051
10.10.32.1
SERVER-DC-01V26100YesNoNo192.168.5.1
192.168.7.1
+
Table 227 - Infrastructure Summary - PHARMAX.LOCAL

+

3.1.1.1 Forwarder Options

+ + + + + + + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
CAGUAS-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
CAROLINA-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
CAYEY-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
NAGUABO-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
PONCE-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
SERVER-DC-01V10.0.0.138
8.8.8.8
1.1.1.1
3/sYesYes
+
Table 228 - Forwarders - PHARMAX.LOCAL

+
Health Check:

Best Practices: Configure the servers to use no more than two external DNS servers as Forwarders. Using more than two forwarders can lead to increased resolution times and potential issues with DNS query load balancing. It is recommended to use two reliable and geographically diverse DNS servers to ensure redundancy and optimal performance.

Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/forwarders-resolution-timeouts

3.1.2 CAGUAS-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 229 - Zones - PHARMAX.LOCAL

+

3.1.2.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 230 - Zones - PHARMAX.LOCAL

+

3.1.2.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 231 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.3 CAROLINA-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 232 - Zones - PHARMAX.LOCAL

+

3.1.3.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 233 - Zones - PHARMAX.LOCAL

+

3.1.3.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 234 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.4 CAYEY-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 235 - Zones - PHARMAX.LOCAL

+

3.1.4.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 236 - Zones - PHARMAX.LOCAL

+

3.1.4.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 237 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.5 NAGUABO-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 238 - Zones - PHARMAX.LOCAL

+

3.1.5.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 239 - Zones - PHARMAX.LOCAL

+

3.1.5.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 240 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.6 PONCE-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 241 - Zones - PHARMAX.LOCAL

+

3.1.6.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 242 - Zones - PHARMAX.LOCAL

+

3.1.6.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 243 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.7 SERVER-DC-01V DNS Zones

+ + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localSecondary----NoNo--
BlueTuxedo.localPrimaryNoneNoneNoNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 244 - Zones - PHARMAX.LOCAL

+

3.1.7.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 245 - Zones - PHARMAX.LOCAL

+

3.1.7.2 Conditional Forwarder

+ + + + + + + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
lab.localForwarderNone10.10.30.10No
meereen.essos.localForwarderNone192.168.56.12No
pharam.localForwarderLegacy192.168.7.42Yes
proton.localForwarderNone192.168.5.20No
sevenkingdoms.localForwarderNone192.168.56.10No
winterfell.sevenkingdoms.localForwarderNone192.168.56.11No
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 246 - Conditional Forwarders - PHARMAX.LOCAL

+

3.2 ACAD.PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.2.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

+ + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
ACADE-DC-01V17763YesNoNo172.23.4.1
+
Table 247 - Infrastructure Summary - ACAD.PHARMAX.LOCAL

+

3.2.1.1 Forwarder Options

+ + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
ACADE-DC-01V192.168.5.13/sYesYes
+
Table 248 - Forwarders - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practices: For redundancy reasons, more than one forwarding server should be configured.

3.2.2 ACADE-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenpr.localSecondary----NoNo--
+
Table 249 - Zones - ACAD.PHARMAX.LOCAL

+

3.2.2.1 Reverse Lookup Zone

+ + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 250 - Zones - ACAD.PHARMAX.LOCAL

+

3.2.2.2 Conditional Forwarder

+ + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
zenprsolutions.localForwarderNone8.8.8.8No
+
Table 251 - Conditional Forwarders - ACAD.PHARMAX.LOCAL

+
+

From b71ff63d1ac7df3171181ae508c49829cdddfd5c Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 3 Apr 2026 20:47:38 -0400 Subject: [PATCH 02/18] Fix footer HTML in README.md From 2412c716267c74b5d99c0c3c4d12d4015036af6d Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 3 Apr 2026 20:48:23 -0400 Subject: [PATCH 03/18] Update fmt.Println message from 'Hello' to 'Goodbye' --- README.md | 3418 ++++------------------------------------------------- 1 file changed, 246 insertions(+), 3172 deletions(-) diff --git a/README.md b/README.md index fdb418e..6df76a2 100644 --- a/README.md +++ b/README.md @@ -1,3177 +1,251 @@ - - -Microsoft Active Directory As Built Report - -
+ +

+ + +

+

+ + + + + + +

+

+ + + + + + +

+

+ + +

+ -











-AsBuiltReport Logo -
-
Microsoft Active Directory As Built Report

Zen PR Solutions






















- - - -
Author:As Built Report
Date:Thursday, April 2, 2026
Version:1.0
-
-
-
Microsoft Active Directory As Built Report - v1.0

Table of Contents

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1PHARMAX.LOCAL Active Directory Forest
1.1   Forest Configuration
1.1.1      Forest Diagram
1.1.2      Certificate Authority
1.1.3      Certificate Authority Diagram
1.1.4      Optional Features
1.2   AD Sites & Replication
1.2.1      Replication
1.2.1.1         Replication Diagram
1.2.1.2         Sites
1.2.1.3         Site Subnets
1.2.1.4         Site Topology Diagram
1.2.1.5         Inter-Site Transports
1.2.1.5.1            IP
1.2.1.5.1.1               Site Links
1.2.1.5.1.2               Site Link Bridges
1.2.1.6         Sysvol Replication
1.3   Infrastructure Services
1.3.1      Exchange Infrastructure
1.3.2      SCCM Infrastructure
1.3.3      DHCP Infrastructure
2AD Domain Configuration
2.1   PHARMAX.LOCAL
2.1.1      FSMO Roles
2.1.2      Domain and Trusts
2.1.2.1         Domain and Trusts Diagram
2.1.3      Directory Objects
2.1.3.1         User Objects
2.1.3.2         Group Objects
2.1.3.2.1            Privileged Groups (Built-in)
2.1.3.2.2            Empty Groups (Non-Default)
2.1.3.2.3            Circular Group Membership
2.1.3.2.4            Pre-Windows 2000 Compatible Access Group Membership
2.1.3.3         Computer Objects
2.1.3.3.1            Status of Computer Accounts
2.1.3.3.2            Operating Systems Count
2.1.4      Account Policies
2.1.4.1         Default Domain Password Policy
2.1.4.2         Fined Grained Password Policies
2.1.4.3         Microsoft LAPS
2.1.4.4         gMSA Identities
2.1.4.5         Foreign Security Principals
2.1.5      Domain Controllers
2.1.5.1         Configuration
2.1.5.1.1            CAGUAS-DC-01V
2.1.5.1.2            CAROLINA-DC-01V
2.1.5.1.3            CAYEY-DC-01V
2.1.5.1.4            NAGUABO-DC-01V
2.1.5.1.5            PONCE-DC-01V
2.1.5.1.6            SERVER-DC-01V
2.1.5.2         DNS IP Configuration
2.1.5.3         NTDS Information
2.1.5.4         Time Source Information
2.1.5.5         SRV Records Status
2.1.5.6         File Shares
2.1.5.7         Installed Software
2.1.5.8         Missing Windows Updates
2.1.5.9         Roles
2.1.5.10         Infrastructure Services
2.1.6      Replication
2.1.6.1         Replication Connection
2.1.6.2         Replication Status
2.1.7      Group Policy
2.1.7.1         Group Policy Objects
2.1.7.1.1            GPO Inventory
2.1.7.1.2            GPO Settings
2.1.7.1.3            GPO Health
2.1.8      Organizational Units
2.1.9      Active Directory Hardening
2.1.10      Health Checks
2.2   ACAD.PHARMAX.LOCAL
2.2.1      FSMO Roles
2.2.2      Domain and Trusts
2.2.2.1         Domain and Trusts Diagram
2.2.3      Directory Objects
2.2.3.1         User Objects
2.2.3.2         Group Objects
2.2.3.2.1            Privileged Groups (Built-in)
2.2.3.2.2            Privileged Group (Non-Default)
2.2.3.2.3            Empty Groups (Non-Default)
2.2.3.2.4            Circular Group Membership
2.2.3.2.5            Pre-Windows 2000 Compatible Access Group Membership
2.2.3.3         Computer Objects
2.2.3.3.1            Status of Computer Accounts
2.2.3.3.2            Operating Systems Count
2.2.4      Account Policies
2.2.4.1         Default Domain Password Policy
2.2.4.2         Fined Grained Password Policies
2.2.4.3         gMSA Identities
2.2.4.4         Foreign Security Principals
2.2.5      Domain Controllers
2.2.5.1         Configuration
2.2.5.1.1            ACADE-DC-01V
2.2.5.2         DNS IP Configuration
2.2.5.3         NTDS Information
2.2.5.4         Time Source Information
2.2.5.5         SRV Records Status
2.2.5.6         File Shares
2.2.5.7         Installed Software
2.2.5.8         Missing Windows Updates
2.2.5.9         Roles
2.2.5.10         Infrastructure Services
2.2.6      Replication
2.2.6.1         Replication Connection
2.2.6.2         Replication Status
2.2.7      Group Policy
2.2.7.1         Group Policy Objects
2.2.7.1.1            GPO Inventory
2.2.7.1.2            GPO Settings
2.2.7.1.3            GPO Health
2.2.8      Organizational Units
2.2.9      Active Directory Hardening
2.2.10      Health Checks
3DNS Configuration
3.1   PHARMAX.LOCAL
3.1.1      Infrastructure Summary
3.1.1.1         Forwarder Options
3.1.2      CAGUAS-DC-01V DNS Zones
3.1.2.1         Reverse Lookup Zone
3.1.2.2         Conditional Forwarder
3.1.3      CAROLINA-DC-01V DNS Zones
3.1.3.1         Reverse Lookup Zone
3.1.3.2         Conditional Forwarder
3.1.4      CAYEY-DC-01V DNS Zones
3.1.4.1         Reverse Lookup Zone
3.1.4.2         Conditional Forwarder
3.1.5      NAGUABO-DC-01V DNS Zones
3.1.5.1         Reverse Lookup Zone
3.1.5.2         Conditional Forwarder
3.1.6      PONCE-DC-01V DNS Zones
3.1.6.1         Reverse Lookup Zone
3.1.6.2         Conditional Forwarder
3.1.7      SERVER-DC-01V DNS Zones
3.1.7.1         Reverse Lookup Zone
3.1.7.2         Conditional Forwarder
3.2   ACAD.PHARMAX.LOCAL
3.2.1      Infrastructure Summary
3.2.1.1         Forwarder Options
3.2.2      ACADE-DC-01V DNS Zones
3.2.2.1         Reverse Lookup Zone
3.2.2.2         Conditional Forwarder
-

-
Microsoft Active Directory As Built Report - v1.0

DISCLAIMER

This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages-including lost profits, business interruptions, or financial losses-arising from the use of this report or its recommendations.

-
Microsoft Active Directory As Built Report - v1.0

Report Brief

This report brief provides a high-level summary of the Active Directory environment, including infrastructure topology, domain configuration, and the scope of this document.

- - - - - - -
Company NameZen PR Solutions
ContactJonathan Colon
Email Addressjcolonf@zenprsolutions.com
Target ForestPHARMAX.LOCAL
Generated On2026-04-02 20:03:53
-
Table 1 - Report Overview - PHARMAX.LOCAL

-
- - - - - - - - -
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Root Domainpharmax.local
Total Domains2
Total Sites8
Global Catalog Servers8
UPN Suffixes2
-
Table 2 - Forest Summary - PHARMAX.LOCAL

-
- - - -
Domain NameDomain Functional LevelDomain ControllersPDC Emulator
pharmax.localWindows2016Domain7Server-DC-01V.pharmax.local
acad.pharmax.localWindows2016Domain1acade-dc-01v.acad.pharmax.local
-
Table 3 - Domain Summary - PHARMAX.LOCAL

-
- - - - -
SectionDetail Level
ForestEnabled (Advanced Summary)
DomainEnabled (Advanced Summary)
DNSEnabled (Summary)
-
Table 4 - Report Scope - PHARMAX.LOCAL

-

-
Microsoft Active Directory As Built Report - v1.0

1 PHARMAX.LOCAL Active Directory Forest

This section provides a detailed overview of the Active Directory infrastructure and configuration for the PHARMAX.LOCAL forest.

1.1 Forest Configuration

The following section provides a detailed overview of the Active Directory Forest infrastructure and configuration.

- - - - - - - - - - - - - - - -
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Schema VersionObjectVersion 91, Correspond to Windows Server 2025
Tombstone Lifetime (days)180
Domainsacad.pharmax.local; pharmax.local
Global CatalogsServer-DC-01V.pharmax.local; acade-dc-01v.acad.pharmax.local; Server-DC-02V.pharmax.local; Caguas-DC-01V.pharmax.local; Carolina-DC-01V.pharmax.local; Ponce-DC-01V.pharmax.local; Naguabo-DC-01V.pharmax.local; Cayey-Dc-01V.pharmax.local
Domains Count2
Global Catalogs Count8
Sites Count8
Application PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local DC=DomainDnsZones,DC=pharmax,DC=local
Partitions ContainerCN=Partitions,CN=Configuration,DC=pharmax,DC=local
SPN Suffixes--
UPN Suffixespharmax, acad
Anonymous Access (dsHeuristics)Disabled
-
Table 5 - Forest Summary - PHARMAX.LOCAL

-

-
Microsoft Active Directory As Built Report - v1.0

1.1.1 Forest Diagram

-Forest Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

1.1.2 Certificate Authority

The following section provides an overview of the Public Key Infrastructure (PKI) configuration deployed within the Active Directory environment.

Certificate Authority Root(s)

- - - -
NameDistinguished Name
pharmax-SERVER-DC-01V-CACN=pharmax-SERVER-DC-01V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
pharmax-SERVER-DC-02V-CACN=pharmax-SERVER-DC-02V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
-
Table 6 - Certificate Authority Root(s) - PHARMAX.LOCAL

-

Certificate Authority Issuer(s)

- - - - -
NameDNS Name
acad-ACADE-DC-01V-CAacade-dc-01v.acad.pharmax.local
pharmax-CAYEY-DC-01V-CAcayey-dc-01v.pharmax.local
pharmax-SERVER-DC-01V-CAServer-DC-01V.pharmax.local
-
Table 7 - Certificate Authority Issuer(s) - PHARMAX.LOCAL

-

-
Microsoft Active Directory As Built Report - v1.0

1.1.3 Certificate Authority Diagram

-Certificate Authority Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

1.1.4 Optional Features

- - - - -
NameRequired Forest ModeEnabled
Database 32k Pages FeatureWindows2025ForestNo
Privileged Access Management FeatureWindows2016ForestNo
Recycle Bin FeatureWindows2008R2ForestYes
-
Table 8 - Optional Features - PHARMAX.LOCAL

-

1.2 AD Sites & Replication

The following section provides an overview of the Active Directory site topology, site links, replication connections, and inter-site transport configuration.

1.2.1 Replication

Replication is the process by which Active Directory objects are transferred and synchronized between domain controllers within the domain and forest, ensuring consistency across the infrastructure.

The following section provides detailed information about Active Directory replication and its associated relationships.

-
Microsoft Active Directory As Built Report - v1.0

1.2.1.1 Replication Diagram

-Replication Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

1.2.1.2 Sites

- - - - - - - - - -
Site NameDescriptionSubnetsDomain Controllers
ACAD-- (1)172.23.4.0/24ACADE-DC-01V
Caguas-- (1)172.23.7.0/24CAGUAS-DC-01V
Carolina-- (1)172.23.9.0/24CAROLINA-DC-01V
CayeySite of Cayey, PR Branch10.10.30.0/24CAYEY-DC-01V
Dead-Site-- (1)No subnet assigned (2)No DC assigned (3)
Naguabo-- (1)10.10.31.0/24NAGUABO-DC-01V
Ponce-- (1)10.10.32.0/24PONCE-DC-01V
SanJuanSite of San Juan, PR HQ192.168.5.0/24
192.168.7.0/24
SERVER-DC-01V
SERVER-DC-02V
-
Table 9 - Sites - PHARMAX.LOCAL

-
Health Check:
    -
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. -
  3. Ensure Sites have an associated subnet. If subnets are not associated with AD Sites, users might choose a remote domain controller for authentication, which could result in excessive use of remote domain controllers.
  4. -
  5. It is important to ensure that each site has at least one assigned domain controller. Missing domain controllers can lead to authentication delays and potential service disruptions for users in the site.
  6. -
+> [!WARNING] +> This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages—including lost profits, business interruptions, or financial losses arising from the use of this report or its recommendations. -

Connection Objects

- - - - - - - - - - - - - - - - - - - - - -
NameFrom ServerTo ServerFrom Site
<automatically generated>ACADE-DC-01VSERVER-DC-01VACAD
<automatically generated>CAGUAS-DC-01VSERVER-DC-01VCaguas
<automatically generated>CAROLINA-DC-01VSERVER-DC-01VCarolina
<automatically generated>CAYEY-DC-01VSERVER-DC-01VCayey
<automatically generated>NAGUABO-DC-01VSERVER-DC-01VNaguabo
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-01VPonce
<automatically generated>SERVER-DC-01VNAGUABO-DC-01VSanJuan
<automatically generated>SERVER-DC-02VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAROLINA-DC-01VSanJuan
<automatically generated>SERVER-DC-01VPONCE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VACADE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAYEY-DC-01VSanJuan
<automatically generated>SERVER-DC-02VSERVER-DC-01VSanJuan
<automatically generated>SERVER-DC-01VSERVER-DC-02VSanJuan
<automatically generated>SERVER-DC-02VCAYEY-DC-01VSanJuan
-
Table 10 - Connection Objects - PHARMAX.LOCAL

-

1.2.1.3 Site Subnets

- - - - - - - - - -
SubnetDescriptionSites
10.10.30.0/24-- (1)Cayey
10.10.31.0/24-- (1)Naguabo
10.10.32.0/24-- (1)Ponce
172.23.4.0/24-- (1)ACAD
172.23.7.0/24-- (1)Caguas
172.23.9.0/24-- (1)Carolina
192.168.5.0/24-- (1)SanJuan
192.168.7.0/24-- (1)SanJuan
-
Table 11 - Site Subnets - PHARMAX.LOCAL

-
Health Check:
    -
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. -
+#### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates. -

-
Microsoft Active Directory As Built Report - v1.0

1.2.1.4 Site Topology Diagram

-Site Topology Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

1.2.1.5 Inter-Site Transports

Site links in Active Directory represent the inter-site connectivity and method used to transfer replication traffic. There are two transport protocols that can be used for replication via site links. The default protocol used in site link is IP, and it performs synchronous replication between available domain controllers. The SMTP method can be used when the link between sites is not reliable.

- - - -
NameBridge All Site LinksIgnore Schedules
IPYesNo
SMTPYesYes
-
Table 12 - Inter-Site Transports - PHARMAX.LOCAL

-
1.2.1.5.1 IP
1.2.1.5.1.1 Site Links
- - - - - - - - - -
Site Link NamePharmax-to-Naguabo
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesNaguabo; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 13 - Site Links - Pharmax-to-Naguabo

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- - - - - - - - - -
Site Link NamePharmax-to-Cayey
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCayey; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 14 - Site Links - Pharmax-to-Cayey

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- - - - - - - - - -
Site Link NamePharmax-to-Carolina
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCarolina; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 15 - Site Links - Pharmax-to-Carolina

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- - - - - - - - - -
Site Link NamePharmax-to-Caguas
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesCaguas; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 16 - Site Links - Pharmax-to-Caguas

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- - - - - - - - - -
Site Link NamePharmax-to-Ponce
Cost100
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesPonce; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 17 - Site Links - Pharmax-to-Ponce

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- - - - - - - - - -
Site Link NamePHARMAX-to-ACAD
Cost100
Replication Frequency90 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesACAD; SanJuan
Protected From Accidental DeletionYes
Description--
-
Table 18 - Site Links - PHARMAX-to-ACAD

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

1.2.1.5.1.2 Site Link Bridges
- - - - - - -
Site Link Bridges NameSite-Bridge
Transport ProtocolIP
Site LinksPHARMAX-to-ACAD
Protected From Accidental DeletionNo
Description--
-
Table 19 - Site Link Bridges - Site-Bridge

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Link Bridges in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

1.2.1.6 Sysvol Replication

- - - - - - - - - -
DC NameReplication StatusDomain
acade-dc-01vNormalacad.pharmax.local
Server-DC-01VNormalpharmax.local
Server-DC-02VUnknownpharmax.local
Caguas-DC-01VNormalpharmax.local
Carolina-DC-01VNormalpharmax.local
Ponce-DC-01VNormalpharmax.local
Naguabo-DC-01VNormalpharmax.local
Cayey-Dc-01VNormalpharmax.local
-
Table 20 - Sysvol Replication - PHARMAX.LOCAL

-
Health Check:

Best Practice: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

1.3 Infrastructure Services

The following section provides an overview of infrastructure services registered in Active Directory, including Exchange, MECM/SCCM, and DHCP server information.

1.3.1 Exchange Infrastructure

The following section provides an overview of the Microsoft Exchange Server infrastructure registered in Active Directory, including server names, roles, and version information.

EX16-SERVER-01V

- - - - - -
NameEX16-SERVER-01V
DNS Nameex16-server-01v.pharmax.local
Server RolesUM, CAS, MBX, HUB
VersionVersion 15.1 (Build 32507.6)
-
Table 21 - Exchange Infrastructure - EX16-SERVER-01V

-

1.3.2 SCCM Infrastructure

The following section provides a summary of the Microsoft Endpoint Configuration Manager (MECM/SCCM) infrastructure registered in Active Directory, including site codes, management points, and version details.

SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

- - - - - -
NameSMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL
Management PointSCCM-PRI-01V.PHARMAX.LOCAL
Site CodePMX
Version9012
-
Table 22 - SCCM Infrastructure - SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

-

1.3.3 DHCP Infrastructure

The following section provides an overview of the DHCP servers registered in Active Directory.

- - - - - - - -
Server NameIs Domain Controller?
acad-dhcp-01v.acad.pharmax.localNo
acade-dc-01v.acad.pharmax.localYes
cayey-dc-01v.pharmax.localYes
cayey-dc-01v.pharmax.local -CNF:aa5dd995-2945-449c-8538-37ee3aa289eaNo
dc-uia-01v.uia.localNo
server-dc-01v.pharmax.localYes
-
Table 23 - DHCP Infrastructure - PHARMAX.LOCAL

-

2 AD Domain Configuration

The following table provides a detailed breakdown of the Active Directory domain configuration attributes.

2.1 PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

- - - - - - - - - - - - - - - - - - - - - - -
Domain Namepharmax
NetBIOS NamePHARMAX
Domain SIDS-1-5-21-2867495315-1194516362-180967319
Domain Functional LevelWindows2016Domain
Domains--
Forestpharmax.local
Parent Domain--
Replica Directory ServersServer-DC-01V.pharmax.local Server-DC-02V.pharmax.local Caguas-DC-01V.pharmax.local Carolina-DC-01V.pharmax.local Ponce-DC-01V.pharmax.local Naguabo-DC-01V.pharmax.local Cayey-Dc-01V.pharmax.local
Child Domainsacad.pharmax.local
Domain Pathpharmax.local/
Computers ContainerCN=Computers,DC=pharmax,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=pharmax,DC=local
Systems ContainerCN=System,DC=pharmax,DC=local
Users ContainerCN=Users,DC=pharmax,DC=local
Deleted Objects ContainerCN=Deleted Objects,DC=pharmax,DC=local
Foreign Security Principals ContainerCN=ForeignSecurityPrincipals,DC=pharmax,DC=local
Lost And Found ContainerCN=LostAndFound,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available360600 / 1073381223 (1% Issued)
-
Table 24 - Domain Summary - PHARMAX.LOCAL

-

2.1.1 FSMO Roles

- - - - - - -
Infrastructure MasterServer-DC-01V.pharmax.local
PDC Emulator NameServer-DC-01V.pharmax.local
RID MasterServer-DC-01V.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
-
Table 25 - FSMO Roles - pharmax.local

-
Health Check:

Best Practice: The infrastructure master role in the domain PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.1.2 Domain and Trusts

acad.pharmax.local Trust Details

- - - - - - - - - - - - - - - - -
Nameacad.pharmax.local
Pathpharmax.local/System/acad.pharmax.local
Sourcepharmax
Targetacad.pharmax.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 26 - Trust - acad.pharmax.local

-

lab.local Trust Details

- - - - - - - - - - - - - - - - -
Namelab.local
Pathpharmax.local/System/lab.local
Sourcepharmax
Targetlab.local
Trust TypeUplevel
Trust AttributesForest Trust
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 27 - Trust - lab.local

-

uia.local Trust Details

- - - - - - - - - - - - - - - - -
Nameuia.local
Pathpharmax.local/System/uia.local
Sourcepharmax
Targetuia.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 28 - Trust - uia.local

-

b12.local Trust Details

- - - - - - - - - - - - - - - - -
Nameb12.local
Pathpharmax.local/System/b12.local
Sourcepharmax
Targetb12.local
Trust TypeUplevel
Trust AttributesForest Trust
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 29 - Trust - b12.local

-
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

-
Microsoft Active Directory As Built Report - v1.0

2.1.2.1 Domain and Trusts Diagram

-Domain and Trusts Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

2.1.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.1.3.1 User Objects

Users

-User Objects - Diagram -
-
- - - - -
Users8559
Privileged Users8
Foreign Security Principals7
-
Table 30 - User - PHARMAX.LOCAL

-

Status of Users Accounts

-Status of Users Accounts - Diagram -
-
- - - - - - - - - - - - - -
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users8559100130.158559100
Cannot Change Password130.1500130.15
Password Never Expires330.3920.02330.39
Must Change Password at Logon120.14120.14120.14
Password Age (> 180 days)852199.56100.12852199.56
SmartcardLogonRequired000000
SidHistory000000
Never Logged in853799.74130.15853799.74
Dormant (> 90 days)855599.95130.15855599.95
Password Not Required70.0830.0470.08
Account Expired10.010010.01
Account Lockout000000
-
Table 31 - Status of Users Accounts - PHARMAX.LOCAL

-

2.1.3.2 Group Objects

Groups Categories

-Groups Categories - Diagram -
-
- - - -
Security Groups94
Distribution Groups3
-
Table 32 - Groups Categories - PHARMAX.LOCAL

-

Groups Scopes

-Groups Scopes - Diagram -
-
- - - - -
Domain Locals46
Globals26
Universal25
-
Table 33 - Groups Scopes - PHARMAX.LOCAL

-
2.1.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (4 Members)

- - - - - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
jocolon (USER)12/22/2043**YesYes
scvmm-admin (USER)*9/4/2025**YesYes
veeam_admin (USER)*11/22/2025**YesYes
-
Table 34 - Domain Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Enterprise Admins (1 Members)

- - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
-
Table 35 - Enterprise Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

Unless an account is performing specific tasks that require those highly elevated permissions, every account should be removed from the Enterprise Admins (EA) group. A side benefit of having an empty Enterprise Admins group is that it adds just enough friction to ensure that enterprise-wide changes requiring Enterprise Admin rights are done purposefully and methodically.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

Administrators (3 Members)

- - - - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
Domain Admins (GROUP)------
svc_SCCM_ClientPush (USER)*9/14/2020**YesYes
-
Table 36 - Administrators - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Schema Admins (2 Members)

- - - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
1227935471SA (USER)--NoYes
Administrator (USER)12/10/2053**YesYes
-
Table 37 - Schema Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

The Schema Admins group is a privileged group in a forest root domain. Members of the Schema Admins group can make changes to the schema, which is the framework for the Active Directory forest. Changes to the schema are not frequently required. This group only contains the Built-in Administrator account by default. Additional accounts must only be added when changes to the schema are necessary and then must be removed.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.
2.1.3.2.2 Empty Groups (Non-Default)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Group NameGroup SID
ADSyncBrowseS-1-5-21-2867495315-1194516362-180967319-351274
ADSyncOperatorsS-1-5-21-2867495315-1194516362-180967319-351273
ADSyncPasswordSetS-1-5-21-2867495315-1194516362-180967319-351275
BitLocker Admin UsersS-1-5-21-2867495315-1194516362-180967319-2627
BitLocker Reporting UsersS-1-5-21-2867495315-1194516362-180967319-2626
Compliance ManagementS-1-5-21-2867495315-1194516362-180967319-351235
Delegated SetupS-1-5-21-2867495315-1194516362-180967319-351233
Discovery ManagementS-1-5-21-2867495315-1194516362-180967319-351231
Exchange Trusted SubsystemS-1-5-21-2867495315-1194516362-180967319-351239
ExchangeLegacyInteropS-1-5-21-2867495315-1194516362-180967319-351242
External Trust AccountsS-1-5-21-2867495315-1194516362-180967319-529
FIN-SEC-DATAS-1-5-21-2867495315-1194516362-180967319-351248
Forest Trust AccountsS-1-5-21-2867495315-1194516362-180967319-528
Help DeskS-1-5-21-2867495315-1194516362-180967319-351229
HR-IT-DATAS-1-5-21-2867495315-1194516362-180967319-351247
Hygiene ManagementS-1-5-21-2867495315-1194516362-180967319-351234
Public Folder ManagementS-1-5-21-2867495315-1194516362-180967319-351227
Recipient ManagementS-1-5-21-2867495315-1194516362-180967319-351225
Records ManagementS-1-5-21-2867495315-1194516362-180967319-351230
Sec-IT-DATAS-1-5-21-2867495315-1194516362-180967319-351246
Security AdministratorS-1-5-21-2867495315-1194516362-180967319-351237
Security ReaderS-1-5-21-2867495315-1194516362-180967319-351236
Server ManagementS-1-5-21-2867495315-1194516362-180967319-351232
UM ManagementS-1-5-21-2867495315-1194516362-180967319-351228
UN-GroupS-1-5-21-2867495315-1194516362-180967319-351221
View-Only Organization ManagementS-1-5-21-2867495315-1194516362-180967319-351226
Windows Admin Center CredSSPS-1-5-21-2867495315-1194516362-180967319-351298
WSUS AdministratorsS-1-5-21-2867495315-1194516362-180967319-1200
WSUS ReportersS-1-5-21-2867495315-1194516362-180967319-1201
-
Table 38 - Empty Groups - PHARMAX.LOCAL

-
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.1.3.2.3 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

- - - -
Parent Group NameChild Group Name
AD - SRM Admin GroupESX Admins
ESX AdminsAD - SRM Admin Group
-
Table 39 - Circular Group Membership - PHARMAX.LOCAL

-
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.1.3.2.4 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

- - - - -
NameDistinguished Name
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=pharmax,DC=local
SERVER-DC-01V (COMPUTER)CN=SERVER-DC-01V,OU=Domain Controllers,DC=pharmax,DC=local
SERVER-DC-02V (COMPUTER)CN=SERVER-DC-02V,OU=Domain Controllers,DC=pharmax,DC=local
-
Table 40 - Pre-Windows 2000 Compatible Access - PHARMAX.LOCAL

-
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.1.3.3 Computer Objects

Computers

-Computer Objects - Diagram -
-
- - - -
Computers3102
Servers96
-
Table 41 - Computers - PHARMAX.LOCAL

-
2.1.3.3.1 Status of Computer Accounts
-Status of Computer Accounts - Diagram -
-
- - - - - -
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers308199.32210.683102100
Dormant (> 90 days)305898.58210.68307999.26
Password Age (> 30 days)307098.97210.68309199.65
SidHistory000000
-
Table 42 - Status of Computer Accounts - PHARMAX.LOCAL

-
2.1.3.3.2 Operating Systems Count
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operating SystemCount
CentOS1
Data Domain OS1
EMC File Server1
NetApp Release 9.15.11
NetApp Release 9.17.12
NetApp Release 9.18.11
NetApp Release 9.18.1RC11
NetApp Release 9.5P61
NetApp Release 9.81
NetApp Release 9.9.1P12
No OS Specified2963
OneFS1
pc-linux-gnu2
redhat-linux-gnu2
unknown2
Windows 10 Enterprise2
Windows 10 Enterprise Evaluation18
Windows 11 Enterprise LTSC3
Windows Server 20031
Windows Server 2012 R2 Standard Evaluation1
Windows Server 2016 Standard Evaluation11
Windows Server 2019 Standard1
Windows Server 2019 Standard Evaluation40
Windows Server 2022 Datacenter13
Windows Server 2022 Datacenter Evaluation15
Windows Server 2025 Datacenter12
Windows Server 2025 Standard1
Windows Vista1
Windows XP1
-
Table 43 - - PHARMAX.LOCAL

-
Health Check:

Security Best Practice: Operating systems that are no longer supported for security updates are not maintained or updated to address vulnerabilities, leaving them open to potential attack. Organizations must transition to a supported operating system to ensure continued support and to improve the organization's security posture.

2.1.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.1.4.1 Default Domain Password Policy

- - - - - - - - - - - -
Password Must Meet Complexity RequirementsYes
Pathpharmax.local/
Lockout Duration30 minutes
Lockout Threshold5
Lockout Observation Window30 minutes
Maximum Password Age42 days
Minimum Password Age01 days
Minimum Password Length7
Enforce Password History24
Store Password using Reversible EncryptionNo
-
Table 44 - Default Domain Password Policy - PHARMAX.LOCAL

-

2.1.4.2 Fined Grained Password Policies

Administrators

- - - - - - - - - - - - - - - -
NameAdministrators
Domain NameDC=pharmax,DC=local
Complexity EnabledYes
Pathpharmax.local/System/Password Settings Container/Administrators
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age05 days
Min Password Length12
Password History Count90
Reversible Encryption EnabledNo
Precedence1
Applies Tohorizon-ic, dbuser, jocolon
-
Table 45 - Name - Administrators

-

Test

- - - - - - - - - - - - - - - -
NameTest
Domain NameDC=pharmax,DC=local
Complexity EnabledYes
Pathpharmax.local/System/Password Settings Container/Test
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age01 days
Min Password Length7
Password History Count23
Reversible Encryption EnabledNo
Precedence1
Applies Tovmuserro
-
Table 46 - Name - Test

-

2.1.4.3 Microsoft LAPS

- - - - - -
NameLocal Administrator Password Solution
Domain NameDC=pharmax,DC=local
EnabledYes
Distinguished NameCN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=pharmax,DC=local
-
Table 47 - Microsoft LAPS - PHARMAX.LOCAL

-

2.1.4.4 gMSA Identities

SQLServer

- - - - - - - - - - - - - - -
NameSQLServer
SamAccountNameSQLServer$
Created9/27/2020
EnabledYes
DNS Host NameSQL-Cluster
Host ComputersSQL-CLUSTER-02V, SQL-CLUSTER-01V
Retrieve Managed PasswordSQL-CLUSTER-01V, SQL-CLUSTER-02V
Primary GroupDomain Computers
Last Logon Date*9/27/2020
Locked OutNo
Logon Count3
Password ExpiredNo
Password Last Set9/27/2020
-
Table 48 - gMSA - SQLServer

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

adfsgmsa

- - - - - - - - - - - - - - -
Nameadfsgmsa
SamAccountNameadfsgmsa$
Created10/7/2020
EnabledYes
DNS Host NameADFS.pharmax.local
Host Computers**--
Retrieve Managed PasswordSERVER-ADFS-01V, SERVER-ADFS-02V
Primary GroupDomain Computers
Last Logon Date*10/7/2020
Locked OutNo
Logon Count40
Password ExpiredNo
Password Last Set10/7/2020
-
Table 49 - gMSA - adfsgmsa

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ITFarm1

- - - - - - - - - - - - - - -
NameITFarm1
SamAccountNameITFarm1$
Created7/13/2023
EnabledYes
DNS Host NameITFarm1.pharmax.local
Host Computers**--
Retrieve Managed Password***--
Primary GroupDomain Computers
Last Logon Date*--
Locked OutNo
Logon Count0
Password ExpiredNo
Password Last Set7/13/2023
-
Table 50 - gMSA - ITFarm1

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ADSyncMSAda440

- - - - - - - - - - - - - - -
NameADSyncMSAda440
SamAccountNameADSyncMSAda440$
Created4/21/2025
EnabledYes
DNS Host Name--
Host ComputersSERVER-DC-01V
Retrieve Managed Password***--
Primary GroupDomain Computers
Last Logon Date4/2/2026
Locked OutNo
Logon Count381
Password ExpiredNo
Password Last Set3/28/2026
-
Table 51 - gMSA - ADSyncMSAda440

-
Health Check:

Security Best Practice:

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.1.4.5 Foreign Security Principals

- - - - - - - - -
NamePrincipal Name
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
NT AUTHORITY\Authenticated UsersCertificate Service DCOM Access
Users
Pre-Windows 2000 Compatible Access
NT AUTHORITY\INTERACTIVEUsers
NT AUTHORITY\IUSR--
----
--Backup Operators
--Backup Operators
-
Table 52 - Foreign Security Principals - PHARMAX.LOCAL

-

2.1.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

- - - - - - - - -
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
CAGUAS-DC-01VOnlineCaguasYesNo172.23.7.1
CAROLINA-DC-01VOnlineCarolinaYesNo172.23.9.1
CAYEY-DC-01VOnlineCayeyYesNo10.10.30.1
NAGUABO-DC-01VOnlineNaguaboYesNo10.10.31.1
PONCE-DC-01VOnlinePonceYesNo10.10.32.1
SERVER-DC-01VOnlineSanJuanYesNo192.168.5.1
SERVER-DC-02VOffline--------
-
Table 53 - Domain Controller in Domain - PHARMAX.LOCAL

-
-Domain Controller Object - Chart -
-
- - - -
Domain Controller7
Global Catalog7
-
Table 54 - Domain Controller Counts - PHARMAX.LOCAL

-

2.1.5.1 Configuration

2.1.5.1.1 CAGUAS-DC-01V

General Information

- - - - - - - - - - - - -
DC NameCaguas-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCaguas
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351303
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 55 - General Information - CAGUAS-DC-01V

-

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 56 - Partitions - CAGUAS-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses172.23.7.1
IPv6 Addressesfe80::75c9:eaa3:559a:23de%12
LDAP Port389
LDAPS Port636
-
Table 57 - Networking Settings - CAGUAS-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameCAGUAS-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:10
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 58 - Hardware Inventory - CAGUAS-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.2 CAROLINA-DC-01V

General Information

- - - - - - - - - - - - -
DC NameCarolina-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCarolina
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351304
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 59 - General Information - CAROLINA-DC-01V

-

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 60 - Partitions - CAROLINA-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses172.23.9.1
IPv6 Addressesfe80::586:15a2:ab35:2609%12
LDAP Port389
LDAPS Port636
-
Table 61 - Networking Settings - CAROLINA-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameCAROLINA-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 62 - Hardware Inventory - CAROLINA-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.3 CAYEY-DC-01V

General Information

- - - - - - - - - - - - -
DC NameCayey-Dc-01V.pharmax.local
Domain Namepharmax.local
SiteCayey
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351300
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 63 - General Information - CAYEY-DC-01V

-

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 64 - Partitions - CAYEY-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses10.10.30.1
IPv6 Addressesfe80::74a3:277d:e262:218b%11
LDAP Port389
LDAPS Port636
-
Table 65 - Networking Settings - CAYEY-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameCAYEY-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 12:51:56
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 66 - Hardware Inventory - CAYEY-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.4 NAGUABO-DC-01V

General Information

- - - - - - - - - - - - -
DC NameNaguabo-DC-01V.pharmax.local
Domain Namepharmax.local
SiteNaguabo
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351301
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 67 - General Information - NAGUABO-DC-01V

-

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 68 - Partitions - NAGUABO-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses10.10.31.1
IPv6 Addressesfe80::efb6:c739:603c:1121%12
LDAP Port389
LDAPS Port636
-
Table 69 - Networking Settings - NAGUABO-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameNAGUABO-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 13:50:08
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 70 - Hardware Inventory - NAGUABO-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.5 PONCE-DC-01V

General Information

- - - - - - - - - - - - -
DC NamePonce-DC-01V.pharmax.local
Domain Namepharmax.local
SitePonce
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351302
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 71 - General Information - PONCE-DC-01V

-

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 72 - Partitions - PONCE-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses10.10.32.1
IPv6 Addressesfe80::de92:566e:cf5c:a051%11
LDAP Port389
LDAPS Port636
-
Table 73 - Networking Settings - PONCE-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NamePONCE-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 14:26:27
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 74 - Hardware Inventory - PONCE-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.6 SERVER-DC-01V

General Information

- - - - - - - - - - - - -
DC NameServer-DC-01V.pharmax.local
Domain Namepharmax.local
SiteSanJuan
Global CatalogYes
Read OnlyNo
Operation Master RolesSchemaMaster, DomainNamingMaster, PDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-1602
Operating SystemWindows Server 2025 Standard
SMB1 StatusEnabled
DescriptionPrueba
-
Table 75 - General Information - SERVER-DC-01V

-
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

- - - -
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 76 - Partitions - SERVER-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses192.168.7.1, 192.168.5.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
-
Table 77 - Networking Settings - SERVER-DC-01V

-
Health Check:

Best Practice: On Domain Controllers with more than one NIC where each NIC is connected to a separate network, there is a possibility that the Host A DNS registration can occur for unwanted NICs. Avoid registering unwanted NICs in DNS on a multihomed domain controller.

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameSERVER-DC-01V
Windows Product NameWindows Server 2025 Standard
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date11/17/2025 14:04:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyMY832
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors2
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 78 - Hardware Inventory - SERVER-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.1.5.2 DNS IP Configuration

- - - - - - - - - -
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
CAGUAS-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
CAROLINA-DC-01VEthernet0192.168.5.1127.0.0.1----
CAYEY-DC-01VEthernet0192.168.5.1127.0.0.1----
NAGUABO-DC-01VEthernet0192.168.5.1127.0.0.1----
PONCE-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
SERVER-DC-01VEthernet3192.168.5.1127.0.0.1----
SERVER-DC-01VEthernet0192.168.5.1127.0.0.1----
SERVER-DC-02V----------
-
Table 79 - DNS IP Configuration - PHARMAX.LOCAL

-
Health Check:


Best Practices: DNS configuration on the network adapter should not include the Domain Controller's own IP address as the first entry.

Corrective Actions: Network interfaces must be configured with DNS servers that can resolve names in the forest root domain. The following DNS server did not respond to the query for the forest root domain PHARMAX.LOCAL: 192.168.5.5, 192.168.5.5

2.1.5.3 NTDS Information

- - - - - - - - -
DC NameDatabase FileDatabase SizeLog PathSysVol Path
CAGUAS-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAROLINA-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAYEY-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
NAGUABO-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
PONCE-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
SERVER-DC-01VC:\Windows\NTDS\ntds.dit290 MBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
SERVER-DC-02V--------
-
Table 80 - NTDS Database File Usage - PHARMAX.LOCAL

-

2.1.5.4 Time Source Information

- - - - - - - - -
NameTime ServerType
CAGUAS-DC-01VDomain HierarchyDOMHIER
CAROLINA-DC-01VDomain HierarchyDOMHIER
CAYEY-DC-01VDomain HierarchyDOMHIER
NAGUABO-DC-01VDomain HierarchyDOMHIER
PONCE-DC-01VDomain HierarchyDOMHIER
SERVER-DC-01V192.168.5.254 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
SERVER-DC-02V----
-
Table 81 - Time Source Configuration - PHARMAX.LOCAL

-

2.1.5.5 SRV Records Status

- - - - - - - - -
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
CAGUAS-DC-01VOKOKNon PDCOKOK
CAROLINA-DC-01VOKOKNon PDCOKOK
CAYEY-DC-01VOKOKNon PDCOKOK
NAGUABO-DC-01VOKOKNon PDCOKOK
PONCE-DC-01VOKOKNon PDCFailOK
SERVER-DC-01VOKOKOKOKOK
SERVER-DC-02V----------
-
Table 82 - SRV Records Status - PHARMAX.LOCAL

-
Health Check:

Best Practice: The SRV record is a Domain Name System (DNS) resource record. It is used to identify computers hosting specific services. SRV resource records are used to locate domain controllers for Active Directory. These records are essential for the proper functioning of Active Directory as they allow clients to locate domain controllers and other critical services within the network. Ensuring that these records are correctly configured and available is crucial for maintaining the health and accessibility of the Active Directory environment.

2.1.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

SERVER-DC-01V

- - - - - -
NamePathDescription
UpdateServicesPackagesE:\wsus\UpdateServicesPackagesA network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
VcenterBackupF:\VcenterBackup--
VeeamConfBackupF:\VeeamConfBackup--
WsusContentE:\wsus\WsusContentA network share to be used by Local Publishing to place published content on this WSUS system.
-
Table 83 - File Shares - SERVER-DC-01V

-
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.1.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the PHARMAX.LOCAL domain.

SERVER-DC-01V

- - - - - - - - - -
NamePublisherInstall Date
Dell Data Domain DDBoost SDKVeeam Software Group GmbH20260317
HPE StoreOnce Catalyst SDKVeeam Software Group GmbH20260317
OpenSSL v3.0.0 FIPSVeeam Software Group GmbH20251119
Veeam Agent for Microsoft WindowsVeeam Software Group GmbH20260317
Veeam Backup TransportVeeam Software Group GmbH20260326
Veeam Backup VSS IntegrationVeeam Software Group GmbH20260317
Veeam Guest Interaction Proxy ServiceVeeam Software Group GmbH20260317
Veeam Installer ServiceVeeam Software Group GmbH--
-
Table 84 - Installed Software - SERVER-DC-01V

-
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.1.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the PHARMAX.LOCAL domain.

CAROLINA-DC-01V

- - -
KB ArticleName
KB50787402026-03 Cumulative Update for Microsoft server operating system version 24H2 for x64-based Systems (KB5078740) (26100.32522)
-
Table 85 - Missing Windows Updates - CAROLINA-DC-01V

-
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

PONCE-DC-01V

- - -
KB ArticleName
KB50661312025-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Microsoft server operating system version 24H2 for x64 (KB5066131)
-
Table 86 - Missing Windows Updates - PONCE-DC-01V

-
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

SERVER-DC-01V

- - -
KB ArticleName
KBSystem.__ComObjectMicrosoft Edge-WebView2 Runtime Version 146 Update for x64 based Editions (Build 146.0.3856.97)
-
Table 87 - Missing Windows Updates - SERVER-DC-01V

-
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.1.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in pharmax.local.

CAGUAS-DC-01V

- - - - -
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
-
Table 88 - Roles - CAGUAS-DC-01V

-

CAROLINA-DC-01V

- - - - -
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
-
Table 89 - Roles - CAROLINA-DC-01V

-

CAYEY-DC-01V

- - - - -
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
-
Table 90 - Roles - CAYEY-DC-01V

-

NAGUABO-DC-01V

- - - - -
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
-
Table 91 - Roles - NAGUABO-DC-01V

-

PONCE-DC-01V

- - - - -
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
-
Table 92 - Roles - PONCE-DC-01V

-

SERVER-DC-01V

- - - - - - - - -
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
Windows Server Update Services (1)RoleWindows Server Update Services allows network administrators to specify the Microsoft updates that should be installed, create separate groups of computers for different sets of updates, and get reports on the compliance levels of the computers and the updates that must be installed.
-
Table 93 - Roles - SERVER-DC-01V

-
Health Check:

Best Practices:
    -
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
  2. -
+# Microsoft AD As Built Report -

2.1.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

CAGUAS-DC-01V

- - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 94 - Infrastructure Services Status - CAGUAS-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAROLINA-DC-01V

- - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 95 - Infrastructure Services Status - CAROLINA-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAYEY-DC-01V

- - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 96 - Infrastructure Services Status - CAYEY-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

NAGUABO-DC-01V

- - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 97 - Infrastructure Services Status - NAGUABO-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

PONCE-DC-01V

- - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 98 - Infrastructure Services Status - PONCE-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

SERVER-DC-01V

- - - - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 99 - Infrastructure Services Status - SERVER-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.1.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.1.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: CAGUAS-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUID0fc69a2f-27db-46d0-9d77-fe1e6aa11bbb
Description--
From ServerSERVER-DC-01V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
-
Table 100 - Replication Connection - CAGUAS-DC-01V

-

Site: SanJuan: From: SERVER-DC-02V To: CAGUAS-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUID3e145ba6-3e78-4f99-994b-8eff197b1b4e
Description--
From ServerSERVER-DC-02V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:31:02 GMT
-
Table 101 - Replication Connection - CAGUAS-DC-01V

-

Site: SanJuan: From: SERVER-DC-01V To: CAROLINA-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUID6c379734-f95a-4498-ad32-d001c4c29a89
Description--
From ServerSERVER-DC-01V
To ServerCAROLINA-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:13 GMT
-
Table 102 - Replication Connection - CAROLINA-DC-01V

-

Site: SanJuan: From: SERVER-DC-02V To: CAYEY-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUIDbd8d4d25-a9f8-480d-a56a-49c9c5ac62f3
Description--
From ServerSERVER-DC-02V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
-
Table 103 - Replication Connection - CAYEY-DC-01V

-

Site: SanJuan: From: SERVER-DC-01V To: CAYEY-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUIDec5a6456-5ced-473f-a313-8af9daefdbfb
Description--
From ServerSERVER-DC-01V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
-
Table 104 - Replication Connection - CAYEY-DC-01V

-

Site: SanJuan: From: SERVER-DC-01V To: NAGUABO-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUIDbc36599a-0876-4b1b-9ca7-4e7a5df10cc7
Description--
From ServerSERVER-DC-01V
To ServerNAGUABO-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:33 GMT
-
Table 105 - Replication Connection - NAGUABO-DC-01V

-

Site: SanJuan: From: SERVER-DC-01V To: PONCE-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUID79c509ba-15f9-4204-82d1-856a4cbf222f
Description--
From ServerSERVER-DC-01V
To ServerPONCE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
-
Table 106 - Replication Connection - PONCE-DC-01V

-

Site: ACAD: From: ACADE-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteACAD
GUID6488a593-7cd5-4823-ad44-4d1439b0ac92
Description--
From ServerACADE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 03:22:52 GMT
-
Table 107 - Replication Connection - SERVER-DC-01V

-

Site: SanJuan: From: SERVER-DC-02V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUID8a3b236b-e90b-49ff-9a47-b032b6003318
Description--
From ServerSERVER-DC-02V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport Protocol--
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:21:56 GMT
-
Table 108 - Replication Connection - SERVER-DC-01V

-

Site: Naguabo: From: NAGUABO-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteNaguabo
GUID30240e89-7df7-4985-ad8f-ec5aac00c0a6
Description--
From ServerNAGUABO-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
-
Table 109 - Replication Connection - SERVER-DC-01V

-

Site: Carolina: From: CAROLINA-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteCarolina
GUID021a795d-328f-41aa-a82e-96d947a05b01
Description--
From ServerCAROLINA-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
-
Table 110 - Replication Connection - SERVER-DC-01V

-

Site: Cayey: From: CAYEY-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteCayey
GUIDaaf66f39-f9a6-45bc-bc7b-7c3d0ff77976
Description--
From ServerCAYEY-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
-
Table 111 - Replication Connection - SERVER-DC-01V

-

Site: Caguas: From: CAGUAS-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteCaguas
GUIDf7d2a8e7-04bf-418e-8710-afa13de520f8
Description--
From ServerCAGUAS-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
-
Table 112 - Replication Connection - SERVER-DC-01V

-

Site: Ponce: From: PONCE-DC-01V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SitePonce
GUIDf311cacf-16b7-4c8f-a9f6-a93ba30f7fed
Description--
From ServerPONCE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
-
Table 113 - Replication Connection - SERVER-DC-01V

-

2.1.6.2 Replication Status

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:37:54000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 20:11:56000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:51:57000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:44:26000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:45:1812562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:4312562026-04-02 19:53:3791
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-14 13:59:2217222026-04-02 19:55:01150
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:1712562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:42:0217222026-04-02 19:54:1991
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:46:1517222026-04-02 19:53:3791
-
Table 114 - Replication Status - PHARMAX

-
Health Check:

Best Practices: Replication failures can lead to object inconsistencies, stale credentials, Group Policy application failures, and authentication issues across the environment. Investigate and resolve any replication errors promptly using tools such as repadmin /showrepl or the Active Directory Replication Status Tool to prevent further divergence between domain controllers.

2.1.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.1.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the PHARMAX.LOCAL domain.

2.1.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Security Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID04e1aad5-f19b-4d0b-af25-b4ed4f52048f
Created04/26/2024
Modified11/21/2025
OwnerPHARMAX\Domain Admins
Computer Version18 (AD), 18 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 115 - GPO - Security Policy

-

Deleted GPO in Sysvol

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID09e68095-8cfc-4174-81ed-afb52597dd7f
Created06/20/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 116 - GPO - Deleted GPO in Sysvol

-
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Assign-Applications

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID2168b63b-4bd0-4627-99a8-835aea402534
Created03/10/2021
Modified04/13/2025
OwnerPHARMAX\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security Filteringjocolon
Authenticated Users
Linked Targetpharmax.local/LinuxMachines
DescriptionThis is a bad description example
-
Table 117 - GPO - Assign-Applications

-

Certificate AutoEnrollment

- - - - - - - - - - - - -
GPO StatusUser Settings Disabled
GUID27fa05c8-7c50-4994-9f95-29c4aa3971ed
Created01/25/2020
Modified06/30/2021
OwnerPHARMAX\Domain Admins
Computer Version28 (AD), 28 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 118 - GPO - Certificate AutoEnrollment

-

Default Domain Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created06/10/2018
Modified03/07/2025
OwnerPHARMAX\Domain Admins
Computer Version114 (AD), 114 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 119 - GPO - Default Domain Policy

-

Restricted-Group

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID45497a0f-b3e2-42c0-8a43-992086110bb8
Created02/12/2025
Modified02/13/2025
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Admins PC
Description--
-
Table 120 - GPO - Restricted-Group

-

VEEAM_Disable_Firewall

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID4b2e42eb-2100-4a94-b4b0-7822e30634f6
Created12/13/2019
Modified09/08/2020
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
-
Table 121 - GPO - VEEAM_Disable_Firewall

-

SET - KMS Server

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID502c4398-dc59-49ee-b567-47656f08e09e
Created08/31/2022
Modified08/25/2024
OwnerPHARMAX\Domain Admins
Computer Version10 (AD), 10 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 122 - GPO - SET - KMS Server

-

Default Domain Controllers Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created06/10/2018
Modified11/17/2025
OwnerPHARMAX\Domain Admins
Computer Version26 (AD), 26 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Domain Controllers
Description--
-
Table 123 - GPO - Default Domain Controllers Policy

-

ProfileUnity

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID8f11a3fa-3b68-476d-99fc-32064f696ebe
Created06/08/2020
Modified10/05/2021
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/ProfileUnity VDI/Computers
Description--
-
Table 124 - GPO - ProfileUnity

-

VEEAM_Local_Administrators

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID96cb9511-a88c-45ab-b10c-05b0441b1057
Created12/13/2019
Modified11/29/2024
OwnerPHARMAX\Domain Admins
Computer Version27 (AD), 27 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
-
Table 125 - GPO - VEEAM_Local_Administrators

-

WSUS - Domain Policy

- - - - - - - - - - - - -
GPO StatusUser Settings Disabled
GUIDa9ec1b8c-3520-4e19-b11c-babb27c6da1a
Created02/23/2020
Modified04/15/2025
OwnerPHARMAX\Domain Admins
Computer Version30 (AD), 30 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 126 - GPO - WSUS - Domain Policy

-

SCEP Configuration

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDd6187a9f-118c-4ee7-a18f-6889a0a657f4
Created09/14/2020
Modified10/04/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
pharmax.local/Configuration Manager Computers
Description--
-
Table 127 - GPO - SCEP Configuration

-

Dead Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Disabled
GUIDe360fece-8631-4749-b1a4-e55d0e48aa5e
Created10/05/2021
Modified06/19/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI FilterByUser
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 128 - GPO - Dead Policy

-
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

No Security Filtering Applied

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDecbc276e-0e38-42f5-b6e0-6c133b08203c
Created06/18/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringNo Security Filtering
Linked Target--
Description--
-
Table 129 - GPO - No Security Filtering Applied

-
Health Check:

Corrective Actions: Identify 'No Security Filtering' Group Policy Objects (GPOs) that are not linked to any security groups or users. Determine which of these GPOs should be deleted to reduce clutter and improve manageability in Active Directory.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Horizon-DEM

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDf33e9036-4496-4323-9d5a-3011dfd8f1f7
Created03/01/2020
Modified09/15/2025
OwnerPHARMAX\Domain Admins
Computer Version24 (AD), 24 (SYSVOL)
User Version18 (AD), 18 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VDI-Computers
pharmax.local/Admin
Description--
-
Table 130 - GPO - Horizon-DEM

-

Linux-Settings-GPO

- - - - - - - - - - - - -
GPO StatusAll Settings Disabled
GUIDf46abddd-4ae2-457d-b933-849b164fb3f8
Created05/22/2021
Modified02/04/2022
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version6 (AD), 6 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/LinuxMachines
Description--
-
Table 131 - GPO - Linux-Settings-GPO

-
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

SCCM - Restricted Group and General Settings

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDfc8443e6-43cb-4ea4-9862-47b19813596b
Created09/12/2020
Modified09/12/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
Description--
-
Table 132 - GPO - SCCM - Restricted Group and General Settings

-

LAPS Configuration

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDfe43b055-4f61-4fa1-b387-0fc3e2b5915e
Created11/01/2020
Modified11/01/2020
OwnerPHARMAX\Domain Admins
Computer Version15 (AD), 15 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager Computers
Description--
-
Table 133 - GPO - LAPS Configuration

-
2.1.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

- - - - - -
NameByIP
AuthorAdministrator@pharmax.local
Query1;3;10;78;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where TotalPhysicalMemory >= 1073741824

;
DescriptionFilter by IP
-
Table 134 - WMI Filter - ByIP

-
- - - - - -
NameByUser
AuthorAdministrator@pharmax.local
Query1;3;10;81;WQL;root\CIMv2;Select * from Win32_OperatingSystem where Version like "10.%" and ProductType="1";
DescriptionUser Filter
-
Table 135 - WMI Filter - ByUser

-

Central Store Repository

- - -
DomainConfiguredCentral Store Path
PHARMAXYes\\pharmax.local\SYSVOL\pharmax.local\Policies\PolicyDefinitions
-
Table 136 - GPO Central Store - PHARMAX.LOCAL

-

Logon/Logoff Script

- - - - - -
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
Horizon-DEMAll Settings EnabledLogoffC:\Program Files\Immidio\Flex Profiles\FlexEngine.exe
No Security Filtering AppliedAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
ProfileUnityAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
-
Table 137 - GPO with Logon/Logoff Script - PHARMAX.LOCAL

-

Startup/Shutdown Script

- - - - -
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
No Security Filtering AppliedAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
ProfileUnityAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
-
Table 138 - GPO with Startup/Shutdown Script - PHARMAX.LOCAL

-
2.1.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

- - - - -
GPO NameCreatedModifiedComputer EnabledUser Enabled
Dead Policy2021-10-052023-06-20NoNo
Deleted GPO in Sysvol2023-06-202023-06-20YesYes
No Security Filtering Applied2023-06-192023-06-20YesYes
-
Table 139 - Unlinked GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

- - - -
GPO NameCreatedModifiedDescription
Deleted GPO in Sysvol2023-06-202023-06-20--
Linux-Settings-GPO2021-05-232022-02-04--
-
Table 140 - Empty GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

- - - - - - -
GPO NameTarget
Certificate AutoEnrollmentpharmax.local/
SET - KMS Serverpharmax.local/
LAPS Configurationpharmax.local/Configuration Manager Computers
Linux-Settings-GPOpharmax.local/LinuxMachines
VEEAM_Local_Administratorspharmax.local/VEEAM Servers
-
Table 141 - Enforced GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

- - - - - - - -
NameUnknown
GuidA8DF92D3-BDAF-479E-8C0C-9D78AAE058E4
AD DN DatabaseMissing
AD DN PathCN={A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4},CN=Policies,CN=System,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4} (Valid)
-
Table 142 - Orphaned GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

- - - - - - - -
NameDeleted GPO in Sysvol
Guid09E68095-8CFC-4174-81ED-AFB52597DD7F
AD DN DatabaseValid
AD DN PathCN={09E68095-8CFC-4174-81ED-AFB52597DD7F},CN=Policies,CN=System,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{09E68095-8CFC-4174-81ED-AFB52597DD7F} (Missing)
-
Table 143 - Orphaned GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.1.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameLinked GPOProtected
AdminHorizon-DEMYes
Admins PCRestricted-GroupYes
Configuration ManagerSCEP Configuration, SCCM - Restricted Group and General SettingsYes
Configuration Manager ComputersLAPS Configuration, SCEP ConfigurationYes
Domain ControllersDefault Domain Controllers PolicyNo
EMC NAS servers--No
EMC NAS servers/Computers--No
LinuxMachinesAssign-Applications, Linux-Settings-GPOYes
Member Servers--Yes
Microsoft Exchange Security Groups--No
People--Yes
ProfileUnity VDIVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
ProfileUnity VDI/ComputersProfileUnityYes
ProfileUnity VDI/Servers--Yes
Tier 2--Yes
Tier 2/FIN--No
Tier 2/FIN/Devices--Yes
Tier 2/FIN/Groups--Yes
Tier 2/FIN/ServiceAccounts--Yes
Tier 2/FIN/Test--Yes
Tier 2/HRE--No
Tier 2/HRE/Devices--Yes
Tier 2/HRE/Groups--Yes
Tier 2/HRE/ServiceAccounts--Yes
Tier 2/HRE/Test--Yes
Tier 2/OGC--No
Tier 2/OGC/Devices--Yes
Tier 2/OGC/Groups--Yes
Tier 2/OGC/ServiceAccounts--Yes
Tier 2/OGC/Test--Yes
VDI-ComputersHorizon-DEMYes
VDI-Computers/Finances--Yes
VDI-Computers/HR--Yes
VDI-Computers/Marketing--Yes
VDI-Computers/Sales--Yes
VEEAM ServersVEEAM_Disable_Firewall, VEEAM_Local_AdministratorsYes
VEEAM WorkStationsVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
-
Table 144 - Organizational Unit - PHARMAX.LOCAL

-
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

- - - - -
OU NameContainer TypeInheritance BlockedPath
adminOUYespharmax.local/Admin
linuxmachinesOUYespharmax.local/LinuxMachines
veeam workstationsOUYespharmax.local/VEEAM WorkStations
-
Table 145 - Blocked Inheritance GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.1.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

- - - - - - -
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
-
Table 146 - Active Directory Hardening - PHARMAX.LOCAL

-
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.1.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the PHARMAX.LOCAL domain.

- - - - - - -
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=DomainDnsZones,DC=pharmax,DC=local2025:08:30215
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
DC=pharmax,DC=local2025:08:30215
-
Table 147 - Naming Context Last Backup - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain PHARMAX.LOCAL.

- - - - - - - - -
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
Caguas-DC-01VNormal1919Yes0
Carolina-DC-01VNormal1919Yes0
Cayey-Dc-01VNormal1919Yes0
Naguabo-DC-01VNormal1919Yes0
Ponce-DC-01VNormal1919Yes0
Server-DC-01VNormal1919Yes0
Server-DC-02VOffline0000
-
Table 148 - Sysvol Replication Status - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

Sysvol Content Status

The following section provides the SYSVOL health status for domain PHARMAX.LOCAL.

- - - - - - - - - - - - - - - - - - -
ExtensionFile CountSize
.aas30.09 MB
.adm40.05 MB
.adml497079.15 MB
.admx2363.98 MB
.cmd10.00 MB
.cmt10.00 MB
.cmtx80.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.inf120.01 MB
.INI200.01 MB
.msi3150.78 MB
.pol160.04 MB
.ps120.02 MB
.xml50.01 MB
.zip5143.60 MB
-
Table 149 - Sysvol Content Status - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain PHARMAX.LOCAL.

- - - - - - - - - - - - - -
ExtensionFile CountSize
.adm10.01 MB
.adml10.03 MB
.admx10.02 MB
.cmd10.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.ini10.01 MB
.msi3150.78 MB
.ps120.02 MB
.xml10.00 MB
.zip5143.60 MB
-
Table 150 - Netlogon Content Status - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain PHARMAX.LOCAL.

-User Account Security Assessment - Diagram -
-
- - - - - - - - - - - -
Total8559
Enabled8546
Disabled13
Enabled Inactive1
Reversible Encryption Password1
Password Not Required7
Password Never Expires33
Kerberos DES1
Does Not Require Pre Auth0
SID History0
-
Table 151 - User Account Security Assessment - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain PHARMAX.LOCAL.

- - - - - - - - - -
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
krbtgt6/10/2018--No** Yes
Administrator6/10/201812/10/2053* Yes** Yes
jocolon11/30/202112/22/2043* Yes** Yes
veeam_admin12/13/201911/22/2025No** Yes
svc_SCCM_ClientPush9/12/20209/14/2020No** Yes
1227935471SA5/28/2023--No** Yes
GERARDO_RICE5/29/2023--No** Yes
scvmm-admin9/4/20259/4/2025No** Yes
-
Table 152 - Privileged Users Assessment - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

- - - - - -
UsernameCreatedPassword Last SetLast Logon Date
veeam_admin12/13/201912/13/201911/22/2025
svc_SCCM_ClientPush9/12/20209/12/20209/14/2020
1227935471SA5/28/20235/28/2023--
GERARDO_RICE5/29/20235/29/2023--
-
Table 153 - Inactive Privileged Accounts - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain PHARMAX.LOCAL.

- - - - - - - - - - -
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
vcenterYes12/13/201912/13/2019CIFS/ACAD-DNS-01V
svc_SCCM_ClientPushYes9/12/20209/14/2020CIFS/VEEAM-HV-01
krbtgtNo6/10/2018--CIFS/VEEAM-VBR-01V kadmin/changepw
srmrecadminYes10/25/2021--ftp/VEEAM-EM
jocolonYes11/30/202112/22/2043HTTP/example.com
horizon-icYes9/14/202510/20/2025https/GOOWLPT1000001
** GERARDO_RICEYes5/29/2023--POP3/SECWVIR1000255
** AdministratorYes6/10/201812/10/2053SCVMM/SCVMM-SVR-01V SCVMM/SCVMM-SVR-01V.pharmax.local VeeamCdpSvc/VEEAM-VBR VeeamCdpSvc/VEEAM-VBR.pharmax.local VeeamCloudConnectSvc/VEEAM-VBR VeeamCloudConnectSvc/VEEAM-VBR.pharmax.local VeeamBackupSvc/VEEAM-VBR VeeamBackupSvc/VEEAM-VBR.pharmax.local VeeamCatalogSvc/VEEAM-VBR VeeamCatalogSvc/VEEAM-VBR.pharmax.local VeeamEnterpriseManagerSvc/VEEAM-EM VeeamEnterpriseManagerSvc/VEEAM-EM.pharmax.local VeeamCatalogSvc/VEEAM-EM VeeamCatalogSvc/VEEAM-EM.pharmax.local
veeam_adminYes12/13/201911/22/2025VeeamCdpSvc/VEEAM-DRO-01V VeeamCdpSvc/VEEAM-DRO-01V.pharmax.local VeeamCloudConnectSvc/VEEAM-DRO-01V VeeamCloudConnectSvc/VEEAM-DRO-01V.pharmax.local VeeamBackupSvc/VEEAM-DRO-01V VeeamBackupSvc/VEEAM-DRO-01V.pharmax.local VeeamCatalogSvc/VEEAM-DRO-01V VeeamCatalogSvc/VEEAM-DRO-01V.pharmax.local
-
Table 154 - Service Accounts Assessment (Kerberoastable) - PHARMAX.LOCAL

-
Health Check:

Security Best Practice: ** Attackers are most interested in Service Accounts that are members of highly privileged groups like Domain Admins. A quick way to check for this is to enumerate all user accounts with the attribute AdminCount equal to 1. This means an attacker may just ask Active Directory for all user accounts with an SPN and with AdminCount=1. Ensure that there are no privileged accounts that have SPNs assigned to them.

Unconstrained Kerberos Delegation

The following section identifies systems configured with unconstrained Kerberos delegation, which represents a significant security risk in the domain PHARMAX.LOCAL.

- - -
NameDistinguished Name
HV-SERVER-01VCN=HV-SERVER-01V,OU=Member Servers,DC=pharmax,DC=local
-
Table 155 - Unconstrained Kerberos Delegation - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there are no instances of unconstrained Kerberos delegation in Active Directory, as it poses a security risk by allowing any service to impersonate users.

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain PHARMAX.LOCAL.

- - - - - -
Namekrbtgt
Created06/10/2018 21:00:49
Password Last Set06/10/2018 21:00:49
Distinguished NameCN=krbtgt,CN=Users,DC=pharmax,DC=local
-
Table 156 - KRBTGT Account Audit - PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain PHARMAX.LOCAL.

- - - - - - -
NameAdministrator
Created06/10/2018 21:00:05
Password Last Set06/10/2018 04:01:50
Last Logon Date12/10/2053 19:01:07
Distinguished NameCN=Administrator,CN=Users,DC=pharmax,DC=local
-
Table 157 - Administrator Account Audit - PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

Duplicate Objects

The following section details duplicate objects detected in the domain PHARMAX.LOCAL. These objects may indicate replication issues or administrative errors that require attention.

- - -
NameCreatedChangedConflict Changed
SCCM-DP-01V-Remote-Installation-Services CNF:0b206bf4-6c39-47b2-bd69-3694aa657d762020:09:132020:09:132020:09:13
-
Table 158 - Duplicate Object - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there are no duplicate objects in Active Directory. Duplicate objects can cause various issues such as authentication problems, replication conflicts, and administrative overhead. It is recommended to regularly audit and clean up any duplicate objects to maintain a healthy and efficient Active Directory environment.

2.2 ACAD.PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

- - - - - - - - - - - - - - - - - - - - - - -
Domain Nameacad
NetBIOS NameACAD
Domain SIDS-1-5-21-370360276-377477351-3184454278
Domain Functional LevelWindows2016Domain
Domains--
Forestpharmax.local
Parent Domainpharmax.local
Replica Directory Serversacade-dc-01v.acad.pharmax.local
Child Domains--
Domain Pathacad.pharmax.local/
Computers ContainerCN=Computers,DC=acad,DC=pharmax,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=acad,DC=pharmax,DC=local
Systems ContainerCN=System,DC=acad,DC=pharmax,DC=local
Users ContainerCN=Users,DC=acad,DC=pharmax,DC=local
Deleted Objects ContainerCN=Deleted Objects,DC=acad,DC=pharmax,DC=local
Foreign Security Principals ContainerCN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
Lost And Found ContainerCN=LostAndFound,DC=acad,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=acad,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available2100 / 1073739723 (1% Issued)
-
Table 159 - Domain Summary - ACAD.PHARMAX.LOCAL

-

2.2.1 FSMO Roles

- - - - - - -
Infrastructure Masteracade-dc-01v.acad.pharmax.local
PDC Emulator Nameacade-dc-01v.acad.pharmax.local
RID Masteracade-dc-01v.acad.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
-
Table 160 - FSMO Roles - acad.pharmax.local

-
Health Check:

Best Practice: The infrastructure master role in the domain ACAD.PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.2.2 Domain and Trusts

pharmax.local Trust Details

- - - - - - - - - - - - - - - - -
Namepharmax.local
Pathacad.pharmax.local/System/pharmax.local
Sourceacad
Targetpharmax.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 161 - Trust - pharmax.local

-

lab.local Trust Details

- - - - - - - - - - - - - - - - -
Namelab.local
Pathacad.pharmax.local/System/lab.local
Sourceacad
Targetlab.local
Trust TypeUplevel
Trust AttributesQuarantined Domain (External)
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 162 - Trust - lab.local

-

pharam.local Trust Details

- - - - - - - - - - - - - - - - -
Namepharam.local
Pathacad.pharmax.local/System/pharam.local
Sourceacad
Targetpharam.local
Trust TypeUplevel
Trust Attributes20
Trust DirectionOutbound (Trusted domain)
Intra ForestNo
Selective AuthenticationYes
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 163 - Trust - pharam.local

-
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

-
Microsoft Active Directory As Built Report - v1.0

2.2.2.1 Domain and Trusts Diagram

-Domain and Trusts Diagram -
-

-
Microsoft Active Directory As Built Report - v1.0

2.2.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.2.3.1 User Objects

Users

-User Objects - Diagram -
-
- - - - -
Users7
Privileged Users4
Foreign Security Principals4
-
Table 164 - User - ACAD.PHARMAX.LOCAL

-

Status of Users Accounts

-Status of Users Accounts - Diagram -
-
- - - - - - - - - - - - - -
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users7100342.867100
Cannot Change Password000000
Password Never Expires228.57228.57228.57
Must Change Password at Logon114.29114.29114.29
Password Age (> 180 days)114.29114.29114.29
SmartcardLogonRequired000000
SidHistory000000
Never Logged in685.71342.86685.71
Dormant (> 90 days)685.71342.86685.71
Password Not Required457.14114.29457.14
Account Expired000000
Account Lockout000000
-
Table 165 - Status of Users Accounts - ACAD.PHARMAX.LOCAL

-

2.2.3.2 Group Objects

Groups Categories

-Groups Categories - Diagram -
-
- - - -
Security Groups48
Distribution Groups0
-
Table 166 - Groups Categories - ACAD.PHARMAX.LOCAL

-

Groups Scopes

-Groups Scopes - Diagram -
-
- - - - -
Domain Locals34
Globals14
Universal0
-
Table 167 - Groups Scopes - ACAD.PHARMAX.LOCAL

-
2.2.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (2 Members)

- - - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
SCCM-GMSA (GROUP)------
-
Table 168 - Domain Admins - ACAD.PHARMAX.LOCAL

-

Key Admins (1 Members)

- - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
SCCM-GMSA (GROUP)------
-
Table 169 - Key Admins - ACAD.PHARMAX.LOCAL

-

Backup Operators (1 Members)

- - -
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
-
Table 170 - Backup Operators - ACAD.PHARMAX.LOCAL

-
2.2.3.2.2 Privileged Group (Non-Default)
The following section provides a summary of privileged groups with the AdminCount attribute set to 1 (excluding default groups).

- - - -
Group NameGroup SID
PruebaS-1-5-21-370360276-377477351-3184454278-1114
SCCM-GMSAS-1-5-21-370360276-377477351-3184454278-1104
-
Table 171 - - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: Regularly validate and remove unneeded privileged group members in Active Directory. Ensuring that only necessary accounts have privileged access helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation. Regular audits and reviews of group memberships can help identify and mitigate potential security risks.
2.2.3.2.3 Empty Groups (Non-Default)
- - -
Group NameGroup SID
EmptyGrouptestS-1-5-21-370360276-377477351-3184454278-1117
-
Table 172 - Empty Groups - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.2.3.2.4 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

- - - - - -
Parent Group NameChild Group Name
Key AdminsSCCM-GMSA
PruebaSCCM-GMSA
SCCM-GMSAKey Admins
SCCM-GMSAPrueba
-
Table 173 - Circular Group Membership - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.2.3.2.5 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

- - - -
NameDistinguished Name
ACADE-DC-01V (COMPUTER)CN=ACADE-DC-01V,OU=Domain Controllers,DC=acad,DC=pharmax,DC=local
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
-
Table 174 - Pre-Windows 2000 Compatible Access - ACAD.PHARMAX.LOCAL

-
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.2.3.3 Computer Objects

Computers

-Computer Objects - Diagram -
-
- - - -
Computers5
Servers4
-
Table 175 - Computers - ACAD.PHARMAX.LOCAL

-
2.2.3.3.1 Status of Computer Accounts
-Status of Computer Accounts - Diagram -
-
- - - - - -
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers5100005100
Dormant (> 90 days)48000480
Password Age (> 30 days)48000480
SidHistory000000
-
Table 176 - Status of Computer Accounts - ACAD.PHARMAX.LOCAL

-
2.2.3.3.2 Operating Systems Count
- - - - - -
Operating SystemCount
No OS Specified1
Windows Server 2019 Standard2
Windows Server 2019 Standard Evaluation1
Windows Server 2022 Datacenter Evaluation1
-
Table 177 - - ACAD.PHARMAX.LOCAL

-

2.2.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.2.4.1 Default Domain Password Policy

- - - - - - - - - - - -
Password Must Meet Complexity RequirementsYes
Pathacad.pharmax.local/
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Maximum Password Age42 days
Minimum Password Age01 days
Minimum Password Length7
Enforce Password History24
Store Password using Reversible EncryptionNo
-
Table 178 - Default Domain Password Policy - ACAD.PHARMAX.LOCAL

-

2.2.4.2 Fined Grained Password Policies

ACADTest

- - - - - - - - - - - - - - - -
NameACADTest
Domain NameDC=acad,DC=pharmax,DC=local
Complexity EnabledYes
Pathacad.pharmax.local/System/Password Settings Container/ACADTest
Lockout Duration30 minutes
Lockout Threshold5
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age01 days
Min Password Length14
Password History Count24
Reversible Encryption EnabledNo
Precedence1
Applies To--
-
Table 179 - Name - ACADTest

-

2.2.4.3 gMSA Identities

SCCMMSA

- - - - - - - - - - - - - - -
NameSCCMMSA
SamAccountNameSCCMMSA$
Created9/11/2021
EnabledYes
DNS Host Nameacad.pharmax.local
Host Computers**--
Retrieve Managed PasswordSCCM-GMSA
Primary GroupDomain Computers
Last Logon Date*--
Locked OutNo
Logon Count0
Password ExpiredNo
Password Last Set9/11/2021
-
Table 180 - gMSA - SCCMMSA

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.2.4.4 Foreign Security Principals

- - - - - -
NamePrincipal Name
NT AUTHORITY\INTERACTIVEUsers
NT AUTHORITY\Authenticated UsersPre-Windows 2000 Compatible Access
Certificate Service DCOM Access
Users
NT AUTHORITY\IUSR--
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
-
Table 181 - Foreign Security Principals - ACAD.PHARMAX.LOCAL

-

2.2.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

- - -
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
ACADE-DC-01VOnlineACADYesNo172.23.4.1
-
Table 182 - Domain Controller in Domain - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: All domains should have at least two functioning domain controllers for redundancy. In the event of a failure on the domain's only domain controller, users will not be able to log in to the domain or access domain resources. This ensures high availability and fault tolerance within the domain infrastructure.

-Domain Controller Object - Chart -
-
- - - -
Domain Controller1
Global Catalog1
-
Table 183 - Domain Controller Counts - ACAD.PHARMAX.LOCAL

-

2.2.5.1 Configuration

2.2.5.1.1 ACADE-DC-01V

General Information

- - - - - - - - - - - - -
DC Nameacade-dc-01v.acad.pharmax.local
Domain Nameacad.pharmax.local
SiteACAD
Global CatalogYes
Read OnlyNo
Operation Master RolesPDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-370360276-377477351-3184454278-1000
Operating SystemWindows Server 2019 Standard
SMB1 StatusEnabled
DescriptionACAD PDC Server
-
Table 184 - General Information - ACADE-DC-01V

-
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

- - - -
Default PartitionDC=acad,DC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
-
Table 185 - Partitions - ACADE-DC-01V

-

Networking Settings

- - - - - -
IPv4 Addresses172.23.4.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
-
Table 186 - Networking Settings - ACADE-DC-01V

-

Hardware Inventory

- - - - - - - - - - - - - - - - -
NameACADE-DC-01V
Windows Product NameWindows Server 2019 Standard
Windows Build Number10.0.17763
AD Domainacad.pharmax.local
Windows Installation Date09/05/2021 10:35:50
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyJ464C
ManufacturerVMware, Inc.
ModelVMware7,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 187 - Hardware Inventory - ACADE-DC-01V

-
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.2.5.2 DNS IP Configuration

- - -
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
ACADE-DC-01VEthernet0192.168.5.1127.0.0.1172.23.4.1127.0.0.1
-
Table 188 - DNS IP Configuration - ACAD.PHARMAX.LOCAL

-

2.2.5.3 NTDS Information

- - -
DC NameDatabase FileDatabase SizeLog PathSysVol Path
ACADE-DC-01VC:\Windows\NTDS\ntds.dit1 GBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
-
Table 189 - NTDS Database File Usage - ACAD.PHARMAX.LOCAL

-

2.2.5.4 Time Source Information

- - -
NameTime ServerType
ACADE-DC-01V0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
-
Table 190 - Time Source Configuration - ACAD.PHARMAX.LOCAL

-

2.2.5.5 SRV Records Status

- - -
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
ACADE-DC-01VOKOKOKOKOK
-
Table 191 - SRV Records Status - ACAD.PHARMAX.LOCAL

-

2.2.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

ACADE-DC-01V

- - -
NamePathDescription
CertEnrollC:\Windows\system32\CertSrv\CertEnrollActive Directory Certificate Services share
-
Table 192 - File Shares - ACADE-DC-01V

-
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.2.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

- - - -
NamePublisherInstall Date
7-Zip 22.01 (x64)Igor Pavlov--
DiskMax 7.22KoshyJohn.com06/08/2024
-
Table 193 - Installed Software - ACADE-DC-01V

-
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.2.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

- - -
KB ArticleName
KB50787522026-03 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5078752)
-
Table 194 - Missing Windows Updates - ACADE-DC-01V

-
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.2.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in acad.pharmax.local.

ACADE-DC-01V

- - - - - - - -
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
-
Table 195 - Roles - ACADE-DC-01V

-
Health Check:

Best Practices:
    -
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
  2. -
+Microsoft AD As Built Report is a PowerShell module which works in conjunction with [AsBuiltReport.Core](https://github.com/AsBuiltReport/AsBuiltReport.Core). -

2.2.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

ACADE-DC-01V

- - - - - - - - - - - - - - - - - -
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 196 - Infrastructure Services Status - ACADE-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.2.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.2.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: ACADE-DC-01V

- - - - - - - - - - - - -
Name<automatically generated>
From SiteSanJuan
GUIDca680ef0-acf8-4b96-a041-241cc754b87a
Description--
From ServerSERVER-DC-01V
To ServerACADE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 04:17:40 GMT
-
Table 197 - Replication Connection - ACADE-DC-01V

-

2.2.6.2 Replication Status

- - - - - -
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:06:43000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:36:39000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:44:26000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:13:46000
-
Table 198 - Replication Status - ACAD

-

2.2.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.2.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the ACAD.PHARMAX.LOCAL domain.

2.2.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Empty Policy ACAD

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID053a8be2-fc5e-46de-8dde-4c5047ccd151
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI FilterFilter
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
acad.pharmax.local
Description--
-
Table 199 - GPO - Empty Policy ACAD

-

Default Domain Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created09/05/2021
Modified03/07/2025
OwnerACAD\Domain Admins
Computer Version13 (AD), 13 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local
Description--
-
Table 200 - GPO - Default Domain Policy

-

Unlinked Policy ACAD

- - - - - - - - - - - - -
GPO StatusAll Settings Disabled
GUID40a5cbba-ed3f-460d-9de1-22d2541b7643
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Enterprise Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 201 - GPO - Unlinked Policy ACAD

-
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

ACAD - Deleted GPO in Sysvol

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID696c8f4b-54a9-4456-ae3f-bc52b40c5c33
Created06/21/2023
Modified06/21/2023
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 202 - GPO - ACAD - Deleted GPO in Sysvol

-
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Default Domain Controllers Policy

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created09/05/2021
Modified03/03/2026
OwnerACAD\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Domain Controllers
Description--
-
Table 203 - GPO - Default Domain Controllers Policy

-

ACAD Certificate AutoEnrollment

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDbe6237b7-b1d4-47e3-a8e5-7f6ec1b38d57
Created09/22/2021
Modified09/22/2021
OwnerPHARMAX\Enterprise Admins
Computer Version2 (AD), 2 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local
Description--
-
Table 204 - GPO - ACAD Certificate AutoEnrollment

-

Logon Script

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDfd32ee4c-ac02-4de5-ae91-1316f4f86bf5
Created10/07/2021
Modified10/07/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version2 (AD), 2 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
Description--
-
Table 205 - GPO - Logon Script

-
2.2.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

- - - - - -
NameFilter
AuthorAdministrator@pharmax.local
Query1;3;13;62;WQL;root\Hardware;select * from Win32_OperatingSystem where Version like "6.%"
;
Description--
-
Table 206 - WMI Filter - Filter

-

Central Store Repository

- - -
DomainConfiguredCentral Store Path
ACADNo\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\PolicyDefinitions
-
Table 207 - GPO Central Store - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practices: The Group Policy Central Store is a central location to store all the Group Policy template files (ADMX/ADML files). This eliminates the need for administrators to load and open Group Policy template files on each system used to manage Group Policy. Ensure the Central Store is deployed to a centralized GPO repository to streamline management and ensure consistency across the environment.

Logon/Logoff Script

- - -
GPO NameGPO StatusTypeScript
Logon ScriptAll Settings EnabledLogon\\acad.pharmax.local\NETLOGON\enroll.exe
-
Table 208 - GPO with Logon/Logoff Script - ACAD.PHARMAX.LOCAL

-
2.2.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

- - - -
GPO NameCreatedModifiedComputer EnabledUser Enabled
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21YesYes
Unlinked Policy ACAD2021-10-062021-10-06NoNo
-
Table 209 - Unlinked GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

- - - -
GPO NameCreatedModifiedDescription
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21--
Empty Policy ACAD2021-10-062021-10-06--
-
Table 210 - Empty GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

- - - - - -
GPO NameTarget
ACAD Certificate AutoEnrollmentacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/Acad Computers/SCCM Computers
Logon Scriptacad.pharmax.local/Acad Computers/SCCM Computers
-
Table 211 - Enforced GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

- - - - - - - -
NameUnknown
Guid2E8D7948-6F28-4872-B97C-CA2CB971C9AE
AD DN DatabaseMissing
AD DN PathCN={2E8D7948-6F28-4872-B97C-CA2CB971C9AE},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{2E8D7948-6F28-4872-B97C-CA2CB971C9AE} (Valid)
-
Table 212 - Orphaned GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

- - - - - - - -
NameACAD - Deleted GPO in Sysvol
Guid696C8F4B-54A9-4456-AE3F-BC52B40C5C33
AD DN DatabaseValid
AD DN PathCN={696C8F4B-54A9-4456-AE3F-BC52B40C5C33},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{696C8F4B-54A9-4456-AE3F-BC52B40C5C33} (Missing)
-
Table 213 - Orphaned GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.2.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

- - - - - -
NameLinked GPOProtected
Acad Computers--Yes
Acad Computers/SCCM ComputersLogon Script, Empty Policy ACADYes
Domain ControllersDefault Domain Controllers PolicyNo
Member Servers--No
-
Table 214 - Organizational Unit - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

- - -
OU NameContainer TypeInheritance BlockedPath
sccm computersOUYesacad.pharmax.local/Acad Computers/SCCM Computers
-
Table 215 - Blocked Inheritance GPO - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.2.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

- - - - - - -
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
-
Table 216 - Active Directory Hardening - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.2.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the ACAD.PHARMAX.LOCAL domain.

- - - - - - -
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=acad,DC=pharmax,DC=local2021:09:051670
DC=DomainDnsZones,DC=acad,DC=pharmax,DC=local2021:09:051670
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
-
Table 217 - Naming Context Last Backup - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain ACAD.PHARMAX.LOCAL.

- - -
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
acade-dc-01vNormal77Yes0
-
Table 218 - Sysvol Replication Status - ACAD.PHARMAX.LOCAL

-

Sysvol Content Status

The following section provides the SYSVOL health status for domain ACAD.PHARMAX.LOCAL.

- - - - - - - - - - -
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.cmtx10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.inf30.01 MB
.INI70.00 MB
.pol30.01 MB
.ps120.02 MB
-
Table 219 - Sysvol Content Status - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain ACAD.PHARMAX.LOCAL.

- - - - - - -
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.ps120.02 MB
-
Table 220 - Netlogon Content Status - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain ACAD.PHARMAX.LOCAL.

-User Account Security Assessment - Diagram -
-
- - - - - - - - - - - -
Total7
Enabled4
Disabled3
Enabled Inactive1
Reversible Encryption Password0
Password Not Required4
Password Never Expires2
Kerberos DES0
Does Not Require Pre Auth0
SID History0
-
Table 221 - User Account Security Assessment - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain ACAD.PHARMAX.LOCAL.

- - - - - -
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
grouptest7/21/2023--* YesNo
Administrator3/19/20263/19/2026No** Yes
Guest----No** Yes
krbtgt9/5/2021--No** Yes
-
Table 222 - Privileged Users Assessment - ACAD.PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain ACAD.PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

- - - -
UsernameCreatedPassword Last SetLast Logon Date
grouptest7/21/20237/21/2023--
Guest9/5/2021----
-
Table 223 - Inactive Privileged Accounts - ACAD.PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain ACAD.PHARMAX.LOCAL.

- - -
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
krbtgtNo9/5/2021--kadmin/changepw
-
Table 224 - Service Accounts Assessment (Kerberoastable) - ACAD.PHARMAX.LOCAL

-
Health Check:

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain ACAD.PHARMAX.LOCAL.

- - - - - -
Namekrbtgt
Created09/05/2021 12:25:21
Password Last Set09/05/2021 12:25:21
Distinguished NameCN=krbtgt,CN=Users,DC=acad,DC=pharmax,DC=local
-
Table 225 - KRBTGT Account Audit - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain ACAD.PHARMAX.LOCAL.

- - - - - - -
NameAdministrator
Created09/05/2021 12:24:39
Password Last Set03/19/2026 21:42:01
Last Logon Date03/19/2026 21:42:01
Distinguished NameCN=Administrator,CN=Users,DC=acad,DC=pharmax,DC=local
-
Table 226 - Administrator Account Audit - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

3 DNS Configuration

The following section provides a detailed overview of the DNS infrastructure configuration and settings within the Active Directory environment.

3.1 PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.1.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

- - - - - - - -
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
CAGUAS-DC-01V26100YesYesNofe80::75c9:eaa3:559a:23de
172.23.7.1
CAROLINA-DC-01V26100YesYesNo172.23.9.1
CAYEY-DC-01V26100YesYesNofe80::74a3:277d:e262:218b
10.10.30.1
NAGUABO-DC-01V26100YesYesNofe80::efb6:c739:603c:1121
10.10.31.1
PONCE-DC-01V26100YesYesNofe80::de92:566e:cf5c:a051
10.10.32.1
SERVER-DC-01V26100YesNoNo192.168.5.1
192.168.7.1
-
Table 227 - Infrastructure Summary - PHARMAX.LOCAL

-

3.1.1.1 Forwarder Options

- - - - - - - -
DC NameIP AddressTimeoutUse Root HintUse Recursion
CAGUAS-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
CAROLINA-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
CAYEY-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
NAGUABO-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
PONCE-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
SERVER-DC-01V10.0.0.138
8.8.8.8
1.1.1.1
3/sYesYes
-
Table 228 - Forwarders - PHARMAX.LOCAL

-
Health Check:

Best Practices: Configure the servers to use no more than two external DNS servers as Forwarders. Using more than two forwarders can lead to increased resolution times and potential issues with DNS query load balancing. It is recommended to use two reliable and geographically diverse DNS servers to ensure redundancy and optimal performance.

Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/forwarders-resolution-timeouts

3.1.2 CAGUAS-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 229 - Zones - PHARMAX.LOCAL

-

3.1.2.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 230 - Zones - PHARMAX.LOCAL

-

3.1.2.2 Conditional Forwarder

- - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 231 - Conditional Forwarders - PHARMAX.LOCAL

-

3.1.3 CAROLINA-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 232 - Zones - PHARMAX.LOCAL

-

3.1.3.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 233 - Zones - PHARMAX.LOCAL

-

3.1.3.2 Conditional Forwarder

- - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 234 - Conditional Forwarders - PHARMAX.LOCAL

-

3.1.4 CAYEY-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 235 - Zones - PHARMAX.LOCAL

-

3.1.4.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 236 - Zones - PHARMAX.LOCAL

-

3.1.4.2 Conditional Forwarder

- - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 237 - Conditional Forwarders - PHARMAX.LOCAL

-

3.1.5 NAGUABO-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 238 - Zones - PHARMAX.LOCAL

-

3.1.5.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 239 - Zones - PHARMAX.LOCAL

-

3.1.5.2 Conditional Forwarder

- - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 240 - Conditional Forwarders - PHARMAX.LOCAL

-

3.1.6 PONCE-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 241 - Zones - PHARMAX.LOCAL

-

3.1.6.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 242 - Zones - PHARMAX.LOCAL

-

3.1.6.2 Conditional Forwarder

- - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 243 - Conditional Forwarders - PHARMAX.LOCAL

-

3.1.7 SERVER-DC-01V DNS Zones

- - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localSecondary----NoNo--
BlueTuxedo.localPrimaryNoneNoneNoNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 244 - Zones - PHARMAX.LOCAL

-

3.1.7.1 Reverse Lookup Zone

- - - - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 245 - Zones - PHARMAX.LOCAL

-

3.1.7.2 Conditional Forwarder

- - - - - - - - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
lab.localForwarderNone10.10.30.10No
meereen.essos.localForwarderNone192.168.56.12No
pharam.localForwarderLegacy192.168.7.42Yes
proton.localForwarderNone192.168.5.20No
sevenkingdoms.localForwarderNone192.168.56.10No
winterfell.sevenkingdoms.localForwarderNone192.168.56.11No
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 246 - Conditional Forwarders - PHARMAX.LOCAL

-

3.2 ACAD.PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.2.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

- - -
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
ACADE-DC-01V17763YesNoNo172.23.4.1
-
Table 247 - Infrastructure Summary - ACAD.PHARMAX.LOCAL

-

3.2.1.1 Forwarder Options

- - -
DC NameIP AddressTimeoutUse Root HintUse Recursion
ACADE-DC-01V192.168.5.13/sYesYes
-
Table 248 - Forwarders - ACAD.PHARMAX.LOCAL

-
Health Check:

Best Practices: For redundancy reasons, more than one forwarding server should be configured.

3.2.2 ACADE-DC-01V DNS Zones

- - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenpr.localSecondary----NoNo--
-
Table 249 - Zones - ACAD.PHARMAX.LOCAL

-

3.2.2.1 Reverse Lookup Zone

- - - - - - -
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 250 - Zones - ACAD.PHARMAX.LOCAL

-

3.2.2.2 Conditional Forwarder

- - - -
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
zenprsolutions.localForwarderNone8.8.8.8No
-
Table 251 - Conditional Forwarders - ACAD.PHARMAX.LOCAL

-
-

+[AsBuiltReport](https://github.com/AsBuiltReport/AsBuiltReport) is an open-sourced community project which utilizes PowerShell to produce as-built documentation in multiple document formats for multiple vendors and technologies. + +Please refer to the AsBuiltReport [website](https://www.asbuiltreport.com) for more detailed information about this project. + +# :books: Sample Reports + +## Sample Report - Default Style with EnableHealthCheck + +Sample Microsoft AD As Built report HTML file: [Sample Microsoft AD As-Built Report.html](https://htmlpreview.github.io/?https://raw.githubusercontent.com/AsBuiltReport/AsBuiltReport.Microsoft.AD/dev/Samples/Sample%20Microsoft%20AD%20As%20Built%20Report.html) + +# :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; + +- 2012, 2016, 2019, 2022 & 2025 + +### PowerShell + +This report is compatible with the following PowerShell versions; + + +| Windows PowerShell 5.1 | PowerShell 7 | +| :--------------------: | :----------------: | +| :x: | :white_check_mark: | + +## :wrench: System Requirements + +PowerShell 7.4+, and the following PowerShell modules are required for generating a Microsoft AD As Built report. + +- [AsBuiltReport.Core Module](https://github.com/AsBuiltReport/AsBuiltReport.Core) +- [AsBuiltReport.Chart Module](https://github.com/AsBuiltReport/AsBuiltReport.Chart) +- [AsBuiltReport.Diagram Module](https://github.com/AsBuiltReport/AsBuiltReport.Diagram) +- [AsBuiltReport.Microsoft.AD Module](https://www.powershellgallery.com/packages/AsBuiltReport.Microsoft.AD/) +- [PScribo Module](https://github.com/iainbrighton/PScribo) +- [PSGraph Module](https://github.com/KevinMarquette/PSGraph) +- [ActiveDirectory Module](https://docs.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2019-ps) +- [ADCSAdministration Module](https://learn.microsoft.com/en-us/powershell/module/adcsadministration/?view=windowsserver2019-ps) +- [GroupPolicy Module](https://docs.microsoft.com/en-us/powershell/module/grouppolicy/?view=windowsserver2019-ps) +- [DnsServer Module](https://docs.microsoft.com/en-us/powershell/module/dnsserver/?view=windowsserver2019-ps) + +### Linux & macOS + +This report is not supported on Linux or macOS because the ActiveDirectory and GroupPolicy modules depend on the .NET Framework. These modules are Windows-only until Microsoft migrates them to PowerShell Core. Therefore, only PowerShell 7.4+ on Windows is supported for generating this report. + +### :closed_lock_with_key: Required Privileges + +A Microsoft AD As Built Report can be generated with Active Directory Enterprise Forest level privileges. Since this report relies extensively on the WinRM component, you should make sure that it is enabled and configured. [Reference](https://docs.microsoft.com/en-us/windows/win32/winrm/installation-and-configuration-for-windows-remote-management) + +Due to a limitation of the WinRM component, a domain-joined machine is needed, also it is required to use the FQDN of the DC instead of it's 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 -Name PSGraph +Install-Module -Name AsBuiltReport.Chart +Install-Module -Name AsBuiltReport.Diagram +Install-Module -Name AsBuiltReport.Microsoft.AD +Install-WindowsFeature -Name RSAT-AD-PowerShell +Install-WindowsFeature -Name RSAT-ADCS,RSAT-ADCS-mgmt +Install-WindowsFeature -Name RSAT-DNS-Server +Install-WindowsFeature -Name GPMC +``` + +### PowerShell v5.x running on Windows 10 client computer + +```powershell +Install-Module -Name PSGraph +Install-Module -Name AsBuiltReport.Chart +Install-Module -Name AsBuiltReport.Diagram +Install-Module -Name AsBuiltReport.Microsoft.AD +Add-WindowsCapability -online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' +Add-WindowsCapability -Online -Name 'Rsat.CertificateServices.Tools~~~~0.0.1.0' +Add-WindowsCapability -online -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0' +Add-WindowsCapability –online –Name 'Rsat.Dns.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. + +| Sub-Schema | Setting | Default | Description | +| ----------------------- | ------------------ | --------- | -------------------------------------------------------------------------------- | +| DCStatusPingCount | int | 2 | Set the count value for the cmdlet Test-Connection (Increase if network is slow) | +| DiagramTheme | string | White | Set the diagram theme (Black/White/Neon) | +| DiagramType | true / false | true | Toggle to enable/disable the export of individual diagram diagrams | +| DiagramWaterMark | string | empty | Set the diagram watermark | +| EnableDiagrams | true / false | false | Toggle to enable/disable infrastructure diagrams | +| EnableDiagramsDebug | true / false | false | Toggle to enable/disable diagram debug option | +| EnableDiagramSignature | true / false | false | Toggle to enable/disable diagram signature (bottom right corner) | +| EnableHardwareInventory | true / false | false | Toggle to enable/disable hardware information | +| ExportDiagrams | true / false | true | Toggle to enable/disable diagram export option | +| ExportDiagramsFormat | string array | pdf | Set the format used to export the infrastructure diagram (dot, png, pdf, svg) | +| Exclude.DCs | array List | Empty | Allow to filter on AD Domain Controller Server FQDN. | +| Exclude.Domains | array List | Empty | Allow to filter on AD Domain FQDN | +| Include.DCs | array List | Empty | Allow only a list of Active Directory Domain FQDN to document. | +| Include.Domains | array List | Empty | Allow only a list of Active Directory Domain Controller FQDN to document. | +| JobsTimeOut | int | 900 | Allow to set the timeout (in seconds) for remote jobs execution | +| PSDefaultAuthentication | Negotiate/Kerberos | Negotiate | Allow to set the value of the PSRemoting authentication method. | +| | | | For Workgroup authentication Negotiate value is required. | +| ShowDefinitionInfo | true/false | False | Toggle to enable/disable Microsoft AD term explanations | +| SignatureAuthorName | string | empty | Set the signature author name | +| SignatureCompanyName | string | empty | Set the signature company name | +| WinRMFallbackToNoSSL | bool | True | Allow to fallback to WINRM without SSL | +| WinRMPort | int | 5985 | Allow to set tcp port for WinRM | +| WinRMSSL | bool | True | Allow to enable SSL for WINRM connection | +| WinRMSSLPort | int | 5986 | Allow to set tcp port for WinRM over SSL | + + +### InfoLevel + +The **InfoLevel** schema allows configuration of each section of the report at a granular level. The following sections can be set. + +There are 4 levels (0-3) of detail granularity for each section as follows; + +| Setting | InfoLevel | Description | +| :-----: | ------------ | --------------------------------------------------------------------------------------------------- | +| 0 | Disabled | Does not collect or display any information | +| 1 | Enabled | Provides summarized information for a collection of objects | +| 2 | Adv Summary | Provides condensed, detailed information for a collection of objects | +| 3 | Detailed | Provides detailed information for individual objects | +| 4 | Adv Detailed | Provides detailed information for individual objects, as well as information for associated objects | + + +The table below outlines the default and maximum **InfoLevel** settings for each section. + +| Sub-Schema | Default Setting | Maximum Setting | +| ---------- | :-------------: | :-------------: | +| Forest | 2 | 1 | +| Domain | 2 | 4 | +| DNS | 1 | 2 | + +### 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 +- **PSWriteWord Module Conflict**: PScribo and the EvotecIT "PSWriteWord" project use conflicting cmdlets. The PSWriteWord module must be uninstalled before generating reports. +- **WinRM Dependency**: This report relies heavily on remote connections via WinRM. A Windows 10 client is recommended as a jumpbox for optimal connectivity. +- **DNS Service Requirements**: To extract DNS service configuration, install PowerShell management modules on servers hosting DNS services (RSAT-DNS-Server and RSAT-AD-PowerShell). +- **DNS Cohosting Assumption**: The report assumes DNS Server service runs on the same server as the Domain Controller. +- **Windows Server 2012/2012 R2 Compatibility**: Hexadecimal character errors may occur when running against older Windows Server versions. From 63822ce514f2aad4cdfcb4ed1e62a4fc1f204c81 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 3 Apr 2026 20:48:53 -0400 Subject: [PATCH 04/18] Update print statement from 'Hello' to 'Goodbye' --- .../Sample Microsoft AD As Built Report.html | 3414 ++++++++++++----- 1 file changed, 2514 insertions(+), 900 deletions(-) diff --git a/Samples/Sample Microsoft AD As Built Report.html b/Samples/Sample Microsoft AD As Built Report.html index 6c79a7a..48eac8c 100644 --- a/Samples/Sample Microsoft AD As Built Report.html +++ b/Samples/Sample Microsoft AD As Built Report.html @@ -8,347 +8,476 @@ hr { margin-top: 1.0rem; } .portrait { background: white; width: 210mm; display: block; margin-top: 1rem; margin-left: auto; margin-right: auto; margin-bottom: 1rem; position: relative; border-style: solid; border-width: 1px; border-color: #c6c6c6; } .landscape { background: white; width: 297mm; display: block; margin-top: 1rem; margin-left: auto; margin-right: auto; margin-bottom: 1rem; position: relative; border-style: solid; border-width: 1px; border-color: #c6c6c6; } - .Heading2 { font-family: 'Segoe Ui'; font-size: 1.17rem; text-align: left; font-weight: normal; color: #204369; } - .Title2 { font-family: 'Segoe Ui'; font-size: 1.50rem; text-align: center; font-weight: normal; color: #204369; } - .Warning { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #fff4c7; } + .OK { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #dff0d0; } .Title { font-family: 'Segoe Ui'; font-size: 2.00rem; text-align: center; font-weight: normal; color: #072e58; } .Heading3 { font-family: 'Segoe Ui'; font-size: 1.08rem; text-align: left; font-weight: normal; color: #395879; } - .Title3 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #395879; } - .TableDefaultAltRow { font-family: 'Calibri','Candara','Segoe','Segoe UI','Optima','Arial','Sans-Serif'; font-size: 0.92rem; text-align: left; font-weight: normal; color: #000000; background-color: #d0ddee; } + .Normal { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; } + .Warning { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #fff4c7; } + .Header { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: center; font-weight: normal; color: #565656; } + .Title2 { font-family: 'Segoe Ui'; font-size: 1.50rem; text-align: center; font-weight: normal; color: #204369; } + .Heading4 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #958026; } .NOTOCHeading5 { font-family: 'Segoe Ui'; font-size: 0.92rem; text-align: left; font-weight: normal; color: #009684; } - .NOTOCHeading7 { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; font-style: italic; color: #00ebcd; } + .NOTOCHeading4 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #958026; } .NOTOCHeading6 { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #009683; } - .TableDefaultRow { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; } + .Footer { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: center; font-weight: normal; color: #565656; } .TOC { font-family: 'Segoe Ui'; font-size: 1.33rem; text-align: left; font-weight: normal; color: #072e58; } + .TableDefaultAltRow { font-family: 'Calibri','Candara','Segoe','Segoe UI','Optima','Arial','Sans-Serif'; font-size: 0.92rem; text-align: left; font-weight: normal; color: #000000; background-color: #d0ddee; } + .Heading6 { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #009683; } + .Heading2 { font-family: 'Segoe Ui'; font-size: 1.17rem; text-align: left; font-weight: normal; color: #204369; } + .TableDefaultHeading { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #fafafa; background-color: #072e58; } + .TableDefaultRow { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; } .Heading5 { font-family: 'Segoe Ui'; font-size: 0.92rem; text-align: left; font-weight: normal; color: #009684; } - .Heading4 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #958026; } - .Heading1 { font-family: 'Segoe Ui'; font-size: 1.33rem; text-align: left; font-weight: normal; color: #072e58; } + .Title3 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #395879; } + .NOTOCHeading7 { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; font-style: italic; color: #00ebcd; } .Caption { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; font-style: italic; color: #072e58; } - .Info { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #e3f5fc; } .Critical { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #feddd7; } - .Header { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: center; font-weight: normal; color: #565656; } - .Heading6 { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #009683; } - .NOTOCHeading4 { font-family: 'Segoe Ui'; font-size: 1.00rem; text-align: left; font-weight: normal; color: #958026; } - .OK { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #dff0d0; } - .Footer { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: center; font-weight: normal; color: #565656; } - .Normal { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; } - .TableDefaultHeading { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #fafafa; background-color: #072e58; } - table.borderless { padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } - table.borderless th { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } - table.borderless td { padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } - table.borderless tr:nth-child(odd) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } - table.borderless tr:nth-child(even) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } + .Info { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; background-color: #e3f5fc; } + .Heading1 { font-family: 'Segoe Ui'; font-size: 1.33rem; text-align: left; font-weight: normal; color: #072e58; } table.tabledefault { padding: 0.08rem 0.17rem 0.13rem 0.17rem; border-style: solid; border-width: 0.02rem; border-color: #072e58; border-collapse: collapse; } table.tabledefault th { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #fafafa; background-color: #072e58; padding: 0.08rem 0.17rem 0.13rem 0.17rem; border-style: solid; border-width: 0.02rem; border-color: #072e58; border-collapse: collapse; } table.tabledefault td { padding: 0.08rem 0.17rem 0.13rem 0.17rem; border-style: solid; border-width: 0.02rem; border-color: #072e58; border-collapse: collapse; } table.tabledefault tr:nth-child(odd) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.17rem 0.13rem 0.17rem; border-style: solid; border-width: 0.02rem; border-color: #072e58; border-collapse: collapse; } table.tabledefault tr:nth-child(even) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.17rem 0.13rem 0.17rem; border-style: solid; border-width: 0.02rem; border-color: #072e58; border-collapse: collapse; } + table.borderless { padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } + table.borderless th { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } + table.borderless td { padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } + table.borderless tr:nth-child(odd) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; } + table.borderless tr:nth-child(even) { font-family: 'Segoe Ui'; font-size: 0.83rem; text-align: left; font-weight: normal; color: #565656; padding: 0.08rem 0.33rem 0rem 0.33rem; border-style: none; border-collapse: collapse; }











AsBuiltReport Logo
-
Microsoft Active Directory As Built Report

As Built Report






















+
Microsoft Active Directory As Built Report

Zen PR Solutions






















- +
Author:As Built Report
Date:Saturday, February 21, 2026
Date:Thursday, April 2, 2026
Version:1.0

Microsoft Active Directory As Built Report - v1.0

Table of Contents

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1PHARMAX.LOCAL
1.1   Forest Configuration
1.1.1      Forest Diagram
1.1.2      Certificate Authority
1.1.3      Certificate Authority Diagram
1.1.4      Optional Features
1.1.5      Replication
1.1.5.1         Site Inventory Diagram
1.1.5.2         Sites
1.1.5.3         Site Subnets
1.1.5.4         Site Topology Diagram
1.1.5.5         Inter-Site Transports
1.1.5.5.1            IP
1.1.5.5.1.1               Site Links
1.1.5.5.1.2               Site Link Bridges
1.1.5.5.2            SMTP
1.1.5.5.2.1               Site Links
1.1.5.5.2.2               Site Link Bridges
1.1.5.6         Sysvol Replication
1.1.6      Exchange Infrastructure
1.1.7      SCCM Infrastructure
1.1.8      DHCP Infrastructure
2AD Domain Configuration
2.1   PHARMAX.LOCAL
2.1.1      FSMO Roles
2.1.2      Domain and Trusts
2.1.2.1         Domain and Trusts Diagram
2.1.3      Active Directory Hardening
2.1.4      Domain Objects
2.1.4.1         User Objects
2.1.4.2         Group Objects
2.1.4.2.1            Privileged Groups (Built-in)
2.1.4.2.2            Empty Groups (Non-Default)
2.1.4.2.3            Circular Group Membership
2.1.4.3         Computer Objects
2.1.4.3.1            Status of Computer Accounts
2.1.4.3.2            Operating Systems Count
2.1.4.4         Default Domain Password Policy
2.1.4.5         Fined Grained Password Policies
2.1.4.6         Microsoft LAPS
2.1.4.7         gMSA Identities
2.1.4.8         Foreign Security Principals
2.1.5      Health Checks
2.1.6      Domain Controllers
2.1.6.1         Configuration
2.1.6.1.1            SERVER-DC-01V
2.1.6.2         DNS IP Configuration
2.1.6.3         NTDS Information
2.1.6.4         Time Source Information
2.1.6.5         SRV Records Status
2.1.6.6         File Shares
2.1.6.7         Installed Software
2.1.6.8         Roles
2.1.6.9         Infrastructure Services
2.1.7      Replication Connection
2.1.8      Replication Status
2.1.9      Group Policy Objects
2.1.9.1         WMI Filters
2.1.9.2         Central Store Repository
2.1.9.3         Logon/Logoff Script
2.1.9.4         Startup/Shutdown Script
2.1.9.5         Unlinked GPO
2.1.9.6         Empty GPOs
2.1.9.7         Enforced GPO
2.1.9.8         Orphaned GPO
2.1.10      Organizational Units
3DNS Configuration
3.1   PHARMAX.LOCAL
3.1.1      Infrastructure Summary
3.1.1.1         Forwarder Options
3.1.2      SERVER-DC-01V DNS Zones
3.1.2.1         Reverse Lookup Zone
3.1.2.2         Conditional Forwarder
1PHARMAX.LOCAL Active Directory Forest
1.1   Forest Configuration
1.1.1      Forest Diagram
1.1.2      Certificate Authority
1.1.3      Certificate Authority Diagram
1.1.4      Optional Features
1.2   AD Sites & Replication
1.2.1      Replication
1.2.1.1         Replication Diagram
1.2.1.2         Sites
1.2.1.3         Site Subnets
1.2.1.4         Site Topology Diagram
1.2.1.5         Inter-Site Transports
1.2.1.5.1            IP
1.2.1.5.1.1               Site Links
1.2.1.5.1.2               Site Link Bridges
1.2.1.6         Sysvol Replication
1.3   Infrastructure Services
1.3.1      Exchange Infrastructure
1.3.2      SCCM Infrastructure
1.3.3      DHCP Infrastructure
2AD Domain Configuration
2.1   PHARMAX.LOCAL
2.1.1      FSMO Roles
2.1.2      Domain and Trusts
2.1.2.1         Domain and Trusts Diagram
2.1.3      Directory Objects
2.1.3.1         User Objects
2.1.3.2         Group Objects
2.1.3.2.1            Privileged Groups (Built-in)
2.1.3.2.2            Empty Groups (Non-Default)
2.1.3.2.3            Circular Group Membership
2.1.3.2.4            Pre-Windows 2000 Compatible Access Group Membership
2.1.3.3         Computer Objects
2.1.3.3.1            Status of Computer Accounts
2.1.3.3.2            Operating Systems Count
2.1.4      Account Policies
2.1.4.1         Default Domain Password Policy
2.1.4.2         Fined Grained Password Policies
2.1.4.3         Microsoft LAPS
2.1.4.4         gMSA Identities
2.1.4.5         Foreign Security Principals
2.1.5      Domain Controllers
2.1.5.1         Configuration
2.1.5.1.1            CAGUAS-DC-01V
2.1.5.1.2            CAROLINA-DC-01V
2.1.5.1.3            CAYEY-DC-01V
2.1.5.1.4            NAGUABO-DC-01V
2.1.5.1.5            PONCE-DC-01V
2.1.5.1.6            SERVER-DC-01V
2.1.5.2         DNS IP Configuration
2.1.5.3         NTDS Information
2.1.5.4         Time Source Information
2.1.5.5         SRV Records Status
2.1.5.6         File Shares
2.1.5.7         Installed Software
2.1.5.8         Missing Windows Updates
2.1.5.9         Roles
2.1.5.10         Infrastructure Services
2.1.6      Replication
2.1.6.1         Replication Connection
2.1.6.2         Replication Status
2.1.7      Group Policy
2.1.7.1         Group Policy Objects
2.1.7.1.1            GPO Inventory
2.1.7.1.2            GPO Settings
2.1.7.1.3            GPO Health
2.1.8      Organizational Units
2.1.9      Active Directory Hardening
2.1.10      Health Checks
2.2   ACAD.PHARMAX.LOCAL
2.2.1      FSMO Roles
2.2.2      Domain and Trusts
2.2.2.1         Domain and Trusts Diagram
2.2.3      Directory Objects
2.2.3.1         User Objects
2.2.3.2         Group Objects
2.2.3.2.1            Privileged Groups (Built-in)
2.2.3.2.2            Privileged Group (Non-Default)
2.2.3.2.3            Empty Groups (Non-Default)
2.2.3.2.4            Circular Group Membership
2.2.3.2.5            Pre-Windows 2000 Compatible Access Group Membership
2.2.3.3         Computer Objects
2.2.3.3.1            Status of Computer Accounts
2.2.3.3.2            Operating Systems Count
2.2.4      Account Policies
2.2.4.1         Default Domain Password Policy
2.2.4.2         Fined Grained Password Policies
2.2.4.3         gMSA Identities
2.2.4.4         Foreign Security Principals
2.2.5      Domain Controllers
2.2.5.1         Configuration
2.2.5.1.1            ACADE-DC-01V
2.2.5.2         DNS IP Configuration
2.2.5.3         NTDS Information
2.2.5.4         Time Source Information
2.2.5.5         SRV Records Status
2.2.5.6         File Shares
2.2.5.7         Installed Software
2.2.5.8         Missing Windows Updates
2.2.5.9         Roles
2.2.5.10         Infrastructure Services
2.2.6      Replication
2.2.6.1         Replication Connection
2.2.6.2         Replication Status
2.2.7      Group Policy
2.2.7.1         Group Policy Objects
2.2.7.1.1            GPO Inventory
2.2.7.1.2            GPO Settings
2.2.7.1.3            GPO Health
2.2.8      Organizational Units
2.2.9      Active Directory Hardening
2.2.10      Health Checks
3DNS Configuration
3.1   PHARMAX.LOCAL
3.1.1      Infrastructure Summary
3.1.1.1         Forwarder Options
3.1.2      CAGUAS-DC-01V DNS Zones
3.1.2.1         Reverse Lookup Zone
3.1.2.2         Conditional Forwarder
3.1.3      CAROLINA-DC-01V DNS Zones
3.1.3.1         Reverse Lookup Zone
3.1.3.2         Conditional Forwarder
3.1.4      CAYEY-DC-01V DNS Zones
3.1.4.1         Reverse Lookup Zone
3.1.4.2         Conditional Forwarder
3.1.5      NAGUABO-DC-01V DNS Zones
3.1.5.1         Reverse Lookup Zone
3.1.5.2         Conditional Forwarder
3.1.6      PONCE-DC-01V DNS Zones
3.1.6.1         Reverse Lookup Zone
3.1.6.2         Conditional Forwarder
3.1.7      SERVER-DC-01V DNS Zones
3.1.7.1         Reverse Lookup Zone
3.1.7.2         Conditional Forwarder
3.2   ACAD.PHARMAX.LOCAL
3.2.1      Infrastructure Summary
3.2.1.1         Forwarder Options
3.2.2      ACADE-DC-01V DNS Zones
3.2.2.1         Reverse Lookup Zone
3.2.2.2         Conditional Forwarder

-
Microsoft Active Directory As Built Report - v1.0

DISCLAIMER

This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages-including lost profits, business interruptions, or financial losses-arising from the use of this report or its recommendations.

-
Microsoft Active Directory As Built Report - v1.0

1 PHARMAX.LOCAL

This section provides a comprehensive overview of the Active Directory infrastructure and configuration for the PHARMAX.LOCAL forest.

1.1 Forest Configuration

The following section provides a detailed summary of the Active Directory Forest infrastructure and configuration.

+
Microsoft Active Directory As Built Report - v1.0

DISCLAIMER

This report combines automated data analysis with professional observations. While these findings offer expert insight, this assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages-including lost profits, business interruptions, or financial losses-arising from the use of this report or its recommendations.

+
Microsoft Active Directory As Built Report - v1.0

Report Brief

This report brief provides a high-level summary of the Active Directory environment, including infrastructure topology, domain configuration, and the scope of this document.

+ + + + + + +
Company NameZen PR Solutions
ContactJonathan Colon
Email Addressjcolonf@zenprsolutions.com
Target ForestPHARMAX.LOCAL
Generated On2026-04-02 20:03:53
+
Table 1 - Report Overview - PHARMAX.LOCAL

+
+ + + + + + + + +
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Root Domainpharmax.local
Total Domains2
Total Sites8
Global Catalog Servers8
UPN Suffixes2
+
Table 2 - Forest Summary - PHARMAX.LOCAL

+
+ + + +
Domain NameDomain Functional LevelDomain ControllersPDC Emulator
pharmax.localWindows2016Domain7Server-DC-01V.pharmax.local
acad.pharmax.localWindows2016Domain1acade-dc-01v.acad.pharmax.local
+
Table 3 - Domain Summary - PHARMAX.LOCAL

+
+ + + + +
SectionDetail Level
ForestEnabled (Advanced Summary)
DomainEnabled (Advanced Summary)
DNSEnabled (Summary)
+
Table 4 - Report Scope - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1 PHARMAX.LOCAL Active Directory Forest

This section provides a detailed overview of the Active Directory infrastructure and configuration for the PHARMAX.LOCAL forest.

1.1 Forest Configuration

The following section provides a detailed overview of the Active Directory Forest infrastructure and configuration.

- + - - + +
Forest Namepharmax.local
Forest Functional LevelWindows2016Forest
Schema VersionObjectVersion 91, Correspond to Windows Server 2025
Tombstone Lifetime (days)180
Domainsacad.pharmax.local; pharmax.local
Global CatalogsServer-DC-01V.pharmax.local; acade-dc-01v.acad.pharmax.local; acade-dc-02v.acad.pharmax.local; Server-DC-02V.pharmax.local
Global CatalogsServer-DC-01V.pharmax.local; acade-dc-01v.acad.pharmax.local; Server-DC-02V.pharmax.local; Caguas-DC-01V.pharmax.local; Carolina-DC-01V.pharmax.local; Ponce-DC-01V.pharmax.local; Naguabo-DC-01V.pharmax.local; Cayey-Dc-01V.pharmax.local
Domains Count2
Global Catalogs Count4
Sites Count9
Global Catalogs Count8
Sites Count8
Application PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local DC=DomainDnsZones,DC=pharmax,DC=local
Partitions ContainerCN=Partitions,CN=Configuration,DC=pharmax,DC=local
SPN Suffixes--
UPN Suffixespharmax, acad
Anonymous Access (dsHeuristics)Disabled
-
Table 1 - Forest Summary - PHARMAX.LOCAL

-

1.1.1 Forest Diagram

-Forest Diagram +
Table 5 - Forest Summary - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.1 Forest Diagram

+Forest Diagram
-

1.1.2 Certificate Authority

The following section provides an overview of the Public Key Infrastructure (PKI) configuration deployed within the Active Directory environment.

Certificate Authority Root(s)

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.2 Certificate Authority

The following section provides an overview of the Public Key Infrastructure (PKI) configuration deployed within the Active Directory environment.

Certificate Authority Root(s)

NameDistinguished Name
pharmax-SERVER-DC-01V-CACN=pharmax-SERVER-DC-01V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
pharmax-SERVER-DC-02V-CACN=pharmax-SERVER-DC-02V-CA,CN=Certification Authorities,CN=Public Key Services,CN=Services,CN=Configuration,DC=pharmax,DC=local
-
Table 2 - Certificate Authority Root(s) - PHARMAX.LOCAL

-

Certificate Authority Issuer(s)

+
Table 6 - Certificate Authority Root(s) - PHARMAX.LOCAL

+

Certificate Authority Issuer(s)

NameDNS Name
acad-ACADE-DC-01V-CAacade-dc-01v.acad.pharmax.local
pharmax-CAYEY-DC-01V-CAcayey-dc-01v.pharmax.local
pharmax-SERVER-DC-01V-CAServer-DC-01V.pharmax.local
-
Table 3 - Certificate Authority Issuer(s) - PHARMAX.LOCAL

-

1.1.3 Certificate Authority Diagram

-Certificate Authority Diagram +
Table 7 - Certificate Authority Issuer(s) - PHARMAX.LOCAL

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.3 Certificate Authority Diagram

+Certificate Authority Diagram
-

1.1.4 Optional Features

+

+
Microsoft Active Directory As Built Report - v1.0

1.1.4 Optional Features

NameRequired Forest ModeEnabled
Database 32k Pages FeatureWindows2025ForestNo
Privileged Access Management FeatureWindows2016ForestNo
Recycle Bin FeatureWindows2008R2ForestYes
-
Table 4 - Optional Features - PHARMAX.LOCAL

-

1.1.5 Replication

Replication is the process by which Active Directory objects are transferred and synchronized between domain controllers within the domain and forest, ensuring consistency across the infrastructure.

The following section provides detailed information about Active Directory replication and its associated relationships.

1.1.5.1 Site Inventory Diagram

-Site Inventory Diagram +
Table 8 - Optional Features - PHARMAX.LOCAL

+

1.2 AD Sites & Replication

The following section provides an overview of the Active Directory site topology, site links, replication connections, and inter-site transport configuration.

1.2.1 Replication

Replication is the process by which Active Directory objects are transferred and synchronized between domain controllers within the domain and forest, ensuring consistency across the infrastructure.

The following section provides detailed information about Active Directory replication and its associated relationships.

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.1 Replication Diagram

+Replication Diagram
-

1.1.5.2 Sites

+

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.2 Sites

- - - - + + + + - - - - + + +
Site NameDescriptionSubnetsDomain Controllers
ACAD-- (1)172.23.4.0/24ACADE-DC-01V
ACADE-DC-02V
Caguas-- (1)No subnet assigned (2)No DC assigned (3)
Carolina-- (1)No subnet assigned (2)No DC assigned (3)
Cayey-BranchSite of Cayey, PR BranchNo subnet assigned (2)No DC assigned (3)
ACAD-- (1)172.23.4.0/24ACADE-DC-01V
Caguas-- (1)172.23.7.0/24CAGUAS-DC-01V
Carolina-- (1)172.23.9.0/24CAROLINA-DC-01V
CayeySite of Cayey, PR Branch10.10.30.0/24CAYEY-DC-01V
Dead-Site-- (1)No subnet assigned (2)No DC assigned (3)
Naguabo-- (1)No subnet assigned (2)No DC assigned (3)
Pharmax-HQSite of San Juan, PR HQ192.168.7.0/24
192.168.5.0/24
10.9.1.0/24
SERVER-DC-01V
SERVER-DC-02V
Ponce-- (1)No subnet assigned (2)No DC assigned (3)
UIA-- (1)172.23.7.0/24No DC assigned (3)
Naguabo-- (1)10.10.31.0/24NAGUABO-DC-01V
Ponce-- (1)10.10.32.0/24PONCE-DC-01V
SanJuanSite of San Juan, PR HQ192.168.5.0/24
192.168.7.0/24
SERVER-DC-01V
SERVER-DC-02V
-
Table 5 - Sites - PHARMAX.LOCAL

+
Table 9 - Sites - PHARMAX.LOCAL

Health Check:
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. -
  3. Ensure Sites have an associated subnet. If subnets are not associated with AD Sites users in the AD Sites might choose a remote domain controller for authentication which in turn might result in excessive use of a remote domain controller.
  4. +
  5. Ensure Sites have an associated subnet. If subnets are not associated with AD Sites, users might choose a remote domain controller for authentication, which could result in excessive use of remote domain controllers.
  6. It is important to ensure that each site has at least one assigned domain controller. Missing domain controllers can lead to authentication delays and potential service disruptions for users in the site.
-

Connection Objects

+

Connection Objects

- - - - - - - - -
NameFrom ServerTo ServerFrom Site
<automatically generated>ACADE-DC-01VACADE-DC-02VACAD
ACADE-DC-02VACADE-DC-02VACADE-DC-01VACAD
<automatically generated>ACADE-DC-01VSERVER-DC-01VACAD
7e2cfb0e-a793-4788-be39-79f2d83a5d5fACADE-DC-02VSERVER-DC-01VACAD
<automatically generated>ACADE-DC-01VSERVER-DC-02VACAD
<automatically generated>SERVER-DC-02VACADE-DC-01VPharmax-HQ
<automatically generated>SERVER-DC-01VACADE-DC-01VPharmax-HQ
88f6e353-7a1e-462d-9c4d-231ae30cfa6aSERVER-DC-02VSERVER-DC-01VPharmax-HQ
<automatically generated>SERVER-DC-01VSERVER-DC-02VPharmax-HQ
-
Table 6 - Connection Objects - PHARMAX.LOCAL

-
Health Check:

Best Practice: By default, the replication topology is managed automatically and optimizes existing connections. However, manual connections created by an administrator are not modified or optimized. Verify that all topology information is entered for Site Links and delete all manual connection objects.

1.1.5.3 Site Subnets

+ + + + + + + + + + + + + + + + + + + +
<automatically generated>CAGUAS-DC-01VSERVER-DC-01VCaguas
<automatically generated>CAROLINA-DC-01VSERVER-DC-01VCarolina
<automatically generated>CAYEY-DC-01VSERVER-DC-01VCayey
<automatically generated>NAGUABO-DC-01VSERVER-DC-01VNaguabo
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-02VPonce
<automatically generated>PONCE-DC-01VSERVER-DC-01VPonce
<automatically generated>SERVER-DC-01VNAGUABO-DC-01VSanJuan
<automatically generated>SERVER-DC-02VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAGUAS-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAROLINA-DC-01VSanJuan
<automatically generated>SERVER-DC-01VPONCE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VACADE-DC-01VSanJuan
<automatically generated>SERVER-DC-01VCAYEY-DC-01VSanJuan
<automatically generated>SERVER-DC-02VSERVER-DC-01VSanJuan
<automatically generated>SERVER-DC-01VSERVER-DC-02VSanJuan
<automatically generated>SERVER-DC-02VCAYEY-DC-01VSanJuan
+
Table 10 - Connection Objects - PHARMAX.LOCAL

+

1.2.1.3 Site Subnets

- - + + + - - - - + + + +
SubnetDescriptionSites
10.10.0.0/16Cayey-NetworksNo site assigned (2)
10.9.1.0/24-- (1)Pharmax-HQ
10.10.30.0/24-- (1)Cayey
10.10.31.0/24-- (1)Naguabo
10.10.32.0/24-- (1)Ponce
172.23.4.0/24-- (1)ACAD
172.23.7.0/24-- (1)UIA
192.168.5.0/24-- (1)Pharmax-HQ
192.168.7.0/24-- (1)Pharmax-HQ
25.25.25.0/24-- (1)No site assigned (2)
172.23.7.0/24-- (1)Caguas
172.23.9.0/24-- (1)Carolina
192.168.5.0/24-- (1)SanJuan
192.168.7.0/24-- (1)SanJuan
-
Table 7 - Site Subnets - PHARMAX.LOCAL

+
Table 11 - Site Subnets - PHARMAX.LOCAL

Health Check:
  1. It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.
  2. -
  3. Ensure Subnet have an associated site. If subnets are not associated with AD Sites, users in the AD Sites might choose a remote domain controller for authentication. This can lead to increased latency and potential performance issues for users authenticating against a domain controller that is not local to their site.
-

1.1.5.4 Site Topology Diagram

-Site Topology Diagram +

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.4 Site Topology Diagram

+Site Topology Diagram
-

1.1.5.5 Inter-Site Transports

Site links in Active Directory represent the inter-site connectivity and method used to transfer replication traffic. There are two transport protocols that can be used for replication via site links. The default protocol used in site link is IP, and it performs synchronous replication between available domain controllers. The SMTP method can be used when the link between sites is not reliable.

+

+
Microsoft Active Directory As Built Report - v1.0

1.2.1.5 Inter-Site Transports

Site links in Active Directory represent the inter-site connectivity and method used to transfer replication traffic. There are two transport protocols that can be used for replication via site links. The default protocol used in site link is IP, and it performs synchronous replication between available domain controllers. The SMTP method can be used when the link between sites is not reliable.

NameBridge All Site LinksIgnore Schedules
IPYesNo
SMTPYesYes
-
Table 8 - Inter-Site Transports - PHARMAX.LOCAL

-
1.1.5.5.1 IP
1.1.5.5.1.1 Site Links
+
Table 12 - Inter-Site Transports - PHARMAX.LOCAL

+
1.2.1.5.1 IP
1.2.1.5.1.1 Site Links
- + - - + + - +
Site Link NamePharmax-to-All
Site Link NamePharmax-to-Naguabo
Cost100
Replication Frequency15 min
Transport ProtocolIP
OptionsChange Notification is Disabled
SitesCaguas; Ponce; Dead-Site; Cayey-Branch; Pharmax-HQ
Options(1) Change Notification is Enabled with Compression
SitesNaguabo; SanJuan
Protected From Accidental DeletionNo
DescriptionFrom Pharmax Forest to all Domains
Description--
-
Table 9 - Site Links - Pharmax-to-All

-
Health Check:

Best Practice: Enabling change notification treats an inter-site replication connection like an intra-site connection. Replication between sites with change notification is almost instant. Microsoft recommends using an option number value of 5 (Change Notification is Enabled without Compression).

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

+
Table 13 - Site Links - Pharmax-to-Naguabo

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- + - + - - + +
Site Link NamePHARMAX-to-ACAD
Site Link NamePharmax-to-Cayey
Cost100
Replication Frequency90 min
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesACAD; Pharmax-HQ
Protected From Accidental DeletionYes
SitesCayey; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 10 - Site Links - PHARMAX-to-ACAD

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

+
Table 14 - Site Links - Pharmax-to-Cayey

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- + - - + +
Site Link NamePHARMAX-to-UIA
Site Link NamePharmax-to-Carolina
Cost100
Replication Frequency15 min
Transport ProtocolIP
OptionsChange Notification is Disabled
SitesUIA; Pharmax-HQ
Options(1) Change Notification is Enabled with Compression
SitesCarolina; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 11 - Site Links - PHARMAX-to-UIA

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: Enabling change notification treats an inter-site replication connection like an intra-site connection. Replication between sites with change notification is almost instant. Microsoft recommends using an option number value of 5 (Change Notification is Enabled without Compression).

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

1.1.5.5.1.2 Site Link Bridges
+
Table 15 - Site Links - Pharmax-to-Carolina

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- + + + - + +
Site Link Bridges NameSite-Bridge
Site Link NamePharmax-to-Caguas
Cost100
Replication Frequency15 min
Transport ProtocolIP
Site LinksPHARMAX-to-UIA; PHARMAX-to-ACAD
Options(1) Change Notification is Enabled with Compression
SitesCaguas; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 12 - Site Links Bridges - Site-Bridge

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links Bridges in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

1.1.5.5.2 SMTP
SMTP replication is used for sites that cannot use the others, but as a general rule, it should never be used. It is reserved when network connections are not always available, therefore, you can schedule replication.
1.1.5.5.2.1 Site Links
+
Table 16 - Site Links - Pharmax-to-Caguas

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- + - - - - + + + +
Site Link NamePonceTo-Carolina
Site Link NamePharmax-to-Ponce
Cost100
Replication Frequency180 min
Transport ProtocolSMTP
OptionsChange Notification is Disabled
SitesCarolina; Ponce
Replication Frequency15 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesPonce; SanJuan
Protected From Accidental DeletionNo
Description--
-
Table 13 - Site Links - PonceTo-Carolina

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: Enabling change notification treats an INTER-site replication connection like an INTRA-site connection. Replication between sites with change notification is almost instant. Microsoft recommends using an Option number value of 5 (Change Notification is Enabled without Compression).

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

+
Table 17 - Site Links - Pharmax-to-Ponce

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

- + - - - - - + + + + +
Site Link NameCaguas-To-Naguabo
Site Link NamePHARMAX-to-ACAD
Cost100
Replication Frequency180 min
Transport ProtocolSMTP
OptionsChange Notification is Disabled
SitesNaguabo; Caguas
Protected From Accidental DeletionNo
Replication Frequency90 min
Transport ProtocolIP
Options(1) Change Notification is Enabled with Compression
SitesACAD; SanJuan
Protected From Accidental DeletionYes
Description--
-
Table 14 - Site Links - Caguas-To-Naguabo

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: Enabling change notification treats an INTER-site replication connection like an INTRA-site connection. Replication between sites with change notification is almost instant. Microsoft recommends using an Option number value of 5 (Change Notification is Enabled without Compression).

Best Practice: If the Site Links in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

1.1.5.5.2.2 Site Link Bridges
+
Table 18 - Site Links - PHARMAX-to-ACAD

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

1.2.1.5.1.2 Site Link Bridges
- - - + + +
Site Link Bridges NameArea-Sur-Bridge
Transport ProtocolSMTP
Site LinksCaguas-To-Naguabo; PonceTo-Carolina
Site Link Bridges NameSite-Bridge
Transport ProtocolIP
Site LinksPHARMAX-to-ACAD
Protected From Accidental DeletionNo
Description--
-
Table 15 - Site Links Bridges - Area-Sur-Bridge

-
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Links Bridges in your Active Directory are not protected from accidental deletion, your environment can experience disruptions that might be caused by accidental bulk deletion of objects.

1.1.5.6 Sysvol Replication

+
Table 19 - Site Link Bridges - Site-Bridge

+
Health Check:

Best Practice: It is a good practice to establish well-defined descriptions. This helps to speed up the fault identification process and enables better documentation of the environment.

Best Practice: If the Site Link Bridges in your Active Directory are not protected from accidental deletion, your environment may experience disruptions caused by accidental bulk deletion of objects.

1.2.1.6 Sysvol Replication

- - -
DC NameReplication StatusDomain
Server-DC-01VIn error statepharmax.local
Server-DC-02VIn error statepharmax.local
-
Table 16 - Sysvol Replication - PHARMAX.LOCAL

-
Health Check:

Best Practice: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

1.1.6 Exchange Infrastructure

The following section provides a comprehensive overview of the Exchange infrastructure deployed in the Active Directory environment.

EX16-SERVER-01V

+ + + + + + + + +
acade-dc-01vNormalacad.pharmax.local
Server-DC-01VNormalpharmax.local
Server-DC-02VUnknownpharmax.local
Caguas-DC-01VNormalpharmax.local
Carolina-DC-01VNormalpharmax.local
Ponce-DC-01VNormalpharmax.local
Naguabo-DC-01VNormalpharmax.local
Cayey-Dc-01VNormalpharmax.local
+
Table 20 - Sysvol Replication - PHARMAX.LOCAL

+
Health Check:

Best Practice: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

1.3 Infrastructure Services

The following section provides an overview of infrastructure services registered in Active Directory, including Exchange, MECM/SCCM, and DHCP server information.

1.3.1 Exchange Infrastructure

The following section provides an overview of the Microsoft Exchange Server infrastructure registered in Active Directory, including server names, roles, and version information.

EX16-SERVER-01V

- +
NameEX16-SERVER-01V
Dns Nameex16-server-01v.pharmax.local
DNS Nameex16-server-01v.pharmax.local
Server RolesUM, CAS, MBX, HUB
VersionVersion 15.1 (Build 32507.6)
-
Table 17 - Exchange Infrastructure - EX16-SERVER-01V

-

1.1.7 SCCM Infrastructure

The following section provides a summary of the System Center Configuration Manager (SCCM) infrastructure registered in Active Directory.

SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

+
Table 21 - Exchange Infrastructure - EX16-SERVER-01V

+

1.3.2 SCCM Infrastructure

The following section provides a summary of the Microsoft Endpoint Configuration Manager (MECM/SCCM) infrastructure registered in Active Directory, including site codes, management points, and version details.

SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

NameSMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL
Management PointSCCM-PRI-01V.PHARMAX.LOCAL
Site CodePMX
Version9012
-
Table 18 - SCCM Infrastructure - SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

-

1.1.8 DHCP Infrastructure

The following section provides an overview of the DHCP servers registered in Active Directory.

+
Table 22 - SCCM Infrastructure - SMS-MP-PMX-SCCM-PRI-01V.PHARMAX.LOCAL

+

1.3.3 DHCP Infrastructure

The following section provides an overview of the DHCP servers registered in Active Directory.

- - + +
Server NameIs Domain Controller?
acad-dhcp-01v.acad.pharmax.localNo
acade-dc-01v.acad.pharmax.localNo
cayey-dc-01v.pharmax.localNo
acade-dc-01v.acad.pharmax.localYes
cayey-dc-01v.pharmax.localYes
cayey-dc-01v.pharmax.local CNF:aa5dd995-2945-449c-8538-37ee3aa289eaNo
dc-uia-01v.uia.localNo
server-dc-01v.pharmax.localYes
-
Table 19 - DHCP Infrastructure - PHARMAX.LOCAL

-

2 AD Domain Configuration

The following section provides a comprehensive overview of the Active Directory domain configuration, including critical settings and key operational details.

2.1 PHARMAX.LOCAL

This section provides a comprehensive overview of the Active Directory domain configuration, including key settings and critical details.

+
Table 23 - DHCP Infrastructure - PHARMAX.LOCAL

+

2 AD Domain Configuration

The following table provides a detailed breakdown of the Active Directory domain configuration attributes.

2.1 PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

@@ -357,7 +486,7 @@ - + @@ -370,10 +499,10 @@ - +
Domain Namepharmax
NetBIOS NamePHARMAX
Domains--
Forestpharmax.local
Parent Domain--
Replica Directory ServersServer-DC-01V.pharmax.local Server-DC-02V.pharmax.local
Replica Directory ServersServer-DC-01V.pharmax.local Server-DC-02V.pharmax.local Caguas-DC-01V.pharmax.local Carolina-DC-01V.pharmax.local Ponce-DC-01V.pharmax.local Naguabo-DC-01V.pharmax.local Cayey-Dc-01V.pharmax.local
Child Domainsacad.pharmax.local
Domain Pathpharmax.local/
Computers ContainerCN=Computers,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available352600 / 1073389223 (1% Issued)
RID Issued/Available360600 / 1073381223 (1% Issued)
-
Table 20 - Domain Summary - PHARMAX.LOCAL

-

2.1.1 FSMO Roles

+
Table 24 - Domain Summary - PHARMAX.LOCAL

+

2.1.1 FSMO Roles

@@ -381,8 +510,8 @@
Infrastructure MasterServer-DC-01V.pharmax.local
PDC Emulator NameServer-DC-01V.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
-
Table 21 - FSMO Roles - pharmax.local

-
Health Check:

Best Practice: The infrastructure master role in the domain PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.1.2 Domain and Trusts

acad.pharmax.local

+
Table 25 - FSMO Roles - pharmax.local

+
Health Check:

Best Practice: The infrastructure master role in the domain PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.1.2 Domain and Trusts

acad.pharmax.local Trust Details

@@ -396,12 +525,12 @@ - +
Nameacad.pharmax.local
Pathpharmax.local/System/acad.pharmax.local
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 22 - Trusts - acad.pharmax.local

-

lab.local

+
Table 26 - Trust - acad.pharmax.local

+

lab.local Trust Details

@@ -415,12 +544,12 @@ - +
Namelab.local
Pathpharmax.local/System/lab.local
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 23 - Trusts - lab.local

-

uia.local

+
Table 27 - Trust - lab.local

+

uia.local Trust Details

@@ -434,12 +563,12 @@ - +
Nameuia.local
Pathpharmax.local/System/uia.local
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 24 - Trusts - uia.local

-

b12.local

+
Table 28 - Trust - uia.local

+

b12.local Trust Details

@@ -453,25 +582,18 @@ - +
Nameb12.local
Pathpharmax.local/System/b12.local
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
-
Table 25 - Trusts - b12.local

-

2.1.2.1 Domain and Trusts Diagram

-Domain and Trusts Diagram +
Table 29 - Trust - b12.local

+
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

+
Microsoft Active Directory As Built Report - v1.0

2.1.2.1 Domain and Trusts Diagram

+Domain and Trusts Diagram
-

2.1.3 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

- - - - - - -
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
-
Table 26 - Active Directory Hardening - PHARMAX

-
Health Check:

Best Practice: SMBv1 status is enabled: SMBv1 is an outdated protocol that is vulnerable to several security issues. It is recommended to disable SMBv1 on all systems to enhance security and reduce the risk of exploitation. SMBv1 has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: Enforcing LDAP Channel Binding is not configured: LDAP channel binding is a security feature that helps protect against man-in-the-middle attacks by ensuring the authenticity and integrity of LDAP communications.

2.1.4 Domain Objects

The following section provides detailed information about computer, group, and user objects found in the pharmax.local domain.

2.1.4.1 User Objects

Users

-Users Object - Diagram +

+
Microsoft Active Directory As Built Report - v1.0

2.1.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.1.3.1 User Objects

Users

+User Objects - Diagram
@@ -479,37 +601,37 @@
Privileged Users8
Foreign Security Principals7
-
Table 27 - User - PHARMAX.LOCAL

-

Status of Users Accounts

-Status of Users Accounts - Diagram +
Table 30 - User - PHARMAX.LOCAL

+

Status of Users Accounts

+Status of Users Accounts - Diagram
- + - - - + + + - - - - + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users854699.85130.158559100
Total Users8559100130.158559100
Cannot Change Password130.1500130.15
Password Never Expires310.3620.02330.39
Must Change Password at Logon00120.14120.14
Password Age (> 180 days)00120.14120.14
Password Never Expires330.3920.02330.39
Must Change Password at Logon120.14120.14120.14
Password Age (> 180 days)852199.56100.12852199.56
SmartcardLogonRequired000000
SidHistory000000
Never Logged in852499.59130.15853799.74
Dormant (> 90 days)854399.81130.15855699.96
Password Not Required40.0530.0470.08
Account Expired10.0110.0110.01
Never Logged in853799.74130.15853799.74
Dormant (> 90 days)855599.95130.15855599.95
Password Not Required70.0830.0470.08
Account Expired10.010010.01
Account Lockout000000
-
Table 28 - Status of User Accounts - PHARMAX.LOCAL

-

2.1.4.2 Group Objects

Groups Categories

-Groups Categories Object - Diagram +
Table 31 - Status of Users Accounts - PHARMAX.LOCAL

+

2.1.3.2 Group Objects

Groups Categories

+Groups Categories - Diagram
Security Groups94
Distribution Groups3
-
Table 29 - Group Categories - PHARMAX.LOCAL

-

Groups Scopes

-Groups Scopes Object - Diagram +
Table 32 - Groups Categories - PHARMAX.LOCAL

+

Groups Scopes

+Groups Scopes - Diagram
@@ -517,34 +639,34 @@
Globals26
Universal25
-
Table 30 - Group Scopes - PHARMAX.LOCAL

-
2.1.4.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (4 Members)

+
Table 33 - Groups Scopes - PHARMAX.LOCAL

+
2.1.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (4 Members)

NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
jocolon (USER)12/22/2043**YesYes
scvmm-admin (USER)*9/4/2025**YesYes
veeam_admin (USER)*11/22/2025**YesYes
-
Table 31 - Domain Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Enterprise Admins (1 Members)

+
Table 34 - Domain Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Enterprise Admins (1 Members)

NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
-
Table 32 - Enterprise Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

Unless an account is doing specific tasks needing those highly elevated permissions, every account should be removed from Enterprise Admins (EA) group. A side benefit of having an empty Enterprise Admins group is that it adds just enough friction to ensure that enterprise-wide changes requiring Enterprise Admin rights are done purposefully and methodically.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

Administrators (3 Members)

+
Table 35 - Enterprise Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

Unless an account is performing specific tasks that require those highly elevated permissions, every account should be removed from the Enterprise Admins (EA) group. A side benefit of having an empty Enterprise Admins group is that it adds just enough friction to ensure that enterprise-wide changes requiring Enterprise Admin rights are done purposefully and methodically.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

Administrators (3 Members)

NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)12/10/2053**YesYes
Domain Admins (GROUP)------
svc_SCCM_ClientPush (USER)*9/14/2020**YesYes
-
Table 33 - Administrators - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Schema Admins (2 Members)

+
Table 36 - Administrators - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.

*Regularly check for and remove inactive privileged user accounts in Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts have privileged access helps maintain a secure environment.

Schema Admins (2 Members)

NameLast Logon DatePassword Never ExpiresAccount Enabled
1227935471SA (USER)--NoYes
Administrator (USER)12/10/2053**YesYes
-
Table 34 - Schema Admins - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

The Schema Admins group is a privileged group in a forest root domain. Members of the Schema Admins group can make changes to the schema, which is the framework for the Active Directory forest. Changes to the schema are not frequently required. This group only contains the Built-in Administrator account by default. Additional accounts must only be added when changes to the schema are necessary and then must be removed.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.
2.1.4.2.2 Empty Groups (Non-Default)
+
Table 37 - Schema Admins - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

The Schema Admins group is a privileged group in a forest root domain. Members of the Schema Admins group can make changes to the schema, which is the framework for the Active Directory forest. Changes to the schema are not frequently required. This group only contains the Built-in Administrator account by default. Additional accounts must only be added when changes to the schema are necessary and then must be removed.

**Accounts with passwords set to never expire were found in the environment. Ensure there are no accounts with weak security postures. Accounts with passwords that never expire can pose a significant security risk as they may not be updated regularly. It is recommended to enforce password expiration policies to enhance security.
2.1.3.2.2 Empty Groups (Non-Default)
@@ -576,34 +698,41 @@
Group NameGroup SID
ADSyncBrowseS-1-5-21-2867495315-1194516362-180967319-351274
ADSyncOperatorsS-1-5-21-2867495315-1194516362-180967319-351273
WSUS AdministratorsS-1-5-21-2867495315-1194516362-180967319-1200
WSUS ReportersS-1-5-21-2867495315-1194516362-180967319-1201
-
Table 35 - Empty Groups - PHARMAX.LOCAL

-
Health Check:

Best Practice: Remove empty or unused Active Directory Groups. An empty Active Directory security group causes two major problems. First, they add unnecessary clutter and make active directory administration difficult, even when paired with user friendly Active Directory tools. The second and most important point to note is that empty groups are a security risk to your network.
2.1.4.2.3 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member you have a circular nested reference.

Why would that matter?

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

+
Table 38 - Empty Groups - PHARMAX.LOCAL

+
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.1.3.2.3 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

Parent Group NameChild Group Name
AD - SRM Admin GroupESX Admins
ESX AdminsAD - SRM Admin Group
-
Table 36 - Circular Group Membership - PHARMAX.LOCAL

-
Health Check:

Best Practice: In a well structured Active Directory every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.

2.1.4.3 Computer Objects

Computers

-Computers Object - Diagram +
Table 39 - Circular Group Membership - PHARMAX.LOCAL

+
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.1.3.2.4 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

+ + + + +
NameDistinguished Name
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=pharmax,DC=local
SERVER-DC-01V (COMPUTER)CN=SERVER-DC-01V,OU=Domain Controllers,DC=pharmax,DC=local
SERVER-DC-02V (COMPUTER)CN=SERVER-DC-02V,OU=Domain Controllers,DC=pharmax,DC=local
+
Table 40 - Pre-Windows 2000 Compatible Access - PHARMAX.LOCAL

+
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.1.3.3 Computer Objects

Computers

+Computer Objects - Diagram
- - + +
Computers3097
Servers91
Computers3102
Servers96
-
Table 37 - Computers - PHARMAX.LOCAL

-
2.1.4.3.1 Status of Computer Accounts
-Status of Computer Accounts - Diagram +
Table 41 - Computers - PHARMAX.LOCAL

+
2.1.3.3.1 Status of Computer Accounts
+Status of Computer Accounts - Diagram
- - - + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers307699.32210.683097100
Dormant (> 90 days)306098.81210.68308199.48
Password Age (> 30 days)307199.16210.68309299.84
Total Computers308199.32210.683102100
Dormant (> 90 days)305898.58210.68307999.26
Password Age (> 30 days)307098.97210.68309199.65
SidHistory000000
-
Table 38 - Status of Computer Accounts - PHARMAX.LOCAL

-
2.1.4.3.2 Operating Systems Count
+
Table 42 - Status of Computer Accounts - PHARMAX.LOCAL

+
2.1.3.3.2 Operating Systems Count
@@ -630,13 +759,13 @@ - +
Operating SystemCount
CentOS1
Data Domain OS1
Windows Server 2019 Standard Evaluation40
Windows Server 2022 Datacenter13
Windows Server 2022 Datacenter Evaluation15
Windows Server 2025 Datacenter7
Windows Server 2025 Datacenter12
Windows Server 2025 Standard1
Windows Vista1
Windows XP1
-
Table 39 - Operating System Count - PHARMAX.LOCAL

-
Health Check:

Security Best Practice: Operating systems that are no longer supported for security updates are not maintained or updated for vulnerabilities leaving them open to potential attack. Organizations must transition to a supported operating system to ensure continued support and to increase the organization security posture.

2.1.4.4 Default Domain Password Policy

+
Table 43 - - PHARMAX.LOCAL

+
Health Check:

Security Best Practice: Operating systems that are no longer supported for security updates are not maintained or updated to address vulnerabilities, leaving them open to potential attack. Organizations must transition to a supported operating system to ensure continued support and to improve the organization's security posture.

2.1.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.1.4.1 Default Domain Password Policy

@@ -649,8 +778,8 @@
Password Must Meet Complexity RequirementsYes
Pathpharmax.local/
Enforce Password History24
Store Password using Reversible EncryptionNo
-
Table 40 - Default Domain Password Policy - PHARMAX.LOCAL

-

2.1.4.5 Fined Grained Password Policies

Administrators

+
Table 44 - Default Domain Password Policy - PHARMAX.LOCAL

+

2.1.4.2 Fined Grained Password Policies

Administrators

@@ -667,8 +796,8 @@
NameAdministrators
Domain NameDC=pharmax,DC=local
Precedence1
Applies Tohorizon-ic, dbuser, jocolon
-
Table 41 - Fined Grained Password Policies - Administrators

-

Test

+
Table 45 - Name - Administrators

+

Test

@@ -685,16 +814,16 @@
NameTest
Domain NameDC=pharmax,DC=local
Precedence1
Applies Tovmuserro
-
Table 42 - Fined Grained Password Policies - Test

-

2.1.4.6 Microsoft LAPS

+
Table 46 - Name - Test

+

2.1.4.3 Microsoft LAPS

NameLocal Administrator Password Solution
Domain NameDC=pharmax,DC=local
EnabledYes
Distinguished NameCN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=pharmax,DC=local
-
Table 43 - Microsoft LAPS - PHARMAX.LOCAL

-

2.1.4.7 gMSA Identities

SQLServer

+
Table 47 - Microsoft LAPS - PHARMAX.LOCAL

+

2.1.4.4 gMSA Identities

SQLServer

@@ -710,8 +839,8 @@
NameSQLServer
SamAccountNameSQLServer$
Password ExpiredNo
Password Last Set9/27/2020
-
Table 44 - gMSA - SQLServer

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

adfsgmsa

+
Table 48 - gMSA - SQLServer

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

adfsgmsa

@@ -727,8 +856,8 @@
Nameadfsgmsa
SamAccountNameadfsgmsa$
Password ExpiredNo
Password Last Set10/7/2020
-
Table 45 - gMSA - adfsgmsa

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined, please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ITFarm1

+
Table 49 - gMSA - adfsgmsa

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ITFarm1

@@ -744,8 +873,8 @@
NameITFarm1
SamAccountNameITFarm1$
Password ExpiredNo
Password Last Set7/13/2023
-
Table 46 - gMSA - ITFarm1

-
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined, please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

***No 'Retrieve Managed Password' has been defined, please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ADSyncMSAda440

+
Table 50 - gMSA - ITFarm1

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

ADSyncMSAda440

@@ -755,14 +884,14 @@ - + - + - +
NameADSyncMSAda440
SamAccountNameADSyncMSAda440$
Host ComputersSERVER-DC-01V
Retrieve Managed Password***--
Primary GroupDomain Computers
Last Logon Date2/19/2026
Last Logon Date4/2/2026
Locked OutNo
Logon Count340
Logon Count381
Password ExpiredNo
Password Last Set1/25/2026
Password Last Set3/28/2026
-
Table 47 - gMSA - ADSyncMSAda440

-
Health Check:

Security Best Practice:

***No 'Retrieve Managed Password' has been defined, please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.1.4.8 Foreign Security Principals

+
Table 51 - gMSA - ADSyncMSAda440

+
Health Check:

Security Best Practice:

***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.1.4.5 Foreign Security Principals

@@ -772,268 +901,1753 @@
NamePrincipal Name
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
NT AUTHORITY\Authenticated UsersCertificate Service DCOM Access
Users
Pre-Windows 2000 Compatible Access
--Backup Operators
--Backup Operators
-
Table 48 - Foreign Security Principals - PHARMAX.LOCAL

-

2.1.5 Health Checks

Naming Context Last Backup

The following section provides the last backup times for each naming context in the PHARMAX.LOCAL domain.

- - - - - - -
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30174
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30174
DC=DomainDnsZones,DC=pharmax,DC=local2025:08:30174
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30174
DC=pharmax,DC=local2025:08:30174
-
Table 49 - Naming Context Last Backup - PHARMAX.LOCAL

-

Sysvol Replication Status

This section provides the replication status of the SYSVOL folder for domain PHARMAX.LOCAL.

- - - -
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
Server-DC-01VIn error state1919Yes0
Server-DC-02VOffline0000
-
Table 50 - Sysvol Replication Status - PHARMAX.LOCAL)

-
Health Check:

Corrective Actions: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

Sysvol Content Status

The following section provides the SYSVOL health status for domain PHARMAX.LOCAL.

- - - - - - - - - - - - - - - - - - -
ExtensionFile CountSize
.aas30.09 MB
.adm40.05 MB
.adml497079.15 MB
.admx2363.98 MB
.cmd10.00 MB
.cmt10.00 MB
.cmtx80.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.inf120.01 MB
.INI200.01 MB
.msi3150.78 MB
.pol160.04 MB
.ps120.02 MB
.xml50.01 MB
.zip5143.60 MB
-
Table 51 - Sysvol Content Status - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain PHARMAX.LOCAL.

- - - - - - - - - - - - - +
Table 52 - Foreign Security Principals - PHARMAX.LOCAL

+

2.1.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

ExtensionFile CountSize
.adm10.01 MB
.adml10.03 MB
.admx10.02 MB
.cmd10.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.ini10.01 MB
.msi3150.78 MB
.ps120.02 MB
.xml10.00 MB
.zip5143.60 MB
+ + + + + + + +
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
CAGUAS-DC-01VOnlineCaguasYesNo172.23.7.1
CAROLINA-DC-01VOnlineCarolinaYesNo172.23.9.1
CAYEY-DC-01VOnlineCayeyYesNo10.10.30.1
NAGUABO-DC-01VOnlineNaguaboYesNo10.10.31.1
PONCE-DC-01VOnlinePonceYesNo10.10.32.1
SERVER-DC-01VOnlineSanJuanYesNo192.168.5.1
SERVER-DC-02VOffline--------
-
Table 52 - Netlogon Content Status - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a comprehensive summary of account security posture and potential vulnerabilities within the domain PHARMAX.LOCAL.

-User Account Security Assessment - Diagram +
Table 53 - Domain Controller in Domain - PHARMAX.LOCAL

+
+Domain Controller Object - Chart
- - - - - - - - - - -
Total8559
Enabled8546
Disabled13
Enabled Inactive1
Reversible Encryption Password1
Password Not Required7
Password Never Expires33
Kerberos DES1
Does Not Require Pre Auth0
SID History0
-
Table 53 - User Account Security Assessment - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there are no accounts with a weak security posture.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain PHARMAX.LOCAL.

- - - - - - - - - + +
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
krbtgt6/10/2018--No** Yes
Administrator6/10/201812/10/2053* Yes** Yes
jocolon11/30/202112/22/2043* Yes** Yes
veeam_admin12/13/201911/22/2025No** Yes
svc_SCCM_ClientPush9/12/20209/14/2020No** Yes
1227935471SA5/28/2023--No** Yes
GERARDO_RICE5/29/2023--No** Yes
scvmm-admin9/4/20259/4/2025No** Yes
Domain Controller7
Global Catalog7
-
Table 54 - Privileged User Assessment - PHARMAX.LOCAL

-
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

- - - - - +
Table 54 - Domain Controller Counts - PHARMAX.LOCAL

+

2.1.5.1 Configuration

2.1.5.1.1 CAGUAS-DC-01V

General Information

UsernameCreatedPassword Last SetLast Logon Date
veeam_admin12/13/201912/13/201911/22/2025
svc_SCCM_ClientPush9/12/20209/12/20209/14/2020
1227935471SA5/28/20235/28/2023--
GERARDO_RICE5/29/20235/29/2023--
+ + + + + + + + + + + +
DC NameCaguas-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCaguas
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351303
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 55 - Inactive Privileged Accounts - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain PHARMAX.LOCAL.

- - - - - - - - - - +
Table 55 - General Information - CAGUAS-DC-01V

+

Partitions

UsernameEnabledPassword Last SetLast Logon DateService Principal Name
vcenterYes12/13/201912/13/2019CIFS/ACAD-DNS-01V
svc_SCCM_ClientPushYes9/12/20209/14/2020CIFS/VEEAM-HV-01
krbtgtNo6/10/2018--CIFS/VEEAM-VBR-01V kadmin/changepw
srmrecadminYes10/25/2021--ftp/VEEAM-EM
jocolonYes11/30/202112/22/2043HTTP/example.com
horizon-icYes9/14/202510/20/2025https/GOOWLPT1000001
** GERARDO_RICEYes5/29/2023--POP3/SECWVIR1000255
** AdministratorYes6/10/201812/10/2053SCVMM/SCVMM-SVR-01V SCVMM/SCVMM-SVR-01V.pharmax.local VeeamCdpSvc/VEEAM-VBR VeeamCdpSvc/VEEAM-VBR.pharmax.local VeeamCloudConnectSvc/VEEAM-VBR VeeamCloudConnectSvc/VEEAM-VBR.pharmax.local VeeamBackupSvc/VEEAM-VBR VeeamBackupSvc/VEEAM-VBR.pharmax.local VeeamCatalogSvc/VEEAM-VBR VeeamCatalogSvc/VEEAM-VBR.pharmax.local VeeamEnterpriseManagerSvc/VEEAM-EM VeeamEnterpriseManagerSvc/VEEAM-EM.pharmax.local VeeamCatalogSvc/VEEAM-EM VeeamCatalogSvc/VEEAM-EM.pharmax.local
veeam_adminYes12/13/201911/22/2025VeeamCdpSvc/VEEAM-DRO-01V VeeamCdpSvc/VEEAM-DRO-01V.pharmax.local VeeamCloudConnectSvc/VEEAM-DRO-01V VeeamCloudConnectSvc/VEEAM-DRO-01V.pharmax.local VeeamBackupSvc/VEEAM-DRO-01V VeeamBackupSvc/VEEAM-DRO-01V.pharmax.local VeeamCatalogSvc/VEEAM-DRO-01V VeeamCatalogSvc/VEEAM-DRO-01V.pharmax.local
+ + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 56 - Service Accounts Assessment - PHARMAX.LOCAL

-
Health Check:

Security Best Practice: ** Attackers are most interested in Service Accounts that are members of highly privileged groups like Domain Admins. A quick way to check for this is to enumerate all user accounts with the attribute AdminCount equal to 1. This means an attacker may just ask Active Directory for all user accounts with an SPN and with AdminCount=1. Ensure that there are no privileged accounts that have SPNs assigned to them.

Unconstrained Kerberos Delegation

The following section identifies systems configured with unconstrained Kerberos delegation, which represents a significant security risk in the domain PHARMAX.LOCAL.

- - +
Table 56 - Partitions - CAGUAS-DC-01V

+

Networking Settings

NameDistinguished Name
HV-SERVER-01VCN=HV-SERVER-01V,OU=Member Servers,DC=pharmax,DC=local
+ + + + +
IPv4 Addresses172.23.7.1
IPv6 Addressesfe80::75c9:eaa3:559a:23de%12
LDAP Port389
LDAPS Port636
-
Table 57 - Unconstrained Kerberos Delegation - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there are no instances of unconstrained Kerberos delegation in Active Directory, as it poses a security risk by allowing any service to impersonate users.

KRBTGT Account Audit

The following section provides a comprehensive audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain PHARMAX.LOCAL.

+
Table 57 - Networking Settings - CAGUAS-DC-01V

+

Hardware Inventory

- - - - + + + + + + + + + + + + + + +
Namekrbtgt
Created06/10/2018 21:00:49
Password Last Set06/10/2018 21:00:49
Distinguished NameCN=krbtgt,CN=Users,DC=pharmax,DC=local
NameCAGUAS-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:10
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 58 - KRBTGT Account Audit - PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends changing the krbtgt account password regularly to enhance security and protect the environment.

Administrator Account Audit

The following section provides a comprehensive audit of the built-in Administrator account, which is a critical privileged account in the domain PHARMAX.LOCAL.

+
Table 58 - Hardware Inventory - CAGUAS-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.2 CAROLINA-DC-01V

General Information

- - - - - + + + + + + + + + + +
NameAdministrator
Created06/10/2018 21:00:05
Password Last Set06/10/2018 04:01:50
Last Logon Date12/10/2053 19:01:07
Distinguished NameCN=Administrator,CN=Users,DC=pharmax,DC=local
DC NameCarolina-DC-01V.pharmax.local
Domain Namepharmax.local
SiteCarolina
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351304
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 59 - Administrator Account Audit - PHARMAX.LOCAL

-
Health Check:

Best Practice: Microsoft recommends changing the Administrator account password regularly to enhance security and protect the environment.

Duplicate Objects

The following section details duplicate objects detected in the domain PHARMAX.LOCAL. These objects may indicate replication issues or administrative errors that require attention.

- - +
Table 59 - General Information - CAROLINA-DC-01V

+

Partitions

NameCreatedChangedConflict Changed
SCCM-DP-01V-Remote-Installation-Services CNF:0b206bf4-6c39-47b2-bd69-3694aa657d762020:09:132020:09:132020:09:13
+ + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 60 - Duplicate Object - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Ensure there aren't any duplicate objects in the Active Directory. Duplicate objects can cause various issues such as authentication problems, replication conflicts, and administrative overhead. It is recommended to regularly audit and clean up any duplicate objects to maintain a healthy and efficient Active Directory environment.

2.1.6 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

- - - +
Table 60 - Partitions - CAROLINA-DC-01V

+

Networking Settings

DC NameStatusSiteGlobal CatalogRead OnlyIP Address
SERVER-DC-01VOnlinePharmax-HQYesNo192.168.7.1
SERVER-DC-02VOffline--------
+ + + + +
IPv4 Addresses172.23.9.1
IPv6 Addressesfe80::586:15a2:ab35:2609%12
LDAP Port389
LDAPS Port636
-
Table 61 - Domain Controller in Domain - PHARMAX.LOCAL

-
-Domain Controller Object - Chart -
-
+
Table 61 - Networking Settings - CAROLINA-DC-01V

+

Hardware Inventory

- - + + + + + + + + + + + + + + +
Domain Controller2
Global Catalog2
NameCAROLINA-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 15:19:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 62 - Domain Controller Counts - PHARMAX.LOCAL

-

2.1.6.1 Configuration

2.1.6.1.1 SERVER-DC-01V

General Information

+
Table 62 - Hardware Inventory - CAROLINA-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.3 CAYEY-DC-01V

General Information

- + - + - - - - - - + + + + + +
DC NameServer-DC-01V.pharmax.local
DC NameCayey-Dc-01V.pharmax.local
Domain Namepharmax.local
SitePharmax-HQ
SiteCayey
Global CatalogYes
Read OnlyNo
Operation Master RolesSchemaMaster, DomainNamingMaster, PDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-1602
Operating SystemWindows Server 2025 Standard
SMB1 StatusEnabled
DescriptionPrueba
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351300
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 63 - General Information - SERVER-DC-01V

-
Health Check:

Best Practice: Disable SMBv1: SMBv1 is an outdated protocol that is vulnerable to several security issues. It is recommended to disable SMBv1 on all systems to enhance security and reduce the risk of exploitation. SMB v1 has been deprecated and replaced by SMB v2 and SMB v3, which offer improved performance and security features.

Partitions

+
Table 63 - General Information - CAYEY-DC-01V

+

Partitions

Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 64 - Partitions - SERVER-DC-01V

-

Networking Settings

+
Table 64 - Partitions - CAYEY-DC-01V

+

Networking Settings

- - + +
IPv4 Addresses192.168.7.1, 192.168.12.30, 192.168.6.29, 192.168.5.1
IPv6 Addresses--
IPv4 Addresses10.10.30.1
IPv6 Addressesfe80::74a3:277d:e262:218b%11
LDAP Port389
LDAPS Port636
-
Table 65 - Networking Settings - SERVER-DC-01V

-
Health Check:

Best Practice: On Domain Controllers with more than one NIC where each NIC is connected to separate Network, there's a possibility that the Host A DNS registration can occur for unwanted NICs. Avoid registering unwanted NICs in DNS on a multihomed domain controller.

Hardware Inventory

+
Table 65 - Networking Settings - CAYEY-DC-01V

+

Hardware Inventory

- - + + - + - + - +
NameSERVER-DC-01V
Windows Product NameWindows Server 2025 Standard
NameCAYEY-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date11/17/2025 14:04:59
Windows Installation Date03/13/2026 12:51:56
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyMY832
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors2
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
-
Table 66 - Hardware Inventory - SERVER-DC-01V

-
Health Check:

Best Practice: Microsoft recommend putting enough RAM 8GB+ to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.1.6.2 DNS IP Configuration

- - - - - - -
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
SERVER-DC-01VEthernet3192.168.5.1192.168.5.2----
SERVER-DC-01VEthernet0192.168.5.1127.0.0.1----
SERVER-DC-01VEthernet2192.168.5.1------
SERVER-DC-01VEthernet1192.168.5.1------
SERVER-DC-02V----------
-
Table 67 - DNS IP Configuration - PHARMAX.LOCAL

-
Health Check:


Best Practices: DNS configuration on the network adapter should not include the Domain Controller's own IP address as the first entry.

Best Practices: For redundancy reasons, the DNS configuration on the network adapter should include an Alternate DNS address. This ensures that if the primary DNS server becomes unavailable, the system can still resolve domain names using the alternate DNS server, maintaining network stability and connectivity.

Corrective Actions: Network interfaces must be configured with DNS servers that can resolve names in the forest root domain. The following DNS server did not respond to the query for the forest root domain PHARMAX.LOCAL: 192.168.5.2

2.1.6.3 NTDS Information

- - - -
DC NameDatabase FileDatabase SizeLog PathSysVol Path
SERVER-DC-01VC:\Windows\NTDS\ntds.dit288 MBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
SERVER-DC-02V--------
-
Table 68 - NTDS Database File Usage - PHARMAX.LOCAL

-

2.1.6.4 Time Source Information

- - - +
Table 66 - Hardware Inventory - CAYEY-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.4 NAGUABO-DC-01V

General Information

NameTime ServerType
SERVER-DC-01V192.168.5.254 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
SERVER-DC-02V----
+ + + + + + + + + + + +
DC NameNaguabo-DC-01V.pharmax.local
Domain Namepharmax.local
SiteNaguabo
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351301
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
-
Table 69 - Time Source Configuration - PHARMAX.LOCAL

-

2.1.6.5 SRV Records Status

- - - +
Table 67 - General Information - NAGUABO-DC-01V

+

Partitions

NameA RecordKDC SRVPDC SRVGC SRVDC SRV
SERVER-DC-01VOKOKOKOKOK
SERVER-DC-02V----------
+ + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
-
Table 70 - SRV Records Status - PHARMAX.LOCAL

-

2.1.6.6 File Shares

The following Domain Controllers contain non-default file shares beyond the standard administrative, NETLOGON, and SYSVOL shares:

SERVER-DC-01V

- - - - +
Table 68 - Partitions - NAGUABO-DC-01V

+

Networking Settings

NamePathDescription
UpdateServicesPackagesE:\wsus\UpdateServicesPackagesA network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
VcenterBackupF:\VcenterBackup--
WsusContentE:\wsus\WsusContentA network share to be used by Local Publishing to place published content on this WSUS system.
+ + + + +
IPv4 Addresses10.10.31.1
IPv6 Addressesfe80::efb6:c739:603c:1121%12
LDAP Port389
LDAPS Port636
-
Table 71 - File Shares - SERVER-DC-01V

-
Health Check:

Best Practice: Only netlogon, sysvol and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.1.6.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the PHARMAX.LOCAL domain.

SERVER-DC-01V

- - - +
Table 69 - Networking Settings - NAGUABO-DC-01V

+

Hardware Inventory

NamePublisherInstall Date
Dell Data Domain DDBoost SDKVeeam Software Group GmbH20251119
HPE StoreOnce Catalyst SDKVeeam Software Group GmbH20251119
+ + + + + + + + + + + + + + + + +
NameNAGUABO-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 13:50:08
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyYP6DF
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 70 - Hardware Inventory - NAGUABO-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.5 PONCE-DC-01V

General Information

+ + + + + + + + + + + + +
DC NamePonce-DC-01V.pharmax.local
Domain Namepharmax.local
SitePonce
Global CatalogYes
Read OnlyNo
Operation Master Roles--
Location--
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-351302
Operating SystemWindows Server 2025 Datacenter
SMB1 StatusDisabled
Description--
+
Table 71 - General Information - PONCE-DC-01V

+

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 72 - Partitions - PONCE-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses10.10.32.1
IPv6 Addressesfe80::de92:566e:cf5c:a051%11
LDAP Port389
LDAPS Port636
+
Table 73 - Networking Settings - PONCE-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NamePONCE-DC-01V
Windows Product NameWindows Server 2025 Datacenter
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date03/13/2026 14:26:27
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License Type--
Partial Product Key--
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 74 - Hardware Inventory - PONCE-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.
2.1.5.1.6 SERVER-DC-01V

General Information

+ + + + + + + + + + + + +
DC NameServer-DC-01V.pharmax.local
Domain Namepharmax.local
SiteSanJuan
Global CatalogYes
Read OnlyNo
Operation Master RolesSchemaMaster, DomainNamingMaster, PDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-2867495315-1194516362-180967319-1602
Operating SystemWindows Server 2025 Standard
SMB1 StatusEnabled
DescriptionPrueba
+
Table 75 - General Information - SERVER-DC-01V

+
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

+ + + +
Default PartitionDC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local
+
Table 76 - Partitions - SERVER-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses192.168.7.1, 192.168.5.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
+
Table 77 - Networking Settings - SERVER-DC-01V

+
Health Check:

Best Practice: On Domain Controllers with more than one NIC where each NIC is connected to a separate network, there is a possibility that the Host A DNS registration can occur for unwanted NICs. Avoid registering unwanted NICs in DNS on a multihomed domain controller.

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameSERVER-DC-01V
Windows Product NameWindows Server 2025 Standard
Windows Build Number10.0.26100
AD Domainpharmax.local
Windows Installation Date11/17/2025 14:04:59
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyMY832
ManufacturerVMware, Inc.
ModelVMware20,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors2
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 78 - Hardware Inventory - SERVER-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.1.5.2 DNS IP Configuration

+ + + + + + + + + +
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
CAGUAS-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
CAROLINA-DC-01VEthernet0192.168.5.1127.0.0.1----
CAYEY-DC-01VEthernet0192.168.5.1127.0.0.1----
NAGUABO-DC-01VEthernet0192.168.5.1127.0.0.1----
PONCE-DC-01VEthernet0192.168.5.1192.168.5.5127.0.0.1--
SERVER-DC-01VEthernet3192.168.5.1127.0.0.1----
SERVER-DC-01VEthernet0192.168.5.1127.0.0.1----
SERVER-DC-02V----------
+
Table 79 - DNS IP Configuration - PHARMAX.LOCAL

+
Health Check:


Best Practices: DNS configuration on the network adapter should not include the Domain Controller's own IP address as the first entry.

Corrective Actions: Network interfaces must be configured with DNS servers that can resolve names in the forest root domain. The following DNS server did not respond to the query for the forest root domain PHARMAX.LOCAL: 192.168.5.5, 192.168.5.5

2.1.5.3 NTDS Information

+ + + + + + + + +
DC NameDatabase FileDatabase SizeLog PathSysVol Path
CAGUAS-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAROLINA-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
CAYEY-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
NAGUABO-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
PONCE-DC-01VC:\WINDOWS\NTDS\ntds.dit296 MBC:\WINDOWS\NTDSC:\WINDOWS\SYSVOL\sysvol
SERVER-DC-01VC:\Windows\NTDS\ntds.dit290 MBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
SERVER-DC-02V--------
+
Table 80 - NTDS Database File Usage - PHARMAX.LOCAL

+

2.1.5.4 Time Source Information

+ + + + + + + + +
NameTime ServerType
CAGUAS-DC-01VDomain HierarchyDOMHIER
CAROLINA-DC-01VDomain HierarchyDOMHIER
CAYEY-DC-01VDomain HierarchyDOMHIER
NAGUABO-DC-01VDomain HierarchyDOMHIER
PONCE-DC-01VDomain HierarchyDOMHIER
SERVER-DC-01V192.168.5.254 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
SERVER-DC-02V----
+
Table 81 - Time Source Configuration - PHARMAX.LOCAL

+

2.1.5.5 SRV Records Status

+ + + + + + + + +
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
CAGUAS-DC-01VOKOKNon PDCOKOK
CAROLINA-DC-01VOKOKNon PDCOKOK
CAYEY-DC-01VOKOKNon PDCOKOK
NAGUABO-DC-01VOKOKNon PDCOKOK
PONCE-DC-01VOKOKNon PDCFailOK
SERVER-DC-01VOKOKOKOKOK
SERVER-DC-02V----------
+
Table 82 - SRV Records Status - PHARMAX.LOCAL

+
Health Check:

Best Practice: The SRV record is a Domain Name System (DNS) resource record. It is used to identify computers hosting specific services. SRV resource records are used to locate domain controllers for Active Directory. These records are essential for the proper functioning of Active Directory as they allow clients to locate domain controllers and other critical services within the network. Ensuring that these records are correctly configured and available is crucial for maintaining the health and accessibility of the Active Directory environment.

2.1.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

SERVER-DC-01V

+ + + + + +
NamePathDescription
UpdateServicesPackagesE:\wsus\UpdateServicesPackagesA network share to be used by client systems for collecting all software packages (usually applications) published on this WSUS system.
VcenterBackupF:\VcenterBackup--
VeeamConfBackupF:\VeeamConfBackup--
WsusContentE:\wsus\WsusContentA network share to be used by Local Publishing to place published content on this WSUS system.
+
Table 83 - File Shares - SERVER-DC-01V

+
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.1.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the PHARMAX.LOCAL domain.

SERVER-DC-01V

+ + + - - - - + + + +
NamePublisherInstall Date
Dell Data Domain DDBoost SDKVeeam Software Group GmbH20260317
HPE StoreOnce Catalyst SDKVeeam Software Group GmbH20260317
OpenSSL v3.0.0 FIPSVeeam Software Group GmbH20251119
Veeam Agent for Microsoft WindowsVeeam Software Group GmbH20251119
Veeam Backup TransportVeeam Software Group GmbH20251119
Veeam Backup VSS IntegrationVeeam Software Group GmbH20251119
Veeam Guest Interaction Proxy ServiceVeeam Software Group GmbH20251119
Veeam Agent for Microsoft WindowsVeeam Software Group GmbH20260317
Veeam Backup TransportVeeam Software Group GmbH20260326
Veeam Backup VSS IntegrationVeeam Software Group GmbH20260317
Veeam Guest Interaction Proxy ServiceVeeam Software Group GmbH20260317
Veeam Installer ServiceVeeam Software Group GmbH--
-
Table 72 - Installed Software - SERVER-DC-01V

-
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.1.6.8 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in pharmax.local.

SERVER-DC-01V

+
Table 84 - Installed Software - SERVER-DC-01V

+
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.1.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the PHARMAX.LOCAL domain.

CAROLINA-DC-01V

+ + +
KB ArticleName
KB50787402026-03 Cumulative Update for Microsoft server operating system version 24H2 for x64-based Systems (KB5078740) (26100.32522)
+
Table 85 - Missing Windows Updates - CAROLINA-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

PONCE-DC-01V

+ + +
KB ArticleName
KB50661312025-10 Cumulative Update for .NET Framework 3.5 and 4.8.1 for Microsoft server operating system version 24H2 for x64 (KB5066131)
+
Table 86 - Missing Windows Updates - PONCE-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

SERVER-DC-01V

+ + +
KB ArticleName
KBSystem.__ComObjectMicrosoft Edge-WebView2 Runtime Version 146 Update for x64 based Editions (Build 146.0.3856.97)
+
Table 87 - Missing Windows Updates - SERVER-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.1.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in pharmax.local.

CAGUAS-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 88 - Roles - CAGUAS-DC-01V

+

CAROLINA-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 89 - Roles - CAROLINA-DC-01V

+

CAYEY-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 90 - Roles - CAYEY-DC-01V

+

NAGUABO-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 91 - Roles - NAGUABO-DC-01V

+

PONCE-DC-01V

+ + + + +
NameParentDescription
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
+
Table 92 - Roles - PONCE-DC-01V

+

SERVER-DC-01V

+ + + + + + + + +
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
Windows Server Update Services (1)RoleWindows Server Update Services allows network administrators to specify the Microsoft updates that should be installed, create separate groups of computers for different sets of updates, and get reports on the compliance levels of the computers and the updates that must be installed.
+
Table 93 - Roles - SERVER-DC-01V

+
Health Check:

Best Practices:
    +
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
  2. +
+ +

2.1.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

CAGUAS-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 94 - Infrastructure Services Status - CAGUAS-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAROLINA-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 95 - Infrastructure Services Status - CAROLINA-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

CAYEY-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 96 - Infrastructure Services Status - CAYEY-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

NAGUABO-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 97 - Infrastructure Services Status - NAGUABO-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

PONCE-DC-01V

+ + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 98 - Infrastructure Services Status - PONCE-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

SERVER-DC-01V

+ + + + + + + + + + + + + + + + + +
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Kerberos Key Distribution CenterKdcRunning
NetLogonNetlogonRunning
Print SpoolerSpoolerRunning
Remote Procedure Call (RPC)RPCSSRunning
Security Accounts ManagerSAMSSRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
+
Table 99 - Infrastructure Services Status - SERVER-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.1.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.1.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: CAGUAS-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID0fc69a2f-27db-46d0-9d77-fe1e6aa11bbb
Description--
From ServerSERVER-DC-01V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
+
Table 100 - Replication Connection - CAGUAS-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: CAGUAS-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID3e145ba6-3e78-4f99-994b-8eff197b1b4e
Description--
From ServerSERVER-DC-02V
To ServerCAGUAS-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:31:02 GMT
+
Table 101 - Replication Connection - CAGUAS-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: CAROLINA-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID6c379734-f95a-4498-ad32-d001c4c29a89
Description--
From ServerSERVER-DC-01V
To ServerCAROLINA-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:13 GMT
+
Table 102 - Replication Connection - CAROLINA-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: CAYEY-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDbd8d4d25-a9f8-480d-a56a-49c9c5ac62f3
Description--
From ServerSERVER-DC-02V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
+
Table 103 - Replication Connection - CAYEY-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: CAYEY-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDec5a6456-5ced-473f-a313-8af9daefdbfb
Description--
From ServerSERVER-DC-01V
To ServerCAYEY-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 22:02:36 GMT
+
Table 104 - Replication Connection - CAYEY-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: NAGUABO-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUIDbc36599a-0876-4b1b-9ca7-4e7a5df10cc7
Description--
From ServerSERVER-DC-01V
To ServerNAGUABO-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:33 GMT
+
Table 105 - Replication Connection - NAGUABO-DC-01V

+

Site: SanJuan: From: SERVER-DC-01V To: PONCE-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID79c509ba-15f9-4204-82d1-856a4cbf222f
Description--
From ServerSERVER-DC-01V
To ServerPONCE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:20:32 GMT
+
Table 106 - Replication Connection - PONCE-DC-01V

+

Site: ACAD: From: ACADE-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteACAD
GUID6488a593-7cd5-4823-ad44-4d1439b0ac92
Description--
From ServerACADE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 03:22:52 GMT
+
Table 107 - Replication Connection - SERVER-DC-01V

+

Site: SanJuan: From: SERVER-DC-02V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteSanJuan
GUID8a3b236b-e90b-49ff-9a47-b032b6003318
Description--
From ServerSERVER-DC-02V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport Protocol--
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 05:21:56 GMT
+
Table 108 - Replication Connection - SERVER-DC-01V

+

Site: Naguabo: From: NAGUABO-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteNaguabo
GUID30240e89-7df7-4985-ad8f-ec5aac00c0a6
Description--
From ServerNAGUABO-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 109 - Replication Connection - SERVER-DC-01V

+

Site: Carolina: From: CAROLINA-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCarolina
GUID021a795d-328f-41aa-a82e-96d947a05b01
Description--
From ServerCAROLINA-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 110 - Replication Connection - SERVER-DC-01V

+

Site: Cayey: From: CAYEY-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCayey
GUIDaaf66f39-f9a6-45bc-bc7b-7c3d0ff77976
Description--
From ServerCAYEY-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 14 Mar 2026 13:17:10 GMT
+
Table 111 - Replication Connection - SERVER-DC-01V

+

Site: Caguas: From: CAGUAS-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SiteCaguas
GUIDf7d2a8e7-04bf-418e-8710-afa13de520f8
Description--
From ServerCAGUAS-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
+
Table 112 - Replication Connection - SERVER-DC-01V

+

Site: Ponce: From: PONCE-DC-01V To: SERVER-DC-01V

+ + + + + + + + + + + + +
Name<automatically generated>
From SitePonce
GUIDf311cacf-16b7-4c8f-a9f6-a93ba30f7fed
Description--
From ServerPONCE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedThu, 02 Apr 2026 14:47:50 GMT
+
Table 113 - Replication Connection - SERVER-DC-01V

+

2.1.6.2 Replication Status

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:37:54000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 20:11:56000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:51:57000
ACADE-DC-01VSERVER-DC-01VACAD2026-04-02 19:44:26000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:55000
CAGUAS-DC-01VSERVER-DC-01VCaguas2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:55000
CAROLINA-DC-01VSERVER-DC-01VCarolina2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:55000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
CAYEY-DC-01VSERVER-DC-01VCayey2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:54000
NAGUABO-DC-01VSERVER-DC-01VNaguabo2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:55000
PONCE-DC-01VSERVER-DC-01VPonce2026-04-02 20:07:54000
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:45:1812562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:4312562026-04-02 19:53:3791
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-14 13:59:2217222026-04-02 19:55:01150
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:27:1712562026-04-02 19:53:3792
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:42:0217222026-04-02 19:54:1991
SERVER-DC-02VSERVER-DC-01VSanJuan2026-03-19 21:46:1517222026-04-02 19:53:3791
+
Table 114 - Replication Status - PHARMAX

+
Health Check:

Best Practices: Replication failures can lead to object inconsistencies, stale credentials, Group Policy application failures, and authentication issues across the environment. Investigate and resolve any replication errors promptly using tools such as repadmin /showrepl or the Active Directory Replication Status Tool to prevent further divergence between domain controllers.

2.1.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.1.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the PHARMAX.LOCAL domain.

2.1.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Security Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID04e1aad5-f19b-4d0b-af25-b4ed4f52048f
Created04/26/2024
Modified11/21/2025
OwnerPHARMAX\Domain Admins
Computer Version18 (AD), 18 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 115 - GPO - Security Policy

+

Deleted GPO in Sysvol

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID09e68095-8cfc-4174-81ed-afb52597dd7f
Created06/20/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 116 - GPO - Deleted GPO in Sysvol

+
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Assign-Applications

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID2168b63b-4bd0-4627-99a8-835aea402534
Created03/10/2021
Modified04/13/2025
OwnerPHARMAX\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security Filteringjocolon
Authenticated Users
Linked Targetpharmax.local/LinuxMachines
DescriptionThis is a bad description example
+
Table 117 - GPO - Assign-Applications

+

Certificate AutoEnrollment

+ + + + + + + + + + + + +
GPO StatusUser Settings Disabled
GUID27fa05c8-7c50-4994-9f95-29c4aa3971ed
Created01/25/2020
Modified06/30/2021
OwnerPHARMAX\Domain Admins
Computer Version28 (AD), 28 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 118 - GPO - Certificate AutoEnrollment

+

Default Domain Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created06/10/2018
Modified03/07/2025
OwnerPHARMAX\Domain Admins
Computer Version114 (AD), 114 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 119 - GPO - Default Domain Policy

+

Restricted-Group

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID45497a0f-b3e2-42c0-8a43-992086110bb8
Created02/12/2025
Modified02/13/2025
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Admins PC
Description--
+
Table 120 - GPO - Restricted-Group

+

VEEAM_Disable_Firewall

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID4b2e42eb-2100-4a94-b4b0-7822e30634f6
Created12/13/2019
Modified09/08/2020
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
+
Table 121 - GPO - VEEAM_Disable_Firewall

+

SET - KMS Server

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID502c4398-dc59-49ee-b567-47656f08e09e
Created08/31/2022
Modified08/25/2024
OwnerPHARMAX\Domain Admins
Computer Version10 (AD), 10 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 122 - GPO - SET - KMS Server

+

Default Domain Controllers Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created06/10/2018
Modified11/17/2025
OwnerPHARMAX\Domain Admins
Computer Version26 (AD), 26 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Domain Controllers
Description--
+
Table 123 - GPO - Default Domain Controllers Policy

+

ProfileUnity

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID8f11a3fa-3b68-476d-99fc-32064f696ebe
Created06/08/2020
Modified10/05/2021
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/ProfileUnity VDI/Computers
Description--
+
Table 124 - GPO - ProfileUnity

+

VEEAM_Local_Administrators

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUID96cb9511-a88c-45ab-b10c-05b0441b1057
Created12/13/2019
Modified11/29/2024
OwnerPHARMAX\Domain Admins
Computer Version27 (AD), 27 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
+
Table 125 - GPO - VEEAM_Local_Administrators

+

WSUS - Domain Policy

+ + + + + + + + + + + + +
GPO StatusUser Settings Disabled
GUIDa9ec1b8c-3520-4e19-b11c-babb27c6da1a
Created02/23/2020
Modified04/15/2025
OwnerPHARMAX\Domain Admins
Computer Version30 (AD), 30 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
+
Table 126 - GPO - WSUS - Domain Policy

+

SCEP Configuration

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDd6187a9f-118c-4ee7-a18f-6889a0a657f4
Created09/14/2020
Modified10/04/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
pharmax.local/Configuration Manager Computers
Description--
+
Table 127 - GPO - SCEP Configuration

+

Dead Policy

+ + + + + + + + + + + + +
GPO StatusAll Settings Disabled
GUIDe360fece-8631-4749-b1a4-e55d0e48aa5e
Created10/05/2021
Modified06/19/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI FilterByUser
Security FilteringAuthenticated Users
Linked Target--
Description--
+
Table 128 - GPO - Dead Policy

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

No Security Filtering Applied

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDecbc276e-0e38-42f5-b6e0-6c133b08203c
Created06/18/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringNo Security Filtering
Linked Target--
Description--
+
Table 129 - GPO - No Security Filtering Applied

+
Health Check:

Corrective Actions: Identify 'No Security Filtering' Group Policy Objects (GPOs) that are not linked to any security groups or users. Determine which of these GPOs should be deleted to reduce clutter and improve manageability in Active Directory.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Horizon-DEM

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDf33e9036-4496-4323-9d5a-3011dfd8f1f7
Created03/01/2020
Modified09/15/2025
OwnerPHARMAX\Domain Admins
Computer Version24 (AD), 24 (SYSVOL)
User Version18 (AD), 18 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VDI-Computers
pharmax.local/Admin
Description--
+
Table 130 - GPO - Horizon-DEM

+

Linux-Settings-GPO

+ + + + + + + + + + + + +
GPO StatusAll Settings Disabled
GUIDf46abddd-4ae2-457d-b933-849b164fb3f8
Created05/22/2021
Modified02/04/2022
OwnerPHARMAX\Domain Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version6 (AD), 6 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/LinuxMachines
Description--
+
Table 131 - GPO - Linux-Settings-GPO

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

SCCM - Restricted Group and General Settings

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDfc8443e6-43cb-4ea4-9862-47b19813596b
Created09/12/2020
Modified09/12/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
Description--
+
Table 132 - GPO - SCCM - Restricted Group and General Settings

+

LAPS Configuration

+ + + + + + + + + + + + +
GPO StatusAll Settings Enabled
GUIDfe43b055-4f61-4fa1-b387-0fc3e2b5915e
Created11/01/2020
Modified11/01/2020
OwnerPHARMAX\Domain Admins
Computer Version15 (AD), 15 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager Computers
Description--
+
Table 133 - GPO - LAPS Configuration

+
2.1.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

+ + + + + +
NameByIP
AuthorAdministrator@pharmax.local
Query1;3;10;78;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where TotalPhysicalMemory >= 1073741824

;
DescriptionFilter by IP
+
Table 134 - WMI Filter - ByIP

+
+ + + + + +
NameByUser
AuthorAdministrator@pharmax.local
Query1;3;10;81;WQL;root\CIMv2;Select * from Win32_OperatingSystem where Version like "10.%" and ProductType="1";
DescriptionUser Filter
+
Table 135 - WMI Filter - ByUser

+

Central Store Repository

+ + +
DomainConfiguredCentral Store Path
PHARMAXYes\\pharmax.local\SYSVOL\pharmax.local\Policies\PolicyDefinitions
+
Table 136 - GPO Central Store - PHARMAX.LOCAL

+

Logon/Logoff Script

+ + + + + +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
Horizon-DEMAll Settings EnabledLogoffC:\Program Files\Immidio\Flex Profiles\FlexEngine.exe
No Security Filtering AppliedAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
ProfileUnityAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
+
Table 137 - GPO with Logon/Logoff Script - PHARMAX.LOCAL

+

Startup/Shutdown Script

+ + + + +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
No Security Filtering AppliedAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
ProfileUnityAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
+
Table 138 - GPO with Startup/Shutdown Script - PHARMAX.LOCAL

+
2.1.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

+ + + + +
GPO NameCreatedModifiedComputer EnabledUser Enabled
Dead Policy2021-10-052023-06-20NoNo
Deleted GPO in Sysvol2023-06-202023-06-20YesYes
No Security Filtering Applied2023-06-192023-06-20YesYes
+
Table 139 - Unlinked GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

+ + + +
GPO NameCreatedModifiedDescription
Deleted GPO in Sysvol2023-06-202023-06-20--
Linux-Settings-GPO2021-05-232022-02-04--
+
Table 140 - Empty GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

+ + + + + + +
GPO NameTarget
Certificate AutoEnrollmentpharmax.local/
SET - KMS Serverpharmax.local/
LAPS Configurationpharmax.local/Configuration Manager Computers
Linux-Settings-GPOpharmax.local/LinuxMachines
VEEAM_Local_Administratorspharmax.local/VEEAM Servers
+
Table 141 - Enforced GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

+ + + + + + + +
NameUnknown
GuidA8DF92D3-BDAF-479E-8C0C-9D78AAE058E4
AD DN DatabaseMissing
AD DN PathCN={A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4},CN=Policies,CN=System,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4} (Valid)
+
Table 142 - Orphaned GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

+ + + + + + + +
NameDeleted GPO in Sysvol
Guid09E68095-8CFC-4174-81ED-AFB52597DD7F
AD DN DatabaseValid
AD DN PathCN={09E68095-8CFC-4174-81ED-AFB52597DD7F},CN=Policies,CN=System,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{09E68095-8CFC-4174-81ED-AFB52597DD7F} (Missing)
+
Table 143 - Orphaned GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.1.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameLinked GPOProtected
AdminHorizon-DEMYes
Admins PCRestricted-GroupYes
Configuration ManagerSCEP Configuration, SCCM - Restricted Group and General SettingsYes
Configuration Manager ComputersLAPS Configuration, SCEP ConfigurationYes
Domain ControllersDefault Domain Controllers PolicyNo
EMC NAS servers--No
EMC NAS servers/Computers--No
LinuxMachinesAssign-Applications, Linux-Settings-GPOYes
Member Servers--Yes
Microsoft Exchange Security Groups--No
People--Yes
ProfileUnity VDIVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
ProfileUnity VDI/ComputersProfileUnityYes
ProfileUnity VDI/Servers--Yes
Tier 2--Yes
Tier 2/FIN--No
Tier 2/FIN/Devices--Yes
Tier 2/FIN/Groups--Yes
Tier 2/FIN/ServiceAccounts--Yes
Tier 2/FIN/Test--Yes
Tier 2/HRE--No
Tier 2/HRE/Devices--Yes
Tier 2/HRE/Groups--Yes
Tier 2/HRE/ServiceAccounts--Yes
Tier 2/HRE/Test--Yes
Tier 2/OGC--No
Tier 2/OGC/Devices--Yes
Tier 2/OGC/Groups--Yes
Tier 2/OGC/ServiceAccounts--Yes
Tier 2/OGC/Test--Yes
VDI-ComputersHorizon-DEMYes
VDI-Computers/Finances--Yes
VDI-Computers/HR--Yes
VDI-Computers/Marketing--Yes
VDI-Computers/Sales--Yes
VEEAM ServersVEEAM_Disable_Firewall, VEEAM_Local_AdministratorsYes
VEEAM WorkStationsVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
+
Table 144 - Organizational Unit - PHARMAX.LOCAL

+
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

+ + + + +
OU NameContainer TypeInheritance BlockedPath
adminOUYespharmax.local/Admin
linuxmachinesOUYespharmax.local/LinuxMachines
veeam workstationsOUYespharmax.local/VEEAM WorkStations
+
Table 145 - Blocked Inheritance GPO - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.1.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

+ + + + + + +
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
+
Table 146 - Active Directory Hardening - PHARMAX.LOCAL

+
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.1.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the PHARMAX.LOCAL domain.

+ + + + + + +
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=DomainDnsZones,DC=pharmax,DC=local2025:08:30215
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
DC=pharmax,DC=local2025:08:30215
+
Table 147 - Naming Context Last Backup - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain PHARMAX.LOCAL.

+ + + + + + + + +
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
Caguas-DC-01VNormal1919Yes0
Carolina-DC-01VNormal1919Yes0
Cayey-Dc-01VNormal1919Yes0
Naguabo-DC-01VNormal1919Yes0
Ponce-DC-01VNormal1919Yes0
Server-DC-01VNormal1919Yes0
Server-DC-02VOffline0000
+
Table 148 - Sysvol Replication Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains.

Sysvol Content Status

The following section provides the SYSVOL health status for domain PHARMAX.LOCAL.

+ + + + + + + + + + + + + + + + + + +
ExtensionFile CountSize
.aas30.09 MB
.adm40.05 MB
.adml497079.15 MB
.admx2363.98 MB
.cmd10.00 MB
.cmt10.00 MB
.cmtx80.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.inf120.01 MB
.INI200.01 MB
.msi3150.78 MB
.pol160.04 MB
.ps120.02 MB
.xml50.01 MB
.zip5143.60 MB
+
Table 149 - Sysvol Content Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain PHARMAX.LOCAL.

+ + + + + + + + + + + + + +
ExtensionFile CountSize
.adm10.01 MB
.adml10.03 MB
.admx10.02 MB
.cmd10.00 MB
.config70.03 MB
.dll1012.22 MB
.exe1885.80 MB
.ini10.01 MB
.msi3150.78 MB
.ps120.02 MB
.xml10.00 MB
.zip5143.60 MB
+
Table 150 - Netlogon Content Status - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain PHARMAX.LOCAL.

+User Account Security Assessment - Diagram +
+
+ + + + + + + + + + + +
Total8559
Enabled8546
Disabled13
Enabled Inactive1
Reversible Encryption Password1
Password Not Required7
Password Never Expires33
Kerberos DES1
Does Not Require Pre Auth0
SID History0
+
Table 151 - User Account Security Assessment - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain PHARMAX.LOCAL.

+ + + + + + + + + +
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
krbtgt6/10/2018--No** Yes
Administrator6/10/201812/10/2053* Yes** Yes
jocolon11/30/202112/22/2043* Yes** Yes
veeam_admin12/13/201911/22/2025No** Yes
svc_SCCM_ClientPush9/12/20209/14/2020No** Yes
1227935471SA5/28/2023--No** Yes
GERARDO_RICE5/29/2023--No** Yes
scvmm-admin9/4/20259/4/2025No** Yes
+
Table 152 - Privileged Users Assessment - PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

+ + + + + +
UsernameCreatedPassword Last SetLast Logon Date
veeam_admin12/13/201912/13/201911/22/2025
svc_SCCM_ClientPush9/12/20209/12/20209/14/2020
1227935471SA5/28/20235/28/2023--
GERARDO_RICE5/29/20235/29/2023--
+
Table 153 - Inactive Privileged Accounts - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain PHARMAX.LOCAL.

+ + + + + + + + + + +
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
vcenterYes12/13/201912/13/2019CIFS/ACAD-DNS-01V
svc_SCCM_ClientPushYes9/12/20209/14/2020CIFS/VEEAM-HV-01
krbtgtNo6/10/2018--CIFS/VEEAM-VBR-01V kadmin/changepw
srmrecadminYes10/25/2021--ftp/VEEAM-EM
jocolonYes11/30/202112/22/2043HTTP/example.com
horizon-icYes9/14/202510/20/2025https/GOOWLPT1000001
** GERARDO_RICEYes5/29/2023--POP3/SECWVIR1000255
** AdministratorYes6/10/201812/10/2053SCVMM/SCVMM-SVR-01V SCVMM/SCVMM-SVR-01V.pharmax.local VeeamCdpSvc/VEEAM-VBR VeeamCdpSvc/VEEAM-VBR.pharmax.local VeeamCloudConnectSvc/VEEAM-VBR VeeamCloudConnectSvc/VEEAM-VBR.pharmax.local VeeamBackupSvc/VEEAM-VBR VeeamBackupSvc/VEEAM-VBR.pharmax.local VeeamCatalogSvc/VEEAM-VBR VeeamCatalogSvc/VEEAM-VBR.pharmax.local VeeamEnterpriseManagerSvc/VEEAM-EM VeeamEnterpriseManagerSvc/VEEAM-EM.pharmax.local VeeamCatalogSvc/VEEAM-EM VeeamCatalogSvc/VEEAM-EM.pharmax.local
veeam_adminYes12/13/201911/22/2025VeeamCdpSvc/VEEAM-DRO-01V VeeamCdpSvc/VEEAM-DRO-01V.pharmax.local VeeamCloudConnectSvc/VEEAM-DRO-01V VeeamCloudConnectSvc/VEEAM-DRO-01V.pharmax.local VeeamBackupSvc/VEEAM-DRO-01V VeeamBackupSvc/VEEAM-DRO-01V.pharmax.local VeeamCatalogSvc/VEEAM-DRO-01V VeeamCatalogSvc/VEEAM-DRO-01V.pharmax.local
+
Table 154 - Service Accounts Assessment (Kerberoastable) - PHARMAX.LOCAL

+
Health Check:

Security Best Practice: ** Attackers are most interested in Service Accounts that are members of highly privileged groups like Domain Admins. A quick way to check for this is to enumerate all user accounts with the attribute AdminCount equal to 1. This means an attacker may just ask Active Directory for all user accounts with an SPN and with AdminCount=1. Ensure that there are no privileged accounts that have SPNs assigned to them.

Unconstrained Kerberos Delegation

The following section identifies systems configured with unconstrained Kerberos delegation, which represents a significant security risk in the domain PHARMAX.LOCAL.

+ + +
NameDistinguished Name
HV-SERVER-01VCN=HV-SERVER-01V,OU=Member Servers,DC=pharmax,DC=local
+
Table 155 - Unconstrained Kerberos Delegation - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there are no instances of unconstrained Kerberos delegation in Active Directory, as it poses a security risk by allowing any service to impersonate users.

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain PHARMAX.LOCAL.

+ + + + + +
Namekrbtgt
Created06/10/2018 21:00:49
Password Last Set06/10/2018 21:00:49
Distinguished NameCN=krbtgt,CN=Users,DC=pharmax,DC=local
+
Table 156 - KRBTGT Account Audit - PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain PHARMAX.LOCAL.

+ + + + + + +
NameAdministrator
Created06/10/2018 21:00:05
Password Last Set06/10/2018 04:01:50
Last Logon Date12/10/2053 19:01:07
Distinguished NameCN=Administrator,CN=Users,DC=pharmax,DC=local
+
Table 157 - Administrator Account Audit - PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

Duplicate Objects

The following section details duplicate objects detected in the domain PHARMAX.LOCAL. These objects may indicate replication issues or administrative errors that require attention.

+ + +
NameCreatedChangedConflict Changed
SCCM-DP-01V-Remote-Installation-Services CNF:0b206bf4-6c39-47b2-bd69-3694aa657d762020:09:132020:09:132020:09:13
+
Table 158 - Duplicate Object - PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there are no duplicate objects in Active Directory. Duplicate objects can cause various issues such as authentication problems, replication conflicts, and administrative overhead. It is recommended to regularly audit and clean up any duplicate objects to maintain a healthy and efficient Active Directory environment.

2.2 ACAD.PHARMAX.LOCAL

This section provides an overview of the Active Directory domain configuration, including key settings and operational details.

+ + + + + + + + + + + + + + + + + + + + + + +
Domain Nameacad
NetBIOS NameACAD
Domain SIDS-1-5-21-370360276-377477351-3184454278
Domain Functional LevelWindows2016Domain
Domains--
Forestpharmax.local
Parent Domainpharmax.local
Replica Directory Serversacade-dc-01v.acad.pharmax.local
Child Domains--
Domain Pathacad.pharmax.local/
Computers ContainerCN=Computers,DC=acad,DC=pharmax,DC=local
Domain Controllers ContainerOU=Domain Controllers,DC=acad,DC=pharmax,DC=local
Systems ContainerCN=System,DC=acad,DC=pharmax,DC=local
Users ContainerCN=Users,DC=acad,DC=pharmax,DC=local
Deleted Objects ContainerCN=Deleted Objects,DC=acad,DC=pharmax,DC=local
Foreign Security Principals ContainerCN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
Lost And Found ContainerCN=LostAndFound,DC=acad,DC=pharmax,DC=local
Quotas ContainerCN=NTDS Quotas,DC=acad,DC=pharmax,DC=local
ReadOnly Replica Directory Servers--
ms-DS-MachineAccountQuota10
RID Issued/Available2100 / 1073739723 (1% Issued)
+
Table 159 - Domain Summary - ACAD.PHARMAX.LOCAL

+

2.2.1 FSMO Roles

+ + + + + + +
Infrastructure Masteracade-dc-01v.acad.pharmax.local
PDC Emulator Nameacade-dc-01v.acad.pharmax.local
RID Masteracade-dc-01v.acad.pharmax.local
Domain Naming MasterServer-DC-01V.pharmax.local
Schema MasterServer-DC-01V.pharmax.local
+
Table 160 - FSMO Roles - acad.pharmax.local

+
Health Check:

Best Practice: The infrastructure master role in the domain ACAD.PHARMAX.LOCAL should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain.

Reference: http://go.microsoft.com/fwlink/?LinkId=168841

2.2.2 Domain and Trusts

pharmax.local Trust Details

+ + + + + + + + + + + + + + + + +
Namepharmax.local
Pathacad.pharmax.local/System/pharmax.local
Sourceacad
Targetpharmax.local
Trust TypeUplevel
Trust AttributesIntra-Forest Trust (trust within the forest)
Trust DirectionBidirectional (two-way trust)
Intra ForestYes
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedNo
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 161 - Trust - pharmax.local

+

lab.local Trust Details

+ + + + + + + + + + + + + + + + +
Namelab.local
Pathacad.pharmax.local/System/lab.local
Sourceacad
Targetlab.local
Trust TypeUplevel
Trust AttributesQuarantined Domain (External)
Trust DirectionBidirectional (two-way trust)
Intra ForestNo
Selective AuthenticationNo
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 162 - Trust - lab.local

+

pharam.local Trust Details

+ + + + + + + + + + + + + + + + +
Namepharam.local
Pathacad.pharmax.local/System/pharam.local
Sourceacad
Targetpharam.local
Trust TypeUplevel
Trust Attributes20
Trust DirectionOutbound (Trusted domain)
Intra ForestNo
Selective AuthenticationYes
SID Filtering Forest AwareNo
SID Filtering QuarantinedYes
TGT DelegationNo
Kerberos AES EncryptionNo
Kerberos RC4 EncryptionNo
Uplevel OnlyNo
+
Table 163 - Trust - pharam.local

+
Health Check:

Best Practice: Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718

+
Microsoft Active Directory As Built Report - v1.0

2.2.2.1 Domain and Trusts Diagram

+Domain and Trusts Diagram +
+

+
Microsoft Active Directory As Built Report - v1.0

2.2.3 Directory Objects

The following section provides an inventory and statistical overview of user, group, and computer objects within the domain.

2.2.3.1 User Objects

Users

+User Objects - Diagram +
+
+ + + + +
Users7
Privileged Users4
Foreign Security Principals4
+
Table 164 - User - ACAD.PHARMAX.LOCAL

+

Status of Users Accounts

+Status of Users Accounts - Diagram +
+
+ + + + + + + + + + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Users7100342.867100
Cannot Change Password000000
Password Never Expires228.57228.57228.57
Must Change Password at Logon114.29114.29114.29
Password Age (> 180 days)114.29114.29114.29
SmartcardLogonRequired000000
SidHistory000000
Never Logged in685.71342.86685.71
Dormant (> 90 days)685.71342.86685.71
Password Not Required457.14114.29457.14
Account Expired000000
Account Lockout000000
+
Table 165 - Status of Users Accounts - ACAD.PHARMAX.LOCAL

+

2.2.3.2 Group Objects

Groups Categories

+Groups Categories - Diagram +
+
+ + + +
Security Groups48
Distribution Groups0
+
Table 166 - Groups Categories - ACAD.PHARMAX.LOCAL

+

Groups Scopes

+Groups Scopes - Diagram +
+
+ + + + +
Domain Locals34
Globals14
Universal0
+
Table 167 - Groups Scopes - ACAD.PHARMAX.LOCAL

+
2.2.3.2.1 Privileged Groups (Built-in)
The following section provides detailed information about the user members of each privileged group. Groups without members are excluded.

Domain Admins (2 Members)

+ + + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
SCCM-GMSA (GROUP)------
+
Table 168 - Domain Admins - ACAD.PHARMAX.LOCAL

+

Key Admins (1 Members)

+ + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
SCCM-GMSA (GROUP)------
+
Table 169 - Key Admins - ACAD.PHARMAX.LOCAL

+

Backup Operators (1 Members)

+ + +
NameLast Logon DatePassword Never ExpiresAccount Enabled
Administrator (USER)3/19/2026NoYes
+
Table 170 - Backup Operators - ACAD.PHARMAX.LOCAL

+
2.2.3.2.2 Privileged Group (Non-Default)
The following section provides a summary of privileged groups with the AdminCount attribute set to 1 (excluding default groups).

+ + + +
Group NameGroup SID
PruebaS-1-5-21-370360276-377477351-3184454278-1114
SCCM-GMSAS-1-5-21-370360276-377477351-3184454278-1104
+
Table 171 - - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Regularly validate and remove unneeded privileged group members in Active Directory. Ensuring that only necessary accounts have privileged access helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation. Regular audits and reviews of group memberships can help identify and mitigate potential security risks.
2.2.3.2.3 Empty Groups (Non-Default)
+ + +
Group NameGroup SID
EmptyGrouptestS-1-5-21-370360276-377477351-3184454278-1117
+
Table 172 - Empty Groups - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Remove empty or unused Active Directory groups. An empty Active Directory security group creates two significant problems. First, it adds unnecessary clutter and makes Active Directory administration more difficult, even when paired with user-friendly Active Directory tools. More critically, empty groups represent a security risk to your network, as they can be repurposed or inadvertently granted permissions.
2.2.3.2.4 Circular Group Membership
If an Active Directory (AD) group has another AD group as both its parent and as a child member, you have a circular nested reference.

Understanding the impact of circular group membership:

There is no technical reason preventing the use of circular references between AD groups, Active Directory can still calculate and grant access. The main reason that circular references are considered harmful is that they tend to make management more difficult.

+ + + + + +
Parent Group NameChild Group Name
Key AdminsSCCM-GMSA
PruebaSCCM-GMSA
SCCM-GMSAKey Admins
SCCM-GMSAPrueba
+
Table 173 - Circular Group Membership - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: In a well-structured Active Directory, every group will have a single purpose, ideally with people and resources in separate groups and following a clear hierarchy. If the personnel group is a member of the color_printing group and the color_printing group is also a member of the personnel group, then neither group has a single clear purpose, and both groups are now granting two permissions. Circular references are often the cause of unintended privilege escalation.
2.2.3.2.5 Pre-Windows 2000 Compatible Access Group Membership
The following section provides information about the members of the Pre-Windows 2000 Compatible Access group.

+ + + +
NameDistinguished Name
ACADE-DC-01V (COMPUTER)CN=ACADE-DC-01V,OU=Domain Controllers,DC=acad,DC=pharmax,DC=local
NT AUTHORITY\Authenticated Users (FOREIGN SECURITY PRINCIPAL)CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=acad,DC=pharmax,DC=local
+
Table 174 - Pre-Windows 2000 Compatible Access - ACAD.PHARMAX.LOCAL

+
Health Check:

Security Risk: The Pre-Windows 2000 Compatible Access group provides backward compatibility with Windows NT 4.0 and earlier systems. If Authenticated Users or Anonymous Logon are members, it grants read access to all Active Directory objects to any authenticated or unauthenticated user, creating a significant security vulnerability. Review and remove any unnecessary members from this group.

2.2.3.3 Computer Objects

Computers

+Computer Objects - Diagram +
+
+ + + +
Computers5
Servers4
+
Table 175 - Computers - ACAD.PHARMAX.LOCAL

+
2.2.3.3.1 Status of Computer Accounts
+Status of Computer Accounts - Diagram +
+
+ + + + + +
CategoryEnabledEnabled %DisabledDisabled %TotalTotal %
Total Computers5100005100
Dormant (> 90 days)48000480
Password Age (> 30 days)48000480
SidHistory000000
+
Table 176 - Status of Computer Accounts - ACAD.PHARMAX.LOCAL

+
2.2.3.3.2 Operating Systems Count
+ + + + + +
Operating SystemCount
No OS Specified1
Windows Server 2019 Standard2
Windows Server 2019 Standard Evaluation1
Windows Server 2022 Datacenter Evaluation1
+
Table 177 - - ACAD.PHARMAX.LOCAL

+

2.2.4 Account Policies

The following section provides details about password policies, fine-grained password policies, LAPS configuration, group Managed Service Accounts (gMSA), and Foreign Security Principals within the domain.

2.2.4.1 Default Domain Password Policy

+ + + + + + + + + + + +
Password Must Meet Complexity RequirementsYes
Pathacad.pharmax.local/
Lockout Duration30 minutes
Lockout Threshold0
Lockout Observation Window30 minutes
Maximum Password Age42 days
Minimum Password Age01 days
Minimum Password Length7
Enforce Password History24
Store Password using Reversible EncryptionNo
+
Table 178 - Default Domain Password Policy - ACAD.PHARMAX.LOCAL

+

2.2.4.2 Fined Grained Password Policies

ACADTest

+ + + + + + + + + + + + + + + +
NameACADTest
Domain NameDC=acad,DC=pharmax,DC=local
Complexity EnabledYes
Pathacad.pharmax.local/System/Password Settings Container/ACADTest
Lockout Duration30 minutes
Lockout Threshold5
Lockout Observation Window30 minutes
Max Password Age42 days
Min Password Age01 days
Min Password Length14
Password History Count24
Reversible Encryption EnabledNo
Precedence1
Applies To--
+
Table 179 - Name - ACADTest

+

2.2.4.3 gMSA Identities

SCCMMSA

+ + + + + + + + + + + + + + +
NameSCCMMSA
SamAccountNameSCCMMSA$
Created9/11/2021
EnabledYes
DNS Host Nameacad.pharmax.local
Host Computers**--
Retrieve Managed PasswordSCCM-GMSA
Primary GroupDomain Computers
Last Logon Date*--
Locked OutNo
Logon Count0
Password ExpiredNo
Password Last Set9/11/2021
+
Table 180 - gMSA - SCCMMSA

+
Health Check:

Security Best Practice:

*Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation.

**No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory.

2.2.4.4 Foreign Security Principals

+ + + + + +
NamePrincipal Name
NT AUTHORITY\INTERACTIVEUsers
NT AUTHORITY\Authenticated UsersPre-Windows 2000 Compatible Access
Certificate Service DCOM Access
Users
NT AUTHORITY\IUSR--
NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERSWindows Authorization Access Group
+
Table 181 - Foreign Security Principals - ACAD.PHARMAX.LOCAL

+

2.2.5 Domain Controllers

The following section presents an in-depth overview of the Active Directory domain controllers, including their configuration and key details.

+ + +
DC NameStatusSiteGlobal CatalogRead OnlyIP Address
ACADE-DC-01VOnlineACADYesNo172.23.4.1
+
Table 182 - Domain Controller in Domain - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: All domains should have at least two functioning domain controllers for redundancy. In the event of a failure on the domain's only domain controller, users will not be able to log in to the domain or access domain resources. This ensures high availability and fault tolerance within the domain infrastructure.

+Domain Controller Object - Chart +
+
+ + + +
Domain Controller1
Global Catalog1
+
Table 183 - Domain Controller Counts - ACAD.PHARMAX.LOCAL

+

2.2.5.1 Configuration

2.2.5.1.1 ACADE-DC-01V

General Information

+ + + + + + + + + + + + +
DC Nameacade-dc-01v.acad.pharmax.local
Domain Nameacad.pharmax.local
SiteACAD
Global CatalogYes
Read OnlyNo
Operation Master RolesPDCEmulator, RIDMaster, InfrastructureMaster
LocationCayey, PR
Computer Object SIDS-1-5-21-370360276-377477351-3184454278-1000
Operating SystemWindows Server 2019 Standard
SMB1 StatusEnabled
DescriptionACAD PDC Server
+
Table 184 - General Information - ACADE-DC-01V

+
Health Check:

Best Practice: SMBv1 is enabled on this domain controller. SMBv1 is an outdated protocol vulnerable to critical security issues, including the EternalBlue exploit. Disable or uninstall SMBv1 on all domain controllers; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved performance and security features.

Partitions

+ + + +
Default PartitionDC=acad,DC=pharmax,DC=local
PartitionsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
+
Table 185 - Partitions - ACADE-DC-01V

+

Networking Settings

+ + + + + +
IPv4 Addresses172.23.4.1
IPv6 Addresses--
LDAP Port389
LDAPS Port636
+
Table 186 - Networking Settings - ACADE-DC-01V

+

Hardware Inventory

+ + + + + + + + + + + + + + + + +
NameACADE-DC-01V
Windows Product NameWindows Server 2019 Standard
Windows Build Number10.0.17763
AD Domainacad.pharmax.local
Windows Installation Date09/05/2021 10:35:50
Time Zone(UTC-04:00) Georgetown, La Paz, Manaus, San Juan
License TypeVolume:GVLK
Partial Product KeyJ464C
ManufacturerVMware, Inc.
ModelVMware7,1
Processor ModelIntel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Number of Processors1
Number of CPU Cores1
Number of Logical Cores1
Physical Memory4 GB
+
Table 187 - Hardware Inventory - ACADE-DC-01V

+
Health Check:

Best Practice: Microsoft recommends putting enough RAM (8GB+) to load the entire DIT into memory, plus accommodate the operating system and other installed applications, such as anti-virus, backup software, monitoring, and so on. Insufficient memory can lead to performance issues and slow response times, which can affect the overall health and efficiency of the domain controller. Ensuring adequate memory helps maintain optimal performance and reliability of the Active Directory services.

2.2.5.2 DNS IP Configuration

+ + +
DC NameInterfacePrefered DNSAlternate DNSDNS 3DNS 4
ACADE-DC-01VEthernet0192.168.5.1127.0.0.1172.23.4.1127.0.0.1
+
Table 188 - DNS IP Configuration - ACAD.PHARMAX.LOCAL

+

2.2.5.3 NTDS Information

+ + +
DC NameDatabase FileDatabase SizeLog PathSysVol Path
ACADE-DC-01VC:\Windows\NTDS\ntds.dit1 GBC:\Windows\NTDSC:\Windows\SYSVOL\sysvol
+
Table 189 - NTDS Database File Usage - ACAD.PHARMAX.LOCAL

+

2.2.5.4 Time Source Information

+ + +
NameTime ServerType
ACADE-DC-01V0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.orgMANUAL (NTP)
+
Table 190 - Time Source Configuration - ACAD.PHARMAX.LOCAL

+

2.2.5.5 SRV Records Status

+ + +
NameA RecordKDC SRVPDC SRVGC SRVDC SRV
ACADE-DC-01VOKOKOKOKOK
+
Table 191 - SRV Records Status - ACAD.PHARMAX.LOCAL

+

2.2.5.6 File Shares

The following table lists non-default file shares detected on Domain Controllers, beyond the standard administrative, NETLOGON, and SYSVOL shares.

ACADE-DC-01V

+ + +
NamePathDescription
CertEnrollC:\Windows\system32\CertSrv\CertEnrollActive Directory Certificate Services share
+
Table 192 - File Shares - ACADE-DC-01V

+
Health Check:

Best Practice: Only NETLOGON, SYSVOL, and the default administrative shares should exist on a Domain Controller. If possible, non-default file shares should be moved to another server, preferably a dedicated file server. This helps to minimize the attack surface and ensures that the Domain Controller is dedicated to its primary role of managing security and authentication within the domain. Additionally, it reduces the risk of performance degradation and potential conflicts that can arise from running multiple services on a single server.

2.2.5.7 Installed Software

This section provides an overview of third-party and non-default software installations detected on Domain Controllers within the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

+ + + +
NamePublisherInstall Date
7-Zip 22.01 (x64)Igor Pavlov--
DiskMax 7.22KoshyJohn.com06/08/2024
+
Table 193 - Installed Software - ACADE-DC-01V

+
Health Check:

Best Practices: Do not run other software or services on a Domain Controller. Running additional software or services on a Domain Controller can introduce security vulnerabilities, increase the attack surface, and potentially degrade the performance of critical domain services. It is recommended to keep Domain Controllers dedicated to their primary role of managing security and authentication within the domain. If additional services are required, consider deploying them on separate, dedicated servers.

2.2.5.8 Missing Windows Updates

The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the ACAD.PHARMAX.LOCAL domain.

ACADE-DC-01V

+ + +
KB ArticleName
KB50787522026-03 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5078752)
+
Table 194 - Missing Windows Updates - ACADE-DC-01V

+
Health Check:

Security Best Practices: It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates.

2.2.5.9 Roles

The following section provides a detailed overview of the installed roles and features on domain controllers in acad.pharmax.local.

ACADE-DC-01V

- + -
NameParentDescription
Active Directory Certificate Services (1)RoleActive Directory Certificate Services (AD CS) is used to create certification authorities and related role services that allow you to issue and manage certificates used in a variety of applications.
Active Directory Domain ServicesRoleActive Directory Domain Services (AD DS) stores information about objects on the network and makes this information available to users and network administrators. AD DS uses domain controllers to give network users access to permitted resources anywhere on the network through a single logon process.
DHCP ServerRoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DHCP Server (1)RoleDynamic Host Configuration Protocol (DHCP) Server enables you to centrally configure, manage, and provide temporary IP addresses and related information for client computers.
DNS ServerRoleDomain Name System (DNS) Server provides name resolution for TCP/IP networks. DNS Server is easier to manage when it is installed on the same server as Active Directory Domain Services. If you select the Active Directory Domain Services role, you can install and configure DNS Server and Active Directory Domain Services to work together.
File and Storage ServicesRoleFile and Storage Services includes services that are always installed, as well as functionality that you can install to help manage file servers and storage.
Web Server (IIS) (1)RoleWeb Server (IIS) provides a reliable, manageable, and scalable Web application infrastructure.
Windows Server Update Services (1)RoleWindows Server Update Services allows network administrators to specify the Microsoft updates that should be installed, create separate groups of computers for different sets of updates, and get reports on the compliance levels of the computers and the updates that must be installed.
-
Table 73 - Roles - SERVER-DC-01V

+
Table 195 - Roles - ACADE-DC-01V

Health Check:

Best Practices:
  1. Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation.
-

2.1.6.9 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

SERVER-DC-01V

+

2.2.5.10 Infrastructure Services

The following section provides a detailed overview of the status and configuration of infrastructure services on the domain controllers.

ACADE-DC-01V

- + @@ -1045,488 +2659,455 @@
Display NameShort NameStatus
Active Directory Certificate ServicesCertSvcRunning
Active Directory Domain ServicesNTDSRunning
Active Directory Web ServicesADWSRunning
COM+ Event SystemEVENTSYSTEMRunning
DFS ReplicationDFSRRunning
DHCP ServerDHCPServerRunning
DHCP ServerDHCPServerRunning
DNS ClientDNSCACHERunning
DNS ServerDNSRunning
Intersite MessagingIsmServRunning
Windows TimeW32TimeRunning
WORKSTATIONLanmanWorkstationRunning
-
Table 74 - Infrastructure Services Status - SERVER-DC-01V

-
Health Check:

Corrective Actions: The Print Spooler service has been known to have vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can help reduce the attack surface and improve the overall security posture of your Active Directory environment.

2.1.7 Replication Connection

The following section provides comprehensive details about each Active Directory replication connection object configured in the domain.

Site: ACAD: From: ACADE-DC-01V To: SERVER-DC-01V

+
Table 196 - Infrastructure Services Status - ACADE-DC-01V

+
Health Check:

Corrective Actions: The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment.

Corrective Actions: Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services.

2.2.6 Replication

The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain.

2.2.6.1 Replication Connection

The following section provides detailed information about each Active Directory replication connection object configured in the domain.

Site: SanJuan: From: SERVER-DC-01V To: ACADE-DC-01V

- - + + - - - + + + - -
Name<automatically generated>
From SiteACAD
GUID1ef3d25a-78b0-4129-8c09-aed28afc823f
From SiteSanJuan
GUIDca680ef0-acf8-4b96-a041-241cc754b87a
Description--
From ServerACADE-DC-01V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
From ServerSERVER-DC-01V
To ServerACADE-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=acad,DC=pharmax,DC=local DC=acad,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedYes
EnabledYes
CreatedSat, 21 Feb 2026 14:34:16 GMT
-
Table 75 - Replication Connection - SERVER-DC-01V

-

Site: Pharmax-HQ: From: SERVER-DC-02V To: SERVER-DC-01V

- - - - - - - - - - - - -
Name88f6e353-7a1e-462d-9c4d-231ae30cfa6a
From SitePharmax-HQ
GUID6c0646a2-6141-4485-a2f3-6dc91cc3f559
Description--
From ServerSERVER-DC-02V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport Protocol--
Auto GeneratedNo
EnabledYes
CreatedMon, 25 Aug 2025 01:00:26 GMT
-
Table 76 - Replication Connection - SERVER-DC-01V

-

Site: ACAD: From: ACADE-DC-02V To: SERVER-DC-01V

- - - - - - - - - - - - +
Name7e2cfb0e-a793-4788-be39-79f2d83a5d5f
From SiteACAD
GUID4db4a590-7da7-48af-a7b4-34ee4216d431
Description--
From ServerACADE-DC-02V
To ServerSERVER-DC-01V
Replicated Naming ContextsDC=DomainDnsZones,DC=pharmax,DC=local DC=ForestDnsZones,DC=pharmax,DC=local CN=Schema,CN=Configuration,DC=pharmax,DC=local CN=Configuration,DC=pharmax,DC=local DC=pharmax,DC=local
Transport ProtocolIP
Auto GeneratedNo
EnabledYes
CreatedFri, 23 Jan 2026 18:33:13 GMT
CreatedSat, 14 Mar 2026 04:17:40 GMT
-
Table 77 - Replication Connection - SERVER-DC-01V

-

2.1.8 Replication Status

+
Table 197 - Replication Connection - ACADE-DC-01V

+

2.2.6.2 Replication Status

- - - - - - - - - - -
From ServerTo ServerFrom SiteLast Success TimeLast Failure StatusLast Failure TimeFailures
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:21:2417222026-02-21 12:59:1675
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:20:4417222026-02-21 12:59:5975
ACADE-DC-02VSERVER-DC-01VACAD2026-02-06 22:26:3317222026-02-21 13:00:41550
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:20:4417222026-02-21 13:01:2375
ACADE-DC-02VSERVER-DC-01VACAD2026-02-06 22:26:3317222026-02-21 13:02:05549
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:21:2412562026-02-21 12:59:1674
ACADE-DC-02VSERVER-DC-01VACAD2026-02-06 22:26:3312562026-02-21 13:00:41549
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:21:2412562026-02-21 12:59:1674
SERVER-DC-02VSERVER-DC-01VPharmax-HQ2026-02-15 23:21:3712562026-02-21 12:59:1674
ACADE-DC-02VSERVER-DC-01VACAD2026-02-06 22:26:3312562026-02-21 13:00:41524
-
Table 78 - Replication Status - PHARMAX

-
Health Check:

Best Practices: Replication failure can lead to object inconsistencies and significant issues in Active Directory.

2.1.9 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the PHARMAX.LOCAL domain.

Security Policy

- - - - - - - - - - - - + + + +
GPO StatusAll Settings Enabled
GUID04e1aad5-f19b-4d0b-af25-b4ed4f52048f
Created04/26/2024
Modified11/21/2025
OwnerPHARMAX\Domain Admins
Computer Version18 (AD), 18 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:06:43000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:36:39000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 19:44:26000
SERVER-DC-01VACADE-DC-01VSanJuan2026-04-02 20:13:46000
-
Table 79 - GPO - Security Policy

-

Deleted GPO in Sysvol

+
Table 198 - Replication Status - ACAD

+

2.2.7 Group Policy

The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain.

2.2.7.1 Group Policy Objects

The following section provides an overview of the Group Policy Objects (GPOs) configured within the ACAD.PHARMAX.LOCAL domain.

2.2.7.1.1 GPO Inventory
The following section provides an overview of all Group Policy Objects configured in the domain, including their status, security filtering, and link count.

Empty Policy ACAD

- - - - + + + + - - - - -
GPO StatusAll Settings Enabled
GUID09e68095-8cfc-4174-81ed-afb52597dd7f
Created06/20/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
GUID053a8be2-fc5e-46de-8dde-4c5047ccd151
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 80 - GPO - Deleted GPO in Sysvol

-
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Assign-Applications

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID2168b63b-4bd0-4627-99a8-835aea402534
Created03/10/2021
Modified04/13/2025
OwnerPHARMAX\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security Filteringjocolon
Authenticated Users
Linked Targetpharmax.local/LinuxMachines
DescriptionThis is a bad description example
-
Table 81 - GPO - Assign-Applications

-

Certificate AutoEnrollment

- - - - - - - - - + - +
GPO StatusUser Settings Disabled
GUID27fa05c8-7c50-4994-9f95-29c4aa3971ed
Created01/25/2020
Modified06/30/2021
OwnerPHARMAX\Domain Admins
Computer Version28 (AD), 28 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
WMI FilterFilter
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
acad.pharmax.local
Description--
-
Table 82 - GPO - Certificate AutoEnrollment

-

Default Domain Policy

+
Table 199 - GPO - Empty Policy ACAD

+

Default Domain Policy

- + - - - - - - - -
GPO StatusAll Settings Enabled
GUID31b2f340-016d-11d2-945f-00c04fb984f9
Created06/10/2018
Created09/05/2021
Modified03/07/2025
OwnerPHARMAX\Domain Admins
Computer Version114 (AD), 114 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 83 - GPO - Default Domain Policy

-

Restricted-Group

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID45497a0f-b3e2-42c0-8a43-992086110bb8
Created02/12/2025
Modified02/13/2025
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Admins PC
Description--
-
Table 84 - GPO - Restricted-Group

-

VEEAM_Disable_Firewall

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID4b2e42eb-2100-4a94-b4b0-7822e30634f6
Created12/13/2019
Modified09/08/2020
OwnerPHARMAX\Domain Admins
Computer Version12 (AD), 12 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
-
Table 85 - GPO - VEEAM_Disable_Firewall

-

SET - KMS Server

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID502c4398-dc59-49ee-b567-47656f08e09e
Created08/31/2022
Modified08/25/2024
OwnerPHARMAX\Domain Admins
Computer Version10 (AD), 10 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 86 - GPO - SET - KMS Server

-

Default Domain Controllers Policy

- - - - - - - + + - +
GPO StatusAll Settings Enabled
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created06/10/2018
Modified11/17/2025
OwnerPHARMAX\Domain Admins
Computer Version26 (AD), 26 (SYSVOL)
OwnerACAD\Domain Admins
Computer Version13 (AD), 13 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Domain Controllers
Linked Targetacad.pharmax.local
Description--
-
Table 87 - GPO - Default Domain Controllers Policy

-

ProfileUnity

+
Table 200 - GPO - Default Domain Policy

+

Unlinked Policy ACAD

- - - + + + - + - - - - - -
GPO StatusAll Settings Enabled
GUID8f11a3fa-3b68-476d-99fc-32064f696ebe
Created06/08/2020
GPO StatusAll Settings Disabled
GUID40a5cbba-ed3f-460d-9de1-22d2541b7643
Created10/05/2021
Modified10/05/2021
OwnerPHARMAX\Domain Admins
OwnerPHARMAX\Enterprise Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/ProfileUnity VDI/Computers
Description--
-
Table 88 - GPO - ProfileUnity

-

VEEAM_Local_Administrators

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUID96cb9511-a88c-45ab-b10c-05b0441b1057
Created12/13/2019
Modified11/29/2024
OwnerPHARMAX\Domain Admins
Computer Version27 (AD), 27 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VEEAM Servers
pharmax.local/VEEAM WorkStations
pharmax.local/ProfileUnity VDI
Description--
-
Table 89 - GPO - VEEAM_Local_Administrators

-

WSUS - Domain Policy

- - - - - - - - - - - - -
GPO StatusUser Settings Disabled
GUIDa9ec1b8c-3520-4e19-b11c-babb27c6da1a
Created02/23/2020
Modified04/15/2025
OwnerPHARMAX\Domain Admins
Computer Version30 (AD), 30 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local
Description--
-
Table 90 - GPO - WSUS - Domain Policy

-

SCEP Configuration

- - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDd6187a9f-118c-4ee7-a18f-6889a0a657f4
Created09/14/2020
Modified10/04/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
pharmax.local/Configuration Manager Computers
Description--
-
Table 91 - GPO - SCEP Configuration

-

Dead Policy

- - - - - - - - - -
GPO StatusAll Settings Disabled
GUIDe360fece-8631-4749-b1a4-e55d0e48aa5e
Created10/05/2021
Modified06/19/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI FilterByUser
Security FilteringAuthenticated Users
Linked Target--
Description--
-
Table 92 - GPO - Dead Policy

-
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

No Security Filtering Applied

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDecbc276e-0e38-42f5-b6e0-6c133b08203c
Created06/18/2023
Modified06/20/2023
OwnerPHARMAX\Domain Admins
Computer Version1 (AD), 1 (SYSVOL)
User Version1 (AD), 1 (SYSVOL)
WMI Filter--
Security FilteringNo Security Filtering
Linked Target--
Description--
-
Table 93 - GPO - No Security Filtering Applied

-
Health Check:

Corrective Actions: Identify 'No Security Filtering' Group Policy Objects (GPOs) that are not linked to any security groups or users. Determine which of these GPOs should be deleted to reduce clutter and improve manageability in Active Directory.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Horizon-DEM

- - - - - - - - - - - - -
GPO StatusAll Settings Enabled
GUIDf33e9036-4496-4323-9d5a-3011dfd8f1f7
Created03/01/2020
Modified09/15/2025
OwnerPHARMAX\Domain Admins
Computer Version24 (AD), 24 (SYSVOL)
User Version18 (AD), 18 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/VDI-Computers
pharmax.local/Admin
Description--
-
Table 94 - GPO - Horizon-DEM

-

Linux-Settings-GPO

- - - - - - +
Table 201 - GPO - Unlinked Policy ACAD

+
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

ACAD - Deleted GPO in Sysvol

GPO StatusAll Settings Disabled
GUIDf46abddd-4ae2-457d-b933-849b164fb3f8
Created05/22/2021
Modified02/04/2022
OwnerPHARMAX\Domain Admins
+ + + + + + - + - +
GPO StatusAll Settings Enabled
GUID696c8f4b-54a9-4456-ae3f-bc52b40c5c33
Created06/21/2023
Modified06/21/2023
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version6 (AD), 6 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/LinuxMachines
Linked Target--
Description--
-
Table 95 - GPO - Linux-Settings-GPO

-
Health Check:

Best Practices: Ensure 'All Settings Disabled' Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause confusion or clutter in the environment.

SCCM - Restricted Group and General Settings

+
Table 202 - GPO - ACAD - Deleted GPO in Sysvol

+
Health Check:

Corrective Actions: Ensure unused or unlinked Group Policy Objects (GPOs) are removed from Active Directory. These GPOs do not apply any settings and can cause unnecessary complexity and potential confusion in the environment. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory structure.

Default Domain Controllers Policy

- - - - - + + + + + - +
GPO StatusAll Settings Enabled
GUIDfc8443e6-43cb-4ea4-9862-47b19813596b
Created09/12/2020
Modified09/12/2020
OwnerPHARMAX\Domain Admins
Computer Version6 (AD), 6 (SYSVOL)
GUID6ac1786c-016f-11d2-945f-00c04fb984f9
Created09/05/2021
Modified03/03/2026
OwnerACAD\Domain Admins
Computer Version8 (AD), 8 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager
Linked Targetacad.pharmax.local/Domain Controllers
Description--
-
Table 96 - GPO - SCCM - Restricted Group and General Settings

-

LAPS Configuration

+
Table 203 - GPO - Default Domain Controllers Policy

+

ACAD Certificate AutoEnrollment

- - - - - + + + + + - +
GPO StatusAll Settings Enabled
GUIDfe43b055-4f61-4fa1-b387-0fc3e2b5915e
Created11/01/2020
Modified11/01/2020
OwnerPHARMAX\Domain Admins
Computer Version15 (AD), 15 (SYSVOL)
GUIDbe6237b7-b1d4-47e3-a8e5-7f6ec1b38d57
Created09/22/2021
Modified09/22/2021
OwnerPHARMAX\Enterprise Admins
Computer Version2 (AD), 2 (SYSVOL)
User Version0 (AD), 0 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetpharmax.local/Configuration Manager Computers
Linked Targetacad.pharmax.local
Description--
-
Table 97 - GPO - LAPS Configuration

-

2.1.9.1 WMI Filters

+
Table 204 - GPO - ACAD Certificate AutoEnrollment

+

Logon Script

- - - - + + + + + + + + + + +
NameByIP
AuthorAdministrator@pharmax.local
Query1;3;10;78;WQL;root\CIMv2;Select * from WIN32_ComputerSystem where TotalPhysicalMemory >= 1073741824

;
DescriptionFilter by IP
GPO StatusAll Settings Enabled
GUIDfd32ee4c-ac02-4de5-ae91-1316f4f86bf5
Created10/07/2021
Modified10/07/2021
OwnerPHARMAX\Enterprise Admins
Computer Version0 (AD), 0 (SYSVOL)
User Version2 (AD), 2 (SYSVOL)
WMI Filter--
Security FilteringAuthenticated Users
Linked Targetacad.pharmax.local/Acad Computers/SCCM Computers
Description--
-
Table 98 - WMI Filter - ByIP

-
+
Table 205 - GPO - Logon Script

+
2.2.7.1.2 GPO Settings
The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs.

WMI Filters

- + - - + +
NameByUser
NameFilter
AuthorAdministrator@pharmax.local
Query1;3;10;81;WQL;root\CIMv2;Select * from Win32_OperatingSystem where Version like "10.%" and ProductType="1";
DescriptionUser Filter
Query1;3;13;62;WQL;root\Hardware;select * from Win32_OperatingSystem where Version like "6.%"
;
Description--
-
Table 99 - WMI Filter - ByUser

-

2.1.9.2 Central Store Repository

+
Table 206 - WMI Filter - Filter

+

Central Store Repository

- -
DomainConfiguredCentral Store Path
PHARMAXYes\\pharmax.local\SYSVOL\pharmax.local\Policies\PolicyDefinitions
-
Table 100 - GPO Central Store - PHARMAX.LOCAL

-

2.1.9.3 Logon/Logoff Script

- - - - - +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
Horizon-DEMAll Settings EnabledLogoffC:\Program Files\Immidio\Flex Profiles\FlexEngine.exe
No Security Filtering AppliedAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
ProfileUnityAll Settings EnabledLogoff%systemdrive%\Program Files\ProfileUnity\Client.NET\LwL.ProfileUnity.Client.Logoff.exe
ACADNo\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\PolicyDefinitions
-
Table 101 - GPO with Logon/Logoff Script - PHARMAX.LOCAL

-

2.1.9.4 Startup/Shutdown Script

+
Table 207 - GPO Central Store - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practices: The Group Policy Central Store is a central location to store all the Group Policy template files (ADMX/ADML files). This eliminates the need for administrators to load and open Group Policy template files on each system used to manage Group Policy. Ensure the Central Store is deployed to a centralized GPO repository to streamline management and ensure consistency across the environment.

Logon/Logoff Script

- - - +
GPO NameGPO StatusTypeScript
Dead PolicyAll Settings DisabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
No Security Filtering AppliedAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
ProfileUnityAll Settings EnabledStartup\\pharmax.local\netlogon\profileunity\LwL.ProfileUnity.Client.Startup.exe
Logon ScriptAll Settings EnabledLogon\\acad.pharmax.local\NETLOGON\enroll.exe
-
Table 102 - GPO with Startup/Shutdown Script - PHARMAX.LOCAL

-

2.1.9.5 Unlinked GPO

+
Table 208 - GPO with Logon/Logoff Script - ACAD.PHARMAX.LOCAL

+
2.2.7.1.3 GPO Health
The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs.

Unlinked GPO

- - - + +
GPO NameCreatedModifiedComputer EnabledUser Enabled
Dead Policy2021-10-052023-06-20NoNo
Deleted GPO in Sysvol2023-06-202023-06-20YesYes
No Security Filtering Applied2023-06-192023-06-20YesYes
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21YesYes
Unlinked Policy ACAD2021-10-062021-10-06NoNo
-
Table 103 - Unlinked GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

2.1.9.6 Empty GPOs

+
Table 209 - Unlinked GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Remove unused Group Policy Objects (GPOs) from Active Directory. Unused GPOs can create unnecessary complexity and potential confusion. Regularly review and clean up GPOs to maintain an organized and efficient Active Directory environment.

Empty GPOs

- - + +
GPO NameCreatedModifiedDescription
Deleted GPO in Sysvol2023-06-202023-06-20--
Linux-Settings-GPO2021-05-232022-02-04--
ACAD - Deleted GPO in Sysvol2023-06-212023-06-21--
Empty Policy ACAD2021-10-062021-10-06--
-
Table 104 - Empty GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

2.1.9.7 Enforced GPO

+
Table 210 - Empty GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: No user or computer parameters are set in this GPO. Remove unused GPOs in Active Directory to reduce clutter and improve manageability.

Enforced GPO

- - - - - + + + +
GPO NameTarget
Certificate AutoEnrollmentpharmax.local/
SET - KMS Serverpharmax.local/
LAPS Configurationpharmax.local/Configuration Manager Computers
Linux-Settings-GPOpharmax.local/LinuxMachines
VEEAM_Local_Administratorspharmax.local/VEEAM Servers
ACAD Certificate AutoEnrollmentacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/
Empty Policy ACADacad.pharmax.local/Acad Computers/SCCM Computers
Logon Scriptacad.pharmax.local/Acad Computers/SCCM Computers
-
Table 105 - Enforced GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

2.1.9.8 Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

+
Table 211 - Enforced GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforcement and blocked policy inheritance in Active Directory. Enforced policies ensure that critical settings are applied consistently across the organization, while blocked policy inheritance can prevent higher-level policies from affecting specific organizational units. Proper use of these settings is essential for maintaining a secure and well-managed environment.

Orphaned GPO

The following table summarizes Group Policy Objects (GPOs) that are orphaned or missing either in the Active Directory database or in the SYSVOL directory. Review these entries to identify and remediate inconsistencies between AD and SYSVOL.

- + - + - +
NameUnknown
GuidA8DF92D3-BDAF-479E-8C0C-9D78AAE058E4
Guid2E8D7948-6F28-4872-B97C-CA2CB971C9AE
AD DN DatabaseMissing
AD DN PathCN={A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4},CN=Policies,CN=System,DC=pharmax,DC=local (Missing)
AD DN PathCN={2E8D7948-6F28-4872-B97C-CA2CB971C9AE},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Missing)
SYSVOL Guid DirectoryValid
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{A8DF92D3-BDAF-479E-8C0C-9D78AAE058E4} (Valid)
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{2E8D7948-6F28-4872-B97C-CA2CB971C9AE} (Valid)
-
Table 106 - Orphaned GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned group policies objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

+
Table 212 - Orphaned GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy objects that exist in SYSVOL but not in AD or the Group Policy Management Console (GPMC). These take up space in SYSVOL and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

- - + + - + - +
NameDeleted GPO in Sysvol
Guid09E68095-8CFC-4174-81ED-AFB52597DD7F
NameACAD - Deleted GPO in Sysvol
Guid696C8F4B-54A9-4456-AE3F-BC52B40C5C33
AD DN DatabaseValid
AD DN PathCN={09E68095-8CFC-4174-81ED-AFB52597DD7F},CN=Policies,CN=System,DC=pharmax,DC=local (Valid)
AD DN PathCN={696C8F4B-54A9-4456-AE3F-BC52B40C5C33},CN=Policies,CN=System,DC=acad,DC=pharmax,DC=local (Valid)
SYSVOL Guid DirectoryMissing
SYSVOL Guid Path\\pharmax.local\SYSVOL\pharmax.local\Policies\{09E68095-8CFC-4174-81ED-AFB52597DD7F} (Missing)
SYSVOL Guid Path\\acad.pharmax.local\SYSVOL\acad.pharmax.local\Policies\{696C8F4B-54A9-4456-AE3F-BC52B40C5C33} (Missing)
-
Table 107 - Orphaned GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Evaluate orphaned group policies folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.1.10 Organizational Units

The following section provides a comprehensive overview of Active Directory Organizational Units within the domain.

+
Table 213 - Orphaned GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Evaluate orphaned Group Policy folders and files that exist in AD or the Group Policy Management Console (GPMC) but not in SYSVOL. These take up space in the AD database and consume bandwidth during replication. Ensure that these orphaned objects are reviewed and removed if they are no longer needed to maintain a clean and efficient Active Directory environment.

2.2.8 Organizational Units

The following section provides a detailed overview of Active Directory Organizational Units within the domain.

- - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
NameLinked GPOProtected
AdminHorizon-DEMYes
Admins PCRestricted-GroupYes
Configuration ManagerSCEP Configuration, SCCM - Restricted Group and General SettingsYes
Configuration Manager ComputersLAPS Configuration, SCEP ConfigurationYes
Acad Computers--Yes
Acad Computers/SCCM ComputersLogon Script, Empty Policy ACADYes
Domain ControllersDefault Domain Controllers PolicyNo
EMC NAS servers--No
EMC NAS servers/Computers--No
LinuxMachinesAssign-Applications, Linux-Settings-GPOYes
Member Servers--Yes
Microsoft Exchange Security Groups--No
People--Yes
ProfileUnity VDIVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
ProfileUnity VDI/ComputersProfileUnityYes
ProfileUnity VDI/Servers--Yes
Tier 2--Yes
Tier 2/FIN--No
Tier 2/FIN/Devices--Yes
Tier 2/FIN/Groups--Yes
Tier 2/FIN/ServiceAccounts--Yes
Tier 2/FIN/Test--Yes
Tier 2/HRE--No
Tier 2/HRE/Devices--Yes
Tier 2/HRE/Groups--Yes
Tier 2/HRE/ServiceAccounts--Yes
Tier 2/HRE/Test--Yes
Tier 2/OGC--No
Tier 2/OGC/Devices--Yes
Tier 2/OGC/Groups--Yes
Tier 2/OGC/ServiceAccounts--Yes
Tier 2/OGC/Test--Yes
VDI-ComputersHorizon-DEMYes
VDI-Computers/Finances--Yes
VDI-Computers/HR--Yes
VDI-Computers/Marketing--Yes
VDI-Computers/Sales--Yes
VEEAM ServersVEEAM_Disable_Firewall, VEEAM_Local_AdministratorsYes
VEEAM WorkStationsVEEAM_Local_Administrators, VEEAM_Disable_FirewallYes
Member Servers--No
-
Table 108 - Organizational Unit - PHARMAX.LOCAL

-
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

+
Table 214 - Organizational Unit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: If the Organizational Units (OUs) in your Active Directory are not protected from accidental deletion, your environment can experience disruptions caused by accidental bulk deletion of objects. All OUs in this domain should be protected from accidental deletion.

GPO Blocked Inheritance

- - - +
OU NameContainer TypeInheritance BlockedPath
adminOUYespharmax.local/Admin
linuxmachinesOUYespharmax.local/LinuxMachines
veeam workstationsOUYespharmax.local/VEEAM WorkStations
sccm computersOUYesacad.pharmax.local/Acad Computers/SCCM Computers
-
Table 109 - Blocked Inheritance GPO - PHARMAX.LOCAL

-
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

3 DNS Configuration

The following section provides a comprehensive overview of the DNS infrastructure configuration and settings within the Active Directory environment.

3.1 PHARMAX.LOCAL

The following section provides a comprehensive summary of the DNS service configuration and settings for this domain.

3.1.1 Infrastructure Summary

This section provides a comprehensive overview of the DNS infrastructure configuration for the domain.

- - +
Table 215 - Blocked Inheritance GPO - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues.

2.2.9 Active Directory Hardening

The following section provides an overview of critical Active Directory security hardening settings, including authentication protocols, SMB configurations, and LDAP security enforcement mechanisms.

DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
SERVER-DC-01V26100YesNoNo192.168.5.1
192.168.6.29
192.168.12.30
192.168.7.1
+ + + + + + +
NTLMv1 configurationSend NTLMv2 response only\refuse LM & NTLM
SMBv1 statusInstalled\Enabled
Enforcing SMB SigningEnable
Enforcing LDAP SigningRequire Signing
Enforcing LDAP Channel BindingNot Configured/Disabled
+
Table 216 - Active Directory Hardening - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: SMBv1 is enabled on this system. SMBv1 is an outdated protocol that is vulnerable to several security issues, including the EternalBlue exploit used in widespread ransomware attacks. Disable or uninstall SMBv1 on all systems; it has been deprecated and replaced by SMBv2 and SMBv3, which offer improved security features.

Best Practice: LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers.

2.2.10 Health Checks

Naming Context Last Backup

The following section provides the last backup timestamps for each Active Directory naming context (Domain, Configuration, and Schema partitions) in the ACAD.PHARMAX.LOCAL domain.

+ + + + + + +
Naming ContextLast BackupLast Backup in Days
CN=Configuration,DC=pharmax,DC=local2025:08:30215
CN=Schema,CN=Configuration,DC=pharmax,DC=local2025:08:30215
DC=acad,DC=pharmax,DC=local2021:09:051670
DC=DomainDnsZones,DC=acad,DC=pharmax,DC=local2021:09:051670
DC=ForestDnsZones,DC=pharmax,DC=local2025:08:30215
+
Table 217 - Naming Context Last Backup - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Ensure there is a recent (<180 days) Active Directory backup. Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss.

Sysvol Replication Status

The following section provides the replication status of the SYSVOL folder for domain ACAD.PHARMAX.LOCAL.

+ + +
DC NameReplication StatusGPO CountSysvol CountIdentical CountStop Replication On AutoRecovery
acade-dc-01vNormal77Yes0
+
Table 218 - Sysvol Replication Status - ACAD.PHARMAX.LOCAL

+

Sysvol Content Status

The following section provides the SYSVOL health status for domain ACAD.PHARMAX.LOCAL.

+ + + + + + + + + + +
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.cmtx10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.inf30.01 MB
.INI70.00 MB
.pol30.01 MB
.ps120.02 MB
+
Table 219 - Sysvol Content Status - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment.

Netlogon Content Status

The following section provides the Netlogon health status for domain ACAD.PHARMAX.LOCAL.

+ + + + + + +
ExtensionFile CountSize
.cab122,866.91 MB
.cmd10.00 MB
.esd13,193.66 MB
.exe1191,117.91 MB
.ps120.02 MB
+
Table 220 - Netlogon Content Status - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment.

User Account Security Assessment

The following section provides a detailed summary of account security posture and potential vulnerabilities within the domain ACAD.PHARMAX.LOCAL.

+User Account Security Assessment - Diagram +
+
+ + + + + + + + + + + +
Total7
Enabled4
Disabled3
Enabled Inactive1
Reversible Encryption Password0
Password Not Required4
Password Never Expires2
Kerberos DES0
Does Not Require Pre Auth0
SID History0
+
Table 221 - User Account Security Assessment - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Review and remediate accounts flagged with a weak security configuration. Problematic settings include passwords that never expire, reversible password encryption enabled, Kerberos pre-authentication disabled, Kerberos DES encryption in use, and the presence of SID history. These settings can significantly increase the risk of unauthorized access or privilege escalation.

Privileged Users Assessment

The following section provides a detailed assessment of privileged administrative accounts (user accounts with AdminCount attribute set to 1) within the domain ACAD.PHARMAX.LOCAL.

+ + + + + +
UsernamePassword Last SetLast Logon DateEmail Enabled?Trusted for Delegation
grouptest7/21/2023--* YesNo
Administrator3/19/20263/19/2026No** Yes
Guest----No** Yes
krbtgt9/5/2021--No** Yes
+
Table 222 - Privileged Users Assessment - ACAD.PHARMAX.LOCAL

+
Health Check:

Security Best Practice:

* Privileged accounts such as those belonging to any of the Administrators groups must not have configured email.

** Privileged accounts such as those belonging to any of the administrator groups must not be trusted for delegation. Allowing privileged accounts to be trusted for delegation provides a means for privilege escalation from a compromised system. Delegation of privileged accounts must be prohibited. Reference: https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435

Inactive Privileged Accounts

The following section identifies privileged accounts in domain ACAD.PHARMAX.LOCAL that have remained inactive for over 30 days and have not had their passwords changed in at least 365 days.

+ + + +
UsernameCreatedPassword Last SetLast Logon Date
grouptest7/21/20237/21/2023--
Guest9/5/2021----
+
Table 223 - Inactive Privileged Accounts - ACAD.PHARMAX.LOCAL

+
Health Check:

Corrective Actions: Unused or underutilized accounts in highly privileged groups, outside of any break-glass emergency accounts like the default Administrator account, should have their AD Admin privileges removed.

Service Accounts Assessment (Kerberoastable)

The following section provides an overview of service accounts (user accounts with Service Principal Names) that are potentially vulnerable to Kerberoasting attacks in domain ACAD.PHARMAX.LOCAL.

+ + +
UsernameEnabledPassword Last SetLast Logon DateService Principal Name
krbtgtNo9/5/2021--kadmin/changepw
+
Table 224 - Service Accounts Assessment (Kerberoastable) - ACAD.PHARMAX.LOCAL

+
Health Check:

KRBTGT Account Audit

The following section provides a detailed audit of the KRBTGT account, which is critical for Kerberos ticket-granting services in the domain ACAD.PHARMAX.LOCAL.

+ + + + + +
Namekrbtgt
Created09/05/2021 12:25:21
Password Last Set09/05/2021 12:25:21
Distinguished NameCN=krbtgt,CN=Users,DC=acad,DC=pharmax,DC=local
+
Table 225 - KRBTGT Account Audit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends resetting the KRBTGT account password at least twice per year (approximately every 180 days) to reduce the risk of Kerberos ticket forgery attacks, such as Golden Ticket attacks. Note that a second reset is required after the maximum domain replication cycle has completed to fully invalidate previously issued tickets.

Administrator Account Audit

The following section provides a detailed audit of the built-in Administrator account, which is a critical privileged account in the domain ACAD.PHARMAX.LOCAL.

+ + + + + +
NameAdministrator
Created09/05/2021 12:24:39
Password Last Set03/19/2026 21:42:01
Last Logon Date03/19/2026 21:42:01
Distinguished NameCN=Administrator,CN=Users,DC=acad,DC=pharmax,DC=local
-
Table 110 - Infrastructure Summary - PHARMAX.LOCAL

-

3.1.1.1 Forwarder Options

+
Table 226 - Administrator Account Audit - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practice: Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account.

3 DNS Configuration

The following section provides a detailed overview of the DNS infrastructure configuration and settings within the Active Directory environment.

3.1 PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.1.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

+ + + + + + + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
CAGUAS-DC-01V26100YesYesNofe80::75c9:eaa3:559a:23de
172.23.7.1
CAROLINA-DC-01V26100YesYesNo172.23.9.1
CAYEY-DC-01V26100YesYesNofe80::74a3:277d:e262:218b
10.10.30.1
NAGUABO-DC-01V26100YesYesNofe80::efb6:c739:603c:1121
10.10.31.1
PONCE-DC-01V26100YesYesNofe80::de92:566e:cf5c:a051
10.10.32.1
SERVER-DC-01V26100YesNoNo192.168.5.1
192.168.7.1
+
Table 227 - Infrastructure Summary - PHARMAX.LOCAL

+

3.1.1.1 Forwarder Options

+ + + + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
CAGUAS-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
CAROLINA-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
CAYEY-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
NAGUABO-DC-01V192.168.5.1
192.168.5.5
3/sYesYes
PONCE-DC-01V10.0.0.138
1.1.1.1
8.8.8.8
2.2.2.2
3/sYesYes
SERVER-DC-01V10.0.0.138
8.8.8.8
1.1.1.1
3/sYesYes
-
Table 111 - Forwarders - PHARMAX.LOCAL

-
Health Check:

Best Practices: Configure the servers to use no more than two external DNS servers as Forwarders. Using more than two forwarders can lead to increased resolution times and potential issues with DNS query load balancing. It is recommended to use two reliable and geographically diverse DNS servers to ensure redundancy and optimal performance.

Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/forwarders-resolution-timeouts

3.1.2 SERVER-DC-01V DNS Zones

+
Table 228 - Forwarders - PHARMAX.LOCAL

+
Health Check:

Best Practices: Configure the servers to use no more than two external DNS servers as Forwarders. Using more than two forwarders can lead to increased resolution times and potential issues with DNS query load balancing. It is recommended to use two reliable and geographically diverse DNS servers to ensure redundancy and optimal performance.

Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/forwarders-resolution-timeouts

3.1.2 CAGUAS-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 229 - Zones - PHARMAX.LOCAL

+

3.1.2.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 230 - Zones - PHARMAX.LOCAL

+

3.1.2.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 231 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.3 CAROLINA-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 232 - Zones - PHARMAX.LOCAL

+

3.1.3.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 233 - Zones - PHARMAX.LOCAL

+

3.1.3.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 234 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.4 CAYEY-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 235 - Zones - PHARMAX.LOCAL

+

3.1.4.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 236 - Zones - PHARMAX.LOCAL

+

3.1.4.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 237 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.5 NAGUABO-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 238 - Zones - PHARMAX.LOCAL

+

3.1.5.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 239 - Zones - PHARMAX.LOCAL

+

3.1.5.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 240 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.6 PONCE-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
+
Table 241 - Zones - PHARMAX.LOCAL

+

3.1.6.1 Reverse Lookup Zone

+ + + + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
168.192.in-addr.arpaPrimaryDomainSecureYesNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 242 - Zones - PHARMAX.LOCAL

+

3.1.6.2 Conditional Forwarder

+ + + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
pharam.localForwarderLegacy192.168.7.42Yes
zenprsolutions.govForwarderDomain8.8.8.8Yes
+
Table 243 - Conditional Forwarders - PHARMAX.LOCAL

+

3.1.7 SERVER-DC-01V DNS Zones

@@ -1535,8 +3116,8 @@
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localSecondary----NoNo--
TrustAnchorsPrimaryForestNoneYesNoNo
zenprsolutions.localStubDomain--YesNo--
-
Table 112 - Zones - PHARMAX.LOCAL

-

3.1.2.1 Reverse Lookup Zone

+
Table 244 - Zones - PHARMAX.LOCAL

+

3.1.7.1 Reverse Lookup Zone

@@ -1546,8 +3127,8 @@
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
10.10.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
-
Table 113 - Zones - PHARMAX.LOCAL

-

3.1.2.2 Conditional Forwarder

+
Table 245 - Zones - PHARMAX.LOCAL

+

3.1.7.2 Conditional Forwarder

@@ -1558,6 +3139,39 @@
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
lab.localForwarderNone10.10.30.10No
winterfell.sevenkingdoms.localForwarderNone192.168.56.11No
zenprsolutions.govForwarderDomain8.8.8.8Yes
-
Table 114 - Conditional Forwarders - PHARMAX.LOCAL

+
Table 246 - Conditional Forwarders - PHARMAX.LOCAL

+

3.2 ACAD.PHARMAX.LOCAL

The following section provides a detailed overview of the DNS service configuration and settings for this domain.

3.2.1 Infrastructure Summary

The following section provides a detailed overview of the DNS infrastructure configuration for the domain.

+ + +
DC NameBuild NumberIPv6DnsSecReadOnly DCListening IP
ACADE-DC-01V17763YesNoNo172.23.4.1
+
Table 247 - Infrastructure Summary - ACAD.PHARMAX.LOCAL

+

3.2.1.1 Forwarder Options

+ + +
DC NameIP AddressTimeoutUse Root HintUse Recursion
ACADE-DC-01V192.168.5.13/sYesYes
+
Table 248 - Forwarders - ACAD.PHARMAX.LOCAL

+
Health Check:

Best Practices: For redundancy reasons, more than one forwarding server should be configured.

3.2.2 ACADE-DC-01V DNS Zones

+ + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
_msdcs.pharmax.localPrimaryForestSecureYesNoNo
acad.pharmax.localPrimaryDomainSecureYesNoNo
TrustAnchorsPrimaryForestNoneYesNoNo
zenpr.localSecondary----NoNo--
+
Table 249 - Zones - ACAD.PHARMAX.LOCAL

+

3.2.2.1 Reverse Lookup Zone

+ + + + + + +
Zone NameZone TypeReplication ScopeDynamic UpdateDS IntegratedRead OnlySigned
0.in-addr.arpaPrimaryNoneNoneNoNoNo
127.in-addr.arpaPrimaryNoneNoneNoNoNo
23.172.in-addr.arpaPrimaryDomainSecureYesNoNo
255.in-addr.arpaPrimaryNoneNoneNoNoNo
70.23.172.in-addr.arpaPrimaryForestSecureYesNoNo
+
Table 250 - Zones - ACAD.PHARMAX.LOCAL

+

3.2.2.2 Conditional Forwarder

+ + + +
Zone NameZone TypeReplication ScopeMaster ServersDS Integrated
b12.localForwarderForest10.10.30.1Yes
zenprsolutions.localForwarderNone8.8.8.8No
+
Table 251 - Conditional Forwarders - ACAD.PHARMAX.LOCAL

-

+

From 5fcc7763ba9af8dd628d944a09acade97627e0a6 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sun, 5 Apr 2026 13:18:04 -0400 Subject: [PATCH 05/18] Refactor error handling messages in various report scripts to utilize translation functions for improved localization and clarity. Updated messages in Get-AbrADInfrastructureService.ps1, Get-AbrADKerberosAudit.ps1, Get-AbrADOU.ps1, Get-AbrADReportBrief.ps1, Get-AbrADSCCM.ps1, Get-AbrADSecurityAssessment.ps1, Get-AbrADSite.ps1, Get-AbrADSiteReplication.ps1, Get-AbrADTrust.ps1, Get-AbrDHCPinAD.ps1, Get-AbrDNSSection.ps1, Get-AbrDomainSection.ps1, and Invoke-DcDiag.ps1. --- .../Language/en-US/MicrosoftAD.psd1 | 279 +++++++++++++- .../Language/es-ES/MicrosoftAD.psd1 | 347 ++++++++++++++++-- .../Src/Private/Diagram/Get-AbrDiagrammer.ps1 | 8 +- .../Private/Report/Get-ADExchangeServer.ps1 | 2 +- .../Report/Get-AbrADAuthenticationPolicy.ps1 | 30 +- .../Src/Private/Report/Get-AbrADDCDiag.ps1 | 4 +- .../Private/Report/Get-AbrADDCRoleFeature.ps1 | 6 +- .../Src/Private/Report/Get-AbrADDFSHealth.ps1 | 16 +- .../Report/Get-AbrADDNSInfrastructure.ps1 | 30 +- .../Src/Private/Report/Get-AbrADDNSZone.ps1 | 38 +- .../Src/Private/Report/Get-AbrADDomain.ps1 | 4 +- .../Report/Get-AbrADDomainController.ps1 | 92 ++--- .../Report/Get-AbrADDomainLastBackup.ps1 | 4 +- .../Private/Report/Get-AbrADDomainObject.ps1 | 94 ++--- .../Report/Get-AbrADDuplicateObject.ps1 | 4 +- .../Private/Report/Get-AbrADDuplicateSPN.ps1 | 4 +- .../Src/Private/Report/Get-AbrADExchange.ps1 | 6 +- .../Src/Private/Report/Get-AbrADFSMO.ps1 | 8 +- .../Src/Private/Report/Get-AbrADForest.ps1 | 16 +- .../Src/Private/Report/Get-AbrADGPO.ps1 | 42 +-- .../Src/Private/Report/Get-AbrADHardening.ps1 | 4 +- .../Report/Get-AbrADInfrastructureService.ps1 | 6 +- .../Private/Report/Get-AbrADKerberosAudit.ps1 | 12 +- .../Src/Private/Report/Get-AbrADOU.ps1 | 8 +- .../Private/Report/Get-AbrADReportBrief.ps1 | 12 +- .../Src/Private/Report/Get-AbrADSCCM.ps1 | 6 +- .../Report/Get-AbrADSecurityAssessment.ps1 | 26 +- .../Src/Private/Report/Get-AbrADSite.ps1 | 84 ++--- .../Report/Get-AbrADSiteReplication.ps1 | 14 +- .../Src/Private/Report/Get-AbrADTrust.ps1 | 12 +- .../Src/Private/Report/Get-AbrDHCPinAD.ps1 | 6 +- .../Src/Private/Report/Get-AbrDNSSection.ps1 | 2 +- .../Private/Report/Get-AbrDomainSection.ps1 | 4 +- .../Src/Private/Report/Invoke-DcDiag.ps1 | 2 +- 34 files changed, 902 insertions(+), 330 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 b/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 index a0c3154..298b7bf 100644 --- a/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 +++ b/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 @@ -24,10 +24,10 @@ IncludeDomainsEnabled = - Include.Domains option enabled: Including only the following domains in the report: {0} ExcludeDomainsEnabled = - Including all child domains in the report except the following excluded domains: {0} GettingForestInfo = - Retrieving forest information {0}. - DiscoveringChildDomains = - Discovering child domains of the forest {0}: {1} + DiscoveringChildDomains = - Discovering child domains of the forest {0}: {1}. DCAvailable = - Initial configuration: A DC is available in the domain {0}. Adding domain to the report. DCUnavailable = - Unable to obtain an available DC in the domain {0}. Removing domain from the report. - FinishingDomainList = - Finalizing the list of domains in the forest {0}: {1} + FinishingDomainList = - Finalizing the list of domains in the forest {0}: {1}. WorkingOnForest = - Working on the Forest section. WorkingOnDomain = - Working on the Domain section. WorkingOnDNS = - Working on the DNS section. @@ -84,6 +84,12 @@ ScopeEnabled = Enabled (Summary) ScopeAdvanced = Enabled (Advanced Summary) ScopeDetailed = Enabled (Detailed) + ErrorReportOverview = Report Brief - Report Overview + ErrorForestSummary = Report Brief - Forest Summary + ErrorDomainSummaryItem = Report Brief - Domain Summary Item + ErrorDomainSummary = Report Brief - Domain Summary + ErrorReportScope = Report Brief - Report Scope + ErrorReportBriefSection = Report Brief Section '@ # Get-AbrForestSection @@ -150,6 +156,14 @@ RecycleBinBP = Accidental deletion of Active Directory objects is a common issue for AD DS users. Enabling the Recycle Bin feature allows for the recovery of these accidentally deleted objects, helping to maintain the integrity and continuity of the Active Directory environment. RecycleBinRef = https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/the-ad-recycle-bin-understanding-implementing-best-practices-and/ba-p/396944 CADiagram = Certificate Authority Diagram + TableName = Forest Summary + ErrorForestDiagramGraph = Forest Diagram Graph: + ErrorForestDiagramSection = Forest Diagram Section: + NoCARootInfo = No Certificate Authority Root information found in {0}, Disabling this section. + NoCAIssuerInfo = No Certificate Authority Issuer information found, Disabling this section. + ErrorCADiagramGraph = Certificate Authority Diagram Graph: + ErrorCADiagramSection = Certificate Authority Diagram Section: + NoOptionalFeatureInfo = No Optional Feature information found in {0}, Disabling this section. '@ NewADDiagram = ConvertFrom-StringData @' @@ -272,9 +286,11 @@ DnsName = DNS Name ServerRoles = Server Roles Version = Version + ErrorExchangeItem = Exchange Item + NoExchangeInfo = No Exchange Infrastructure information found in {0}, Disabling this section. + ErrorExchangeTable = Exchange Table + ErrorExchangeServerItem = ExchangeServer: [{0}]. '@ - - # Get-AbrADSCCM GetAbrADSCCM = ConvertFrom-StringData @' Collecting = Collecting AD SCCM information of {0}. Heading = SCCM Infrastructure @@ -284,6 +300,9 @@ ManagementPoint = Management Point SiteCode = Site Code Version = Version + ErrorSCCMItem = SCCM Item + NoSCCMInfo = No SCCM Infrastructure information found in {0}, Disabling this section. + ErrorSCCMTable = SCCM Table '@ # Get-AbrDHCPinAD @@ -297,6 +316,9 @@ Yes = Yes No = No Unknown = Unknown + ErrorDHCPItem = DHCP Item + NoDHCPInfo = No DHCP Infrastructure information found in {0}, Disabling this section. + ErrorDHCPTable = DHCP Table '@ # Get-AbrADSite @@ -383,6 +405,41 @@ StatusUnknown = Unknown StatusOffline = Offline SysvolBP = SYSVOL is a special directory that resides on each domain controller (DC) within a domain. The directory comprises folders that store Group Policy objects (GPOs) and logon scripts that clients need to access and synchronize between DCs. For these logon scripts and GPOs to function properly, SYSVOL should be replicated accurately and rapidly throughout the domain. Ensure that proper SYSVOL replication is in place to ensure identical GPO/SYSVOL content for the domain controller across all Active Directory domains. + ErrorReplicationDiagramGraph = Replication Diagram Graph: + ErrorReplicationDiagramSection = Replication Diagram Section: + ErrorDomainSite = Domain Site + ErrorSiteReplicationConnectionItem = Site Replication Connection Item + NoConnectionObjectsInfo = No Connection Objects information found in {0}, Disabling this section. + ErrorConnectionObjects = Connection Objects + ErrorSiteSubnets = Site Subnets + UnableToRead = Unable to read {0} on {1} + ErrorMissingSubnetPSSession = Missing Subnet in AD Section: New-PSSession: Unable to connect to {0}: {1} + ErrorMissingSubnetItemTable = Missing Subnet in AD Item table: + NoMissingSubnetsInfo = No Missing Subnets in AD information found in {0}, Disabling this section. + ErrorMissingSubnetItemSection = Missing Subnet in AD Item Section: + NoSiteSubnetsInfo = No Site Subnets information found in {0}, Disabling this section. + ErrorSiteTopologyDiagramGraph = Site Topology Diagram Graph: + ErrorSiteTopologyDiagramSection = Site Topology Diagram Section: + ErrorInterSiteTransports = Inter-Site Transports section + ErrorIPSiteLinksTable = IP Site Links table + NoIPSiteLinksInfo = No IP Site Links information found in {0}, Disabling this section. + ErrorIPSiteLinksSection = IP Site Links Section + ErrorIPSiteLinksBridgesTable = IP Site Links Bridges table + NoIPSiteLinksBridgesInfo = No IP Site Links Bridges information found in {0}, Disabling this section. + ErrorIP = IP + ErrorSMTPSiteLinksTable = SMTP Site Links table + ErrorSMTPSiteLinksSection = SMTP Site Links Section + ErrorSMTPSiteLinksBridgesTable = SMTP Site Links Bridges table + NoSMTPSiteLinksBridgesInfo = No SMTP Site Links Bridges information found in {0}, Disabling this section. + NoSMTPSiteLinksInfo = No SMTP Site Links information found in {0}, Disabling this section. + ErrorSMTP = SMTP + ErrorSysvolReplicationItemSection = Sysvol Replication Item Section: + UnableToCollect = Unable to collect information from {0}. + ErrorDNSIPConfigItem = DNS IP Configuration Item + NoSysvolReplicationInfo = No Sysvol Replication information found in {0}, Disabling this section. + ErrorSysvolReplicationTableSection = Sysvol Replication Table Section: + NoSitesInfo = No Sites information found in {0}, Disabling this section. + ErrorDomainSiteGlobal = Domain Site Global '@ # Get-AbrDNSSection @@ -396,6 +453,7 @@ DefinitionParagraph = The Domain Name System (DNS) is a hierarchical and decentralized naming system for computers, services, or other resources connected to the Internet or a private network. It associates various information with domain names assigned to each of the participating entities. Most prominently, it translates more readily memorized domain names to the numerical IP addresses needed for locating and identifying computer services and devices with the underlying network protocols. Paragraph = The following section provides a detailed overview of the DNS infrastructure configuration and settings within the Active Directory environment. NoCIMSession = DNS infrastructure configuration data requires a CIM session and could not be collected. Verify that WinRM and CIM connectivity to the domain controllers is available. + ErrorDNSInfo = Domain Name System Information '@ # Get-AbrADDNSInfrastructure @@ -457,6 +515,21 @@ ForwarderMinBP = For redundancy reasons, more than one forwarding server should be configured. RootHintsMissingCA = A default installation of the DNS server role should have root hints unless the server has a root zone - .(root). If the server has a root zone then delete it. If the server doesn't have a root zone and there are no root servers listed on the Root Hints tab of the DNS server properties then the server may be missing the cache.dns file in the %systemroot%\\system32\\dns directory, which is where the list of root servers is loaded from. RootHintsDuplicateCA = Duplicate IP Address found in the table of the DNS root hints servers. The DNS console does not show the duplicate Root Hint servers; you can only see them using the DNS PowerShell cmdlets. While there is a dnscmd utility to replace the Root Hints file, Using PowerShell is the best way to remediate this issue. + ErrorInfrastructureSummarySection = DNS Infrastructure Summary Section: + ErrorDirectoryPartitionsItemSection = Directory Partitions Item Section: + ErrorDirectoryPartitionsTableSection = Directory Partitions Table Section: + ErrorDirectoryPartitionsSection = Directory Partitions Section: + ErrorRRLItem = Response Rate Limiting (RRL) Item + ErrorRRLTable = Response Rate Limiting (RRL) Table + ErrorScavengingItem = Scavenging Item + ErrorScavengingTable = Scavenging Table + ErrorForwarderItem = Forwarder Item + ErrorForwarderTable = Forwarder Table + ErrorRootHintsTable = Root Hints Table + ErrorRootHintsSection = Root Hints Section + ErrorZoneScopeRecursionItem = Zone Scope Recursion Item + ErrorZoneScopeRecursionTable = Zone Scope Recursion Table + ErrorDNSInfrastructureSection = DNS Infrastructure Section '@ # Get-AbrADDNSZone @@ -499,6 +572,25 @@ BestPractice = Best Practices: ZoneTransferBP = Configure all DNS zones to allow zone transfers only from trusted IP addresses. This ensures that only authorized DNS servers can receive zone data, reducing the risk of unauthorized access or data leakage. It is a best practice to specify the IP addresses of the secondary DNS servers that are allowed to receive zone transfers. ZoneAgingBP = Microsoft recommends enabling aging/scavenging on all DNS servers. However, with AD-integrated zones, ensure DNS scavenging is enabled on only one DC at the main site. The results will be replicated to other DCs. + ErrorDNSZoneItem = Domain Name System Zone Item + NoDelegationInfo = DNS Zones {0} Section: No Zone Delegation information found, Disabling this section. + ErrorZoneDelegationItem = Zone Delegation Item + NoDelegationInfoDC = DNS Zones Section: No Zone Delegation information found in {0}, Disabling this section. + ErrorZoneDelegationTable = Zone Delegation Table + ErrorZoneTransferPSSession = DNS Zones Transfers Section: New-PSSession: Unable to connect to {0}: {1} + ErrorZoneTransfersItem = Zone Transfers Item + NoZoneTransferInfo = DNS Zones Section: No Zone Transfer information found in {0}, Disabling this section. + ErrorZoneTransfersTable = Zone Transfers Table + ErrorReverseLookupZoneItem = Reverse Lookup Zone Configuration Item + NoReverseLookupZoneInfo = DNS Zones Section: No Reverse lookup zone information found in {0}, Disabling this section. + ErrorReverseLookupZoneTable = Reverse Lookup Zone Configuration Table + ErrorConditionalForwarderItem = Conditional Forwarder Item + NoConditionalForwarderInfo = DNS Zones Section: No Conditional forwarder zone information found in {0}, Disabling this section. + ErrorConditionalForwarderTable = Conditional Forwarder Table + ErrorZoneScopeAgingItem = Zone Scope Aging Item + NoZoneAgingInfo = DNS Zones Section: No Zone Aging property information found in {0}, Disabling this section. + ErrorZoneScopeAgingTable = Zone Scope Aging Table + ErrorGlobalDNSZoneInfo = Global DNS Zone Information '@ # Get-AbrPKISection @@ -516,6 +608,7 @@ # Get-AbrDomainSection GetAbrDomainSection = ConvertFrom-StringData @' Collecting = Collecting Domain information from {0}. + CollectingDomain = Collecting Domain information from {0}. Paragraph = This section provides an overview of the Active Directory domain configuration, including key settings and operational details. SectionTitle = AD Domain Configuration DefinitionText = An Active Directory domain is a collection of objects within a Microsoft Active Directory network. An object can be a single user, a group, or a hardware component such as a computer or printer. Each domain holds a database containing object identity information. Active Directory domains can be identified using a DNS name, which can be the same as an organization's public domain name, a sub-domain, or an alternate version (which may end in .local). @@ -539,6 +632,7 @@ ReplicationParagraph = The following section provides an overview of Active Directory replication connections and status between domain controllers in this domain. GPOSection = Group Policy GPOParagraph = The following section provides an overview of the Group Policy Objects (GPOs) configured and applied within this domain. + ErrorADDomain = Active Directory Domain '@ # Get-AbrADDomain @@ -570,6 +664,8 @@ Reference = Reference: RIDBestPractice = The RID Issued percentage exceeds 80%. It is recommended to evaluate the utilization of RIDs to prevent potential exhaustion and ensure the stability of the domain. The Relative Identifier (RID) is a crucial component in the SID (Security Identifier) for objects within the domain. Exhaustion of the RID pool can lead to the inability to create new security principals, such as user or computer accounts. Regular monitoring and proactive management of the RID pool are essential to maintain domain health and avoid disruptions. RIDReference = https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/managing-rid-pool-depletion/ba-p/399736 + TableName = Domain Summary + ErrorSection = AD Domain Summary Section: '@ # Get-AbrADFSMO @@ -586,6 +682,9 @@ Reference = Reference: InfraMasterBP = The infrastructure master role in the domain {0} should be held by a domain controller that is not a global catalog server. The infrastructure master is responsible for updating references from objects in its domain to objects in other domains. If the infrastructure master runs on a global catalog server, it will not function properly because the global catalog holds a partial replica of every object in the forest, and it will not update the references. This issue does not affect forests that have a single domain. InfraMasterRef = http://go.microsoft.com/fwlink/?LinkId=168841 + TableName = FSMO Roles + ErrorFSMOItem = Flexible Single Master Operations + ErrorPSSession = FSMO Roles Section: New-PSSession: Unable to connect to {0}: {1} '@ # Get-AbrADTrust @@ -627,6 +726,12 @@ BestPractice = Best Practice: AESBP = Ensure that AES Kerberos encryption is enabled on all Active Directory trusts. RC4 encryption is considered weak and vulnerable to various attacks. Enabling AES encryption on trusts enhances Kerberos security and aligns with modern security standards. Reference: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718 TrustDiagramSection = Domain and Trusts Diagram + ErrorTrustItem = Trust Item + ErrorTrustDiagramGraph = Domain and Trusts Diagram Graph: + ErrorTrustDiagramSection = Domain and Trusts Diagram Section: + NoTrustInfo = No Domain Trust information found in {0}, Disabling this section. + ErrorTrustTable = Trust Table + ErrorTrustSection = Trust Section '@ # Get-AbrADAuthenticationPolicy @@ -660,6 +765,20 @@ ServiceTGTLifetime = Service TGT Lifetime (mins) ComputerTGTLifetime = Computer TGT Lifetime (mins) PolicyBP = Authentication Policies should be set to Enforce mode to actively restrict Kerberos TGT lifetimes and account sign-in. Policies in audit mode only log events without enforcing restrictions. + ErrorSiloItem = Authentication Policy Silo Item + SiloTableName = Authentication Policy Silo + SilosTableName = Authentication Policy Silos + ErrorSiloMemberItem = Authentication Policy Silo Member Item + SiloMembersTableName = Authentication Policy Silo Members + ErrorSiloMembersTable = Authentication Policy Silo Members Table + ErrorSilosSectionA = Authentication Policy Silos Section + NoSiloInfo = No Authentication Policy Silo information found in {0}, Disabling this section. + ErrorPolicyItem = Authentication Policy Item + PolicyTableName = Authentication Policy + PoliciesTableName = Authentication Policies + ErrorPoliciesSection = Authentication Policies Section + NoPolicyInfo = No Authentication Policy information found in {0}, Disabling this section. + NoAuthPolicyOrSiloInfo = No Authentication Policy or Silo information found in {0}, Disabling this section. '@ # Get-AbrADDomainObject @@ -829,6 +948,45 @@ GMSAInactiveBP = *Regularly check for and remove inactive group managed service accounts from Active Directory. Inactive accounts can pose a security risk as they may be exploited by malicious actors. Ensuring that only active and necessary accounts exist helps maintain a secure environment and reduces the risk of unauthorized access or privilege escalation. GMSANoHostComputersBP = **No 'Host Computers' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory. GMSANoRetrieveManagedPasswordBP = ***No 'Retrieve Managed Password' has been defined; please validate that the gMSA is currently in use. If not, it is recommended to remove these unused resources from Active Directory. + PrivilegedGroupMembersTableName = Privileged Group Members: + GMSATableName = gMSA + MembersLabel = Members + TypeLabelUser = USER + TypeLabelComputer = COMPUTER + TypeLabelGroup = GROUP + TypeLabelFSP = FOREIGN SECURITY PRINCIPAL + ErrorDomainObjectStats = Domain Object Stats + ErrorUserObjectCountChart = User Object Count Chart + ErrorStatusOfUserAccounts = Status of User Accounts + ErrorStatusOfUsersAccountsChart = Status of Users Accounts Chart + ErrorUsersObjectsTable = Users Objects Table + ErrorUsersObjectsSection = Users Objects Section + ErrorGroupCategoryObjectChart = Group Category Object Chart + ErrorGroupScopesObjectChart = Group Scopes Object Chart + ErrorGroupsObjectsTable = Groups Objects Table + ErrorGroupsObjectsSection = Groups Objects Section + ErrorPrivilegedGroup = Privileged Group in Active Directory + ErrorPrivilegedGroupNonDefaultTable = Privileged Group (Non-Default) Table + ErrorPrivilegedGroupNonDefaultSection = Privileged Group (Non-Default) Section + ErrorEmptyGroupsObjectsTable = Empty Groups Objects Table + ErrorEmptyGroupsObjectsSection = Empty Groups Objects Section + ErrorCircularGroupMembershipTable = Circular Group Membership Table + ErrorCircularGroupMembershipSection = Circular Group Membership Section + ErrorPreWin2000 = Pre-Windows 2000 Compatible Access + ErrorComputersObjectCountChart = Computers Object Count Chart + ErrorStatusOfComputerAccounts = Status of Computer Accounts + ErrorStatusOfComputersAccountsChart = Status of Computers Accounts Chart + ErrorOperatingSystemsInAD = Operating Systems in Active Directory + ErrorComputersPasswordNotRequired = Computers with Password-Not-Required + ErrorComputersObjectsTable = Computers Objects Table + ErrorComputersObjectsSection = Computers Objects Section + ErrorDefaultDomainPasswordPolicy = Default Domain Password Policy + ErrorFGPP = Fine Grained Password Policies + ErrorWindowsLAPS = Windows LAPS + ErrorGMSAItem = Group Managed Service Accounts Item + ErrorGMSASection = Group Managed Service Accounts Section + ErrorFSPItem = Foreign Security Principals Item + ErrorFSPSection = Foreign Security Principals Section '@ # Get-AbrADHardening @@ -872,6 +1030,8 @@ LDAPSigningBP = LDAP signing enforcement is not configured on this domain controller. LDAP signing is a security feature that protects the integrity and confidentiality of LDAP communications by requiring data signing. Configure LDAP signing to require signing on all domain controllers. LDAPCBBindingBP = LDAP channel binding enforcement is not configured on this domain controller. LDAP channel binding is a security feature that protects against man-in-the-middle attacks by binding the LDAP session to the TLS channel, ensuring the authenticity and integrity of LDAP communications. Configure LDAP channel binding on all domain controllers. NTLMv1BP = NTLMv1 authentication is enabled on this domain controller. NTLMv1 is an outdated authentication protocol that is vulnerable to credential capture and relay attacks. Disable NTLMv1 on all systems; it has been superseded by NTLMv2, which offers significantly improved security protections. + ErrorADHardeningItem = ADHardening Item + ErrorADHardeningSection = ADHardening Section '@ # Get-AbrADDomainLastBackup @@ -890,6 +1050,8 @@ BackupBP1 = Ensure there is a recent (<180 days) Active Directory backup. BackupBP2 = Regular backups are crucial for disaster recovery and maintaining the integrity of your Active Directory environment. BackupBP3 = Consider setting up automated backup schedules and regularly verifying the backup status to prevent data loss. + ErrorDomainLastBackupItem = Domain Last Backup Item + ErrorDomainLastBackupTable = Domain Last Backup Table '@ # Get-AbrADDuplicateSPN @@ -905,6 +1067,8 @@ HealthCheck = Health Check: CorrectiveActions = Corrective Actions: SPNBP = Ensure there aren't any duplicate SPNs (other than krbtgt). Duplicate SPNs can cause authentication issues and should be resolved promptly. Use the `setspn -X` command to identify duplicate SPNs. Remove or reassign duplicate SPNs as necessary to maintain a healthy AD environment. + ErrorSPNItem = SPN Item + ErrorSPNTable = SPN Table '@ # Get-AbrADDuplicateObject @@ -921,6 +1085,8 @@ HealthCheck = Health Check: CorrectiveActions = Corrective Actions: DuplicateObjectBP = Ensure there are no duplicate objects in Active Directory. Duplicate objects can cause various issues such as authentication problems, replication conflicts, and administrative overhead. It is recommended to regularly audit and clean up any duplicate objects to maintain a healthy and efficient Active Directory environment. + ErrorDuplicateObjectItem = Duplicate Object Item + ErrorDuplicateObjectTable = Duplicate Object Table '@ # Get-AbrADDCRoleFeature @@ -933,6 +1099,9 @@ HealthCheck = Health Check: BestPractices = Best Practices: RoleBP = Domain Controllers should have limited software and agents installed including roles and services. Non-essential code running on Domain Controllers is a risk to the enterprise Active Directory environment. A Domain Controller should only run required software, services and roles critical to essential operation. + ErrorPSSession = Roles Section: New-PSSession: Unable to connect to {0}: {1} + ErrorRoleFeatureSection = Roles {0} Section: + ErrorRolesSection = Roles Section: '@ # Get-AbrADDCDiag @@ -944,6 +1113,9 @@ Description = Description TableName = DCDiag Test Status NoData = No DCDiag information found in {0}, Disabling this section. + ErrorDCDiagTestSection = Active Directory DCDiag {0} Section: + ErrorDCDiagSection = Active Directory DCDiag Section: + ErrorInvokeDcDiag = Invoke-DcDiag - Failed to get DCDiag for {0} with error: '@ # Get-AbrADInfrastructureService @@ -958,6 +1130,9 @@ CorrectiveActions = Corrective Actions: SpoolerBP = The Print Spooler service has known vulnerabilities that can be exploited by attackers to gain unauthorized access or execute malicious code. Disabling this service on Domain Controllers and other critical servers that do not require print services can reduce the attack surface and improve the overall security posture of your Active Directory environment. DHCPServerBP = Per security best practices, DHCP Server services should run on a dedicated server separate from domain controllers to minimize security risks, reduce resource contention, and ensure optimal performance of both DHCP and Active Directory services. + ErrorPSSession = Domain Controller Infrastructure Services Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDCInfraServicesItem = Domain Controller Infrastructure Services Item + ErrorDCInfraServicesTable = Domain Controller Infrastructure Services Table '@ # Get-AbrADDFSHealth @@ -992,6 +1167,14 @@ ContentCorrectiveActions = Corrective Actions: ContentSysvolBP = Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Sysvol folder to maintain a healthy and secure Active Directory environment. ContentNetlogonBP = Review the files and extensions listed above and ensure they are necessary for the operation of your domain. Remove any files that are not required or that appear suspicious. Regularly monitor the Netlogon folder to maintain a healthy and secure Active Directory environment. + ErrorSysvolReplicationStatusItemSection = Sysvol Replication Status Item Section: + ErrorSysvolReplicationStatusTableSection = Sysvol Replication Status Table Section: + ErrorSysvolContentPSSession = Sysvol Content Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorSysvolHealthSection = Sysvol Health {0} Section: + ErrorSysvolHealthTableSection = Sysvol Health Table Section: + ErrorNetlogonContentPSSession = Netlogon Content Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorNetlogonHealthSection = Netlogon Health {0} Section: + ErrorNetlogonContentStatusSection = Netlogon Content Status Section: '@ # Get-AbrADKerberosAudit @@ -1023,6 +1206,10 @@ AdminHealthCheck = Health Check: AdminBestPractice = Best Practice: AdminBP = Microsoft recommends using a unique, complex password for the built-in Administrator account and rotating it regularly (at least every 90 days). Consider renaming the account and disabling it when not actively in use to reduce the risk of brute-force or credential-stuffing attacks targeting this well-known account. + ErrorUnconstrainedKerberosItem = Unconstrained Kerberos delegation + ErrorKRBTGTAccountItem = KRBTGT account Item + ErrorAdminAccountItem = ADMIN account Item + ErrorUnconstrainedKerberosSection = Unconstrained Kerberos delegation Section '@ # Get-AbrADSiteReplication @@ -1055,6 +1242,15 @@ ReplicationStatusBestPractices = Best Practices: ReplicationStatusBP = Replication failures can lead to object inconsistencies, stale credentials, Group Policy application failures, and authentication issues across the environment. Investigate and resolve any replication errors promptly using tools such as repadmin /showrepl or the Active Directory Replication Status Tool to prevent further divergence between domain controllers. AutoGeneratedValue = + ErrorSiteReplicationConnectionItem = Site Replication Connection Item + ErrorSiteReplicationConnectionSection = Site Replication Connection Section + SiteLabel = Site: + FromLabel = From: + ToLabel = To: + ErrorReplicationConnection = Replication Connection + ErrorPSSession = Replication Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorReplicationStatus = Replication Status + ErrorSiteReplicationStatus = Site Replication Status '@ # Get-AbrADOU @@ -1079,6 +1275,10 @@ GPOBlockedHealthCheck = Health Check: GPOBlockedCorrectiveActions = Corrective Actions: GPOBlockedBP = Review the use of enforced policies and blocked policy inheritance in Active Directory. Enforced policies ensure that specific Group Policy Objects (GPOs) are applied and cannot be overridden by other GPOs. Blocked policy inheritance prevents GPOs from parent containers from being applied to the Organizational Unit (OU). While these settings can be useful for maintaining strict policy application, they can also lead to unexpected results and complicate troubleshooting. Ensure that the use of these settings aligns with your organization's policy management strategy and does not inadvertently cause issues. + ErrorOUItem = Organizational Unit Item + ErrorBlockedInheritanceGPOItem = Blocked Inheritance GPO Item + ErrorBlockedInheritanceGPOSection = Blocked Inheritance GPO Section + ErrorOUSection = Organizational Unit Section '@ # Get-AbrADSecurityAssessment @@ -1135,6 +1335,19 @@ PrivilegedUsersReference = Reference: PrivilegedUsersReferenceURL = https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435 ServiceAccountsAdminCountNote = ** Attackers are most interested in Service Accounts that are members of highly privileged groups like Domain Admins. A quick way to check for this is to enumerate all user accounts with the attribute AdminCount equal to 1. This means an attacker may just ask Active Directory for all user accounts with an SPN and with AdminCount=1. Ensure that there are no privileged accounts that have SPNs assigned to them. + ErrorAccountSecurityAssessmentItem = Account Security Assessment Item + ErrorUserAccountSecurityAssessmentChart = User Account Security Assessment Chart + NoUserInfo = No Domain users information found in {0}, Disabling this section. + ErrorAccountSecurityAssessmentTable = Account Security Assessment Table + ErrorPrivilegedUsersAssessmentItem = Privileged Users Assessment Item + NoPrivilegedUserInfo = No Privileged User Assessment information found in {0}, Disabling this section. + ErrorPrivilegedUsersTable = Privileged Users Table + ErrorInactivePrivilegedAccountsItem = Inactive Privileged Accounts Item + NoInactivePrivilegedInfo = No Inactive Privileged Accounts information found in {0}, Disabling this section. + ErrorInactivePrivilegedAccountsTable = Inactive Privileged Accounts Table + ErrorServiceAccountsAssessmentItem = Service Accounts Assessment Item + NoServiceAccountsInfo = No Service Accounts Assessment information found in {0}, Disabling this section. + ErrorServiceAccountsAssessmentTable = Service Accounts Assessment Table '@ # Get-AbrADGPO @@ -1232,6 +1445,23 @@ GPOSettingsParagraph = The following section provides details about Group Policy configuration resources, including WMI filters, the Central Store repository, and scripts attached to GPOs. GPOHealthTitle = GPO Health GPOHealthParagraph = The following section highlights Group Policy Objects that may require attention, including unlinked, empty, enforced, and orphaned GPOs. + ErrorGPOItem = Group Policy Objects + ErrorWMIFiltersItem = WMI Filters + ErrorWMIFiltersPSSession = WMI Filters Section: New-PSSession: Unable to connect to {0}: {1} + ErrorGPOCentralStore = GPO Central Store + ErrorGPOLogonLogoffItem = GPO with Logon/Logoff Script Item + ErrorGPOLogonLogoffSection = GPO with Logon/Logoff Script Section + ErrorGPOStartupShutdownItem = GPO with Computer Startup/Shutdown Item + ErrorGPOStartupShutdownSection = GPO with Computer Startup/Shutdown Section + ErrorUnlinkedGPOItem = Unlinked Group Policy Objects Item + ErrorUnlinkedGPOSection = Unlinked Group Policy Objects Section + ErrorEmptyGPOItem = Empty Group Policy Objects Item + ErrorEmptyGPOSection = Empty Group Policy Objects Section + ErrorEnforcedGPOItem = Enforced Group Policy Objects Item + ErrorEnforcedGPOTable = Enforced Group Policy Objects Table + ErrorOrphanedGPOPSSession = Orphaned GPO Section: New-PSSession: Unable to connect to {0}: {1} + ErrorOrphanedGPOItem = Orphaned GPO + ErrorGPOSection = Group Policy Objects Section '@ # Get-AbrADDomainController GetAbrADDomainController = ConvertFrom-StringData @' @@ -1347,6 +1577,47 @@ MissingUpdatesParagraph = The following table provides a summary of pending or missing Windows updates detected on Domain Controllers in the {0} domain. MissingUpdatesBestPractice = It is critical to install security updates to protect your systems from malicious attacks. Regularly applying updates ensures that your systems are safeguarded against newly discovered vulnerabilities. Additionally, installing software updates provides access to new features and improvements, enhancing overall system performance and stability. Neglecting updates can leave your systems exposed to potential threats and exploitation. Therefore, it is in your best interest to maintain an up-to-date environment by promptly installing all recommended updates. DCObjectChart = Domain Controller Object - Chart + ErrorNetworkInterfacesInfo = Unable to get {0} network interfaces information + ErrorDCNetSettingsPSSession = DC Net Settings Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDCItem = Domain Controller Item + UnableToCollect = Unable to collect information from {0}. + ErrorDCTable = Domain Controller Table + ErrorGeneralInfoSection = General Information Section + ErrorPartitionsSection = Partitions Section + ErrorNetworkingSettingsSection = Networking Settings Section + ErrorHardwareInventoryTable = Hardware Inventory Table + ErrorDCHardwareSection = Domain Controller Hardware Section + ErrorDCSection = Domain Controller Section + ErrorDNSIPConfigPSSession = DNS IP Configuration Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDNSIPConfigTableSection = Domain Controller DNS IP Configuration Table Section: + ErrorDNSIPConfigItem = DNS IP Configuration Item + ErrorDNSIPConfigSection = Domain Controller DNS IP Configuration Section: + ErrorNTDSPSSession = NTDS Section: New-PSSession: Unable to connect to {0}: {1} + ErrorNTDSItem = NTDS Item + ErrorNTDSSection = NTDS section + ErrorTimeSourcePSSession = Time Source Section: New-PSSession: Unable to connect to {0}: {1} + ErrorTimeSourceItem = Time Source Item + ErrorTimeSourceTable = Time Source Table + ErrorTimeSource = Time Source + ErrorSRVRecordsStatusItem = SRV Records Status Item + ErrorSRVRecordsStatusTable = SRV Records Status Table + ErrorSRVRecordsStatus = SRV Records Status + ErrorFileSharesPSSession = Domain Controllers File Shares Section: New-PSSession: Unable to connect to {0}: {1} + ErrorFileSharesItem = File Shares Item + ErrorFileSharesTable = File Shares Table + ErrorInstalledSoftwarePSSession = Domain Controller Installed Software Section: New-PSSession: Unable to connect to {0}: {1} + ErrorInstalledSoftwareTable = Installed Software Table + ErrorInstalledSoftwareSection = Installed Software Section + ErrorMissingPatchPSSession = Domain Controller Pending Missing Patch Section: New-PSSession: Unable to connect to {0}: {1} + ErrorMissingPatchTable = Installed Software Table + ErrorMissingPatchSection = Domain Controller Section +'@ + + # Get-AbrDiagrammer + GetAbrDiagrammer = ConvertFrom-StringData @' + GettingDiagram = Getting {0} diagram from {1}. + ErrorExportDiagram = Unable to export the {0} Diagram: + ErrorGetDiagram = Unable to get the {0} Diagram: '@ } \ No newline at end of file diff --git a/AsBuiltReport.Microsoft.AD/Language/es-ES/MicrosoftAD.psd1 b/AsBuiltReport.Microsoft.AD/Language/es-ES/MicrosoftAD.psd1 index bae0268..8e9ceb4 100644 --- a/AsBuiltReport.Microsoft.AD/Language/es-ES/MicrosoftAD.psd1 +++ b/AsBuiltReport.Microsoft.AD/Language/es-ES/MicrosoftAD.psd1 @@ -2,17 +2,45 @@ @{ # InvokeAsBuiltReportMicrosoftAD InvokeAsBuiltReportMicrosoftAD = ConvertFrom-StringData @' - PwshISE = Este script no se puede ejecutar dentro del ISE de PowerShell. Por favor, ejecútalo desde la ventana de comandos de PowerShell. + PwshISE = Este script no se puede ejecutar dentro de PowerShell ISE. Por favor, ejecútalo desde la ventana de comandos de PowerShell. ReportModuleInfo3 = - Documentación: https://github.com/AsBuiltReport/AsBuiltReport.{0} ReportModuleInfo2 = - Informes de problemas o errores: https://github.com/AsBuiltReport/AsBuiltReport.{0}/issues - ReportModuleInfo1 = - No olvides actualizar tu archivo de configuración de informe después de cada nueva versión: https://www.asbuiltreport.com/user-guide/new-asbuiltreportconfig/ + ReportModuleInfo1 = - No olvides actualizar tu archivo de configuración de informe después de cada nuevo lanzamiento de versión: https://www.asbuiltreport.com/user-guide/new-asbuiltreportconfig/ ReportModuleInfo4 = - Para patrocinar este proyecto, por favor visita: ReportModuleInfo5 = https://ko-fi.com/F1F8DEV80 ReportModuleInfo6 = - Obteniendo información de dependencias: ProjectWebsite = - Por favor consulta el sitio web de GitHub de AsBuiltReport.Microsoft.AD para obtener información más detallada sobre este proyecto. CommunityProject = - AsBuiltReport es un proyecto de código abierto mantenido por la comunidad. No tiene patrocinio, respaldo o afiliación con ningún proveedor de tecnología, sus empleados o afiliados. - DISCLAIMER = Este informe combina análisis de datos automatizado con observaciones profesionales. Aunque estos hallazgos ofrecen información experta, esta evaluación no es exhaustiva. Todas las recomendaciones deben ser revisadas e implementadas por personal calificado. Los autores no asumen responsabilidad alguna por daños, incluidas pérdidas de ganancias, interrupciones comerciales o pérdidas financieras, derivadas del uso de este informe o sus recomendaciones. - DisclaimerSection = AVISO LEGAL + DISCLAIMER = Este informe combina análisis de datos automatizado con observaciones profesionales. Aunque estos hallazgos ofrecen información experta, esta evaluación no es exhaustiva. Todas las recomendaciones deben ser revisadas e implementadas por personal calificado. Los autores no asumen ninguna responsabilidad por daños, incluyendo pérdidas de ganancias, interrupciones comerciales o pérdidas financieras, derivados del uso de este informe o sus recomendaciones. + DisclaimerSection = DESCARGO DE RESPONSABILIDAD + ModuleInstalled = - El módulo {0} v{1} está actualmente instalado. + ModuleAvailable = - El módulo {0} v{1} está disponible. + ModuleUpdate = - Ejecuta 'Update-Module -Name {0} -Force' para instalar la versión más reciente. + IPAddressError = Por favor, usa el Nombre de Dominio Completamente Calificado (FQDN) en lugar de una dirección IP al conectar con el Controlador de Dominio: {0} + PSSessionError = Error al establecer una PSSession ({0}) con el Controlador de Dominio '{1}': {2} + CIMSessionError = Error al establecer una sesión CIM ({0}) con el Controlador de Dominio '{1}'. + ConnectingForest = Conectando para recuperar información del bosque desde el Controlador de Dominio '{0}'. + ForestError = Error al recuperar información del bosque desde el Controlador de Dominio '{0}'. Asegúrate de que el sistema proporcionado sea un Controlador de Dominio y que las credenciales proporcionadas tengan permisos suficientes para consultar información del bosque de Active Directory. Detalles del error: {1} + IncludeDomainsEnabled = - Opción Include.Domains habilitada: Incluyendo solo los siguientes dominios en el informe: {0} + ExcludeDomainsEnabled = - Incluyendo todos los dominios secundarios en el informe excepto los siguientes dominios excluidos: {0} + GettingForestInfo = - Recuperando información del bosque {0}. + DiscoveringChildDomains = - Descubriendo dominios secundarios del bosque {0}: {1}. + DCAvailable = - Configuración inicial: Un DC está disponible en el dominio {0}. Agregando dominio al informe. + DCUnavailable = - No se puede obtener un DC disponible en el dominio {0}. Removiendo dominio del informe. + FinishingDomainList = - Finalizando la lista de dominios en el bosque {0}: {1}. + WorkingOnForest = - Trabajando en la sección del Bosque. + WorkingOnDomain = - Trabajando en la sección del Dominio. + WorkingOnDNS = - Trabajando en la sección de DNS. + WorkingOnPKI = - Trabajando en la sección de PKI. + ExportDiagramsEnabled = - Opción ExportDiagrams habilitada: Exportando diagramas: + TrustsDiagramError = No se puede generar el diagrama de 'Confianzas' para el dominio '{0}': {1} + DiagramExportError = No se puede exportar el diagrama {0}: {1} + ClearPSSession = Limpiando PSSession con ID {0} + ClearCIMSession = Limpiando sesión CIM con ID {0} + FinishedReport = - Se ha terminado de generar el informe para el bosque {0}: + SystemsUnreachable = Los siguientes sistemas no pudieron ser contactados: + DomainControllers = Controladores de Dominio + Domains = Dominios '@ # ConvertToTextYN @@ -56,6 +84,12 @@ ScopeEnabled = Habilitado (Resumen) ScopeAdvanced = Habilitado (Resumen Avanzado) ScopeDetailed = Habilitado (Detallado) + ErrorReportOverview = Report Brief - Report Overview + ErrorForestSummary = Report Brief - Forest Summary + ErrorDomainSummaryItem = Report Brief - Domain Summary Item + ErrorDomainSummary = Report Brief - Domain Summary + ErrorReportScope = Report Brief - Report Scope + ErrorReportBriefSection = Report Brief Section '@ # Get-AbrForestSection @@ -122,6 +156,14 @@ RecycleBinBP = La eliminación accidental de objetos de Active Directory es un problema común para usuarios de AD DS. Habilitar la función Papelera de Reciclaje permite la recuperación de estos objetos eliminados accidentalmente, ayudando a mantener la integridad y continuidad del entorno de Active Directory. RecycleBinRef = https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/the-ad-recycle-bin-understanding-implementing-best-practices-and/ba-p/396944 CADiagram = Diagrama de Autoridad de Certificación + TableName = Resumen del Bosque + ErrorForestDiagramGraph = Forest Diagram Graph: + ErrorForestDiagramSection = Forest Diagram Section: + NoCARootInfo = No se encontró información de Autoridad de Certificación raíz en {0}, deshabilitando esta sección. + NoCAIssuerInfo = No se encontró información de Autoridad de Certificación emisora, deshabilitando esta sección. + ErrorCADiagramGraph = Certificate Authority Diagram Graph: + ErrorCADiagramSection = Certificate Authority Diagram Section: + NoOptionalFeatureInfo = No se encontró información de Características Opcionales en {0}, deshabilitando esta sección. '@ NewADDiagram = ConvertFrom-StringData @' @@ -245,6 +287,10 @@ DnsName = Nombre DNS ServerRoles = Roles del Servidor Version = Versión + ErrorExchangeItem = Exchange Item + NoExchangeInfo = No se encontró información de infraestructura de Exchange en {0}, deshabilitando esta sección. + ErrorExchangeTable = Exchange Table + ErrorExchangeServerItem = ExchangeServer: [{0}]. '@ # Get-AbrADSCCM @@ -257,6 +303,9 @@ ManagementPoint = Punto de Gestión SiteCode = Código de Sitio Version = Versión + ErrorSCCMItem = SCCM Item + NoSCCMInfo = No se encontró información de infraestructura de SCCM en {0}, deshabilitando esta sección. + ErrorSCCMTable = SCCM Table '@ # Get-AbrDHCPinAD @@ -270,6 +319,9 @@ Yes = Sí No = No Unknown = Desconocido + ErrorDHCPItem = DHCP Item + NoDHCPInfo = No se encontró información de infraestructura de DHCP en {0}, deshabilitando esta sección. + ErrorDHCPTable = DHCP Table '@ # Get-AbrADSite @@ -306,7 +358,7 @@ MissingSubnets = Subredes Faltantes en AD MissingSubnetsTable = Subredes Faltantes MissingSubnetsParagraph = La siguiente tabla lista las entradas NO_CLIENT_SITE encontradas en el archivo netlogon.log en cada Controlador de Dominio del bosque. Estas entradas indican direcciones IP de clientes que no pudieron ser mapeadas a un sitio de Active Directory. - DC = CD + DC = DC IP = IP MissingSubnetsBP = Asegúrate de que todas las subredes en cada sitio estén correctamente definidas. Las definiciones de subred faltantes pueden impedir que los clientes usen sus Controladores de Dominio más cercanos, resultando en mayor latencia de autenticación. InterSiteTransports = Transportes Entre Sitios @@ -343,7 +395,7 @@ SMTPParagraph = La replicación SMTP se usa para sitios que no pueden usar otros protocolos de replicación, pero como regla general, nunca debe usarse. Se reserva para escenarios donde las conexiones de red no siempre están disponibles, permitiendo que la replicación se programe en intervalos específicos. SMTPChangeNotifBP = Habilitar la notificación de cambio trata una conexión de replicación entre sitios como si fuera una conexión dentro de un sitio. La replicación entre sitios con notificación de cambio es casi instantánea. Microsoft recomienda usar un valor de Opción de 5 (Notificación de Cambio Habilitada sin Compresión). SysvolReplication = Replicación de Sysvol - DCName = Nombre del CD + DCName = Nombre del DC ReplicationStatus = Estado de Replicación Domain = Dominio StatusUninitialized = No Inicializado @@ -355,7 +407,42 @@ StatusDisabled = Deshabilitado StatusUnknown = Desconocido StatusOffline = Fuera de Línea - SysvolBP = SYSVOL es un directorio especial que reside en cada controlador de dominio (CD) dentro de un dominio. El directorio comprende carpetas que almacenan objetos de Política de Grupo (GPO) y scripts de inicio de sesión que los clientes necesitan acceder y sincronizar entre CDs. Para que estos scripts de inicio de sesión y GPO funcionen correctamente, SYSVOL debe replicarse con precisión y rapidez en todo el dominio. Asegúrate de que se implemente una replicación correcta de SYSVOL para asegurar contenido idéntico de GPO/SYSVOL para el controlador de dominio en todos los dominios de Active Directory. + SysvolBP = SYSVOL es un directorio especial que reside en cada controlador de dominio (DC) dentro de un dominio. El directorio comprende carpetas que almacenan objetos de Política de Grupo (GPO) y scripts de inicio de sesión que los clientes necesitan acceder y sincronizar entre DCs. Para que estos scripts de inicio de sesión y GPO funcionen correctamente, SYSVOL debe replicarse con precisión y rapidez en todo el dominio. Asegúrate de que se implemente una replicación correcta de SYSVOL para asegurar contenido idéntico de GPO/SYSVOL para el controlador de dominio en todos los dominios de Active Directory. + ErrorReplicationDiagramGraph = Replication Diagram Graph: + ErrorReplicationDiagramSection = Replication Diagram Section: + ErrorDomainSite = Domain Site + ErrorSiteReplicationConnectionItem = Site Replication Connection Item + NoConnectionObjectsInfo = No se encontró información de Objetos de Conexión en {0}, deshabilitando esta sección. + ErrorConnectionObjects = Connection Objects + ErrorSiteSubnets = Site Subnets + UnableToRead = No se puede leer {0} en {1} + ErrorMissingSubnetPSSession = Missing Subnet in AD Section: New-PSSession: Unable to connect to {0}: {1} + ErrorMissingSubnetItemTable = Missing Subnet in AD Item table: + NoMissingSubnetsInfo = No se encontró información de Subredes Faltantes en {0}, deshabilitando esta sección. + ErrorMissingSubnetItemSection = Missing Subnet in AD Item Section: + NoSiteSubnetsInfo = No se encontró información de Subredes de Sitio en {0}, deshabilitando esta sección. + ErrorSiteTopologyDiagramGraph = Site Topology Diagram Graph: + ErrorSiteTopologyDiagramSection = Site Topology Diagram Section: + ErrorInterSiteTransports = Inter-Site Transports section + ErrorIPSiteLinksTable = IP Site Links table + NoIPSiteLinksInfo = No se encontró información de Vínculos de Sitio IP en {0}, deshabilitando esta sección. + ErrorIPSiteLinksSection = IP Site Links Section + ErrorIPSiteLinksBridgesTable = IP Site Links Bridges table + NoIPSiteLinksBridgesInfo = No se encontró información de Puentes de Vínculos de Sitio IP en {0}, deshabilitando esta sección. + ErrorIP = IP + ErrorSMTPSiteLinksTable = SMTP Site Links table + ErrorSMTPSiteLinksSection = SMTP Site Links Section + ErrorSMTPSiteLinksBridgesTable = SMTP Site Links Bridges table + NoSMTPSiteLinksBridgesInfo = No se encontró información de Puentes de Vínculos de Sitio SMTP en {0}, deshabilitando esta sección. + NoSMTPSiteLinksInfo = No se encontró información de Vínculos de Sitio SMTP en {0}, deshabilitando esta sección. + ErrorSMTP = SMTP + ErrorSysvolReplicationItemSection = Sysvol Replication Item Section: + UnableToCollect = No se puede recopilar información de {0}. + ErrorDNSIPConfigItem = DNS IP Configuration Item + NoSysvolReplicationInfo = No se encontró información de Replicación Sysvol en {0}, deshabilitando esta sección. + ErrorSysvolReplicationTableSection = Sysvol Replication Table Section: + NoSitesInfo = No se encontró información de Sitios en {0}, deshabilitando esta sección. + ErrorDomainSiteGlobal = Domain Site Global '@ # Get-AbrDNSSection @@ -364,11 +451,12 @@ CollectingDomain = Recopilando información de DNS desde {0}. DomainParagraph = La siguiente sección proporciona una descripción general detallada de la configuración del servicio DNS y su configuración para este dominio. ExcludedDomain = {0} deshabilitado en variable Exclude.Domain - NoDCAvailable = No se puede obtener un CD disponible en el dominio {0}. Removiendo dominio de la sección DNS. + NoDCAvailable = No se puede obtener un DC disponible en el dominio {0}. Removiendo dominio de la sección DNS. Heading = Configuración de DNS DefinitionParagraph = El Sistema de Nombres de Dominio (DNS) es un sistema de nomenclatura jerárquico y descentralizado para computadoras, servicios u otros recursos conectados a Internet o a una red privada. Asocia varios tipos de información con nombres de dominio asignados a cada una de las entidades participantes. Más prominentemente, traduce nombres de dominio más fáciles de recordar a direcciones IP numéricas necesarias para localizar e identificar servicios y dispositivos de computadora dentro de los protocolos de red subyacentes. Paragraph = La siguiente sección proporciona una descripción general detallada de la configuración de infraestructura de DNS y su configuración dentro del entorno de Active Directory. NoCIMSession = La configuración de la infraestructura de DNS requiere una sesión CIM y no pudo ser recopilada. Verifica que la conectividad WinRM y CIM a los controladores de dominio esté disponible. + ErrorDNSInfo = Domain Name System Information '@ # Get-AbrADDNSInfrastructure - Continue with the rest of the translations... @@ -389,11 +477,11 @@ RootHintsParagraph = La siguiente sección proporciona información detallada sobre la configuración de Sugerencias de Raíz para cada servidor DNS en el dominio {0}. ZoneScopeRecursion = Recursión de Alcance de Zona DirectoryPartitions = Particiones de Directorio - DCName = Nombre del CD + DCName = Nombre del DC BuildNumber = Número de Compilación IPv6 = IPv6 DnsSec = DnsSec - ReadOnlyDC = CD de Solo Lectura + ReadOnlyDC = DC de Solo Lectura ListeningIP = IP de Escucha Name = Nombre State = Estado @@ -425,12 +513,27 @@ BestPractice = Mejores Prácticas: CorrectiveActions = Acciones Correctivas: Reference = Referencia: - ScavengingBP = Microsoft recomienda habilitar envejecimiento/limpieza en todos los servidores DNS. Sin embargo, con zonas integradas en AD, asegúrate de que la limpieza de DNS esté habilitada solo en un CD del sitio principal. Los resultados se replicarán a otros CDs. + ScavengingBP = Microsoft recomienda habilitar envejecimiento/limpieza en todos los servidores DNS. Sin embargo, con zonas integradas en AD, asegúrate de que la limpieza de DNS esté habilitada solo en un DC del sitio principal. Los resultados se replicarán a otros DCs. ForwarderMaxBP = Configura los servidores para usar no más de dos servidores DNS externos como Reenviadores. Usar más de dos reenviadores puede llevar a tiempos de resolución aumentados y problemas potenciales con el equilibrio de carga de consultas DNS. Se recomienda usar dos servidores DNS confiables y geográficamente diversos para asegurar redundancia y rendimiento óptimo. ForwarderRefURL = https://learn.microsoft.com/es-es/troubleshoot/windows-server/networking/forwarders-resolution-timeouts ForwarderMinBP = Por razones de redundancia, se debe configurar más de un servidor de reenvío. RootHintsMissingCA = Una instalación predeterminada del rol de servidor DNS debe tener sugerencias de raíz a menos que el servidor tenga una zona raíz - .(raíz). Si el servidor tiene una zona raíz, elimínala. Si el servidor no tiene una zona raíz y no hay servidores raíz listados en la pestaña Sugerencias de Raíz de las propiedades del servidor DNS, el servidor puede estar perdiendo el archivo cache.dns en el directorio %systemroot%\\system32\\dns, desde donde se carga la lista de servidores raíz. RootHintsDuplicateCA = Se encontró dirección IP duplicada en la tabla de servidores de sugerencias de raíz de DNS. La consola de DNS no muestra los servidores de Sugerencias de Raíz duplicados; solo puedes verlos usando cmdlets de PowerShell de DNS. Aunque existe una utilidad dnscmd para reemplazar el archivo de Sugerencias de Raíz, usar PowerShell es la mejor forma de remediar este problema. + ErrorInfrastructureSummarySection = DNS Infrastructure Summary Section: + ErrorDirectoryPartitionsItemSection = Directory Partitions Item Section: + ErrorDirectoryPartitionsTableSection = Directory Partitions Table Section: + ErrorDirectoryPartitionsSection = Directory Partitions Section: + ErrorRRLItem = Response Rate Limiting (RRL) Item + ErrorRRLTable = Response Rate Limiting (RRL) Table + ErrorScavengingItem = Scavenging Item + ErrorScavengingTable = Scavenging Table + ErrorForwarderItem = Forwarder Item + ErrorForwarderTable = Forwarder Table + ErrorRootHintsTable = Root Hints Table + ErrorRootHintsSection = Root Hints Section + ErrorZoneScopeRecursionItem = Zone Scope Recursion Item + ErrorZoneScopeRecursionTable = Zone Scope Recursion Table + ErrorDNSInfrastructureSection = DNS Infrastructure Section '@ # Get-AbrADDNSZone @@ -472,7 +575,26 @@ HealthCheck = Verificación de Salud: BestPractice = Mejores Prácticas: ZoneTransferBP = Configura todas las zonas de DNS para permitir transferencias de zona solo desde direcciones IP de confianza. Esto asegura que solo servidores DNS autorizados puedan recibir datos de zona, reduciendo el riesgo de acceso no autorizado o fuga de datos. Es una mejor práctica especificar las direcciones IP de los servidores DNS secundarios autorizados a recibir transferencias de zona. - ZoneAgingBP = Microsoft recomienda habilitar envejecimiento/limpieza en todos los servidores DNS. Sin embargo, con zonas integradas en AD, asegúrate de que la limpieza de DNS esté habilitada solo en un CD del sitio principal. Los resultados se replicarán a otros CDs. + ZoneAgingBP = Microsoft recomienda habilitar envejecimiento/limpieza en todos los servidores DNS. Sin embargo, con zonas integradas en AD, asegúrate de que la limpieza de DNS esté habilitada solo en un DC del sitio principal. Los resultados se replicarán a otros DCs. + ErrorDNSZoneItem = Domain Name System Zone Item + NoDelegationInfo = Sección de Zonas DNS {0}: No se encontró información de Delegación de Zona, deshabilitando esta sección. + ErrorZoneDelegationItem = Zone Delegation Item + NoDelegationInfoDC = Sección de Zonas DNS: No se encontró información de Delegación de Zona en {0}, deshabilitando esta sección. + ErrorZoneDelegationTable = Zone Delegation Table + ErrorZoneTransferPSSession = DNS Zones Transfers Section: New-PSSession: Unable to connect to {0}: {1} + ErrorZoneTransfersItem = Zone Transfers Item + NoZoneTransferInfo = Sección de Zonas DNS: No se encontró información de Transferencia de Zona en {0}, deshabilitando esta sección. + ErrorZoneTransfersTable = Zone Transfers Table + ErrorReverseLookupZoneItem = Reverse Lookup Zone Configuration Item + NoReverseLookupZoneInfo = Sección de Zonas DNS: No se encontró información de zona de búsqueda inversa en {0}, deshabilitando esta sección. + ErrorReverseLookupZoneTable = Reverse Lookup Zone Configuration Table + ErrorConditionalForwarderItem = Conditional Forwarder Item + NoConditionalForwarderInfo = Sección de Zonas DNS: No se encontró información de zona de reenviador condicional en {0}, deshabilitando esta sección. + ErrorConditionalForwarderTable = Conditional Forwarder Table + ErrorZoneScopeAgingItem = Zone Scope Aging Item + NoZoneAgingInfo = Sección de Zonas DNS: No se encontró información de propiedad de envejecimiento de zona en {0}, deshabilitando esta sección. + ErrorZoneScopeAgingTable = Zone Scope Aging Table + ErrorGlobalDNSZoneInfo = Global DNS Zone Information '@ # Continuing with remaining sections... @@ -563,7 +685,7 @@ ValidityPeriod = Período de Validez ACL = Lista de Control de Acceso (ACL) ACLTable = Lista de Control de Acceso - DCName = Nombre del CD + DCName = Nombre del DC Owner = Propietario Group = Grupo AccessRights = Derechos de Acceso @@ -672,22 +794,23 @@ # Get-AbrDomainSection GetAbrDomainSection = ConvertFrom-StringData @' Collecting = Recopilando información de Dominio desde {0}. + CollectingDomain = Recopilando información de Dominio desde {0}. Paragraph = Esta sección proporciona una descripción general de la configuración del dominio de Active Directory, incluyendo configuraciones clave y detalles operacionales. SectionTitle = Configuración del Dominio de AD DefinitionText = Un dominio de Active Directory es una colección de objetos dentro de una red de Microsoft Active Directory. Un objeto puede ser un usuario individual, un grupo o un componente de hardware como una computadora o impresora. Cada dominio contiene una base de datos con información de identidad de objetos. Los dominios de Active Directory se pueden identificar usando un nombre DNS, que puede ser el mismo que el nombre de dominio público de una organización, un subdominio o una versión alternativa (que puede terminar en .local). ParagraphDetail = La siguiente tabla proporciona un desglose detallado de los atributos de configuración del dominio de Active Directory. HealthChecks = Verificaciones de Salud DomainControllersSection = Controladores de Dominio - DCDefinitionText = Un controlador de dominio (CD) es una computadora servidor que responde solicitudes de autenticación de seguridad dentro de un dominio de red de computadoras. Es un servidor de red responsable de permitir el acceso del anfitrión a recursos del dominio. Autentica usuarios, almacena información de cuenta de usuario e implementa la política de seguridad para un dominio. + DCDefinitionText = Un controlador de dominio (DC) es una computadora servidor que responde solicitudes de autenticación de seguridad dentro de un dominio de red de computadoras. Es un servidor de red responsable de permitir el acceso del anfitrión a recursos del dominio. Autentica usuarios, almacena información de cuenta de usuario e implementa la política de seguridad para un dominio. DCParagraphDetail = La siguiente sección presenta una descripción general profunda de los controladores de dominio de Active Directory, incluyendo su configuración y detalles clave. DCParagraphSummary = La siguiente sección proporciona un resumen de la configuración y detalles clave de los controladores de dominio de Active Directory. RolesSection = Roles RolesParagraph = La siguiente sección proporciona una descripción general detallada de los roles y funciones instalados en controladores de dominio en {0}. - DCDiagSection = Diagnóstico de CD - DCDiagParagraph = La siguiente sección proporciona un resumen del Diagnóstico de CD de Active Directory. + DCDiagSection = Diagnóstico de DC + DCDiagParagraph = La siguiente sección proporciona un resumen del Diagnóstico de DC de Active Directory. InfraServicesSection = Servicios de Infraestructura InfraServicesParagraph = La siguiente sección proporciona una descripción general detallada del estado y configuración de servicios de infraestructura en los controladores de dominio. - NoDCAvailable = No se puede obtener un CD disponible en el dominio {0}. Removiendo dominio de la sección de Dominio. + NoDCAvailable = No se puede obtener un DC disponible en el dominio {0}. Removiendo dominio de la sección de Dominio. WinRMErrorDCDiag = Error: La conexión al servidor remoto {0} falló: WinRM no puede completar la operación. (Información de DCDiag) WinRMErrorInfraService = Error: La conexión al servidor remoto {0} falló: WinRM no puede completar la operación. (ADInfrastructureService) DomainExcluded = {0} deshabilitado en variable Exclude.Domain @@ -695,6 +818,7 @@ ReplicationParagraph = La siguiente sección proporciona una descripción general de las conexiones de replicación de Active Directory y estado entre controladores de dominio en este dominio. GPOSection = Política de Grupo GPOParagraph = La siguiente sección proporciona una descripción general de los Objetos de Política de Grupo (GPO) configurados y aplicados dentro de este dominio. + ErrorADDomain = Active Directory Domain '@ # Get-AbrADDomain @@ -726,6 +850,8 @@ Reference = Referencia: RIDBestPractice = El porcentaje de RID Emitido excede el 80%. Se recomienda evaluar la utilización de RID para prevenir posible agotamiento y asegurar la estabilidad del dominio. El Identificador Relativo (RID) es un componente crucial en el SID (Identificador de Seguridad) para objetos dentro del dominio. El agotamiento del grupo de RID puede llevar a la incapacidad de crear nuevos principales de seguridad, como cuentas de usuario o computadora. El monitoreo regular y la gestión proactiva del grupo de RID son esenciales para mantener la salud del dominio y evitar disrupciones. RIDReference = https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/managing-rid-pool-depletion/ba-p/399736 + TableName = Resumen del Dominio + ErrorSection = Sección de Resumen del Dominio de AD: '@ # Get-AbrADFSMO @@ -742,6 +868,9 @@ Reference = Referencia: InfraMasterBP = El rol maestro de infraestructura en el dominio {0} debe ser mantenido por un controlador de dominio que no sea un servidor de catálogo global. El maestro de infraestructura es responsable de actualizar referencias de objetos en su dominio a objetos en otros dominios. Si el maestro de infraestructura se ejecuta en un servidor de catálogo global, no funcionará correctamente porque el catálogo global contiene una réplica parcial de cada objeto en el bosque, y no actualizará las referencias. Este problema no afecta bosques que tienen un único dominio. InfraMasterRef = http://go.microsoft.com/fwlink/?LinkId=168841 + TableName = Roles FSMO + ErrorFSMOItem = Flexible Single Master Operations + ErrorPSSession = FSMO Roles Section: New-PSSession: Unable to connect to {0}: {1} '@ # Get-AbrADTrust @@ -783,6 +912,12 @@ BestPractice = Mejor Práctica: AESBP = Asegúrate de que la encriptación Kerberos AES esté habilitada en todas las confianzas de Active Directory. La encriptación RC4 se considera débil y vulnerable a varios ataques. Habilitar la encriptación AES en confianzas mejora la seguridad de Kerberos y se alinea con estándares de seguridad modernos. Referencia: https://techcommunity.microsoft.com/t5/itops-talk-blog/tough-questions-answered-can-i-disable-rc4-etype-for-kerberos-on/ba-p/382718 TrustDiagramSection = Diagrama de Dominios y Confianzas + ErrorTrustItem = Trust Item + ErrorTrustDiagramGraph = Domain and Trusts Diagram Graph: + ErrorTrustDiagramSection = Domain and Trusts Diagram Section: + NoTrustInfo = No se encontró información de confianza de dominio en {0}, deshabilitando esta sección. + ErrorTrustTable = Trust Table + ErrorTrustSection = Trust Section '@ # Continue with remaining sections... @@ -816,6 +951,20 @@ ServiceTGTLifetime = Tiempo de Vida de TGT del Servicio (mins) ComputerTGTLifetime = Tiempo de Vida de TGT de la Computadora (mins) PolicyBP = Las Políticas de Autenticación deben estar configuradas en modo Aplicar para restringir activamente los tiempos de vida de TGT de Kerberos e inicio de sesión de cuenta. Las políticas en modo auditoría solo registran eventos sin aplicar restricciones. + ErrorSiloItem = Authentication Policy Silo Item + SiloTableName = Silo de Política de Autenticación + SilosTableName = Silos de Políticas de Autenticación + ErrorSiloMemberItem = Authentication Policy Silo Member Item + SiloMembersTableName = Miembros del Silo de Política de Autenticación + ErrorSiloMembersTable = Authentication Policy Silo Members Table + ErrorSilosSectionA = Authentication Policy Silos Section + NoSiloInfo = No se encontró información de Silos de Política de Autenticación en {0}, deshabilitando esta sección. + ErrorPolicyItem = Authentication Policy Item + PolicyTableName = Política de Autenticación + PoliciesTableName = Políticas de Autenticación + ErrorPoliciesSection = Authentication Policies Section + NoPolicyInfo = No se encontró información de Políticas de Autenticación en {0}, deshabilitando esta sección. + NoAuthPolicyOrSiloInfo = No se encontró información de Política de Autenticación o Silo en {0}, deshabilitando esta sección. '@ # Get-AbrADDomainObject @@ -985,6 +1134,45 @@ GMSAInactiveBP = *Verifica regularmente y elimina cuentas de servicio administradas grupales inactivas de Active Directory. Las cuentas inactivas pueden ser un riesgo de seguridad ya que pueden ser explotadas por actores maliciosos. Asegurar que solo cuentas activas y necesarias existan ayuda a mantener un entorno seguro y reduce el riesgo de acceso no autorizado o escalada de privilegios. GMSANoHostComputersBP = **No se ha definido "Computadoras Anfitrión"; por favor valida que gMSA esté actualmente en uso. Si no, se recomienda eliminar estos recursos no utilizados de Active Directory. GMSANoRetrieveManagedPasswordBP = ***No se ha definido "Recuperar Contraseña Administrada"; por favor valida que gMSA esté actualmente en uso. Si no, se recomienda eliminar estos recursos no utilizados de Active Directory. + PrivilegedGroupMembersTableName = Miembros del Grupo Privilegiado: + GMSATableName = gMSA + MembersLabel = Miembros + TypeLabelUser = USUARIO + TypeLabelComputer = COMPUTADORA + TypeLabelGroup = GRUPO + TypeLabelFSP = ENTIDAD DE SEGURIDAD EXTERNA + ErrorDomainObjectStats = Domain Object Stats + ErrorUserObjectCountChart = User Object Count Chart + ErrorStatusOfUserAccounts = Status of User Accounts + ErrorStatusOfUsersAccountsChart = Status of Users Accounts Chart + ErrorUsersObjectsTable = Users Objects Table + ErrorUsersObjectsSection = Users Objects Section + ErrorGroupCategoryObjectChart = Group Category Object Chart + ErrorGroupScopesObjectChart = Group Scopes Object Chart + ErrorGroupsObjectsTable = Groups Objects Table + ErrorGroupsObjectsSection = Groups Objects Section + ErrorPrivilegedGroup = Privileged Group in Active Directory + ErrorPrivilegedGroupNonDefaultTable = Privileged Group (Non-Default) Table + ErrorPrivilegedGroupNonDefaultSection = Privileged Group (Non-Default) Section + ErrorEmptyGroupsObjectsTable = Empty Groups Objects Table + ErrorEmptyGroupsObjectsSection = Empty Groups Objects Section + ErrorCircularGroupMembershipTable = Circular Group Membership Table + ErrorCircularGroupMembershipSection = Circular Group Membership Section + ErrorPreWin2000 = Pre-Windows 2000 Compatible Access + ErrorComputersObjectCountChart = Computers Object Count Chart + ErrorStatusOfComputerAccounts = Status of Computer Accounts + ErrorStatusOfComputersAccountsChart = Status of Computers Accounts Chart + ErrorOperatingSystemsInAD = Operating Systems in Active Directory + ErrorComputersPasswordNotRequired = Computers with Password-Not-Required + ErrorComputersObjectsTable = Computers Objects Table + ErrorComputersObjectsSection = Computers Objects Section + ErrorDefaultDomainPasswordPolicy = Default Domain Password Policy + ErrorFGPP = Fine Grained Password Policies + ErrorWindowsLAPS = Windows LAPS + ErrorGMSAItem = Group Managed Service Accounts Item + ErrorGMSASection = Group Managed Service Accounts Section + ErrorFSPItem = Foreign Security Principals Item + ErrorFSPSection = Foreign Security Principals Section '@ # Get-AbrADHardening @@ -1028,6 +1216,8 @@ LDAPSigningBP = La aplicación de firmas LDAP no se configura en este controlador de dominio. La firma LDAP es una función de seguridad que protege la integridad y confidencialidad de las comunicaciones LDAP requiriendo firma de datos. Configura la firma LDAP para requerir firma en todos los controladores de dominio. LDAPCBBindingBP = La aplicación de vinculación de canal de LDAP no se configura en este controlador de dominio. La vinculación de canal de LDAP es una función de seguridad que protege contra ataques de intermediario vinculando la sesión LDAP al canal TLS, asegurando la autenticidad e integridad de las comunicaciones LDAP. Configura la vinculación de canal de LDAP en todos los controladores de dominio. NTLMv1BP = La autenticación NTLMv1 está habilitada en este controlador de dominio. NTLMv1 es un protocolo de autenticación obsoleto que es vulnerable a ataques de captura y retransmisión de credenciales. Deshabilita NTLMv1 en todos los sistemas; ha sido superado por NTLMv2, que ofrece protecciones de seguridad significativamente mejoradas. + ErrorADHardeningItem = ADHardening Item + ErrorADHardeningSection = ADHardening Section '@ # Get-AbrADDomainLastBackup @@ -1046,6 +1236,8 @@ BackupBP1 = Asegúrate de que haya un respaldo reciente de Active Directory (<180 días). BackupBP2 = Los respaldos regulares son cruciales para la recuperación ante desastres y el mantenimiento de la integridad de tu entorno de Active Directory. BackupBP3 = Considera configurar cronogramas de respaldo automatizados y verifica regularmente el estado del respaldo para prevenir pérdida de datos. + ErrorDomainLastBackupItem = Domain Last Backup Item + ErrorDomainLastBackupTable = Domain Last Backup Table '@ # Get-AbrADDuplicateSPN @@ -1061,6 +1253,8 @@ HealthCheck = Verificación de Salud: CorrectiveActions = Acciones Correctivas: SPNBP = Asegúrate de que no haya SPN duplicados (otros que krbtgt). Los SPN duplicados pueden causar problemas de autenticación y deben resolverse rápidamente. Usa el comando `setspn -X` para identificar SPN duplicados. Elimina o reasigna SPN duplicados según sea necesario para mantener un entorno de AD saludable. + ErrorSPNItem = SPN Item + ErrorSPNTable = SPN Table '@ # Get-AbrADDuplicateObject @@ -1077,11 +1271,13 @@ HealthCheck = Verificación de Salud: CorrectiveActions = Acciones Correctivas: DuplicateObjectBP = Asegúrate de que no haya objetos duplicados en Active Directory. Los objetos duplicados pueden causar varios problemas tales como problemas de autenticación, conflictos de replicación y gastos administrativos adicionales. Se recomienda auditar y limpiar regularmente cualquier objeto duplicado para mantener un entorno de Active Directory saludable y eficiente. + ErrorDuplicateObjectItem = Duplicate Object Item + ErrorDuplicateObjectTable = Duplicate Object Table '@ # Get-AbrADDCRoleFeature GetAbrADDCRoleFeature = ConvertFrom-StringData @' - Collecting = Recopilando información de Rol y Características de CD de Active Directory de {0}. + Collecting = Recopilando información de Rol y Características de DC de Active Directory de {0}. Name = Nombre Parent = Padre Description = Descripción @@ -1089,6 +1285,9 @@ HealthCheck = Verificación de Salud: BestPractices = Mejores Prácticas: RoleBP = Los Controladores de Dominio deben tener software y agentes limitados instalados incluyendo roles y servicios. El código no esencial ejecutándose en Controladores de Dominio es un riesgo para el entorno empresarial de Active Directory. Un Controlador de Dominio debe ejecutar solo software requerido, servicios y roles críticos para la operación esencial. + ErrorPSSession = Roles Section: New-PSSession: Unable to connect to {0}: {1} + ErrorRoleFeatureSection = Roles {0} Section: + ErrorRolesSection = Roles Section: '@ # Get-AbrADDCDiag @@ -1100,11 +1299,14 @@ Description = Descripción TableName = Estado de Prueba de DCDiag NoData = No se encontró información de DCDiag en {0}, deshabilitando esta sección. + ErrorDCDiagTestSection = Active Directory DCDiag {0} Section: + ErrorDCDiagSection = Active Directory DCDiag Section: + ErrorInvokeDcDiag = Invoke-DcDiag - Failed to get DCDiag for {0} with error: '@ # Get-AbrADInfrastructureService GetAbrADInfrastructureService = ConvertFrom-StringData @' - Collecting = Recopilando información de Servicios de Infraestructura de CD de Active Directory de {0}. + Collecting = Recopilando información de Servicios de Infraestructura de DC de Active Directory de {0}. DisplayName = Nombre Mostrado ShortName = Nombre Corto Status = Estado @@ -1114,6 +1316,9 @@ CorrectiveActions = Acciones Correctivas: SpoolerBP = El servicio Print Spooler tiene vulnerabilidades conocidas que pueden ser explotadas por atacantes para obtener acceso no autorizado o ejecutar código malicioso. Deshabilitar este servicio en Controladores de Dominio y otros servidores críticos que no requieren servicios de impresión puede reducir la superficie de ataque y mejorar la postura de seguridad general de tu entorno de Active Directory. DHCPServerBP = De acuerdo con las mejores prácticas de seguridad, los servicios de Servidor DHCP deben ejecutarse en un servidor dedicado separado de los controladores de dominio para minimizar riesgos de seguridad, reducir contención de recursos y asegurar rendimiento óptimo de ambos servicios DHCP y Active Directory. + ErrorPSSession = Domain Controller Infrastructure Services Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDCInfraServicesItem = Domain Controller Infrastructure Services Item + ErrorDCInfraServicesTable = Domain Controller Infrastructure Services Table '@ # Get-AbrADDFSHealth @@ -1121,7 +1326,7 @@ Collecting = Recopilando información de Salud de DFS de Dominio de AD en {0}. SysvolReplicationTitle = Estado de Replicación de Sysvol SysvolReplicationParagraph = La siguiente sección proporciona el estado de replicación de la carpeta SYSVOL para el dominio {0}. - DCName = Nombre del CD + DCName = Nombre del DC ReplicationStatus = Estado de Replicación GPOCount = Conteo de GPO SysvolCount = Conteo de Sysvol @@ -1132,7 +1337,7 @@ SysvolReplicationNoData = No se encontró información de DFS en {0}, deshabilitando esta sección. SysvolReplicationHealthCheck = Verificación de Salud: SysvolReplicationCorrectiveActions = Acciones Correctivas: - SysvolReplicationBP = SYSVOL es un directorio especial que reside en cada controlador de dominio (CD) dentro de un dominio. El directorio comprende carpetas que almacenan objetos de Política de Grupo (GPO) y scripts de inicio de sesión que los clientes necesitan acceder y sincronizar entre CDs. Para que estos scripts de inicio de sesión y GPO funcionen correctamente, SYSVOL debe replicarse con precisión y rapidez en todo el dominio. Asegúrate de que se implemente una replicación correcta de SYSVOL para asegurar contenido idéntico de GPO/SYSVOL para el controlador de dominio en todos los dominios de Active Directory. + SysvolReplicationBP = SYSVOL es un directorio especial que reside en cada controlador de dominio (DC) dentro de un dominio. El directorio comprende carpetas que almacenan objetos de Política de Grupo (GPO) y scripts de inicio de sesión que los clientes necesitan acceder y sincronizar entre DCs. Para que estos scripts de inicio de sesión y GPO funcionen correctamente, SYSVOL debe replicarse con precisión y rapidez en todo el dominio. Asegúrate de que se implemente una replicación correcta de SYSVOL para asegurar contenido idéntico de GPO/SYSVOL para el controlador de dominio en todos los dominios de Active Directory. SysvolContentTitle = Estado de Contenido de Sysvol SysvolContentParagraph = La siguiente sección proporciona el estado de salud de SYSVOL para el dominio {0}. SysvolContentNoData = No se encontró información de carpeta SYSVOL en {0}, deshabilitando esta sección. @@ -1148,6 +1353,14 @@ ContentCorrectiveActions = Acciones Correctivas: ContentSysvolBP = Revisa los archivos y extensiones listados arriba y asegúrate de que sean necesarios para la operación de tu dominio. Elimina cualquier archivo que no sea requerido o que parezca sospechoso. Monitorea regularmente la carpeta Sysvol para mantener un entorno de Active Directory saludable y seguro. ContentNetlogonBP = Revisa los archivos y extensiones listados arriba y asegúrate de que sean necesarios para la operación de tu dominio. Elimina cualquier archivo que no sea requerido o que parezca sospechoso. Monitorea regularmente la carpeta Netlogon para mantener un entorno de Active Directory saludable y seguro. + ErrorSysvolReplicationStatusItemSection = Sysvol Replication Status Item Section: + ErrorSysvolReplicationStatusTableSection = Sysvol Replication Status Table Section: + ErrorSysvolContentPSSession = Sysvol Content Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorSysvolHealthSection = Sysvol Health {0} Section: + ErrorSysvolHealthTableSection = Sysvol Health Table Section: + ErrorNetlogonContentPSSession = Netlogon Content Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorNetlogonHealthSection = Netlogon Health {0} Section: + ErrorNetlogonContentStatusSection = Netlogon Content Status Section: '@ # Get-AbrADKerberosAudit @@ -1179,6 +1392,10 @@ AdminHealthCheck = Verificación de Salud: AdminBestPractice = Mejor Práctica: AdminBP = Microsoft recomienda usar una contraseña única y compleja para la cuenta de Administrador integrada y rotarla regularmente (al menos cada 90 días). Considera renombrar la cuenta y deshabilitarla cuando no esté activamente en uso para reducir el riesgo de ataques de fuerza bruta o relleno de credenciales dirigidos a esta cuenta bien conocida. + ErrorUnconstrainedKerberosItem = Unconstrained Kerberos delegation + ErrorKRBTGTAccountItem = KRBTGT account Item + ErrorAdminAccountItem = ADMIN account Item + ErrorUnconstrainedKerberosSection = Unconstrained Kerberos delegation Section '@ # Get-AbrADSiteReplication @@ -1211,6 +1428,15 @@ ReplicationStatusBestPractices = Mejores Prácticas: ReplicationStatusBP = Los fallos de replicación pueden llevar a inconsistencias de objetos, credenciales obsoletas, fallos en la aplicación de Política de Grupo e problemas de autenticación en todo el entorno. Investiga y resuelve cualquier error de replicación rápidamente usando herramientas como repadmin /showrepl o la Herramienta de Estado de Replicación de Active Directory para prevenir mayor divergencia entre controladores de dominio. AutoGeneratedValue = + ErrorSiteReplicationConnectionItem = Site Replication Connection Item + ErrorSiteReplicationConnectionSection = Site Replication Connection Section + SiteLabel = Sitio: + FromLabel = Desde: + ToLabel = Hacia: + ErrorReplicationConnection = Replication Connection + ErrorPSSession = Replication Status Section: New-PSSession: Unable to connect to {0}: {1} + ErrorReplicationStatus = Replication Status + ErrorSiteReplicationStatus = Site Replication Status '@ # Get-AbrADOU @@ -1235,6 +1461,10 @@ GPOBlockedHealthCheck = Verificación de Salud: GPOBlockedCorrectiveActions = Acciones Correctivas: GPOBlockedBP = Revisa el uso de políticas aplicadas y herencia de política bloqueada en Active Directory. Las políticas aplicadas aseguran que Objetos de Política de Grupo (GPO) específicos se apliquen y no puedan ser anulados por otros GPO. La herencia de política bloqueada previene que GPO de contenedores padres se apliquen a la Unidad Organizativa (OU). Aunque estas configuraciones pueden ser útiles para mantener la aplicación de política estricta, también pueden llevar a resultados inesperados y complicar la solución de problemas. Asegúrate de que el uso de estas configuraciones se alinee con la estrategia de gestión de políticas de tu organización y no cause inadvertidamente problemas. + ErrorOUItem = Organizational Unit Item + ErrorBlockedInheritanceGPOItem = Blocked Inheritance GPO Item + ErrorBlockedInheritanceGPOSection = Blocked Inheritance GPO Section + ErrorOUSection = Organizational Unit Section '@ # Get-AbrADSecurityAssessment @@ -1291,6 +1521,19 @@ PrivilegedUsersReference = Referencia: PrivilegedUsersReferenceURL = https://www.stigviewer.com/stig/active_directory_domain/2017-12-15/finding/V-36435 ServiceAccountsAdminCountNote = ** Los Atacantes están más interesados en Cuentas de Servicio que son miembros de grupos altamente privilegiados como Domain Admins. Una forma rápida de verificar esto es enumerar todas las cuentas de usuario con el atributo AdminCount igual a 1. Esto significa que un atacante puede simplemente pedir al Active Directory todas las cuentas de usuario con un SPN y con AdminCount=1. Asegúrate de que no haya cuentas privilegiadas que tengan SPN asignado a ellas. + ErrorAccountSecurityAssessmentItem = Account Security Assessment Item + ErrorUserAccountSecurityAssessmentChart = User Account Security Assessment Chart + NoUserInfo = No se encontró información de usuarios del dominio en {0}, deshabilitando esta sección. + ErrorAccountSecurityAssessmentTable = Account Security Assessment Table + ErrorPrivilegedUsersAssessmentItem = Privileged Users Assessment Item + NoPrivilegedUserInfo = No se encontró información de Evaluación de Usuarios Privilegiados en {0}, deshabilitando esta sección. + ErrorPrivilegedUsersTable = Privileged Users Table + ErrorInactivePrivilegedAccountsItem = Inactive Privileged Accounts Item + NoInactivePrivilegedInfo = No se encontró información de Cuentas Privilegiadas Inactivas en {0}, deshabilitando esta sección. + ErrorInactivePrivilegedAccountsTable = Inactive Privileged Accounts Table + ErrorServiceAccountsAssessmentItem = Service Accounts Assessment Item + NoServiceAccountsInfo = No se encontró información de Evaluación de Cuentas de Servicio en {0}, deshabilitando esta sección. + ErrorServiceAccountsAssessmentTable = Service Accounts Assessment Table '@ # Get-AbrADGPO @@ -1388,6 +1631,23 @@ GPOSettingsParagraph = La siguiente sección proporciona detalles sobre recursos de configuración de Política de Grupo, incluyendo filtros WMI, el repositorio de Almacenamiento Central y scripts anexados a GPO. GPOHealthTitle = Salud de GPO GPOHealthParagraph = La siguiente sección destaca Objetos de Política de Grupo que pueden requerir atención, incluyendo GPO sin vincular, vacíos, aplicados y huérfanos. + ErrorGPOItem = Group Policy Objects + ErrorWMIFiltersItem = WMI Filters + ErrorWMIFiltersPSSession = WMI Filters Section: New-PSSession: Unable to connect to {0}: {1} + ErrorGPOCentralStore = GPO Central Store + ErrorGPOLogonLogoffItem = GPO with Logon/Logoff Script Item + ErrorGPOLogonLogoffSection = GPO with Logon/Logoff Script Section + ErrorGPOStartupShutdownItem = GPO with Computer Startup/Shutdown Item + ErrorGPOStartupShutdownSection = GPO with Computer Startup/Shutdown Section + ErrorUnlinkedGPOItem = Unlinked Group Policy Objects Item + ErrorUnlinkedGPOSection = Unlinked Group Policy Objects Section + ErrorEmptyGPOItem = Empty Group Policy Objects Item + ErrorEmptyGPOSection = Empty Group Policy Objects Section + ErrorEnforcedGPOItem = Enforced Group Policy Objects Item + ErrorEnforcedGPOTable = Enforced Group Policy Objects Table + ErrorOrphanedGPOPSSession = Orphaned GPO Section: New-PSSession: Unable to connect to {0}: {1} + ErrorOrphanedGPOItem = Orphaned GPO + ErrorGPOSection = Group Policy Objects Section '@ # Get-AbrADDomainController GetAbrADDomainController = ConvertFrom-StringData @' @@ -1397,7 +1657,7 @@ BestPractices = Mejores Prácticas: CorrectiveActions = Acciones Correctivas: SecurityBestPractices = Mejores Prácticas de Seguridad: - DCName = Nombre del CD + DCName = Nombre del DC Status = Estado Online = En Línea Offline = Fuera de Línea @@ -1503,6 +1763,47 @@ MissingUpdatesParagraph = La siguiente tabla proporciona un resumen de actualizaciones de Windows pendientes o faltantes detectadas en Controladores de Dominio en el dominio {0}. MissingUpdatesBestPractice = Es crítico instalar actualizaciones de seguridad para proteger tus sistemas de ataques maliciosos. Aplicar regularmente actualizaciones asegura que tus sistemas estén protegidos contra vulnerabilidades recién descubiertos. Además, instalar actualizaciones de software proporciona acceso a nuevas características y mejoras, mejorando el rendimiento y estabilidad general del sistema. Descuidar las actualizaciones puede dejar tus sistemas expuestos a amenazas potenciales y explotación. Por lo tanto, es en tu mejor interés mantener un entorno actualizado instalando rápidamente todas las actualizaciones recomendadas. DCObjectChart = Gráfico de Objeto de Controlador de Dominio + ErrorNetworkInterfacesInfo = No se puede obtener información de interfaces de red de {0} + ErrorDCNetSettingsPSSession = DC Net Settings Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDCItem = Domain Controller Item + UnableToCollect = No se puede recopilar información de {0}. + ErrorDCTable = Domain Controller Table + ErrorGeneralInfoSection = General Information Section + ErrorPartitionsSection = Partitions Section + ErrorNetworkingSettingsSection = Networking Settings Section + ErrorHardwareInventoryTable = Hardware Inventory Table + ErrorDCHardwareSection = Domain Controller Hardware Section + ErrorDCSection = Domain Controller Section + ErrorDNSIPConfigPSSession = DNS IP Configuration Section: New-PSSession: Unable to connect to {0}: {1} + ErrorDNSIPConfigTableSection = Domain Controller DNS IP Configuration Table Section: + ErrorDNSIPConfigItem = DNS IP Configuration Item + ErrorDNSIPConfigSection = Domain Controller DNS IP Configuration Section: + ErrorNTDSPSSession = NTDS Section: New-PSSession: Unable to connect to {0}: {1} + ErrorNTDSItem = NTDS Item + ErrorNTDSSection = NTDS section + ErrorTimeSourcePSSession = Time Source Section: New-PSSession: Unable to connect to {0}: {1} + ErrorTimeSourceItem = Time Source Item + ErrorTimeSourceTable = Time Source Table + ErrorTimeSource = Time Source + ErrorSRVRecordsStatusItem = SRV Records Status Item + ErrorSRVRecordsStatusTable = SRV Records Status Table + ErrorSRVRecordsStatus = SRV Records Status + ErrorFileSharesPSSession = Domain Controllers File Shares Section: New-PSSession: Unable to connect to {0}: {1} + ErrorFileSharesItem = File Shares Item + ErrorFileSharesTable = File Shares Table + ErrorInstalledSoftwarePSSession = Domain Controller Installed Software Section: New-PSSession: Unable to connect to {0}: {1} + ErrorInstalledSoftwareTable = Installed Software Table + ErrorInstalledSoftwareSection = Installed Software Section + ErrorMissingPatchPSSession = Domain Controller Pending Missing Patch Section: New-PSSession: Unable to connect to {0}: {1} + ErrorMissingPatchTable = Installed Software Table + ErrorMissingPatchSection = Domain Controller Section +'@ + + # Get-AbrDiagrammer + GetAbrDiagrammer = ConvertFrom-StringData @' + GettingDiagram = Getting {0} diagram from {1}. + ErrorExportDiagram = Unable to export the {0} Diagram: + ErrorGetDiagram = Unable to get the {0} Diagram: '@ -} \ No newline at end of file +} diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagrammer.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagrammer.ps1 index 4885b3a..ee7bca4 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagrammer.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagrammer.ps1 @@ -61,7 +61,7 @@ function Get-AbrDiagrammer { ) begin { - Write-PScriboMessage -Message "Getting $($DiagramType) diagram from $DomainController ." + Write-PScriboMessage -Message ($reportTranslate.GetAbrDiagrammer.GettingDiagram -f $DiagramType, $DomainController) } process { @@ -136,7 +136,7 @@ function Get-AbrDiagrammer { if (Test-Path -Path $FilePath -PathType Leaf) { $FilePath } else { - Write-PScriboMessage -IsWarning -Message "Unable to export the $DiagramType Diagram: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrDiagrammer.ErrorExportDiagram -f $DiagramType) $($_.Exception.Message)" } } else { Write-Information "Saved '$FileName' diagram to '$($OutputFolderPath)'." -InformationAction Continue @@ -145,10 +145,10 @@ function Get-AbrDiagrammer { } } } catch { - Write-PScriboMessage -IsWarning -Message "Unable to export the $DiagramType Diagram: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrDiagrammer.ErrorExportDiagram -f $DiagramType) $($_.Exception.Message)" } } catch { - Write-PScriboMessage -IsWarning -Message "Unable to get the $DiagramType Diagram: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrDiagrammer.ErrorGetDiagram -f $DiagramType) $($_.Exception.Message)" } } end {} diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-ADExchangeServer.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-ADExchangeServer.ps1 index 51d3171..d12c181 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-ADExchangeServer.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-ADExchangeServer.ps1 @@ -59,7 +59,7 @@ function Get-ADExchangeServer { ServerRoles = $roles; } } catch { - Write-PScriboMessage -IsWarning -Message "ExchangeServer: [$($server.Name)]. $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADExchange.ErrorExchangeServerItem -f $server.Name) $($_.Exception.Message)" } } } \ No newline at end of file diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADAuthenticationPolicy.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADAuthenticationPolicy.ps1 index 1d255b6..b2f1625 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADAuthenticationPolicy.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADAuthenticationPolicy.ps1 @@ -61,7 +61,7 @@ function Get-AbrADAuthenticationPolicy { } $SiloInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Silo Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorSiloItem) $($_.Exception.Message)" } } @@ -73,7 +73,7 @@ function Get-AbrADAuthenticationPolicy { foreach ($Silo in $SiloInfo) { Section -Style NOTOCHeading5 -ExcludeFromTOC "$($Silo.Name)" { $TableParams = @{ - Name = "Authentication Policy Silo - $($Silo.Name)" + Name = "$($reportTranslate.GetAbrADAuthenticationPolicy.SiloTableName) - $($Silo.Name)" List = $true ColumnWidths = 40, 60 } @@ -85,7 +85,7 @@ function Get-AbrADAuthenticationPolicy { } } else { $TableParams = @{ - Name = "Authentication Policy Silos - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADAuthenticationPolicy.SilosTableName) - $($Domain.DNSRoot.ToString().ToUpper())" List = $false Columns = $reportTranslate.GetAbrADAuthenticationPolicy.SiloName, $reportTranslate.GetAbrADAuthenticationPolicy.SiloEnforce, $reportTranslate.GetAbrADAuthenticationPolicy.UserAuthPolicy, $reportTranslate.GetAbrADAuthenticationPolicy.ServiceAuthPolicy, $reportTranslate.GetAbrADAuthenticationPolicy.ComputerAuthPolicy ColumnWidths = 20, 12, 23, 23, 22 @@ -126,7 +126,7 @@ function Get-AbrADAuthenticationPolicy { $SiloMemberInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Silo Member Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorSiloMemberItem) $($_.Exception.Message)" } } } @@ -135,7 +135,7 @@ function Get-AbrADAuthenticationPolicy { Paragraph ($reportTranslate.GetAbrADAuthenticationPolicy.SiloMembersParagraph -f $Domain.DNSRoot.ToString().ToUpper()) BlankLine $TableParams = @{ - Name = "Authentication Policy Silo Members - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADAuthenticationPolicy.SiloMembersTableName) - $($Domain.DNSRoot.ToString().ToUpper())" List = $false ColumnWidths = 20, 20, 15, 45 } @@ -146,14 +146,14 @@ function Get-AbrADAuthenticationPolicy { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Silo Members Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorSiloMembersTable) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Silos Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorSilosSectionA) $($_.Exception.Message)" } } else { - Write-PScriboMessage -Message "No Authentication Policy Silo information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADAuthenticationPolicy.NoSiloInfo -f $Domain.DNSRoot) } if ($AuthPolicies) { try { @@ -181,7 +181,7 @@ function Get-AbrADAuthenticationPolicy { } $PolicyInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorPolicyItem) $($_.Exception.Message)" } } @@ -193,7 +193,7 @@ function Get-AbrADAuthenticationPolicy { foreach ($Policy in $PolicyInfo) { Section -Style NOTOCHeading5 -ExcludeFromTOC "$($Policy.Name)" { $TableParams = @{ - Name = "Authentication Policy - $($Policy.Name)" + Name = "$($reportTranslate.GetAbrADAuthenticationPolicy.PolicyTableName) - $($Policy.Name)" List = $true ColumnWidths = 40, 60 } @@ -205,7 +205,7 @@ function Get-AbrADAuthenticationPolicy { } } else { $TableParams = @{ - Name = "Authentication Policies - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADAuthenticationPolicy.PoliciesTableName) - $($Domain.DNSRoot.ToString().ToUpper())" List = $false Columns = $reportTranslate.GetAbrADAuthenticationPolicy.PolicyName, $reportTranslate.GetAbrADAuthenticationPolicy.PolicyEnforce, $reportTranslate.GetAbrADAuthenticationPolicy.UserTGTLifetime, $reportTranslate.GetAbrADAuthenticationPolicy.ServiceTGTLifetime, $reportTranslate.GetAbrADAuthenticationPolicy.ComputerTGTLifetime ColumnWidths = 20, 12, 23, 23, 22 @@ -227,17 +227,17 @@ function Get-AbrADAuthenticationPolicy { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policies Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorPoliciesSection) $($_.Exception.Message)" } } else { - Write-PScriboMessage -Message "No Authentication Policy information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADAuthenticationPolicy.NoPolicyInfo -f $Domain.DNSRoot) } } } else { - Write-PScriboMessage -Message "No Authentication Policy or Silo information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADAuthenticationPolicy.NoAuthPolicyOrSiloInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Authentication Policy Silos Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADAuthenticationPolicy.ErrorSilosSectionA) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCDiag.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCDiag.ps1 index a116853..117783c 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCDiag.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCDiag.ps1 @@ -69,7 +69,7 @@ function Get-AbrADDCDiag { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Active Directory DCDiag $($Result.TestName) Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDCDiag.ErrorDCDiagTestSection -f $Result.TestName) $($_.Exception.Message)" } } if ($HealthCheck.DomainController.Diagnostic) { @@ -89,7 +89,7 @@ function Get-AbrADDCDiag { Write-PScriboMessage -Message ($reportTranslate.GetAbrADDCDiag.NoData -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "Active Directory DCDiag Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDCDiag.ErrorDCDiagSection) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCRoleFeature.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCRoleFeature.ps1 index c827c01..e6aefea 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCRoleFeature.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDCRoleFeature.ps1 @@ -33,7 +33,7 @@ function Get-AbrADDCRoleFeature { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Roles Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDCRoleFeature.ErrorPSSession -f $DC, $ErrorMessage) } if ($Features) { Section -ExcludeFromTOC -Style NOTOCHeading5 $($DC.ToString().ToUpper().Split('.')[0]) { @@ -47,7 +47,7 @@ function Get-AbrADDCRoleFeature { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Roles $($Feature.DisplayName) Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDCRoleFeature.ErrorRoleFeatureSection -f $Feature.DisplayName) $($_.Exception.Message)" } } @@ -78,7 +78,7 @@ function Get-AbrADDCRoleFeature { } } } catch { - Write-PScriboMessage -IsWarning -Message "Roles Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDCRoleFeature.ErrorRolesSection) $($_.Exception.Message)" } } end { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDFSHealth.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDFSHealth.ps1 index c270c2e..1c1a924 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDFSHealth.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDFSHealth.ps1 @@ -71,7 +71,7 @@ } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Replication Status Iten Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorSysvolReplicationStatusItemSection) $($_.Exception.Message)" } } @@ -117,7 +117,7 @@ Write-PScriboMessage -Message ($reportTranslate.GetAbrADDFSHealth.SysvolReplicationNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Replication Status Table Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorSysvolReplicationStatusTableSection) $($_.Exception.Message)" } try { @@ -134,7 +134,7 @@ if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Sysvol Content Status Section: New-PSSession: Unable to connect to $($ValidDcFromDomain): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDFSHealth.ErrorSysvolContentPSSession -f $ValidDcFromDomain, $ErrorMessage) } if ($SYSVOLFolder) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADDFSHealth.SysvolContentTitle { @@ -150,7 +150,7 @@ } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Health $($Extension.Extension) Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorSysvolHealthSection -f $Extension.Extension) $($_.Exception.Message)" } } @@ -181,7 +181,7 @@ Write-PScriboMessage -Message ($reportTranslate.GetAbrADDFSHealth.SysvolContentNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Health Table Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorSysvolHealthTableSection) $($_.Exception.Message)" } try { $DCPssSession = Get-ValidPSSession -ComputerName $ValidDcFromDomain -SessionName $($ValidDcFromDomain) -PSSTable ([ref]$PSSTable) @@ -197,7 +197,7 @@ if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Netlogon Content Status Section: New-PSSession: Unable to connect to $($ValidDcFromDomain): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDFSHealth.ErrorNetlogonContentPSSession -f $ValidDcFromDomain, $ErrorMessage) } if ($NetlogonFolder) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADDFSHealth.NetlogonContentTitle { @@ -213,7 +213,7 @@ } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Netlogon Health $($Extension.Extension) Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorNetlogonHealthSection -f $Extension.Extension) $($_.Exception.Message)" } } @@ -244,7 +244,7 @@ Write-PScriboMessage -Message ($reportTranslate.GetAbrADDFSHealth.NetlogonContentNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "Netlogon Content Status Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDFSHealth.ErrorNetlogonContentStatusSection) $($_.Exception.Message)" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSInfrastructure.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSInfrastructure.ps1 index 8681b6f..c47f808 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSInfrastructure.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSInfrastructure.ps1 @@ -47,7 +47,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "DNS Infrastructure Summary Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorInfrastructureSummarySection) $($_.Exception.Message)" } } } @@ -93,7 +93,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Directory Partitions Item Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorDirectoryPartitionsItemSection) $($_.Exception.Message)" } } $TableParams = @{ @@ -107,13 +107,13 @@ function Get-AbrADDNSInfrastructure { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDNSInfrastructure.Name | Table @TableParams } } catch { - Write-PScriboMessage -IsWarning -Message "Directory Partitions Table Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorDirectoryPartitionsTableSection) $($_.Exception.Message)" } } } } } catch { - Write-PScriboMessage -IsWarning -Message "Directory Partitions Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorDirectoryPartitionsSection) $($_.Exception.Message)" } } #---------------------------------------------------------------------------------------------# @@ -140,7 +140,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Response Rate Limiting (RRL) Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorRRLItem) $($_.Exception.Message)" } } } @@ -156,7 +156,7 @@ function Get-AbrADDNSInfrastructure { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDNSInfrastructure.DCName | Table @TableParams } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Response Rate Limiting (RRL) Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorRRLTable) $($_.Exception.Message)" } } #---------------------------------------------------------------------------------------------# @@ -189,7 +189,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Scavenging Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorScavengingItem) $($_.Exception.Message)" } } } @@ -217,7 +217,7 @@ function Get-AbrADDNSInfrastructure { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Scavenging Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorScavengingTable) $($_.Exception.Message)" } } #---------------------------------------------------------------------------------------------# @@ -241,7 +241,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Forwarder Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorForwarderItem) $($_.Exception.Message)" } } } @@ -285,7 +285,7 @@ function Get-AbrADDNSInfrastructure { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Forwarder Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorForwarderTable) $($_.Exception.Message)" } #---------------------------------------------------------------------------------------------# # DNS Root Hints Section # @@ -383,13 +383,13 @@ function Get-AbrADDNSInfrastructure { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Root Hints Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorRootHintsTable) $($_.Exception.Message)" } } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Root Hints Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorRootHintsSection) $($_.Exception.Message)" } } #---------------------------------------------------------------------------------------------# @@ -415,7 +415,7 @@ function Get-AbrADDNSInfrastructure { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Scope Recursion Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorZoneScopeRecursionItem) $($_.Exception.Message)" } } } @@ -431,13 +431,13 @@ function Get-AbrADDNSInfrastructure { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDNSInfrastructure.DCName | Table @TableParams } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Scope Recursion Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorZoneScopeRecursionTable) $($_.Exception.Message)" } } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (DNS Infrastructure Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSInfrastructure.ErrorDNSInfrastructureSection) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSZone.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSZone.ps1 index f055409..dfb5221 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSZone.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDNSZone.ps1 @@ -47,7 +47,7 @@ function Get-AbrADDNSZone { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Name System Zone Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorDNSZoneItem) $($_.Exception.Message)" } } @@ -83,14 +83,14 @@ function Get-AbrADDNSZone { } } } else { - Write-PScriboMessage -Message "DNS Zones $($Zone) Section: No Zone Delegation information found, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoDelegationInfo -f $Zone) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Delegation Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneDelegationItem) $($_.Exception.Message)" } } } else { - Write-PScriboMessage -Message "DNS Zones Section: No Zone Delegation information found in $DC, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoDelegationInfoDC -f $DC) } if ($OutObj) { @@ -108,7 +108,7 @@ function Get-AbrADDNSZone { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Delegation Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneDelegationTable) $($_.Exception.Message)" } } @@ -122,7 +122,7 @@ function Get-AbrADDNSZone { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "DNS Zones Transfers Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDNSZone.ErrorZoneTransferPSSession -f $DC, $ErrorMessage) } if ($DNSSetting) { Section -Style Heading4 $reportTranslate.GetAbrADDNSZone.ZoneTransfers { @@ -147,7 +147,7 @@ function Get-AbrADDNSZone { $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDNSZone.SecureSecondaries) -eq $reportTranslate.GetAbrADDNSZone.SecureSecondariesAll } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADDNSZone.SecureSecondaries } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Transfers Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneTransfersItem) $($_.Exception.Message)" } } @@ -170,10 +170,10 @@ function Get-AbrADDNSZone { } } } else { - Write-PScriboMessage -Message "DNS Zones Section: No Zone Transfer information found in $DC, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoZoneTransferInfo -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Transfers Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneTransfersTable) $($_.Exception.Message)" } } try { @@ -194,7 +194,7 @@ function Get-AbrADDNSZone { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Reverse Lookup Zone Configuration Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorReverseLookupZoneItem) $($_.Exception.Message)" } } @@ -209,10 +209,10 @@ function Get-AbrADDNSZone { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDNSZone.ZoneName | Table @TableParams } } else { - Write-PScriboMessage -Message "DNS Zones Section: No Reverse lookup zone information found in $DC, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoReverseLookupZoneInfo -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Reverse Lookup Zone Configuration Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorReverseLookupZoneTable) $($_.Exception.Message)" } try { $DNSSetting = Get-DnsServerZone -CimSession $TempCIMSession -ComputerName $DC | Where-Object { $_.IsReverseLookupZone -like 'False' -and $_.ZoneType -like 'Forwarder' } @@ -230,7 +230,7 @@ function Get-AbrADDNSZone { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Conditional Forwarder Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorConditionalForwarderItem) $($_.Exception.Message)" } } @@ -245,10 +245,10 @@ function Get-AbrADDNSZone { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDNSZone.ZoneName | Table @TableParams } } else { - Write-PScriboMessage -Message "DNS Zones Section: No Conditional forwarder zone information found in $DC, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoConditionalForwarderInfo -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Conditional Forwarder Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorConditionalForwarderTable) $($_.Exception.Message)" } if ($InfoLevel.DNS -ge 2) { try { @@ -272,7 +272,7 @@ function Get-AbrADDNSZone { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Scope Aging Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneScopeAgingItem) $($_.Exception.Message)" } } @@ -299,16 +299,16 @@ function Get-AbrADDNSZone { } } } else { - Write-PScriboMessage -Message "DNS Zones Section: No Zone Aging property information found in $DC, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDNSZone.NoZoneAgingInfo -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Zone Scope Aging Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorZoneScopeAgingTable) $($_.Exception.Message)" } } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Global DNS Zone Information)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDNSZone.ErrorGlobalDNSZoneInfo) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomain.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomain.ps1 index 22880a7..c866ea4 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomain.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomain.ps1 @@ -68,7 +68,7 @@ function Get-AbrADDomain { } $TableParams = @{ - Name = "Domain Summary - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADDomain.TableName) - $($Domain.DNSRoot.ToString().ToUpper())" List = $true ColumnWidths = 40, 60 } @@ -91,7 +91,7 @@ function Get-AbrADDomain { } } } catch { - Write-PScriboMessage -IsWarning -Message "AD Domain Summary Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomain.ErrorSection) $($_.Exception.Message)" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 index 0cd679d..3180504 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 @@ -1,4 +1,4 @@ -function Get-AbrADDomainController { +function Get-AbrADDomainController { <# .SYNOPSIS Used by As Built Report to retrieve Microsoft AD Domain Controller information. @@ -34,12 +34,12 @@ function Get-AbrADDomainController { $DCPssSession = Get-ValidPSSession -ComputerName $DC -SessionName $($DC) -PSSTable ([ref]$PSSTable) if ($DCPssSession ) { - $DCNetSettings = try { Invoke-CommandWithTimeout -Session $DCPssSession -ScriptBlock { Get-NetIPAddress } } catch { Write-PScriboMessage -IsWarning -Message "Unable to get $DC network interfaces information" } + $DCNetSettings = try { Invoke-CommandWithTimeout -Session $DCPssSession -ScriptBlock { Get-NetIPAddress } } catch { Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorNetworkInterfacesInfo -f $DC) } } else { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "DC Net Settings Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorDCNetSettingsPSSession -f $DC, $ErrorMessage) } try { $inObj = [ordered] @{ @@ -60,11 +60,11 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCItem) $($_.Exception.Message)" } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainController.UnableToCollect -f $DC) $inObj = [ordered] @{ $($reportTranslate.GetAbrADDomainController.DCName) = $DC.ToString().ToUpper().Split('.')[0] $($reportTranslate.GetAbrADDomainController.Status) = $reportTranslate.GetAbrADDomainController.Offline @@ -75,7 +75,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCItem) $($_.Exception.Message)" } } } @@ -103,7 +103,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCTable) $($_.Exception.Message)" } try { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -151,7 +151,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "DC Net Settings Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorDCNetSettingsPSSession -f $DC, $ErrorMessage) } try { Section -Style Heading5 $DCInfo.Name { @@ -204,7 +204,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (General Information Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorGeneralInfoSection) $($_.Exception.Message)" } try { Section -ExcludeFromTOC -Style NOTOCHeading6 $reportTranslate.GetAbrADDomainController.PartitionsTitle { @@ -227,7 +227,7 @@ function Get-AbrADDomainController { $OutObj | Table @TableParams } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Partitions Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorPartitionsSection) $($_.Exception.Message)" } try { if ($DCNetSettings) { @@ -274,7 +274,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Networking Settings Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNetworkingSettingsSection) $($_.Exception.Message)" } try { $DCHWInfo = [System.Collections.Generic.List[object]]::new() @@ -343,14 +343,14 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Hardware Inventory Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorHardwareInventoryTable) $($_.Exception.Message)" } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Hardware Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCHardwareSection) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCSection) $($_.Exception.Message)" } } } @@ -360,7 +360,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCSection) $($_.Exception.Message)" } } #---------------------------------------------------------------------------------------------# @@ -381,7 +381,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "DNS IP Configuration Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorDNSIPConfigPSSession -f $DC, $ErrorMessage) } foreach ($DNSServer in $DNSSettings.ServerAddresses) { if ($DCPssSession) { @@ -403,15 +403,15 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($DC.ToString().ToUpper().Split('.')[0]) DNS IP Configuration Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDNSIPConfigItem) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "Domain Controller DNS IP Configuration Table Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDNSIPConfigTableSection) $($_.Exception.Message)" } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainController.UnableToCollect -f $DC) $inObj = [ordered] @{ $($reportTranslate.GetAbrADDomainController.DCName) = $DC.ToString().ToUpper().Split('.')[0] $($reportTranslate.GetAbrADDomainController.Interface) = '--' @@ -422,7 +422,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (DNS IP Configuration Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDNSIPConfigItem) $($_.Exception.Message)" } } } @@ -482,7 +482,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "Domain Controller DNS IP Configuration Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDNSIPConfigSection) $($_.Exception.Message)" } try { @@ -501,7 +501,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "NTDS Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorNTDSPSSession -f $DC, $ErrorMessage) } if ( $NTDS -and $size ) { $inObj = [ordered] @{ @@ -514,11 +514,11 @@ function Get-AbrADDomainController { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (NTDS Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNTDSItem) $($_.Exception.Message)" } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainController.UnableToCollect -f $DC) $inObj = [ordered] @{ $($reportTranslate.GetAbrADDomainController.DCName) = $DC.ToString().ToUpper().Split('.')[0] $($reportTranslate.GetAbrADDomainController.DatabaseFile) = '--' @@ -528,7 +528,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (NTDS Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNTDSItem) $($_.Exception.Message)" } } } @@ -547,7 +547,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (NTDS section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNTDSSection) $($_.Exception.Message)" } try { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -563,7 +563,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Time Source Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorTimeSourcePSSession -f $DC, $ErrorMessage) } if ( $NtpServer -and $SourceType ) { try { @@ -583,15 +583,15 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning "$($_.Exception.Message) (Time Source Item)" + Write-PScriboMessage -IsWarning "$($reportTranslate.GetAbrADDomainController.ErrorTimeSourceItem) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Time Source Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorTimeSourceTable) $($_.Exception.Message)" } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainController.UnableToCollect -f $DC) $inObj = [ordered] @{ $($reportTranslate.GetAbrADDomainController.Name) = $DC.ToString().ToUpper().Split('.')[0] $($reportTranslate.GetAbrADDomainController.TimeServer) = '--' @@ -599,7 +599,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (NTDS Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNTDSItem) $($_.Exception.Message)" } } } @@ -619,7 +619,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Time Source)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorTimeSource) $($_.Exception.Message)" } if ($HealthCheck.DomainController.Diagnostic) { try { @@ -691,7 +691,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning "$($_.Exception.Message) (SRV Records Status Item)" + Write-PScriboMessage -IsWarning "$($reportTranslate.GetAbrADDomainController.ErrorSRVRecordsStatusItem) $($_.Exception.Message)" } if ($HealthCheck.DomainController.Diagnostic) { $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDomainController.ARecord) -eq $reportTranslate.GetAbrADDomainController.Fail } | Set-Style -Style Critical -Property $reportTranslate.GetAbrADDomainController.ARecord @@ -703,11 +703,11 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SRV Records Status Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorSRVRecordsStatusTable) $($_.Exception.Message)" } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainController.UnableToCollect -f $DC) $inObj = [ordered] @{ $($reportTranslate.GetAbrADDomainController.Name) = $DC.ToString().ToUpper().Split('.')[0] $($reportTranslate.GetAbrADDomainController.ARecord) = '--' @@ -718,7 +718,7 @@ function Get-AbrADDomainController { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (NTDS Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorNTDSItem) $($_.Exception.Message)" } } } @@ -746,7 +746,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SRV Records Status)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorSRVRecordsStatus) $($_.Exception.Message)" } } try { @@ -763,7 +763,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Domain Controllers File Shares Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorFileSharesPSSession -f $DC, $ErrorMessage) } if ($Shares) { Section -ExcludeFromTOC -Style NOTOCHeading5 $($DC.ToString().ToUpper().Split('.')[0]) { @@ -794,7 +794,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (File Shares Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorFileSharesItem) $($_.Exception.Message)" } } } @@ -813,7 +813,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (File Shares Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorFileSharesTable) $($_.Exception.Message)" } if ($HealthCheck.DomainController.Software) { try { @@ -832,7 +832,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Domain Controller Installed Software Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorInstalledSoftwarePSSession -f $DC, $ErrorMessage) } if ($SoftwareX64) { @@ -897,7 +897,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Installed Software Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorInstalledSoftwareTable) $($_.Exception.Message)" } } } @@ -909,7 +909,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Installed Software Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorInstalledSoftwareSection) $($_.Exception.Message)" } try { # Todo: Fix arraylist issue with foreach @@ -926,7 +926,7 @@ function Get-AbrADDomainController { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Domain Controller Pending Missing Patch Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADDomainController.ErrorMissingPatchPSSession -f $DC, $ErrorMessage) } if ( $Updates ) { @@ -967,7 +967,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Installed Software Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorInstalledSoftwareTable) $($_.Exception.Message)" } } } @@ -979,7 +979,7 @@ function Get-AbrADDomainController { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainController.ErrorDCSection) $($_.Exception.Message)" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainLastBackup.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainLastBackup.ps1 index ac50a68..d78e2d9 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainLastBackup.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainLastBackup.ps1 @@ -49,7 +49,7 @@ function Get-AbrADDomainLastBackup { $OutObj | Where-Object { [int]$_.$($reportTranslate.GetAbrADDomainLastBackup.LastBackupInDays) -gt 180 } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADDomainLastBackup.LastBackupInDays } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Last Backup Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDomainLastBackup.ErrorDomainLastBackupItem))" } } @@ -78,7 +78,7 @@ function Get-AbrADDomainLastBackup { Write-PScriboMessage -Message ($reportTranslate.GetAbrADDomainLastBackup.NoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Last Backup Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDomainLastBackup.ErrorDomainLastBackupTable))" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 index dea976f..f70662a 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 @@ -65,10 +65,10 @@ function Get-AbrADDomainObject { $ADObjects = $Users + $GroupObj } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Object Stats)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorDomainObjectStats) $($_.Exception.Message)" } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Object Stats)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorDomainObjectStats) $($_.Exception.Message)" } try { Section -Style Heading4 $reportTranslate.GetAbrADDomainObject.UserObjectsSection { @@ -94,7 +94,7 @@ function Get-AbrADDomainObject { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Category' $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.UserObjectsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (User Object Count Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorUserObjectCountChart) $($_.Exception.Message)" } if ($OutObj) { @@ -170,7 +170,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Status of User Accounts)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfUserAccounts) $($_.Exception.Message)" } } @@ -186,7 +186,7 @@ function Get-AbrADDomainObject { $sampleData = $OutObj $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfUsersSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 800 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Status of Users Accounts Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfUsersAccountsChart) $($_.Exception.Message)" } } if ($OutObj) { @@ -223,7 +223,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Users Objects Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorUsersObjectsTable) $($_.Exception.Message)" } } @@ -241,7 +241,7 @@ function Get-AbrADDomainObject { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Users Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorUsersObjectsSection) $($_.Exception.Message)" } } Show-AbrDebugExecutionTime -End -TitleMessage 'User Objects' @@ -272,7 +272,7 @@ function Get-AbrADDomainObject { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupCategoriesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Category Object Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupCategoryObjectChart) $($_.Exception.Message)" } if ($OutObj) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADDomainObject.GroupCategoriesSubSection { @@ -306,7 +306,7 @@ function Get-AbrADDomainObject { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupScopesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Scopes Object Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupScopesObjectChart) $($_.Exception.Message)" } if ($OutObj) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADDomainObject.GroupScopesSubSection { @@ -335,7 +335,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Groups Objects Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupsObjectsTable) $($_.Exception.Message)" } } @@ -353,7 +353,7 @@ function Get-AbrADDomainObject { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Groups Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupsObjectsSection) $($_.Exception.Message)" } } if ($GroupOBj) { @@ -379,7 +379,7 @@ function Get-AbrADDomainObject { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group in Active Directory item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroup) $($_.Exception.Message)" } } @@ -438,7 +438,7 @@ function Get-AbrADDomainObject { if ($Group = ($GroupOBj | Where-Object { $_.SID -like $GroupSID })) { $GroupObjects = $Group.Members if ($GroupObjFilter = $ADObjects | Where-Object { $_.distinguishedName -in $GroupObjects }) { - Section -ExcludeFromTOC -Style NOTOCHeading4 "$($Group.Name) ($(($GroupObjects | Measure-Object).count) Members)" { + Section -ExcludeFromTOC -Style NOTOCHeading4 "$($Group.Name) ($(($GroupObjects | Measure-Object).count) $($reportTranslate.GetAbrADDomainObject.MembersLabel))" { $OutObj = [System.Collections.Generic.List[object]]::new() foreach ($GroupObject in $GroupObjFilter) { try { @@ -454,7 +454,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group in Active Directory item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroup) $($_.Exception.Message)" } } @@ -472,7 +472,7 @@ function Get-AbrADDomainObject { } $TableParams = @{ - Name = "$($Group.Name) - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADDomainObject.PrivilegedGroupMembersTableName) $($Group.Name) - $($Domain.DNSRoot.ToString().ToUpper())" List = $false ColumnWidths = 50, 20, 15, 15 } @@ -520,13 +520,13 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group in Active Directory item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroup) $($_.Exception.Message)" } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group in Active Directory)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroup) $($_.Exception.Message)" } Show-AbrDebugExecutionTime -End -TitleMessage 'Privileged Groups (Built-in)' } @@ -545,7 +545,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group (Non-Default) Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroupNonDefaultTable) $($_.Exception.Message)" } } } @@ -576,7 +576,7 @@ function Get-AbrADDomainObject { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Group (Non-Default) Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPrivilegedGroupNonDefaultSection) $($_.Exception.Message)" } } if ($HealthCheck.Domain.BestPractice -and ($EmptyGroupOBj)) { @@ -594,7 +594,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Empty Groups Objects Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorEmptyGroupsObjectsTable) $($_.Exception.Message)" } } } @@ -620,7 +620,7 @@ function Get-AbrADDomainObject { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Empty Groups Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorEmptyGroupsObjectsSection) $($_.Exception.Message)" } } if ($HealthCheck.Domain.BestPractice -and $InfoLevel.Domain -ge 2) { @@ -648,7 +648,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Circular Group Membership Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorCircularGroupMembershipTable) $($_.Exception.Message)" } } } @@ -686,7 +686,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Circular Group Membership Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorCircularGroupMembershipSection) $($_.Exception.Message)" } } if ($HealthCheck.Domain.Security) { @@ -699,15 +699,15 @@ function Get-AbrADDomainObject { foreach ($MemberDN in $GroupMembers) { try { if ($MemberUser = $Users | Where-Object { $_.DistinguishedName -eq $MemberDN }) { - $MemberName = "$($MemberUser.SamAccountName) (USER)" + $MemberName = "$($MemberUser.SamAccountName) ($($reportTranslate.GetAbrADDomainObject.TypeLabelUser))" } elseif ($MemberComputer = $Computers | Where-Object { $_.DistinguishedName -eq $MemberDN }) { - $MemberName = "$($MemberComputer.Name) (COMPUTER)" + $MemberName = "$($MemberComputer.Name) ($($reportTranslate.GetAbrADDomainObject.TypeLabelComputer))" } elseif ($MemberGroup = $GroupOBj | Where-Object { $_.DistinguishedName -eq $MemberDN }) { - $MemberName = "$($MemberGroup.Name) (GROUP)" + $MemberName = "$($MemberGroup.Name) ($($reportTranslate.GetAbrADDomainObject.TypeLabelGroup))" } elseif ($MemberFSP = $FSP | Where-Object { $_.DistinguishedName -eq $MemberDN }) { - $MemberName = "$($MemberFSP.'msds-principalname') (FOREIGN SECURITY PRINCIPAL)" + $MemberName = "$($MemberFSP.'msds-principalname') ($($reportTranslate.GetAbrADDomainObject.TypeLabelFSP))" } elseif ($MemberDN -match 'ForeignSecurityPrincipals') { - $MemberName = "$(($MemberDN -split ',')[0] -replace '^CN=') (FOREIGN SECURITY PRINCIPAL)" + $MemberName = "$(($MemberDN -split ',')[0] -replace '^CN=') ($($reportTranslate.GetAbrADDomainObject.TypeLabelFSP))" } else { $MemberName = ($MemberDN -split ',')[0] -replace '^CN=' } @@ -717,7 +717,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Pre-Windows 2000 Compatible Access Group Member)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPreWin2000) $($_.Exception.Message)" } } if ($OutObj) { @@ -745,7 +745,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Pre-Windows 2000 Compatible Access Group Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorPreWin2000) $($_.Exception.Message)" } Show-AbrDebugExecutionTime -End -TitleMessage 'Pre-Windows 2000 Compatible Access Group' } @@ -776,7 +776,7 @@ function Get-AbrADDomainObject { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.ComputersCount)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Computers Object Count Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersObjectCountChart) $($_.Exception.Message)" } if ($OutObj) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADDomainObject.ComputersSubSection { @@ -838,7 +838,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Status of Computer Accounts)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfComputerAccounts) $($_.Exception.Message)" } } @@ -854,7 +854,7 @@ function Get-AbrADDomainObject { $sampleData = $OutObj $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfComputerAccountsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Status of Computers Accounts Chart)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfComputersAccountsChart) $($_.Exception.Message)" } if ($OutObj) { @@ -910,7 +910,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Operating Systems in Active Directory)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorOperatingSystemsInAD) $($_.Exception.Message)" } Show-AbrDebugExecutionTime -End -TitleMessage 'Operating Systems Count' } @@ -951,14 +951,14 @@ function Get-AbrADDomainObject { Text $reportTranslate.GetAbrADDomainObject.PasswordNotRequiredBP } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Computers with Password-Not-Required table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersPasswordNotRequired) $($_.Exception.Message)" } } Show-AbrDebugExecutionTime -End -TitleMessage 'Computers with Password-Not-Required Attribute Set' } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Computers with Password-Not-Required section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersPasswordNotRequired) $($_.Exception.Message)" } if ($InfoLevel.Domain -ge 4) { try { @@ -979,7 +979,7 @@ function Get-AbrADDomainObject { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Computers Objects Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersObjectsTable) $($_.Exception.Message)" } } @@ -997,7 +997,7 @@ function Get-AbrADDomainObject { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Computers Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersObjectsSection) $($_.Exception.Message)" } } Show-AbrDebugExecutionTime -End -TitleMessage 'Computer Objects' @@ -1051,7 +1051,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Default Domain Password Policy)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorDefaultDomainPasswordPolicy) $($_.Exception.Message)" } Show-AbrDebugExecutionTime -End -TitleMessage 'Default Domain Password Policy' } @@ -1123,7 +1123,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Fined Grained Password Policies)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorFGPP) $($_.Exception.Message)" } try { @@ -1192,7 +1192,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Windows LAPS)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorWindowsLAPS) $($_.Exception.Message)" } try { @@ -1231,7 +1231,7 @@ function Get-AbrADDomainObject { $GMSAInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Managed Service Accounts Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGMSAItem) $($_.Exception.Message)" } } @@ -1264,7 +1264,7 @@ function Get-AbrADDomainObject { foreach ($Account in $GMSAInfo) { Section -Style NOTOCHeading4 -ExcludeFromTOC "$($Account.$($reportTranslate.GetAbrADDomainObject.GMSAName))" { $TableParams = @{ - Name = "gMSA - $($Account.$($reportTranslate.GetAbrADDomainObject.GMSAName))" + Name = "$($reportTranslate.GetAbrADDomainObject.GMSATableName) - $($Account.$($reportTranslate.GetAbrADDomainObject.GMSAName))" List = $true ColumnWidths = 40, 60 } @@ -1299,7 +1299,7 @@ function Get-AbrADDomainObject { } } else { $TableParams = @{ - Name = "gMSA - $($Domain.DNSRoot.ToString().ToUpper())" + Name = "$($reportTranslate.GetAbrADDomainObject.GMSATableName) - $($Domain.DNSRoot.ToString().ToUpper())" List = $false Columns = $reportTranslate.GetAbrADDomainObject.GMSAName, $reportTranslate.GetAbrADDomainObject.GMSALogonCount, $reportTranslate.GetAbrADDomainObject.GMSALockedOut, $reportTranslate.GetAbrADDomainObject.GMSALastLogonDate, $reportTranslate.GetAbrADDomainObject.GMSAPasswordLastSet, $reportTranslate.GetAbrADDomainObject.GMSAEnabled ColumnWidths = 25, 15, 15, 15, 15, 15 @@ -1323,7 +1323,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Managed Service Accounts Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGMSASection) $($_.Exception.Message)" } } catch { Write-PScriboMessage -IsWarning $($_.Exception.Message) @@ -1349,7 +1349,7 @@ function Get-AbrADDomainObject { $FSPInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Foreign Security Principals Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorFSPItem) $($_.Exception.Message)" } } @@ -1366,7 +1366,7 @@ function Get-AbrADDomainObject { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Foreign Security Principals Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorFSPSection) $($_.Exception.Message)" } } catch { Write-PScriboMessage -IsWarning $($_.Exception.Message) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateObject.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateObject.ps1 index e1b7660..d13417c 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateObject.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateObject.ps1 @@ -47,7 +47,7 @@ function Get-AbrADDuplicateObject { $OutObj | Set-Style -Style Warning } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Duplicate Object Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDuplicateObject.ErrorDuplicateObjectItem))" } } @@ -72,7 +72,7 @@ function Get-AbrADDuplicateObject { Write-PScriboMessage -Message ($reportTranslate.GetAbrADDuplicateObject.NoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Duplicate Object Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDuplicateObject.ErrorDuplicateObjectTable))" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateSPN.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateSPN.ps1 index f0306c5..4389cf8 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateSPN.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDuplicateSPN.ps1 @@ -46,7 +46,7 @@ function Get-AbrADDuplicateSPN { $OutObj | Set-Style -Style Warning } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SPN Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDuplicateSPN.ErrorSPNItem))" } } @@ -73,7 +73,7 @@ function Get-AbrADDuplicateSPN { Write-PScriboMessage -Message ($reportTranslate.GetAbrADDuplicateSPN.NoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SPN Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADDuplicateSPN.ErrorSPNTable))" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADExchange.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADExchange.ps1 index fea6e8d..8a8c723 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADExchange.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADExchange.ps1 @@ -41,7 +41,7 @@ function Get-AbrADExchange { } $EXInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Exchange Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADExchange.ErrorExchangeItem))" } } @@ -73,12 +73,12 @@ function Get-AbrADExchange { } } } else { - Write-PScriboMessage -Message "No Exchange Infrastructure information found in $($ForestInfo.toUpper()), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADExchange.NoExchangeInfo -f $ForestInfo.toUpper()) Paragraph $reportTranslate.GetAbrADExchange.NotFound BlankLine } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Exchabge Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADExchange.ErrorExchangeTable))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADFSMO.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADFSMO.ps1 index 48efead..dcb2a2c 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADFSMO.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADFSMO.ps1 @@ -45,7 +45,7 @@ function Get-AbrADFSMO { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Flexible Single Master Operations)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADFSMO.ErrorFSMOItem))" } if ($HealthCheck.Domain.BestPractice) { @@ -55,7 +55,7 @@ function Get-AbrADFSMO { } $TableParams = @{ - Name = "FSMO Roles - $($Domain.DNSRoot)" + Name = "$($reportTranslate.GetAbrADFSMO.TableName) - $($Domain.DNSRoot)" List = $true ColumnWidths = 40, 60 } @@ -81,12 +81,12 @@ function Get-AbrADFSMO { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "FSMO Roles Section: New-PSSession: Unable to connect to $($Domain.DNSRoot): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADFSMO.ErrorPSSession -f $Domain.DNSRoot, $ErrorMessage) } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Flexible Single Master Operations)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADFSMO.ErrorFSMOItem))" } } end { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADForest.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADForest.ps1 index 76d07c6..81d81ef 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADForest.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADForest.ps1 @@ -79,7 +79,7 @@ function Get-AbrADForest { } $TableParams = @{ - Name = "Forest Summary - $($ForestInfo)" + Name = "$($reportTranslate.GetAbrADForest.TableName) - $($ForestInfo)" List = $true ColumnWidths = 40, 60 } @@ -112,7 +112,7 @@ function Get-AbrADForest { try { $Graph = Get-AbrDiagrammer -DiagramType 'Forest' -DiagramOutput base64 -PSSessionObject $TempPssSession } catch { - Write-PScriboMessage -IsWarning -Message "Forest Diagram Graph: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADForest.ErrorForestDiagramGraph) $($_.Exception.Message)" } if ($Graph) { @@ -124,7 +124,7 @@ function Get-AbrADForest { } } } catch { - Write-PScriboMessage -IsWarning -Message "Forest Diagram Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADForest.ErrorForestDiagramSection) $($_.Exception.Message)" } } } @@ -183,7 +183,7 @@ function Get-AbrADForest { } } } else { - Write-PScriboMessage -Message "No Certificate Authority Root information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADForest.NoCARootInfo -f $ForestInfo) } if ($subordinateCA) { @@ -212,7 +212,7 @@ function Get-AbrADForest { $OutObj | Sort-Object -Property $reportTranslate.GetAbrADForest.CAName | Table @TableParams } } else { - Write-PScriboMessage -Message 'No Certificate Authority Issuer information found, Disabling this section.' + Write-PScriboMessage -Message $reportTranslate.GetAbrADForest.NoCAIssuerInfo } } if ($Options.EnableDiagrams) { @@ -220,7 +220,7 @@ function Get-AbrADForest { try { $Graph = Get-AbrDiagrammer -DiagramType 'CertificateAuthority' -DiagramOutput base64 -PSSessionObject $TempPssSession } catch { - Write-PScriboMessage -IsWarning -Message "Certificate Authority Diagram Graph: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADForest.ErrorCADiagramGraph) $($_.Exception.Message)" } if ($Graph) { @@ -232,7 +232,7 @@ function Get-AbrADForest { } } } catch { - Write-PScriboMessage -IsWarning -Message "Certificate Authority Diagram Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADForest.ErrorCADiagramSection) $($_.Exception.Message)" } } } @@ -289,7 +289,7 @@ function Get-AbrADForest { } } } else { - Write-PScriboMessage -Message "No Optional Feature information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADForest.NoOptionalFeatureInfo -f $ForestInfo) } } } catch { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADGPO.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADGPO.ps1 index 02d228c..11829a4 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADGPO.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADGPO.ps1 @@ -56,7 +56,7 @@ function Get-AbrADGPO { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Policy Objects)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOItem) $($_.Exception.Message)" } } @@ -102,7 +102,7 @@ function Get-AbrADGPO { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Policy Objects)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOItem) $($_.Exception.Message)" } } if ($InfoLevel.Domain -ge 2) { @@ -187,12 +187,12 @@ function Get-AbrADGPO { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Policy Objects)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOItem) $($_.Exception.Message)" } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (WMI Filters)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorWMIFiltersItem) $($_.Exception.Message)" } } } @@ -210,7 +210,7 @@ function Get-AbrADGPO { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Wmi Filters Section: New-PSSession: Unable to connect to $($ValidDCFromDomain): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADGPO.ErrorWMIFiltersPSSession -f $ValidDCFromDomain, $ErrorMessage) } if ($WmiFilters) { @@ -245,7 +245,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.WMINoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (WMI Filters)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorWMIFiltersItem) $($_.Exception.Message)" } } try { @@ -288,7 +288,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.CentralStoreNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO Central Store)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOCentralStore) $($_.Exception.Message)" } try { if ($GPOs) { @@ -313,7 +313,7 @@ function Get-AbrADGPO { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO with Logon/Logoff Script Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOLogonLogoffItem) $($_.Exception.Message)" } } } @@ -338,7 +338,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.LogonLogoffNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO with Logon/Logoff Script Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOLogonLogoffSection) $($_.Exception.Message)" } try { if ($GPOs) { @@ -358,12 +358,12 @@ function Get-AbrADGPO { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO with Computer Startup/Shutdown Script Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOStartupShutdownItem) $($_.Exception.Message)" } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO with Computer Startup/Shutdown Script)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOStartupShutdownItem) $($_.Exception.Message)" } } } @@ -389,7 +389,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.StartupShutdownNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (GPO with Computer Startup/Shutdown Script Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOStartupShutdownSection) $($_.Exception.Message)" } } } @@ -414,7 +414,7 @@ function Get-AbrADGPO { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unlinked Group Policy Objects Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorUnlinkedGPOItem) $($_.Exception.Message)" } } } @@ -445,7 +445,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.UnlinkedGPONoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unlinked Group Policy Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorUnlinkedGPOSection) $($_.Exception.Message)" } try { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -463,7 +463,7 @@ function Get-AbrADGPO { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Empty Group Policy Objects Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorEmptyGPOItem) $($_.Exception.Message)" } } } @@ -494,7 +494,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.EmptyGPONoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Empty Group Policy Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorEmptyGPOSection) $($_.Exception.Message)" } try { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -518,7 +518,7 @@ function Get-AbrADGPO { } } } catch { - Write-PScriboMessage -IsWarning -Message "OU: $($OU): $($_.Exception.Message) (Enforced Group Policy Objects Item)" + Write-PScriboMessage -IsWarning -Message "OU: $($OU): $($reportTranslate.GetAbrADGPO.ErrorEnforcedGPOItem) $($_.Exception.Message)" } } } @@ -551,7 +551,7 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.EnforcedGPONoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Enforced Group Policy Objects Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorEnforcedGPOTable) $($_.Exception.Message)" } # Code taken from Jeremy Saunders # https://github.com/jeremyts/ActiveDirectoryDomainServices/blob/master/Audit/FindOrphanedGPOs.ps1 @@ -564,7 +564,7 @@ function Get-AbrADGPO { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Orphaned GPO Section: New-PSSession: Unable to connect to $($ValidDCFromDomain): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADGPO.ErrorOrphanedGPOPSSession -f $ValidDCFromDomain, $ErrorMessage) } $GPOPoliciesSYSVOLUNC = "\\$($Domain.DNSRoot)\SYSVOL\$($Domain.DNSRoot)\Policies" $OrphanGPOs = [System.Collections.Generic.List[object]]::new() @@ -658,13 +658,13 @@ function Get-AbrADGPO { Write-PScriboMessage -Message ($reportTranslate.GetAbrADGPO.OrphanedGPONoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Orphaned GPO)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorOrphanedGPOItem) $($_.Exception.Message)" } } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Group Policy Objects Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADGPO.ErrorGPOSection) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADHardening.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADHardening.ps1 index 1fd7668..7494f08 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADHardening.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADHardening.ps1 @@ -175,11 +175,11 @@ function Get-AbrADHardening { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (ADHardening Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADHardening.ErrorADHardeningItem))" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (ADHardening Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADHardening.ErrorADHardeningSection))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADInfrastructureService.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADInfrastructureService.ps1 index a0fd536..72304e6 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADInfrastructureService.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADInfrastructureService.ps1 @@ -33,7 +33,7 @@ function Get-AbrADInfrastructureService { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Domain Controller Infrastructure Services Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADInfrastructureService.ErrorPSSession -f $DC, $ErrorMessage) } if ($Available) { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -50,7 +50,7 @@ function Get-AbrADInfrastructureService { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Infrastructure Services Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADInfrastructureService.ErrorDCInfraServicesItem))" } } @@ -96,7 +96,7 @@ function Get-AbrADInfrastructureService { Write-PScriboMessage -Message ($reportTranslate.GetAbrADInfrastructureService.NoData -f $DC) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Controller Infrastructure Services Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADInfrastructureService.ErrorDCInfraServicesTable))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADKerberosAudit.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADKerberosAudit.ps1 index 6ffe642..44080e1 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADKerberosAudit.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADKerberosAudit.ps1 @@ -42,7 +42,7 @@ function Get-AbrADKerberosAudit { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unconstrained Kerberos delegation Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorUnconstrainedKerberosItem))" } } @@ -86,7 +86,7 @@ function Get-AbrADKerberosAudit { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (KRBTGT account Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorKRBTGTAccountItem))" } if ($HealthCheck.Domain.Security) { @@ -114,7 +114,7 @@ function Get-AbrADKerberosAudit { Write-PScriboMessage -Message ($reportTranslate.GetAbrADKerberosAudit.KRBTGTNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unconstrained Kerberos delegation Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorUnconstrainedKerberosItem))" } try { $SID = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { "$($($using:Domain).domainsid.ToString())-500" } @@ -134,7 +134,7 @@ function Get-AbrADKerberosAudit { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (ADMIN account Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorAdminAccountItem))" } if ($HealthCheck.Domain.Security) { @@ -162,10 +162,10 @@ function Get-AbrADKerberosAudit { Write-PScriboMessage -Message ($reportTranslate.GetAbrADKerberosAudit.AdminNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unconstrained Kerberos delegation Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorUnconstrainedKerberosItem))" } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Unconstrained Kerberos delegation Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADKerberosAudit.ErrorUnconstrainedKerberosSection))" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADOU.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADOU.ps1 index eb33870..f1eb319 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADOU.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADOU.ps1 @@ -52,7 +52,7 @@ function Get-AbrADOU { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Organizational Unit Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADOU.ErrorOUItem))" } } @@ -94,7 +94,7 @@ function Get-AbrADOU { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Blocked Inheritance GPO Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADOU.ErrorBlockedInheritanceGPOItem))" } } } @@ -124,7 +124,7 @@ function Get-AbrADOU { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Blocked Inheritance GPO Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADOU.ErrorBlockedInheritanceGPOSection))" } } } @@ -132,7 +132,7 @@ function Get-AbrADOU { Write-PScriboMessage -Message ($reportTranslate.GetAbrADOU.OUNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Organizational Unit Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADOU.ErrorOUSection))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADReportBrief.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADReportBrief.ps1 index fe11695..899ffd1 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADReportBrief.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADReportBrief.ps1 @@ -51,7 +51,7 @@ function Get-AbrADReportBrief { } $OutObj | Table @TableParams } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief - Report Overview)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorReportOverview))" } BlankLine @@ -79,7 +79,7 @@ function Get-AbrADReportBrief { } $OutObj | Table @TableParams } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief - Forest Summary)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorForestSummary))" } BlankLine @@ -103,7 +103,7 @@ function Get-AbrADReportBrief { } $OutObj.Add([pscustomobject]$inObj) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief - Domain Summary - $Domain)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorDomainSummaryItem))" } } @@ -121,7 +121,7 @@ function Get-AbrADReportBrief { $OutObj | Table @TableParams } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief - Domain Summary)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorDomainSummary))" } BlankLine @@ -162,12 +162,12 @@ function Get-AbrADReportBrief { } $OutObj | Table @TableParams } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief - Report Scope)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorReportScope))" } } PageBreak } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Report Brief Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADReportBrief.ErrorReportBriefSection))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSCCM.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSCCM.ps1 index 375886c..cf9604f 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSCCM.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSCCM.ps1 @@ -42,7 +42,7 @@ function Get-AbrADSCCM { } $SCCMInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.SCCMception.Message) (SCCM Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSCCM.ErrorSCCMItem) $($_.Exception.Message)" } } @@ -74,12 +74,12 @@ function Get-AbrADSCCM { } } } else { - Write-PScriboMessage -Message "No SCCM Infrastructure information found in $($ForestInfo.toUpper()), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSCCM.NoSCCMInfo -f $ForestInfo.toUpper()) Paragraph $reportTranslate.GetAbrADSCCM.NotFound BlankLine } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.SCCMception.Message) (SCCM Table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSCCM.ErrorSCCMTable) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 index 99789ea..9e6f2df 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 @@ -56,7 +56,7 @@ function Get-AbrADSecurityAssessment { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Account Security Assessment Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorAccountSecurityAssessmentItem))" } if ($HealthCheck.Domain.Security) { @@ -83,7 +83,7 @@ function Get-AbrADSecurityAssessment { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Category -Title $reportTranslate.GetAbrADSecurityAssessment.UserAccountTitle -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 600 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (User Account Security Assessment Chart)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorUserAccountSecurityAssessmentChart))" } if ($OutObj) { Section -ExcludeFromTOC -Style NOTOCHeading4 $reportTranslate.GetAbrADSecurityAssessment.UserAccountTitle { @@ -101,10 +101,10 @@ function Get-AbrADSecurityAssessment { } } } else { - Write-PScriboMessage -Message "No Domain users information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSecurityAssessment.NoUserInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Account Security Assessment Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorAccountSecurityAssessmentTable))" } if ($InfoLevel.Domain -ge 2) { try { @@ -139,7 +139,7 @@ function Get-AbrADSecurityAssessment { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Users Assessment Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorPrivilegedUsersAssessmentItem))" } } @@ -186,10 +186,10 @@ function Get-AbrADSecurityAssessment { } } } else { - Write-PScriboMessage -Message "No Privileged User Assessment information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSecurityAssessment.NoPrivilegedUserInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Privileged Users Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorPrivilegedUsersTable))" } try { $InactivePrivilegedUsers = $PrivilegedUsers | Where-Object { ($_.LastLogonDate -le (Get-Date).AddDays(-30)) -and ($_.PasswordLastSet -le (Get-Date).AddDays(-365)) -and ($_.SamAccountName -ne 'krbtgt') -and ($_.SamAccountName -ne 'Administrator') } @@ -217,7 +217,7 @@ function Get-AbrADSecurityAssessment { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Inactive Privileged Accounts Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorInactivePrivilegedAccountsItem))" } } @@ -243,10 +243,10 @@ function Get-AbrADSecurityAssessment { } } } else { - Write-PScriboMessage -Message "No Inactive Privileged Accounts information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSecurityAssessment.NoInactivePrivilegedInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Inactive Privileged Accounts Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorInactivePrivilegedAccountsTable))" } try { $UserSPNs = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADUser -ResultPageSize 1000 -Server ($using:Domain).DNSRoot -Filter { ServicePrincipalName -like '*' } -Properties AdminCount, PasswordLastSet, LastLogonDate, ServicePrincipalName, TrustedForDelegation, TrustedtoAuthForDelegation } @@ -273,7 +273,7 @@ function Get-AbrADSecurityAssessment { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Service Accounts Assessment Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorServiceAccountsAssessmentItem))" } } @@ -305,10 +305,10 @@ function Get-AbrADSecurityAssessment { } } } else { - Write-PScriboMessage -Message "No Service Accounts Assessment information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSecurityAssessment.NoServiceAccountsInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Service Accounts Assessment Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorServiceAccountsAssessmentTable))" } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSite.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSite.ps1 index 9cfc160..3064a6f 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSite.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSite.ps1 @@ -36,7 +36,7 @@ function Get-AbrADSite { try { $Graph = Get-AbrDiagrammer -DiagramType 'Replication' -DiagramOutput base64 -PSSessionObject $TempPssSession } catch { - Write-PScriboMessage -IsWarning -Message "Replication Diagram Graph: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorReplicationDiagramGraph) $($_.Exception.Message)" } if ($Graph) { @@ -48,7 +48,7 @@ function Get-AbrADSite { } } } catch { - Write-PScriboMessage -IsWarning -Message "Replication Diagram Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorReplicationDiagramSection) $($_.Exception.Message)" } } Section -Style Heading4 $reportTranslate.GetAbrADSite.Sites { @@ -82,7 +82,7 @@ function Get-AbrADSite { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Site)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorDomainSite) $($_.Exception.Message)" } } @@ -154,12 +154,12 @@ function Get-AbrADSite { $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Name) -ne $reportTranslate.GetAbrADSite.AutoGenerated } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADSite.Name } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Replication Connection Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteReplicationConnectionItem) $($_.Exception.Message)" } } $TableParams = @{ - Name = "$($reportTranslate.GetAbrADSite.ConnectionObjects) - $($ForestInfo)" + Name = "$($reportTranslate.GetAbrADSite.ConnectionObjects)- $($ForestInfo)" List = $false ColumnWidths = 25, 25, 25, 25 } @@ -179,10 +179,10 @@ function Get-AbrADSite { } } } else { - Write-PScriboMessage -Message "No Connection Objects information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoConnectionObjectsInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Connection Objects)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorConnectionObjects) $($_.Exception.Message)" } try { $Subnet = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADReplicationSubnet -Filter * -Properties * } @@ -207,7 +207,7 @@ function Get-AbrADSite { $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Sites) -eq $reportTranslate.GetAbrADSite.NoSiteAssigned } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADSite.Sites } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Subnets)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteSubnets) $($_.Exception.Message)" } } @@ -222,7 +222,7 @@ function Get-AbrADSite { } $List.Add($reportTranslate.GetAbrADSite.DescBP) } - if ($OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Sites) -eq $reportTranslate.GetAbrADSite.NoSiteAssigned }) { + if ($OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Sites) -eq $reportTranslate.GetAbrADSite.NoSiteAssigned }){ $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Sites) -eq $reportTranslate.GetAbrADSite.NoSiteAssigned } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADSite.Sites $Num++ foreach ( $OBJ in ($OutObj | Where-Object { $_.$($reportTranslate.GetAbrADSite.Sites) -eq $reportTranslate.GetAbrADSite.NoSiteAssigned }) ) { @@ -273,16 +273,16 @@ function Get-AbrADSite { } } } else { - Write-PScriboMessage -Message "Unable to read $Path on $DC" + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.UnableToRead -f $Path, $DC) } } else { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Missing Subnet in AD Section: New-PSSession: Unable to connect to $($DC): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADSite.ErrorMissingSubnetPSSession -f $DC, $ErrorMessage) } } catch { - Write-PScriboMessage -IsWarning -Message "Missing Subnet in AD Item table: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorMissingSubnetItemTable) $($_.Exception.Message)" } } } @@ -313,25 +313,25 @@ function Get-AbrADSite { } } } else { - Write-PScriboMessage -Message "No Missing Subnets in AD information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoMissingSubnetsInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "Missing Subnet in AD Item Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorMissingSubnetItemSection) $($_.Exception.Message)" } } } } else { - Write-PScriboMessage -Message "No Site Subnets information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSiteSubnetsInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Subnets)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteSubnets) $($_.Exception.Message)" } if ($Options.EnableDiagrams) { try { try { $Graph = Get-AbrDiagrammer -DiagramType 'Sites' -DiagramOutput base64 -PSSessionObject $TempPssSession } catch { - Write-PScriboMessage -IsWarning -Message "Site Topology Diagram Graph: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteTopologyDiagramGraph) $($_.Exception.Message)" } if ($Graph) { @@ -343,7 +343,7 @@ function Get-AbrADSite { } } } catch { - Write-PScriboMessage -IsWarning -Message "Site Topology Diagram Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteTopologyDiagramSection) $($_.Exception.Message)" } } try { @@ -402,7 +402,7 @@ function Get-AbrADSite { } $OutObj | Sort-Object -Property $reportTranslate.GetAbrADSite.Name | Table @TableParams } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Inter-Site Transports section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorInterSiteTransports) $($_.Exception.Message)" } try { Section -Style Heading4 $reportTranslate.GetAbrADSite.IPSection { @@ -484,15 +484,15 @@ function Get-AbrADSite { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (IP Site Links table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorIPSiteLinksTable) $($_.Exception.Message)" } } } } else { - Write-PScriboMessage -Message "No IP Site Links information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoIPSiteLinksInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (IP Site Links Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorIPSiteLinksSection) $($_.Exception.Message)" } try { $IPLinkBridges = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADReplicationSiteLinkBridge -Filter * -Properties * | Where-Object { $_.InterSiteTransportProtocol -eq 'IP' } } @@ -550,19 +550,19 @@ function Get-AbrADSite { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (IP Site Links Bridges table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorIPSiteLinksBridgesTable) $($_.Exception.Message)" } } } } else { - Write-PScriboMessage -Message "No IP Site Links Bridges information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoIPSiteLinksBridgesInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (IP Site Links Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorIPSiteLinksSection) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (IP)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorIP) $($_.Exception.Message)" } try { $IPLink = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADReplicationSiteLink -Filter * -Properties * | Where-Object { $_.InterSiteTransportProtocol -eq 'SMTP' } } @@ -645,12 +645,12 @@ function Get-AbrADSite { } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SMTP Site Links table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSMTPSiteLinksTable) $($_.Exception.Message)" } } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SMTP Site Links Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSMTPSiteLinksSection) $($_.Exception.Message)" } try { $IPLinkBridges = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADReplicationSiteLinkBridge -Filter * -Properties * | Where-Object { $_.InterSiteTransportProtocol -eq 'SMTP' } } @@ -707,29 +707,29 @@ function Get-AbrADSite { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SMTP Site Links Bridges table)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSMTPSiteLinksBridgesTable) $($_.Exception.Message)" } } } } else { - Write-PScriboMessage -Message "No SMTP Site Links Bridges information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSMTPSiteLinksBridgesInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SMTP Site Links Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSMTPSiteLinksSection) $($_.Exception.Message)" } } } else { - Write-PScriboMessage -Message "No SMTP Site Links information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSMTPSiteLinksInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (SMTP)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSMTP) $($_.Exception.Message)" } } } else { - Write-PScriboMessage -Message "No SMTP Site Links information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSMTPSiteLinksInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Subnets)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSiteSubnets) $($_.Exception.Message)" } try { $OutObj = [System.Collections.Generic.List[object]]::new() @@ -760,7 +760,7 @@ function Get-AbrADSite { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Replication Item Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSysvolReplicationItemSection) $($_.Exception.Message)" } if ($HealthCheck.Site.BestPractice) { @@ -782,7 +782,7 @@ function Get-AbrADSite { } } else { try { - Write-PScriboMessage -Message "Unable to collect infromation from $DC." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.UnableToCollect -f $DC) $inObj = [ordered] @{ $reportTranslate.GetAbrADSite.DCName = $DC.split('.', 2)[0] $reportTranslate.GetAbrADSite.ReplicationStatus = $reportTranslate.GetAbrADSite.StatusUnknown @@ -790,7 +790,7 @@ function Get-AbrADSite { } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (DNS IP Configuration Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorDNSIPConfigItem) $($_.Exception.Message)" } } } @@ -819,17 +819,17 @@ function Get-AbrADSite { } } } else { - Write-PScriboMessage -Message "No Sysvol Replication information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSysvolReplicationInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "Sysvol Replication Table Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorSysvolReplicationTableSection) $($_.Exception.Message)" } } } else { - Write-PScriboMessage -Message "No Sites information found in $ForestInfo, Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADSite.NoSitesInfo -f $ForestInfo) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Site Global)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSite.ErrorDomainSiteGlobal) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSiteReplication.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSiteReplication.ps1 index 10443eb..f743e9c 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSiteReplication.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSiteReplication.ps1 @@ -64,11 +64,11 @@ function Get-AbrADSiteReplication { $ReplInfo | Where-Object { $_.$($reportTranslate.GetAbrADSiteReplication.AutoGenerated) -ne 'Yes' } | Set-Style -Style Warning -Property $reportTranslate.GetAbrADSiteReplication.AutoGenerated } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Replication Connection Item)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSiteReplication.ErrorSiteReplicationConnectionItem) $($_.Exception.Message)" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Replication Connection Section)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSiteReplication.ErrorSiteReplicationConnectionSection) $($_.Exception.Message)" } } } @@ -79,7 +79,7 @@ function Get-AbrADSiteReplication { Paragraph $reportTranslate.GetAbrADSiteReplication.ReplicationConnectionParagraph BlankLine foreach ($Repl in ($ReplInfo | Sort-Object -Property 'Replicate From Directory Server')) { - Section -Style NOTOCHeading4 -ExcludeFromTOC "Site: $($Repl.$($reportTranslate.GetAbrADSiteReplication.FromSite)): From: $($Repl.$($reportTranslate.GetAbrADSiteReplication.FromServer)) To: $($Repl.$($reportTranslate.GetAbrADSiteReplication.ToServer))" { + Section -Style NOTOCHeading4 -ExcludeFromTOC "$($reportTranslate.GetAbrADSiteReplication.SiteLabel) $($Repl.$($reportTranslate.GetAbrADSiteReplication.FromSite)): $($reportTranslate.GetAbrADSiteReplication.FromLabel) $($Repl.$($reportTranslate.GetAbrADSiteReplication.FromServer)) $($reportTranslate.GetAbrADSiteReplication.ToLabel) $($Repl.$($reportTranslate.GetAbrADSiteReplication.ToServer))" { $TableParams = @{ Name = "$($reportTranslate.GetAbrADSiteReplication.ReplicationConnectionTableName) - $($Repl.$($reportTranslate.GetAbrADSiteReplication.ToServer))" List = $true @@ -112,7 +112,7 @@ function Get-AbrADSiteReplication { Write-PScriboMessage -Message ($reportTranslate.GetAbrADSiteReplication.ReplicationConnectionNoData -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Replication Connection)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSiteReplication.ErrorReplicationConnection) $($_.Exception.Message)" } } try { @@ -125,7 +125,7 @@ function Get-AbrADSiteReplication { if (-not $_.Exception.MessageId) { $ErrorMessage = $_.FullyQualifiedErrorId } else { $ErrorMessage = $_.Exception.MessageId } - Write-PScriboMessage -IsWarning -Message "Replication Status Section: New-PSSession: Unable to connect to $($ValidDCFromDomain): $ErrorMessage" + Write-PScriboMessage -IsWarning -Message ($reportTranslate.GetAbrADSiteReplication.ErrorPSSession -f $ValidDCFromDomain, $ErrorMessage) } if ($RepStatus) { Section -Style Heading4 $reportTranslate.GetAbrADSiteReplication.ReplicationStatusTitle { @@ -144,7 +144,7 @@ function Get-AbrADSiteReplication { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Replication Status)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSiteReplication.ErrorReplicationStatus) $($_.Exception.Message)" } } if ($HealthCheck.Site.Replication) { @@ -175,7 +175,7 @@ function Get-AbrADSiteReplication { } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Site Replication Status)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADSiteReplication.ErrorSiteReplicationStatus) $($_.Exception.Message)" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADTrust.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADTrust.ps1 index fa7e28f..69b7715 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADTrust.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADTrust.ps1 @@ -75,7 +75,7 @@ function Get-AbrADTrust { } $TrustInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Trust Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADTrust.ErrorTrustItem))" } } @@ -123,7 +123,7 @@ function Get-AbrADTrust { try { $Graph = Get-AbrDiagrammer -DiagramType 'Trusts' -DiagramOutput base64 -DomainController $ValidDCFromDomain } catch { - Write-PScriboMessage -IsWarning -Message "Domain and Trusts Diagram Graph: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADTrust.ErrorTrustDiagramGraph) $($_.Exception.Message)" } if ($Graph) { @@ -135,19 +135,19 @@ function Get-AbrADTrust { } } } catch { - Write-PScriboMessage -IsWarning -Message "Domain and Trusts Diagram Section: $($_.Exception.Message)" + Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADTrust.ErrorTrustDiagramSection) $($_.Exception.Message)" } } } } else { - Write-PScriboMessage -Message "No Domain Trust information found in $($Domain.DNSRoot), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrADTrust.NoTrustInfo -f $Domain.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Trust Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADTrust.ErrorTrustTable))" } } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Trust Section)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADTrust.ErrorTrustSection))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDHCPinAD.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDHCPinAD.ps1 index 581bec5..4ae7023 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDHCPinAD.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDHCPinAD.ps1 @@ -60,7 +60,7 @@ function Get-AbrDHCPinAD { } $DCHPInfo.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (DHCP Item)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrDHCPinAD.ErrorDHCPItem))" } } @@ -75,12 +75,12 @@ function Get-AbrDHCPinAD { $DCHPInfo | Sort-Object -Property $reportTranslate.GetAbrDHCPinAD.ServerName | Table @TableParams } } else { - Write-PScriboMessage -Message "No DHCP Infrastructure information found in $($ForestInfo.toUpper()), Disabling this section." + Write-PScriboMessage -Message ($reportTranslate.GetAbrDHCPinAD.NoDHCPInfo -f $ForestInfo.toUpper()) Paragraph $reportTranslate.GetAbrDHCPinAD.NotFound BlankLine } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (DHCP Table)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrDHCPinAD.ErrorDHCPTable))" } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDNSSection.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDNSSection.ps1 index 7899718..c442e15 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDNSSection.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDNSSection.ps1 @@ -54,7 +54,7 @@ function Get-AbrDNSSection { Write-PScriboMessage -Message ([string]::Format($reportTranslate.GetAbrDNSSection.ExcludedDomain, $DomainInfo.DNSRoot)) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Domain Name System Information)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrDNSSection.ErrorDNSInfo))" } } else { Write-PScriboMessage -IsWarning -Message ([string]::Format($reportTranslate.GetAbrDNSSection.NoDCAvailable, $DomainInfo.DNSRoot)) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 index 127a644..7567ca9 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 @@ -32,7 +32,7 @@ function Get-AbrDomainSection { # Define Filter option for Domain variable try { if ($DomainInfo = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADDomain -Identity $using:Domain }) { - Write-Host " - Collecting Domain information from $Domain." + Write-Host ([string]::Format(" - $($reportTranslate.GetAbrDomainSection.CollectingDomain)", $Domain)) $DCs = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADDomain -Identity $using:Domain | Select-Object -ExpandProperty ReplicaDirectoryServers | Where-Object { $_ -notin ($using:Options).Exclude.DCs } } | Sort-Object Section -Style Heading2 "$($DomainInfo.DNSRoot.ToString().ToUpper())" { Paragraph $reportTranslate.GetAbrDomainSection.Paragraph @@ -140,7 +140,7 @@ function Get-AbrDomainSection { Write-PScriboMessage -Message ($reportTranslate.GetAbrDomainSection.DomainExcluded -f $DomainInfo.DNSRoot) } } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Active Directory Domain)" + Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrDomainSection.ErrorADDomain))" } } else { $DomainStatus.Value.Add( diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Invoke-DcDiag.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Invoke-DcDiag.ps1 index 0cfdaa3..8249bf8 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Invoke-DcDiag.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Invoke-DcDiag.ps1 @@ -25,7 +25,7 @@ function Invoke-DcDiag { try { $result = Invoke-CommandWithTimeout -Session $DCPssSessionDCDiag -ScriptBlock { dcdiag /c /s:$using:DomainController } } catch { - Write-PScriboMessage -Message "Invoke-DcDiag - Failed to get DCDiag for $DomainController with error: $($_.Exception.Message)" + Write-PScriboMessage -Message "$($reportTranslate.GetAbrADDCDiag.ErrorInvokeDcDiag -f $DomainController) $($_.Exception.Message)" return } From d49307db443099c6530212495e64921ed55c25a2 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sun, 5 Apr 2026 13:48:34 -0400 Subject: [PATCH 06/18] Refactor output formatting in domain and report functions for improved readability and consistency --- .../Language/en-US/MicrosoftAD.psd1 | 10 +++++----- .../Src/Private/Report/Get-AbrDomainSection.ps1 | 2 +- .../Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 b/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 index 298b7bf..01b82cb 100644 --- a/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 +++ b/AsBuiltReport.Microsoft.AD/Language/en-US/MicrosoftAD.psd1 @@ -21,13 +21,13 @@ CIMSessionError = Failed to establish a CimSession ({0}) with the Domain Controller '{1}'. ConnectingForest = Connecting to retrieve forest information from the Domain Controller '{0}'. ForestError = Failed to retrieve forest information from the Domain Controller '{0}'. Ensure the provided system is a Domain Controller and the provided credentials have sufficient permissions to query Active Directory forest information. Error details: {1} - IncludeDomainsEnabled = - Include.Domains option enabled: Including only the following domains in the report: {0} - ExcludeDomainsEnabled = - Including all child domains in the report except the following excluded domains: {0} + IncludeDomainsEnabled = - Include.Domains option enabled: Including only the following domains in the report: {0} + ExcludeDomainsEnabled = - Including all child domains in the report except the following excluded domains: {0} GettingForestInfo = - Retrieving forest information {0}. - DiscoveringChildDomains = - Discovering child domains of the forest {0}: {1}. + DiscoveringChildDomains = - Discovering child domains of the forest {0}: {1}. DCAvailable = - Initial configuration: A DC is available in the domain {0}. Adding domain to the report. - DCUnavailable = - Unable to obtain an available DC in the domain {0}. Removing domain from the report. - FinishingDomainList = - Finalizing the list of domains in the forest {0}: {1}. + DCUnavailable = - Unable to obtain an available DC in the domain {0}. Removing domain from the report. + FinishingDomainList = - Finalizing the list of domains in the forest {0}: {1}. WorkingOnForest = - Working on the Forest section. WorkingOnDomain = - Working on the Domain section. WorkingOnDNS = - Working on the DNS section. diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 index 7567ca9..f39c071 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 @@ -78,7 +78,7 @@ function Get-AbrDomainSection { try { $DCDiagObj = foreach ($DC in $DCs) { if (Get-DCWinRMState -ComputerName $DC -DCStatus ([ref]$DCStatus)) { - # Get-AbrADDCDiag -Domain $Domain -DC $DC + Get-AbrADDCDiag -Domain $Domain -DC $DC } } if ($DCDiagObj) { diff --git a/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 b/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 index 78c02a6..f8c26fb 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 @@ -44,11 +44,11 @@ function Invoke-AsBuiltReport.Microsoft.AD { $InstalledVersion = Get-Module -ListAvailable -Name $Module -ErrorAction SilentlyContinue | Sort-Object -Property Version -Descending | Select-Object -First 1 -ExpandProperty Version if ($InstalledVersion) { - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleInstalled -f $Module, $InstalledVersion.ToString()) + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleInstalled)" -f $Module, $InstalledVersion.ToString()) $LatestVersion = Find-Module -Name $Module -Repository PSGallery -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version if ($InstalledVersion -lt $LatestVersion) { - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleAvailable -f $Module, $LatestVersion.ToString()) -ForegroundColor Red - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleUpdate -f $Module) -ForegroundColor Red + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleAvailable)" -f $Module, $LatestVersion.ToString()) -ForegroundColor Red + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.ModuleUpdate)" -f $Module) -ForegroundColor Red } } } catch { @@ -163,16 +163,16 @@ function Invoke-AsBuiltReport.Microsoft.AD { if ($ChildDomains) { $OrderedDomains.Add($ChildDomains) - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DiscoveringChildDomains -f $RootDomains, ($OrderedDomains -join ', ')) + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DiscoveringChildDomains)" -f $RootDomains, ($OrderedDomains -join ', ')) } # Set initial connection to childs domains to find out if there is an available DC to fulfill the requests foreach ($Domain in $OrderedDomains) { try { if (Get-ValidDCfromDomain -Domain $Domain -DCStatus ([ref]$DCStatus)) { - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DCAvailable -f $Domain) + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DCAvailable)" -f $Domain) } else { - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DCUnavailable -f $Domain) + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.DCUnavailable)" -f $Domain) $DomainStatus.Add( @{ Name = $Domain @@ -183,7 +183,7 @@ function Invoke-AsBuiltReport.Microsoft.AD { } } catch { $null } } - Write-Host ($reportTranslate.InvokeAsBuiltReportMicrosoftAD.FinishingDomainList -f $RootDomains, ($OrderedDomains -join ', ')) + Write-Host (" $($reportTranslate.InvokeAsBuiltReportMicrosoftAD.FinishingDomainList)" -f $RootDomains, ($OrderedDomains -join ', ')) # Report Overview Get-AbrADReportBrief From ad2060cada1016b7278c453248f785dbd7b1b3a9 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sun, 5 Apr 2026 13:53:05 -0400 Subject: [PATCH 07/18] Bump module version to 1.0.0 and update CHANGELOG for improved localization and documentation clarity --- .../AsBuiltReport.Microsoft.AD.psd1 | 2 +- .../Src/Private/Report/Get-AbrDomainSection.ps1 | 2 +- .../Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 | 2 +- CHANGELOG.md | 8 ++++++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 index bdeab47..43a98fa 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 @@ -12,7 +12,7 @@ RootModule = 'AsBuiltReport.Microsoft.AD.psm1' # Version number of this module. - ModuleVersion = '0.9.12' + ModuleVersion = '1.0.0' # Supported PSEditions CompatiblePSEditions = @('Core') diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 index f39c071..c791f57 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrDomainSection.ps1 @@ -5,7 +5,7 @@ function Get-AbrDomainSection { .DESCRIPTION .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux diff --git a/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 b/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 index f8c26fb..b943c1a 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1 @@ -5,7 +5,7 @@ function Invoke-AsBuiltReport.Microsoft.AD { .DESCRIPTION Documents the configuration of Microsoft AD in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a9708..01ea05f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ##### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates. +## [1.0.0] - 2026-04-?? + +### :arrows_clockwise: Changed + +- Improved multi-language support by refactoring localization strings and enhancing documentation clarity in MicrosoftAD.psd1 for English and Spanish languages. + This includes improved grammar, punctuation, and readability across various best practice descriptions related to Active Directory configurations +- Bump module version to `1.0.0` + ## [0.9.12] - 2026-04-02 ### :toolbox: Added From 797eeebdb3d3c8dbb47780f4a9d9316b9cf78734 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 14:16:57 -0400 Subject: [PATCH 08/18] Update module versions for AsBuiltReport.Chart and AsBuiltReport.Diagram in CHANGELOG and module manifest --- AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 | 4 ++-- CHANGELOG.md | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 index 43a98fa..24fc28f 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 @@ -58,11 +58,11 @@ }, @{ ModuleName = 'AsBuiltReport.Chart'; - ModuleVersion = '0.3.0' + ModuleVersion = '0.3.1' }, @{ ModuleName = 'AsBuiltReport.Diagram'; - ModuleVersion = '1.0.5' + ModuleVersion = '1.0.6' } ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01ea05f..e9c2836 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved multi-language support by refactoring localization strings and enhancing documentation clarity in MicrosoftAD.psd1 for English and Spanish languages. This includes improved grammar, punctuation, and readability across various best practice descriptions related to Active Directory configurations - Bump module version to `1.0.0` +- Upgrade AsBuiltReport.Diagram module to version `1.0.6` +- Upgrade AsBuiltReport.Chart module to version `0.3.1` ## [0.9.12] - 2026-04-02 From 36a6bb3bba23352aba1c81157e9924cd51f5d614 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 14:30:04 -0400 Subject: [PATCH 09/18] Implement feature X to enhance user experience and optimize performance --- .github/copilot-instructions.md | 983 ++++++++++++++++++++++++-------- 1 file changed, 751 insertions(+), 232 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 4093fa2..558cea0 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,352 +1,871 @@ -# Copilot Instructions for AsBuiltReport.Microsoft.AD +# AsBuiltReport.Microsoft.AD - Copilot Instructions -## What This Project Does +**Project Overview:** AsBuiltReport.Microsoft.AD is a PowerShell module that generates comprehensive as-built documentation for Microsoft Active Directory (AD) infrastructure in Word/HTML/Text formats. It's part of the larger AsBuiltReport ecosystem and works in conjunction with AsBuiltReport.Core. -A PowerShell module that generates As-Built documentation reports for Microsoft Active Directory environments (Forest, Domains, Domain Controllers, DNS, PKI/CA). It produces HTML/Word/Text output via the **PScribo** library, with optional network topology diagrams via **Diagrammer.Core**. +--- + +## 1. PROJECT STRUCTURE + +### Top-Level Directory Layout +``` +AsBuiltReport.Microsoft.AD/ +├── .github/ # CI/CD workflows and PR templates +│ ├── workflows/ # GitHub Actions workflows +│ │ ├── Pester.yml # Unit testing pipeline +│ │ ├── PSScriptAnalyzer.yml # Linting/code analysis +│ │ ├── CodeQL.yml # Security scanning +│ │ ├── Release.yml # Publishing to PSGallery + social media +│ │ └── Stale.yml # Issue/PR housekeeping +│ └── PULL_REQUEST_TEMPLATE.md +├── .vscode/ # VS Code settings for PowerShell formatting +│ └── settings.json # Formatting rules, rulers @ 115 chars +├── AsBuiltReport.Microsoft.AD/ # MAIN MODULE DIRECTORY +│ ├── AsBuiltReport.Microsoft.AD.psm1 # Module manifest (14 lines - loads all functions) +│ ├── AsBuiltReport.Microsoft.AD.psd1 # Module declaration (v0.9.11) +│ ├── AsBuiltReport.Microsoft.AD.json # Default report config (InfoLevels, HealthChecks) +│ ├── AsBuiltReport.Microsoft.AD.Style.ps1 # Document styling (20.8 KB) +│ ├── Src/ +│ │ ├── Public/ +│ │ │ └── Invoke-AsBuiltReport.Microsoft.AD.ps1 # ENTRY POINT (291 lines) +│ │ └── Private/ +│ │ ├── Get-Abr*.ps1 # 52x data gathering functions +│ │ ├── ConvertTo-*.ps1 # Format/conversion helpers +│ │ ├── Convert-*.ps1 # Data transformation utilities +│ │ ├── Get-*Diagram.ps1 # Visualization generation +│ │ └── Utility functions # Session management, timeout handling, etc. +│ ├── Language/ # Localization files +│ │ ├── en-US/MicrosoftAD.psd1 # English strings (hash of all messages) +│ │ └── es-ES/MicrosoftAD.psd1 # Spanish localization +│ └── icons/ # Image assets for reports +├── Tests/ +│ ├── Invoke-Tests.ps1 # Test runner script (204 lines) +│ ├── AsBuiltReport.Microsoft.AD.Tests.ps1 # Pester unit tests +│ ├── LocalizationData.Tests.ps1 # Localization validation +│ └── README.md +├── Samples/ # Example HTML reports +├── README.md # Project documentation +├── CONTRIBUTING.md # Contribution guidelines +├── CODE_OF_CONDUCT.md # Community standards +├── LICENSE # License file +├── CHANGELOG.md # Version history +├── SECURITY.md # Security policy +└── Todo.md # Development roadmap +``` -## Runtime Requirements +### Key Directories +- **Src/Public**: Only `Invoke-AsBuiltReport.Microsoft.AD` - the single exported public function +- **Src/Private**: 88 total functions (52 Get-Abr* for data gathering, rest are utilities) +- **Language**: Localization for multi-language support (en-US, es-ES) +- **Tests**: Pester tests + custom test runner supporting code coverage -- **Must run as Administrator** — `#Requires -RunAsAdministrator` is enforced in the entry point. -- **Target must be an FQDN** — IP addresses are explicitly rejected; always pass a fully-qualified domain name for `-Target`. -- **Cannot run in PowerShell ISE** — detected and blocked at startup; use the PowerShell console or terminal. -- **PowerShell 7+ recommended** — required for tests; the module itself targets Windows PowerShell 5.1+ on Windows only. -- **Reporting machine must be domain-joined** — required for the PKI/CA section (`Get-ComputerADDomain` check). -- **WinRM must be enabled on DCs** — all remote data collection goes through WinRM; CIMSession is supplementary. +### File Count Summary +- **Total .ps1 files**: 94 +- **Public functions**: 1 (exported) +- **Private functions**: ~88 + utilities +- **Data gathering functions (Get-Abr*)**: 52 -## Testing +--- + +## 2. BUILD, TEST, LINT COMMANDS + +### Test Execution -Run all Pester tests (requires PowerShell 7+, Windows): +**Local Test Execution:** ```powershell -cd Tests -.\Invoke-Tests.ps1 +.\Tests\Invoke-Tests.ps1 # Basic run +.\Tests\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml # With coverage +``` + +**Test Runner Details** (`Tests/Invoke-Tests.ps1`): +- Uses **Pester 5.0.0+** for testing framework +- Supports output formats: Console, NUnitXml, JUnitXml +- Includes code coverage analysis (JaCoCo format) +- Code coverage threshold: 50% minimum (warning at <50%) +- Coverage files tracked: `*.psm1`, `Src/Public/*.ps1`, `Src/Private/*.ps1` +- Test results: `Tests/testResults.xml` +- Coverage output: `Tests/coverage.xml` + +### Code Analysis + +**PSScriptAnalyzer** (`PSScriptAnalyzerSettings.psd1`): +- Linting tool configured in CI/CD +- Custom rules enforced: + - `PSAvoidExclaimOperator` - no `!` operator + - `AvoidUsingDoubleQuotesForConstantString` - use single quotes for constants + - `UseCorrectCasing` - enforce proper case + - `PSAvoidUsingCmdletAliases` - no aliases + - `PSUseConsistentWhitespace` - whitespace consistency +- Excluded rules: + - `PSUseToExportFieldsInManifest` + - `PSAvoidUsingWriteHost` (needed for reports) + +### CI/CD Pipelines + +**Pester Tests Workflow** (`.github/workflows/Pester.yml`): +- Triggers: push (main/dev/master), PR, manual +- Runs on: Windows (pwsh + powershell 5.1) +- Auto-installs: Pester 5.0.0+, PScribo 0.11.1+, PSScriptAnalyzer 1.0.0+, AsBuiltReport.Core 1.6.2+ +- Uploads test results as artifacts +- Uploads code coverage to Codecov + +**PSScriptAnalyzer Workflow** (`.github/workflows/PSScriptAnalyzer.yml`): +- Uses external action: `alagoutte/github-action-psscriptanalyzer@master` +- Fails on errors, comments inline +- Settings: `.github/workflows/PSScriptAnalyzerSettings.psd1` + +**CodeQL Workflow** (`.github/workflows/CodeQL.yml`): +- Security scanning for PowerShell + +**Release Workflow** (`.github/workflows/Release.yml`): +- Triggers on release published +- Tests module manifest +- Publishes to PowerShell Gallery (`Publish-Module`) +- Posts release announcements to Twitter & Bluesky + +**No Build/Invoke-Build found**: This is a pure PowerShell module (no compilation). + +--- + +## 3. ARCHITECTURE + +### High-Level Data Flow + +``` +Invoke-AsBuiltReport.Microsoft.AD (Entry Point) + ↓ + [Input: Target DC, Credentials] + ↓ + [Validate: Requirements, Features, Modules] + ↓ + [Connection: PSSession + CIMSession to DC] + ↓ + [Process Per Forest/Domain] + ├── Get-AbrForestSection (Forest-level data) + ├── Get-AbrDomainSection (Per-domain data) + ├── Get-AbrDnsSection (DNS configuration) + └── Get-AbrPKISection (Certificate Authority) + ↓ + [Diagram Generation: Forest, Replication, Trusts, Sites, CA] + ↓ + [Session Cleanup: Remove PSSession, CIMSession] + ↓ + [Output: HTML/Word/Text Report] ``` -Run with code coverage: +### Main Entry Point + +**File**: `AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1` (291 lines) + +**Signature**: ```powershell -.\Invoke-Tests.ps1 -CodeCoverage +function Invoke-AsBuiltReport.Microsoft.AD { + [CmdletBinding()] + param ( + [String[]] $Target, # Domain controller(s) FQDN + [PSCredential] $Credential # Credentials for remote session + ) + #Requires -RunAsAdministrator +} +``` + +**Key Responsibilities**: +1. Validate prerequisites (Windows PS >= 5.1, admin rights, not ISE) +2. Check installed modules & warn on outdated versions +3. Validate OS features (RSAT tools on workstation, features on server) +4. Load report config (JSON), InfoLevels, HealthChecks, Options +5. Establish PSSession + CIMSession to DC via WinRM +6. Collect forest/domain/DNS/PKI data via section functions +7. Generate diagrams (if enabled) +8. Build report using PScribo +9. Cleanup sessions + +**Critical Design Pattern**: +- **$Target** must be FQDN (not IP) - WinRM limitation +- Must run **-RunAsAdministrator** +- Must run from PowerShell 7+, **NOT** PowerShell ISE +- WinRM must be enabled on DC +- Uses **$Options** hash from config for behavior control + +### Core Section Builders + +These functions call data gatherers and structure output via PScribo's **Section** cmdlet: + +1. **Get-AbrForestSection**: Forest topology, schema, tombstone lifetime, global catalogs +2. **Get-AbrDomainSection**: Per-domain configuration, trusts, replication, GPOs, OUs +3. **Get-AbrDnsSection**: DNS zones, scavenging, delegation +4. **Get-AbrPKISection**: Certificate authorities, templates, security + +### Data Gathering Functions (Get-Abr*) + +**Pattern**: Each function collects specific AD object data via remote PSSession: + +Example: `Get-AbrADForest` (80 lines) +- Uses `Invoke-CommandWithTimeout` to run remote cmdlets +- Parses schema version to determine Windows Server version +- Detects anonymous access via dsHeuristics +- Returns object with translated property names +- Applies HealthCheck styling if enabled + +**All 52 Get-Abr* functions follow this pattern:** +- Accept parameters (Domain, ValidDcFromDomain, etc.) +- Start: Log collection message, start timing +- Process: Remote invocation via session, data transformation +- Output: `[System.Collections.ArrayList]` of objects +- HealthCheck: Conditionally apply styling (Warning/Critical) +- Return: Table/list output via PScribo's **Table** cmdlet + +### InfoLevel Architecture + +**Default Config** (`AsBuiltReport.Microsoft.AD.json`): +```json +"InfoLevel": { + "_comment_": "0 = Disabled, 1 = Enabled, 2 = Adv Summary, 3 = Detailed", + "Forest": 2, + "Domain": 2, + "DNS": 1, + "CA": 0 +} ``` -Run a single test file directly: +**Usage Pattern**: ```powershell -Invoke-Pester -Path .\Tests\AsBuiltReport.Microsoft.AD.Tests.ps1 -Output Detailed +if ($InfoLevel.Forest -ge 1) { ... show basic info } +if ($InfoLevel.Forest -ge 2) { ... show advanced details } +if ($InfoLevel.Forest -ge 3) { ... show comprehensive tables } ``` -Run PSScriptAnalyzer lint locally: +Enables **progressive disclosure** - users control report verbosity. + +### HealthCheck Architecture + +**Default Config**: +```json +"HealthCheck": { + "Domain": { + "GMSA": true, # Group Managed Service Accounts + "GPO": true, # Group Policy Objects + "Backup": true, # Domain backup status + "DFS": true, # DFS health + "SPN": true, # Service Principal Names + "DuplicateObject": true, + "Security": true, + "BestPractice": true + }, + "DomainController": { ... }, + "Site": { ... }, + "DNS": { ... }, + "CA": { ... } +} +``` + +**Styling Application**: ```powershell -Invoke-ScriptAnalyzer -Path .\AsBuiltReport.Microsoft.AD\Src -Settings .\.github\workflows\PSScriptAnalyzerSettings.psd1 -Recurse +if ($HealthCheck.Domain.Security) { + $OutObj | Where-Object { $_.AnonymousAccess -eq 'Enabled' } | + Set-Style -Style Critical -Property AnonymousAccess + $OutObj | Where-Object { $_.TombstoneLifetime -lt 180 } | + Set-Style -Style Warning -Property TombstoneLifetime +} ``` -PSScriptAnalyzer enforces: `UseCorrectCasing`, `PSUseConsistentWhitespace`, `PSAvoidUsingCmdletAliases`, `AvoidUsingDoubleQuotesForConstantString`, `PSAvoidExclaimOperator`. Errors fail CI; warnings do not. +Objects marked as Warning/Critical get colored highlighting in reports. -## Architecture +### Connection Management -### Module Layout +**Session Establishment** (in main entry point): +```powershell +$TempPssSession = Get-ValidPSSession -ComputerName $System -SessionName $System +$TempCIMSession = Get-ValidCIMSession -ComputerName $System -SessionName $System +``` +**Remote Command Execution**: +```powershell +Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADForest } ``` -AsBuiltReport.Microsoft.AD/ - AsBuiltReport.Microsoft.AD.psm1 # Dot-sources all Src/Public and Src/Private *.ps1 files - AsBuiltReport.Microsoft.AD.json # Default report config (InfoLevel, HealthCheck, Options) - AsBuiltReport.Microsoft.AD.psd1 # Module manifest - AsBuiltReport.Microsoft.AD.Style.ps1 # PScribo document styling - Src/ - Public/ - Invoke-AsBuiltReport.Microsoft.AD.ps1 # Entry point; sets up sessions, calls Section functions - Private/ - Get-Abr*Section.ps1 # Top-level section orchestrators - Get-AbrAD*.ps1 # Report content generators (one per AD topic) - Get-AbrDiag*.ps1 # Diagram generators - ConvertTo-*.ps1 # Data conversion helpers - Get-Valid*.ps1 # Session/DC validation helpers - Language/ - en-US/MicrosoftAD.psd1 # English string resources - es-ES/MicrosoftAD.psd1 # Spanish string resources + +**Cleanup**: +```powershell +foreach ($PSSession in $PSSTable | Where { $_.Status -ne 'Offline' }) { + Remove-PSSession -Id $PSSession.id +} ``` -### Data Flow +### Diagram Generation + +**Diagrammer Integration**: +- Uses `Diagrammer.Core` module for topology visualization +- Types: Forest, Replication, Sites, SitesInventory, Trusts, CertificateAuthority +- Controlled by `$Options.EnableDiagrams`, `$Options.DiagramType.*` +- Outputs: PDF/PNG (configurable via `$Options.ExportDiagramsFormat`) +- Theme: White/Dark (via `$Options.DiagramTheme`) -1. `Invoke-AsBuiltReport.Microsoft.AD` (Public) connects via PSSession/CIMSession to a target DC, discovers the forest/domain topology, then calls each `Get-Abr*Section` function. -2. Section functions (e.g., `Get-AbrDomainSection`, `Get-AbrForestSection`, `Get-AbrDNSSection`, `Get-AbrPKISection`) gate execution with `$InfoLevel.*` checks and iterate over domains/DCs. -3. Content functions (e.g., `Get-AbrADDomain`, `Get-AbrADDomainController`) collect AD data via `Invoke-CommandWithTimeout` (remote PSSession) and write output using PScribo DSL (`Section`, `Table`, `Paragraph`, `BlankLine`). -4. The PScribo document is assembled in memory and exported to the requested format by the AsBuiltReport.Core framework. +--- -### Key Script-Scoped Variables +## 4. KEY CONVENTIONS AND PATTERNS -These are set by `Invoke-AsBuiltReport.Microsoft.AD` and used across all Private functions: +### Function Naming Convention -| Variable | Purpose | -|---|---| -| `$script:TempPssSession` | Primary PSSession to initial target DC | -| `$script:TempCIMSession` | CIMSession to initial DC | -| `$script:InfoLevel` | Hash from JSON config — controls section depth (0–3) | -| `$script:Options` | Hash from JSON config — WinRM, exclusions, diagram settings | -| `$script:ADSystem` | `Get-ADForest` result for the target forest | -| `$script:ForestInfo` | Root domain FQDN (uppercased) | -| `$script:OrderedDomains` | Root domain first, then child domains | -| `$script:DCStatus` | ArrayList tracking reachability status per DC | -| `$reportTranslate` | Localized string resources loaded from `Language/` | +**Public Functions**: +- `Invoke-AsBuiltReport.Microsoft.AD` - single entry point (uses dot notation) -## Key Conventions +**Private Functions** - Three categories: -### Function Naming +1. **Data Gatherers** (`Get-Abr*`): + - `Get-AbrADForest` - retrieves Forest info + - `Get-AbrADDomain` - retrieves Domain info + - `Get-AbrADDomainController` - DC inventory + - `Get-AbrADCA*` - CA-specific data + - Pattern: Get-Abr[Section][Subsection] -- `Get-AbrAD*` — collects and renders a specific AD topic (domain info, DC info, GPO, trust, etc.) -- `Get-Abr*Section` — top-level orchestrators that call multiple `Get-AbrAD*` functions inside `Section {}` blocks -- `Get-AbrDiag*` — generate infrastructure diagrams -- `ConvertTo-*` — data transformation helpers (e.g., `ConvertTo-TextYN`, `ConvertTo-HashToYN`, `ConvertTo-FileSizeString`) -- `Get-Valid*` — session/connectivity helpers (`Get-ValidDCfromDomain`, `Get-ValidPSSession`, `Get-ValidCIMSession`) +2. **Section Builders** (`Get-Abr*Section`): + - `Get-AbrForestSection` - orchestrates Forest section + - `Get-AbrDomainSection` - orchestrates Domain section + - `Get-AbrDnsSection` - orchestrates DNS section + - `Get-AbrPKISection` - orchestrates PKI section + - Pattern: Get-Abr[Section]Section -### Building Report Tables +3. **Diagram Builders** (`Get-AbrDiag*`): + - `Get-AbrDiagrammer` - main diagram orchestration + - `Get-AbrDiagForest`, `Get-AbrDiagReplication`, etc. + - Pattern: Get-AbrDiag[DiagramType] -Every content function uses this pattern: +4. **Utility Functions** (various): + - `Convert-IpAddressToMaskLength` - IP/CIDR conversion + - `ConvertTo-HashToYN` - bool → Yes/No conversion + - `Invoke-CommandWithTimeout` - remote execution with timeout + - `Get-ValidPSSession` - session validation/creation + - `Test-WinRM` - WinRM connectivity check + +### Data Structure Patterns + +**Standard Data Object**: ```powershell -$OutObj = [System.Collections.ArrayList]::new() $inObj = [ordered] @{ - $reportTranslate.FunctionName.FieldKey = $value - # ... + 'Property Name' = $Value + 'Health Check Property' = $CheckResult } $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) | Out-Null - -$TableParams = @{ - Name = "Table Title - $Domain" - List = $true # or $false for horizontal tables - ColumnWidths = 40, 60 -} -if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" -} -$OutObj | Table @TableParams ``` -### Localized Strings +**Conversion Helper Usage**: +```powershell +# ConvertTo-HashToYN: Converts boolean $true/$false → "Yes"/"No" +$inObj | ConvertTo-HashToYN +``` -All user-visible strings — table column headers, section headings, paragraph text, health check messages — must come from `$reportTranslate..`. Add new strings to both `Language/en-US/MicrosoftAD.psd1` and `Language/es-ES/MicrosoftAD.psd1`. String keys use PascalCase and match the function name as a top-level key. +**Style Application**: +```powershell +$OutObj | Set-Style -Style Critical -Property $PropertyName +$OutObj | Set-Style -Style Warning -Property $PropertyName +``` -### InfoLevel and HealthCheck Gating +### Report Section Structure -- `$InfoLevel.Domain` (0=Disabled, 1=Enabled, 2=Adv Summary, 3=Detailed) controls whether a section runs and how much detail it shows. -- `$HealthCheck.Domain.BestPractice` (boolean) controls whether health check styling/paragraphs are added to existing tables. -- Pattern for health checks: +**PScribo Section Hierarchy**: ```powershell -if ($HealthCheck.Domain.BestPractice) { - $OutObj | Set-Style -Style Warning -Property $reportTranslate.FunctionName.FieldKey +Section -Style Heading1 "Forest Name" { + Paragraph "Introduction..." + BlankLine + + Section -Style Heading2 "Subsection Title" { + if ($Options.ShowDefinitionInfo) { + Paragraph "Definition text..." + } + + # Call data gatherer + Get-AbrADForest + + if ($InfoLevel.Forest -ge 2) { + # Advanced details + Get-AbrADSite + } + } } ``` -### Remote Execution +**PScribo Elements Used**: +- `Section` - create section with heading levels (Heading1-Heading4) +- `Table` - display data in tabular format +- `Paragraph` - text with styling (Bold, Underline, Colors) +- `BlankLine` - spacing +- `PageBreak` - force page break in Word/PDF -Always use `Invoke-CommandWithTimeout` (not `Invoke-Command` directly) for remote PSSession calls. This respects `$Options.JobsTimeOut`: +### Translation/Localization Pattern + +**Property Names Use Translated Strings**: ```powershell -$Result = Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { - Get-ADDomain -Identity $using:Domain +# From Language/en-US/MicrosoftAD.psd1 +@{ + GetAbrADForest = @{ + Collecting = 'Collecting Active Directory forest information.' + ForestName = 'Forest Name' + ForestFunctionalLevel = 'Forest Functional Level' + ... + } } + +# In function: +$reportTranslate.GetAbrADForest.Collecting # Loaded at module init ``` -### Error Handling Pattern +**Multi-Language Support**: +- Each culture has its own .psd1 file (en-US, es-ES, etc.) +- Strings loaded into `$reportTranslate` hash at module load +- Property names in output tables are localized +### HealthCheck Patterns + +**Pre-Check Pattern** (e.g., RID Pool): ```powershell -begin { - Write-PScriboMessage -Message ($reportTranslate.FunctionName.Collecting -f $Domain) - Show-AbrDebugExecutionTime -Start -TitleMessage 'Section Title' -} -process { - try { - # ... collect and render ... - } catch { - Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) (Context Description)" +if ($HealthCheck.Domain.BestPractice) { + if ([math]::Truncate($CompleteSIDS / $RIDsRemaining) -gt 80) { + $OutObj | Set-Style -Style Warning -Property RIDProperty + Paragraph "Health check message about RID pool..." } } -end { - Show-AbrDebugExecutionTime -End -TitleMessage 'Section Title' +``` + +**28 Functions Use HealthCheck** out of 52 data gatherers (~54%): +- Focus on security, best practices, service health +- Each check compares values against thresholds +- Styling applied: Warning, Critical, or Success + +### Configuration-Driven Behavior + +**Options Hash Controls**: +```json +"Options": { + "ShowExecutionTime": false, # Show timing info + "ShowDefinitionInfo": false, # Show definition text + "PSDefaultAuthentication": "Negotiate", + "Exclude": { "Domains": [], "DCs": [] }, + "Include": { "Domains": [] }, # Only these domains + "WinRMSSL": false, + "WinRMFallbackToNoSSL": true, + "WinRMSSLPort": 5986, + "WinRMPort": 5985, + "EnableDiagrams": true, + "DiagramTheme": "White", + "JobsTimeOut": 900 # 15-minute timeout } ``` -Use `Write-PScriboMessage` (not `Write-Host`) for module logging. `Write-Host` is only allowed in the Public entry point (`Invoke-AsBuiltReport.Microsoft.AD.ps1`) for top-level user-facing progress messages. +**Usage Example**: +```powershell +if ($Options.ShowDefinitionInfo) { + Paragraph $reportTranslate.GetAbrForestSection.DefinitionText +} + +$TimeoutSeconds = $Options.JobsTimeOut +``` -### DC Connectivity Check +### Error Handling & Timeouts -Before running per-DC logic, always check WinRM reachability: +**Invoke-CommandWithTimeout Pattern**: ```powershell -if (Get-DCWinRMState -ComputerName $DC -DCStatus ([ref]$DCStatus)) { - # ... per-DC work ... +function Invoke-CommandWithTimeout { + param( + [System.Management.Automation.Runspaces.PSSession]$Session, + [scriptblock]$ScriptBlock, + [int]$TimeoutSeconds = $Options.JobsTimeOut + ) + + # Run as background job with timeout + $job = Invoke-Command -Session $Session -AsJob -ScriptBlock $ScriptBlock + Wait-Job $job -Timeout $TimeoutSeconds + Receive-Job $job } ``` -### Configuration JSON +**Try-Catch in Data Gatherers**: +```powershell +try { + Get-AbrADForest +} catch { + Write-PScriboMessage -IsWarning $_.Exception.Message +} +``` -`AsBuiltReport.Microsoft.AD.json` defines defaults for `Report`, `Options`, `InfoLevel`, and `HealthCheck`. New configurable options must be added here with sensible defaults. +### Sensitive Data Handling ---- +**No explicit redaction observed**, but patterns suggest: +- Credentials passed via `$PSCredential` object (not stored) +- Session-based execution (no inline secrets) +- Remote execution prevents data capture on local disk +- Output tables contain parsed, non-sensitive data -## Session Management +**Recommendation**: Follow AD best practices - restrict report access, don't email to untrusted parties. -### Three Parallel Session Tables +--- -All remote connectivity is tracked in three `[System.Collections.ArrayList]` caches (passed as `[ref]` throughout): +## 5. CONFIGURATION + +### Primary Config File + +**File**: `AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json` + +**Structure**: +```json +{ + "Report": { + "Name": "Microsoft Active Directory As Built Report", + "Version": "1.0", + "Status": "Released", + "ShowCoverPageImage": true, + "ShowTableOfContents": true, + "ShowHeaderFooter": true, + "ShowTableCaptions": true + }, + "Options": { ... }, // Execution behavior + "InfoLevel": { ... }, // Report verbosity + "HealthCheck": { ... } // Health check toggles +} +``` -| Variable | Cache Contents | Helper | -|---|---|---| -| `$DCStatus` | WinRM reachability per DC | `Get-DCWinRMState` | -| `$PSSTable` | PSSession objects per DC | `Get-ValidPSSession` | -| `$CIMTable` | CIMSession objects per DC | `Get-ValidCIMSession` | +### Configuration Usage -Each entry in these lists is a hashtable with at minimum: `DCName`, `Status` (`Online`/`Offline`), `Protocol`, and `Id`. +Users provide config via **-ReportConfig parameter** to AsBuiltReport.Core: -### `Get-DCWinRMState` — Reachability Gate +```powershell +$ReportConfig = Get-Content 'config.json' | ConvertFrom-Json -Always called **before** establishing a PSSession or CIMSession. It: -1. Checks `$DCStatus` cache first (avoids repeated Test-WSMan calls). -2. Falls back to `Test-WSMan` if not cached, respecting `$Options.WinRMSSL`, `$Options.WinRMSSLPort`, and `$Options.WinRMFallbackToNoSSL`. -3. Records result in `$DCStatus` and returns `$true`/`$false`. -4. Ping count controlled by `$Options.DCStatusPingCount` (default: 2). +New-AsBuiltReport -Report Microsoft.AD ` + -Target 'DC01.contoso.com' ` + -ReportConfig $ReportConfig ` + -Credential $cred ` + -Format HTML +``` +**Module Loads**: ```powershell -# Always gate DC-specific work: -if (Get-DCWinRMState -ComputerName $DC -DCStatus ([ref]$DCStatus)) { - # safe to proceed -} +$script:Report = $ReportConfig.Report +$script:InfoLevel = $ReportConfig.InfoLevel +$script:Options = $ReportConfig.Options ``` -### `Get-ValidPSSession` — PSSession Pool +### Module Manifest -Manages a pool of reusable PSSessions. Behaviour: -- If a cached `Online` session exists for the DC, returns it immediately without creating a new one. -- If `$Options.WinRMSSL` is set, tries SSL first (`$Options.WinRMSSLPort`); if it fails and `$Options.WinRMFallbackToNoSSL` is `$true`, retries on plain WinRM (`$Options.WinRMPort`). -- For the **initial forest connection** (`-InitialForrestConnection $true`), failure throws a terminating error. For per-DC connections, failure is non-terminating (logged as a warning). -- Authentication method is `$Options.PSDefaultAuthentication` (default: `Negotiate`). +**File**: `AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1` -```powershell -$DCPssSession = Get-ValidPSSession -ComputerName $DC -SessionName $DC -PSSTable ([ref]$PSSTable) -``` +**Key Settings**: +- **Version**: 0.9.11 +- **PowerShellVersion**: 5.1 (minimum, actually PS7 required) +- **CompatiblePSEditions**: Desktop, Core +- **GUID**: 0a3e1c04-13b8-418f-89bc-a5a18da07394 -### `Get-ValidCIMSession` — CIMSession Pool +**Required Modules**: +- AsBuiltReport.Core (v1.6.2+) +- AsBuiltReport.Chart (v0.2.0+) +- Diagrammer.Core (v0.2.38+) +- PSPKI (v4.3.0+) -Mirrors `Get-ValidPSSession` but for CIM. SSL uses `New-CimSessionOption -UseSsl`; plain uses `New-CimSession` with `$Options.PSDefaultAuthentication`. CIMSession entries carry an additional `InstanceId` field. +--- -### `Get-ValidDCfromDomain` — Domain DC Discovery +## 6. EXISTING AI CONFIGS -Queries `Get-ADDomain` (via the primary `$TempPssSession`) to get `ReplicaDirectoryServers`, then iterates them through `Get-DCWinRMState` and returns the first reachable DC's FQDN. Used at the start of each domain loop to obtain the `$ValidDC` variable passed to all content functions. +**None Found**. No existing files: +- `.cursorrules` ✗ +- `.clinerules` ✗ +- `.windsurfrules` ✗ +- `CLAUDE.md` ✗ +- `AGENTS.md` ✗ +- `CONVENTIONS.md` ✗ -```powershell -if ($ValidDC = Get-ValidDCfromDomain -Domain $Domain -DCStatus ([ref]$DCStatus)) { - # use $ValidDC as the -Server parameter for AD cmdlets -} -``` +--- + +## 7. README AND CONTRIBUTING + +### README Key Points + +**Project Purpose**: +- Community-maintained, no Microsoft sponsorship +- Generates as-built documentation for AD (Word/HTML/Text) +- Supports AD 2012/2016/2019/2022/2025 +- **PowerShell 7+ required** (not PS 5.1!) +- Windows only (RSAT dependency) + +**Supported Features**: +- Forest topology & schema info +- Domain configuration & replication +- DNS zones & scavenging +- PKI/Certificate Authority details +- Diagrams (Forest, Replication, Trusts, Sites, CA) +- Health checks for security/best practices +- Multi-language support (en-US, es-ES) + +**Key Disclaimer**: +> This assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages. + +### CONTRIBUTING Guidelines + +**Process**: +1. Fork repo, clone, add remote upstream +2. Create topic branch off dev/main +3. Make changes following project conventions +4. Commit with clear messages +5. Pull upstream dev before pushing +6. Open PR with clear description + +**Requirements**: +- Follow existing code conventions (indentation, comments) +- Include test coverage (reference Pester tests) +- Respect git commit message guidelines +- No copyrighted content +- Agree to project license + +**Key Restriction**: +- Ask before embarking on large features/refactoring +- Don't use issue tracker for personal support --- -## Diagram Generation +## 8. CODE CONVENTIONS SUMMARY + +### PowerShell Code Style + +**Enforced via VSCode + PSScriptAnalyzer**: + +**Formatting** (`.vscode/settings.json`): +- Tab size: 4 spaces (insert spaces, not tabs) +- Line length: 115 characters (ruler configured) +- Trim trailing whitespace: enabled +- Code folding: enabled +- Brace style: + - Opening brace on same line: `if (...) {` + - New line after opening brace: `{\n ...` + - New line after closing brace: disabled +- Whitespace: + - Before open brace: enabled + - Before open paren: enabled + - Around operators: enabled + - After separator (;): enabled + - Around pipe: enabled + +**Linting** (`PSScriptAnalyzerSettings.psd1`): +- No single-character variable names +- No double quotes for constant strings +- Case sensitivity enforced +- No aliases (full cmdlet names) +- Consistent whitespace + +### Naming Conventions + +**Variables**: +- PascalCase for scripts/function names: `$ValidDcFromDomain` +- $script: prefix for module-level vars: `$script:Report`, `$script:InfoLevel` +- Hungarian notation for collections: `$PSSTable`, `$DCStatus` (plural hint) + +**Functions**: +- Verb-Noun format: `Get-AbrADForest`, `Invoke-CommandWithTimeout` +- Approved verbs: Get, New, Invoke, Test, Convert +- Hierarchy: `Get-[Abr][Component][Action]` + +**Constants**: +- `[ordered]` for hash ordering +- `[System.Collections.ArrayList]` for dynamic arrays (preferred over `@()`) +- `[pscustomobject]` for object creation + +### Error Handling + +- Use **try-catch** blocks +- Write warnings via `Write-PScriboMessage -IsWarning` +- Write errors via `Write-Error` or `throw` +- Log activity via `Write-PScriboMessage` +- Show timing via `Show-AbrDebugExecutionTime` + +### Documentation + +- SYNOPSIS, DESCRIPTION, NOTES (version, author, twitter, github) +- .EXAMPLE, .LINK for help +- Inline comments for complex logic +- Parameter documentation with `[Parameter(...)]` attributes -### Overview +--- -Diagrams are generated via the **Diagrammer.Core** / **Diagrammer.Microsoft.AD** ecosystem (PSGraph + Graphviz). The pipeline is: +## 9. CRITICAL DEVELOPMENT NOTES -``` -Get-AbrDiagrammer # thin wrapper, reads $Options, calls New-AbrADDiagram - └─ New-AbrADDiagram # builds Graphviz DOT graph, exports to file or base64 - └─ Get-AbrDiag* # per-diagram-type data collectors (called inside New-AbrADDiagram) -``` +### Must-Know Limitations -### Diagram Types +1. **WinRM Requirements**: + - Target must be FQDN (not IP) + - WinRM must be enabled on DC + - Domain-joined machine required to run module + - PowerShell 7+ on Windows only -Six types are supported (controlled by `$Options.DiagramType.*` booleans in the JSON config): +2. **Execution Context**: + - Must run `-RunAsAdministrator` + - Cannot run inside PowerShell ISE + - Remote execution via PSSession (not local cmdlets) -| Type | JSON Key | What it shows | -|---|---|---| -| `Forest` | `DiagramType.Forest` | Forest topology with domains | -| `Sites` | `DiagramType.Sites` | AD site links and connections | -| `SitesInventory` | `DiagramType.SitesInventory` | Sites with DC inventory per site | -| `Trusts` | `DiagramType.Trusts` | Domain trust relationships | -| `CertificateAuthority` | `DiagramType.CertificateAuthority` | PKI CA hierarchy | -| `Replication` | `DiagramType.Replication` | DC replication topology | +3. **Session Timeout**: + - Default timeout: 900 seconds (15 minutes) + - Configurable via `$Options.JobsTimeOut` + - Long operations may timeout on slow links -### How `Get-AbrDiagrammer` Works +### Development Workflow -1. Reads `$Options.DiagramTheme` (`White`/`Black`/`Neon`) and `$Options.ExportDiagramsFormat` (array: `pdf`, `png`, `svg`, `jpg`, `base64`). -2. Passes an existing `$TempPssSession` as `-PSSessionObject` (no credential re-prompt). -3. For `base64` format: returns the base64 string directly (used to embed diagrams inline in HTML reports). -4. For file formats: saves to `$OutputFolderPath` as `AsBuiltReport.Microsoft.AD-().` and returns the file path when `-ExportPath` is set. -5. Optional features toggled via `$Options`: `EnableDiagramDebug` (red edge/subgraph outlines), `EnableDiagramSignature` (footer with `SignatureAuthorName`/`SignatureCompanyName`), `DiagramWaterMark`. +1. **Make changes** to `.ps1` files in `Src/Public` or `Src/Private` +2. **Run tests** locally: `.\Tests\Invoke-Tests.ps1` +3. **Check linting**: PSScriptAnalyzer via VSCode +4. **Push to dev branch** (not master) +5. **CI/CD runs** Pester + PSScriptAnalyzer +6. **Create PR** to merge into master -### Embedding a Diagram in the Report +### Debugging Tips -The typical pattern in a Section function: +**Execution Timing**: ```powershell -if ($Options.EnableDiagrams -and $Options.DiagramType.Forest) { - $DiagramFile = Get-AbrDiagrammer -DiagramType 'Forest' -DiagramOutput 'base64' -PSSessionObject $TempPssSession - if ($DiagramFile) { - Image -Base64 $DiagramFile -Text 'Forest Diagram' -Percent 100 -Align 'Center' - BlankLine - } +if ($Options.ShowExecutionTime) { + Show-AbrDebugExecutionTime -Start/Stop -TitleMessage 'Section Name' } ``` -### `New-AbrADDiagram` Internals +**Logging Messages**: +```powershell +Write-PScriboMessage -Message "Collecting..." +Write-PScriboMessage -IsWarning "Warning message" +``` -- Requires **admin** privileges (checks `WindowsPrincipal` role). -- Builds a `Graph {}` block (PSGraph DSL) with node/edge default styles derived from `$DiagramTheme`. -- Icon images are loaded from `AsBuiltReport.Microsoft.AD/icons/` via `$script:IconPath`. -- The `$reportTranslate.NewADDiagram.*` keys supply graph label strings (supports `en-US`/`es-ES`). -- `$Options.DiagramObjDebug` enables verbose object-level debug output. -- Does **not** use `$TempPssSession` directly — it creates its own internal `$DiagramTempPssSession` or accepts one via `-PSSessionObject`. +**Remote Session Debugging**: +```powershell +$session = Get-PSSession -Name 'DC01.contoso.com' +Invoke-Command -Session $session -ScriptBlock { Get-ADForest } +``` -### Adding a New Diagram Type +### Performance Considerations -1. Add a new `Get-AbrDiag.ps1` in `Src/Private/` following the existing `Get-AbrDiagForest.ps1` / `Get-AbrDiagSite.ps1` pattern. -2. Add the type string to the `ValidateSet` in both `Get-AbrDiagrammer` and `New-AbrADDiagram`. -3. Add a `$MainGraphLabel` switch case in `New-AbrADDiagram`'s `begin` block. -4. Add the corresponding boolean key to `Options.DiagramType` in `AsBuiltReport.Microsoft.AD.json`. -5. Add localized label strings to both `Language/` psd1 files under the `NewADDiagram` key. +- Remote data collection happens sequentially (per domain) +- Large forests (100+ domains) may take 30+ minutes +- CPU-intensive: Schema analysis, trust enumeration +- Network: WinRM traffic, potentially large XML responses +- Disk: HTML/DOCX output can be 50+ MB with diagrams ---- +### Testing Strategy -## PKI / Certificate Authority Section +**Unit Tests** (`Tests/AsBuiltReport.Microsoft.AD.Tests.ps1`): +- Module manifest validation +- Function availability +- Module dependency versions +- Export validation -### Prerequisites +**Integration Tests** (Not present): +- Would require live AD environment +- Manual testing against test domains recommended -The PKI section only runs when **all** of the following are true: -- `$InfoLevel.CA -ge 1` -- The machine running the report is joined to a domain that is **part of the target forest** (`Get-ComputerADDomain` result must be in `$ADSystem.Domains`) -- `Get-CertificationAuthority -Enterprise` returns at least one CA (uses the **PSPKI** module) +**Code Coverage**: +- Current: Unknown (50% threshold enforced) +- Recommendation: Add more tests for edge cases -If the reporting machine's domain is not in the forest, a warning is logged and the section is skipped entirely. +--- -### CA Data Source +## 10. PROJECT-SPECIFIC GUIDANCE FOR AI ASSISTANTS + +### When Making Code Changes + +1. **Respect InfoLevel checks**: Wrap new sections with `if ($InfoLevel.Component -ge N)` +2. **Add HealthCheck conditionals**: Wrap checks with `if ($HealthCheck.Component.Feature)` +3. **Use localization strings**: Reference `$reportTranslate.FunctionName.PropertyName` +4. **Follow try-catch pattern**: Every data gatherer in try-catch with `-IsWarning` +5. **Apply Set-Style**: Mark warning/critical objects for report highlighting +6. **Use OrderedDictionary**: `[ordered] @{}` for property ordering +7. **Pass sessions as parameters**: Don't assume `$TempPssSession` global exists +8. **Document with `.SYNOPSIS`**: All functions need help documentation +9. **Return objects not strings**: Build arrays of `[pscustomobject]` for Table output +10. **Test with `-CodeCoverage`**: Ensure new code is covered by tests + +### Common Tasks + +**Add a new health check:** +1. Add boolean to `AsBuiltReport.Microsoft.AD.json` under `HealthCheck.Component.NewCheck` +2. In Get-Abr* function: `if ($HealthCheck.Component.NewCheck) { ... Set-Style ... }` +3. Add test case to `Tests/AsBuiltReport.Microsoft.AD.Tests.ps1` + +**Add new report section:** +1. Create `Get-AbrNewSection` function in `Src/Private/` +2. Create `Get-AbrNewSectionData` data gatherer +3. Call from main entry point: `if ($InfoLevel.NewComponent -ge 1) { Get-AbrNewSection }` +4. Add InfoLevel config: `"NewComponent": 1` to JSON +5. Add translations to `Language/en-US/MicrosoftAD.psd1` and `es-ES/` + +**Fix a timeout issue:** +1. Increase `$Options.JobsTimeOut` in JSON (default 900) +2. Or reduce data scope (disable HealthChecks or lower InfoLevel) +3. Or optimize remote query (use `-Filter` with better conditions) + +### Module Dependencies to Understand + +- **AsBuiltReport.Core**: Framework for report generation, parameter validation +- **PScribo**: Document markup (Section, Table, Paragraph, Set-Style) +- **ActiveDirectory**: AD cmdlets (Get-ADForest, Get-ADDomain, etc.) - Microsoft module +- **PSPKI**: PKI cmdlets (Get-CertificationAuthority) - community module +- **Diagrammer.Core**: Diagram generation for topology visualization +- **GroupPolicy**: GPO retrieval (Get-GPO, Get-GPOReport) +- **DnsServer**: DNS zone enumeration -The PKI section does **not** use PSSession/CIMSession for CA data. It uses **PSPKI** module cmdlets directly on the machine running the report: -- `Get-CertificationAuthority -Enterprise` — discovers all enterprise CAs -- `Get-CertificationAuthority -Enterprise -ComputerName $CA` — per-CA object -- `Get-CACryptographyConfig -CertificationAuthority $CA` -- `Get-CATemplate`, `Get-CARoleServiceStatus`, `Get-CRLDistributionPoint`, `Get-AuthorityInformationAccess` +--- -The `$script:CAs` variable is set in `Get-AbrPKISection` and used by all CA sub-functions. +## 11. QUICK REFERENCE + +### Module Entry Point +- **Location**: `AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1` +- **Exports**: Single public function (dot-notation name) +- **Parameters**: `$Target` (FQDN array), `$Credential` (PSCredential) +- **Returns**: Report file (HTML/Word/Text) via PScribo + +### Main Directories +| Directory | Purpose | Files | +|-----------|---------|-------| +| `Src/Public` | Exported functions | 1 file (entry point) | +| `Src/Private` | Internal functions | 88 functions | +| `Language` | Localization | .psd1 per culture | +| `Tests` | Unit/integration tests | Pester framework | +| `.github/workflows` | CI/CD pipelines | 5 YAML files | + +### Key Files +| File | Purpose | Size | +|------|---------|------| +| `AsBuiltReport.Microsoft.AD.psm1` | Module loader | 14 lines | +| `AsBuiltReport.Microsoft.AD.psd1` | Manifest | ~100 lines | +| `AsBuiltReport.Microsoft.AD.json` | Config template | 89 lines | +| `AsBuiltReport.Microsoft.AD.Style.ps1` | Report styling | 20 KB | + +### Test Commands +```powershell +# Basic test run +.\Tests\Invoke-Tests.ps1 -### Section Structure (`Get-AbrPKISection`) +# With coverage +.\Tests\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml -``` -PKI (Heading1) ← only when $InfoLevel.CA -ge 1 - Get-AbrADCASummary ← always (CA name, server, type, service status) - Get-AbrADCARoot ← InfoLevel.CA -ge 2 - Get-AbrADCASubordinate ← InfoLevel.CA -ge 2 - foreach accessible CA: - Details (Heading2) - Get-AbrADCASecurity ← always - Get-AbrADCACryptographyConfig ← always - Get-AbrADCAAIA ← InfoLevel.CA -ge 2 - Get-AbrADCACRLSetting ← InfoLevel.CA -ge 2 - Get-AbrADCATemplate ← InfoLevel.CA -ge 2 - Get-AbrADCAKeyRecoveryAgent ← always +# Output formats +.\Tests\Invoke-Tests.ps1 -OutputFormat JUnitXml +.\Tests\Invoke-Tests.ps1 -OutputFormat Console ``` -### HealthCheck Styles for CA +### Required Modules (Minimum Versions) +```powershell +AsBuiltReport.Core 1.6.2+ +AsBuiltReport.Chart 0.2.0+ +Diagrammer.Core 0.2.38+ +PSPKI 4.3.0+ +Pester 5.0.0+ +PScribo 0.11.1+ +PSScriptAnalyzer 1.0.0+ +``` -| Check | Config Key | Style Applied | -|---|---|---| -| CA service not Running | `HealthCheck.CA.Status` | `Critical` on Status column | -| CA statistics thresholds | `HealthCheck.CA.Statistics` | `Warning` | -| Best practice settings | `HealthCheck.CA.BestPractice` | `Warning` | +### Function Categories +| Category | Count | Examples | +|----------|-------|----------| +| Get-Abr* (data gathering) | 52 | Get-AbrADForest, Get-AbrADDomain | +| Get-Abr*Section (orchestration) | 4 | Get-AbrForestSection, Get-AbrDNSSection | +| Get-AbrDiag* (diagrams) | 8 | Get-AbrDiagrammer, Get-AbrDiagForest | +| Utility (conversion, helpers) | 24+ | ConvertTo-HashToYN, Invoke-CommandWithTimeout | -Style values are `Warning` (yellow), `Critical` (red), and `Info` (blue) — passed to `Set-Style -Style -Property `. +--- -### Adding New CA Content +**Document Version**: 1.0 +**Last Updated**: 2024 +**Project Version**: 0.9.11 +**Target PowerShell**: 7+ +**Platform**: Windows Only -CA functions receive `$CA` (a PSPKI `CertificationAuthority` object) as their only parameter. The `$ForestInfo` script variable provides the forest name for table naming. Follow the same `$inObj` → `ConvertTo-HashToYN` → `Table` pattern as all other content functions. From 4eabd2dcd1ebec054dc16746fbe8a22108b5f5ac Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 14:30:16 -0400 Subject: [PATCH 10/18] Remove copilot instructions document to streamline project documentation --- copilot-instructions.md | 871 ---------------------------------------- 1 file changed, 871 deletions(-) delete mode 100644 copilot-instructions.md diff --git a/copilot-instructions.md b/copilot-instructions.md deleted file mode 100644 index 558cea0..0000000 --- a/copilot-instructions.md +++ /dev/null @@ -1,871 +0,0 @@ -# AsBuiltReport.Microsoft.AD - Copilot Instructions - -**Project Overview:** AsBuiltReport.Microsoft.AD is a PowerShell module that generates comprehensive as-built documentation for Microsoft Active Directory (AD) infrastructure in Word/HTML/Text formats. It's part of the larger AsBuiltReport ecosystem and works in conjunction with AsBuiltReport.Core. - ---- - -## 1. PROJECT STRUCTURE - -### Top-Level Directory Layout -``` -AsBuiltReport.Microsoft.AD/ -├── .github/ # CI/CD workflows and PR templates -│ ├── workflows/ # GitHub Actions workflows -│ │ ├── Pester.yml # Unit testing pipeline -│ │ ├── PSScriptAnalyzer.yml # Linting/code analysis -│ │ ├── CodeQL.yml # Security scanning -│ │ ├── Release.yml # Publishing to PSGallery + social media -│ │ └── Stale.yml # Issue/PR housekeeping -│ └── PULL_REQUEST_TEMPLATE.md -├── .vscode/ # VS Code settings for PowerShell formatting -│ └── settings.json # Formatting rules, rulers @ 115 chars -├── AsBuiltReport.Microsoft.AD/ # MAIN MODULE DIRECTORY -│ ├── AsBuiltReport.Microsoft.AD.psm1 # Module manifest (14 lines - loads all functions) -│ ├── AsBuiltReport.Microsoft.AD.psd1 # Module declaration (v0.9.11) -│ ├── AsBuiltReport.Microsoft.AD.json # Default report config (InfoLevels, HealthChecks) -│ ├── AsBuiltReport.Microsoft.AD.Style.ps1 # Document styling (20.8 KB) -│ ├── Src/ -│ │ ├── Public/ -│ │ │ └── Invoke-AsBuiltReport.Microsoft.AD.ps1 # ENTRY POINT (291 lines) -│ │ └── Private/ -│ │ ├── Get-Abr*.ps1 # 52x data gathering functions -│ │ ├── ConvertTo-*.ps1 # Format/conversion helpers -│ │ ├── Convert-*.ps1 # Data transformation utilities -│ │ ├── Get-*Diagram.ps1 # Visualization generation -│ │ └── Utility functions # Session management, timeout handling, etc. -│ ├── Language/ # Localization files -│ │ ├── en-US/MicrosoftAD.psd1 # English strings (hash of all messages) -│ │ └── es-ES/MicrosoftAD.psd1 # Spanish localization -│ └── icons/ # Image assets for reports -├── Tests/ -│ ├── Invoke-Tests.ps1 # Test runner script (204 lines) -│ ├── AsBuiltReport.Microsoft.AD.Tests.ps1 # Pester unit tests -│ ├── LocalizationData.Tests.ps1 # Localization validation -│ └── README.md -├── Samples/ # Example HTML reports -├── README.md # Project documentation -├── CONTRIBUTING.md # Contribution guidelines -├── CODE_OF_CONDUCT.md # Community standards -├── LICENSE # License file -├── CHANGELOG.md # Version history -├── SECURITY.md # Security policy -└── Todo.md # Development roadmap -``` - -### Key Directories -- **Src/Public**: Only `Invoke-AsBuiltReport.Microsoft.AD` - the single exported public function -- **Src/Private**: 88 total functions (52 Get-Abr* for data gathering, rest are utilities) -- **Language**: Localization for multi-language support (en-US, es-ES) -- **Tests**: Pester tests + custom test runner supporting code coverage - -### File Count Summary -- **Total .ps1 files**: 94 -- **Public functions**: 1 (exported) -- **Private functions**: ~88 + utilities -- **Data gathering functions (Get-Abr*)**: 52 - ---- - -## 2. BUILD, TEST, LINT COMMANDS - -### Test Execution - -**Local Test Execution:** -```powershell -.\Tests\Invoke-Tests.ps1 # Basic run -.\Tests\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml # With coverage -``` - -**Test Runner Details** (`Tests/Invoke-Tests.ps1`): -- Uses **Pester 5.0.0+** for testing framework -- Supports output formats: Console, NUnitXml, JUnitXml -- Includes code coverage analysis (JaCoCo format) -- Code coverage threshold: 50% minimum (warning at <50%) -- Coverage files tracked: `*.psm1`, `Src/Public/*.ps1`, `Src/Private/*.ps1` -- Test results: `Tests/testResults.xml` -- Coverage output: `Tests/coverage.xml` - -### Code Analysis - -**PSScriptAnalyzer** (`PSScriptAnalyzerSettings.psd1`): -- Linting tool configured in CI/CD -- Custom rules enforced: - - `PSAvoidExclaimOperator` - no `!` operator - - `AvoidUsingDoubleQuotesForConstantString` - use single quotes for constants - - `UseCorrectCasing` - enforce proper case - - `PSAvoidUsingCmdletAliases` - no aliases - - `PSUseConsistentWhitespace` - whitespace consistency -- Excluded rules: - - `PSUseToExportFieldsInManifest` - - `PSAvoidUsingWriteHost` (needed for reports) - -### CI/CD Pipelines - -**Pester Tests Workflow** (`.github/workflows/Pester.yml`): -- Triggers: push (main/dev/master), PR, manual -- Runs on: Windows (pwsh + powershell 5.1) -- Auto-installs: Pester 5.0.0+, PScribo 0.11.1+, PSScriptAnalyzer 1.0.0+, AsBuiltReport.Core 1.6.2+ -- Uploads test results as artifacts -- Uploads code coverage to Codecov - -**PSScriptAnalyzer Workflow** (`.github/workflows/PSScriptAnalyzer.yml`): -- Uses external action: `alagoutte/github-action-psscriptanalyzer@master` -- Fails on errors, comments inline -- Settings: `.github/workflows/PSScriptAnalyzerSettings.psd1` - -**CodeQL Workflow** (`.github/workflows/CodeQL.yml`): -- Security scanning for PowerShell - -**Release Workflow** (`.github/workflows/Release.yml`): -- Triggers on release published -- Tests module manifest -- Publishes to PowerShell Gallery (`Publish-Module`) -- Posts release announcements to Twitter & Bluesky - -**No Build/Invoke-Build found**: This is a pure PowerShell module (no compilation). - ---- - -## 3. ARCHITECTURE - -### High-Level Data Flow - -``` -Invoke-AsBuiltReport.Microsoft.AD (Entry Point) - ↓ - [Input: Target DC, Credentials] - ↓ - [Validate: Requirements, Features, Modules] - ↓ - [Connection: PSSession + CIMSession to DC] - ↓ - [Process Per Forest/Domain] - ├── Get-AbrForestSection (Forest-level data) - ├── Get-AbrDomainSection (Per-domain data) - ├── Get-AbrDnsSection (DNS configuration) - └── Get-AbrPKISection (Certificate Authority) - ↓ - [Diagram Generation: Forest, Replication, Trusts, Sites, CA] - ↓ - [Session Cleanup: Remove PSSession, CIMSession] - ↓ - [Output: HTML/Word/Text Report] -``` - -### Main Entry Point - -**File**: `AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1` (291 lines) - -**Signature**: -```powershell -function Invoke-AsBuiltReport.Microsoft.AD { - [CmdletBinding()] - param ( - [String[]] $Target, # Domain controller(s) FQDN - [PSCredential] $Credential # Credentials for remote session - ) - #Requires -RunAsAdministrator -} -``` - -**Key Responsibilities**: -1. Validate prerequisites (Windows PS >= 5.1, admin rights, not ISE) -2. Check installed modules & warn on outdated versions -3. Validate OS features (RSAT tools on workstation, features on server) -4. Load report config (JSON), InfoLevels, HealthChecks, Options -5. Establish PSSession + CIMSession to DC via WinRM -6. Collect forest/domain/DNS/PKI data via section functions -7. Generate diagrams (if enabled) -8. Build report using PScribo -9. Cleanup sessions - -**Critical Design Pattern**: -- **$Target** must be FQDN (not IP) - WinRM limitation -- Must run **-RunAsAdministrator** -- Must run from PowerShell 7+, **NOT** PowerShell ISE -- WinRM must be enabled on DC -- Uses **$Options** hash from config for behavior control - -### Core Section Builders - -These functions call data gatherers and structure output via PScribo's **Section** cmdlet: - -1. **Get-AbrForestSection**: Forest topology, schema, tombstone lifetime, global catalogs -2. **Get-AbrDomainSection**: Per-domain configuration, trusts, replication, GPOs, OUs -3. **Get-AbrDnsSection**: DNS zones, scavenging, delegation -4. **Get-AbrPKISection**: Certificate authorities, templates, security - -### Data Gathering Functions (Get-Abr*) - -**Pattern**: Each function collects specific AD object data via remote PSSession: - -Example: `Get-AbrADForest` (80 lines) -- Uses `Invoke-CommandWithTimeout` to run remote cmdlets -- Parses schema version to determine Windows Server version -- Detects anonymous access via dsHeuristics -- Returns object with translated property names -- Applies HealthCheck styling if enabled - -**All 52 Get-Abr* functions follow this pattern:** -- Accept parameters (Domain, ValidDcFromDomain, etc.) -- Start: Log collection message, start timing -- Process: Remote invocation via session, data transformation -- Output: `[System.Collections.ArrayList]` of objects -- HealthCheck: Conditionally apply styling (Warning/Critical) -- Return: Table/list output via PScribo's **Table** cmdlet - -### InfoLevel Architecture - -**Default Config** (`AsBuiltReport.Microsoft.AD.json`): -```json -"InfoLevel": { - "_comment_": "0 = Disabled, 1 = Enabled, 2 = Adv Summary, 3 = Detailed", - "Forest": 2, - "Domain": 2, - "DNS": 1, - "CA": 0 -} -``` - -**Usage Pattern**: -```powershell -if ($InfoLevel.Forest -ge 1) { ... show basic info } -if ($InfoLevel.Forest -ge 2) { ... show advanced details } -if ($InfoLevel.Forest -ge 3) { ... show comprehensive tables } -``` - -Enables **progressive disclosure** - users control report verbosity. - -### HealthCheck Architecture - -**Default Config**: -```json -"HealthCheck": { - "Domain": { - "GMSA": true, # Group Managed Service Accounts - "GPO": true, # Group Policy Objects - "Backup": true, # Domain backup status - "DFS": true, # DFS health - "SPN": true, # Service Principal Names - "DuplicateObject": true, - "Security": true, - "BestPractice": true - }, - "DomainController": { ... }, - "Site": { ... }, - "DNS": { ... }, - "CA": { ... } -} -``` - -**Styling Application**: -```powershell -if ($HealthCheck.Domain.Security) { - $OutObj | Where-Object { $_.AnonymousAccess -eq 'Enabled' } | - Set-Style -Style Critical -Property AnonymousAccess - $OutObj | Where-Object { $_.TombstoneLifetime -lt 180 } | - Set-Style -Style Warning -Property TombstoneLifetime -} -``` - -Objects marked as Warning/Critical get colored highlighting in reports. - -### Connection Management - -**Session Establishment** (in main entry point): -```powershell -$TempPssSession = Get-ValidPSSession -ComputerName $System -SessionName $System -$TempCIMSession = Get-ValidCIMSession -ComputerName $System -SessionName $System -``` - -**Remote Command Execution**: -```powershell -Invoke-CommandWithTimeout -Session $TempPssSession -ScriptBlock { Get-ADForest } -``` - -**Cleanup**: -```powershell -foreach ($PSSession in $PSSTable | Where { $_.Status -ne 'Offline' }) { - Remove-PSSession -Id $PSSession.id -} -``` - -### Diagram Generation - -**Diagrammer Integration**: -- Uses `Diagrammer.Core` module for topology visualization -- Types: Forest, Replication, Sites, SitesInventory, Trusts, CertificateAuthority -- Controlled by `$Options.EnableDiagrams`, `$Options.DiagramType.*` -- Outputs: PDF/PNG (configurable via `$Options.ExportDiagramsFormat`) -- Theme: White/Dark (via `$Options.DiagramTheme`) - ---- - -## 4. KEY CONVENTIONS AND PATTERNS - -### Function Naming Convention - -**Public Functions**: -- `Invoke-AsBuiltReport.Microsoft.AD` - single entry point (uses dot notation) - -**Private Functions** - Three categories: - -1. **Data Gatherers** (`Get-Abr*`): - - `Get-AbrADForest` - retrieves Forest info - - `Get-AbrADDomain` - retrieves Domain info - - `Get-AbrADDomainController` - DC inventory - - `Get-AbrADCA*` - CA-specific data - - Pattern: Get-Abr[Section][Subsection] - -2. **Section Builders** (`Get-Abr*Section`): - - `Get-AbrForestSection` - orchestrates Forest section - - `Get-AbrDomainSection` - orchestrates Domain section - - `Get-AbrDnsSection` - orchestrates DNS section - - `Get-AbrPKISection` - orchestrates PKI section - - Pattern: Get-Abr[Section]Section - -3. **Diagram Builders** (`Get-AbrDiag*`): - - `Get-AbrDiagrammer` - main diagram orchestration - - `Get-AbrDiagForest`, `Get-AbrDiagReplication`, etc. - - Pattern: Get-AbrDiag[DiagramType] - -4. **Utility Functions** (various): - - `Convert-IpAddressToMaskLength` - IP/CIDR conversion - - `ConvertTo-HashToYN` - bool → Yes/No conversion - - `Invoke-CommandWithTimeout` - remote execution with timeout - - `Get-ValidPSSession` - session validation/creation - - `Test-WinRM` - WinRM connectivity check - -### Data Structure Patterns - -**Standard Data Object**: -```powershell -$inObj = [ordered] @{ - 'Property Name' = $Value - 'Health Check Property' = $CheckResult -} -$OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) | Out-Null -``` - -**Conversion Helper Usage**: -```powershell -# ConvertTo-HashToYN: Converts boolean $true/$false → "Yes"/"No" -$inObj | ConvertTo-HashToYN -``` - -**Style Application**: -```powershell -$OutObj | Set-Style -Style Critical -Property $PropertyName -$OutObj | Set-Style -Style Warning -Property $PropertyName -``` - -### Report Section Structure - -**PScribo Section Hierarchy**: -```powershell -Section -Style Heading1 "Forest Name" { - Paragraph "Introduction..." - BlankLine - - Section -Style Heading2 "Subsection Title" { - if ($Options.ShowDefinitionInfo) { - Paragraph "Definition text..." - } - - # Call data gatherer - Get-AbrADForest - - if ($InfoLevel.Forest -ge 2) { - # Advanced details - Get-AbrADSite - } - } -} -``` - -**PScribo Elements Used**: -- `Section` - create section with heading levels (Heading1-Heading4) -- `Table` - display data in tabular format -- `Paragraph` - text with styling (Bold, Underline, Colors) -- `BlankLine` - spacing -- `PageBreak` - force page break in Word/PDF - -### Translation/Localization Pattern - -**Property Names Use Translated Strings**: -```powershell -# From Language/en-US/MicrosoftAD.psd1 -@{ - GetAbrADForest = @{ - Collecting = 'Collecting Active Directory forest information.' - ForestName = 'Forest Name' - ForestFunctionalLevel = 'Forest Functional Level' - ... - } -} - -# In function: -$reportTranslate.GetAbrADForest.Collecting # Loaded at module init -``` - -**Multi-Language Support**: -- Each culture has its own .psd1 file (en-US, es-ES, etc.) -- Strings loaded into `$reportTranslate` hash at module load -- Property names in output tables are localized - -### HealthCheck Patterns - -**Pre-Check Pattern** (e.g., RID Pool): -```powershell -if ($HealthCheck.Domain.BestPractice) { - if ([math]::Truncate($CompleteSIDS / $RIDsRemaining) -gt 80) { - $OutObj | Set-Style -Style Warning -Property RIDProperty - Paragraph "Health check message about RID pool..." - } -} -``` - -**28 Functions Use HealthCheck** out of 52 data gatherers (~54%): -- Focus on security, best practices, service health -- Each check compares values against thresholds -- Styling applied: Warning, Critical, or Success - -### Configuration-Driven Behavior - -**Options Hash Controls**: -```json -"Options": { - "ShowExecutionTime": false, # Show timing info - "ShowDefinitionInfo": false, # Show definition text - "PSDefaultAuthentication": "Negotiate", - "Exclude": { "Domains": [], "DCs": [] }, - "Include": { "Domains": [] }, # Only these domains - "WinRMSSL": false, - "WinRMFallbackToNoSSL": true, - "WinRMSSLPort": 5986, - "WinRMPort": 5985, - "EnableDiagrams": true, - "DiagramTheme": "White", - "JobsTimeOut": 900 # 15-minute timeout -} -``` - -**Usage Example**: -```powershell -if ($Options.ShowDefinitionInfo) { - Paragraph $reportTranslate.GetAbrForestSection.DefinitionText -} - -$TimeoutSeconds = $Options.JobsTimeOut -``` - -### Error Handling & Timeouts - -**Invoke-CommandWithTimeout Pattern**: -```powershell -function Invoke-CommandWithTimeout { - param( - [System.Management.Automation.Runspaces.PSSession]$Session, - [scriptblock]$ScriptBlock, - [int]$TimeoutSeconds = $Options.JobsTimeOut - ) - - # Run as background job with timeout - $job = Invoke-Command -Session $Session -AsJob -ScriptBlock $ScriptBlock - Wait-Job $job -Timeout $TimeoutSeconds - Receive-Job $job -} -``` - -**Try-Catch in Data Gatherers**: -```powershell -try { - Get-AbrADForest -} catch { - Write-PScriboMessage -IsWarning $_.Exception.Message -} -``` - -### Sensitive Data Handling - -**No explicit redaction observed**, but patterns suggest: -- Credentials passed via `$PSCredential` object (not stored) -- Session-based execution (no inline secrets) -- Remote execution prevents data capture on local disk -- Output tables contain parsed, non-sensitive data - -**Recommendation**: Follow AD best practices - restrict report access, don't email to untrusted parties. - ---- - -## 5. CONFIGURATION - -### Primary Config File - -**File**: `AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json` - -**Structure**: -```json -{ - "Report": { - "Name": "Microsoft Active Directory As Built Report", - "Version": "1.0", - "Status": "Released", - "ShowCoverPageImage": true, - "ShowTableOfContents": true, - "ShowHeaderFooter": true, - "ShowTableCaptions": true - }, - "Options": { ... }, // Execution behavior - "InfoLevel": { ... }, // Report verbosity - "HealthCheck": { ... } // Health check toggles -} -``` - -### Configuration Usage - -Users provide config via **-ReportConfig parameter** to AsBuiltReport.Core: - -```powershell -$ReportConfig = Get-Content 'config.json' | ConvertFrom-Json - -New-AsBuiltReport -Report Microsoft.AD ` - -Target 'DC01.contoso.com' ` - -ReportConfig $ReportConfig ` - -Credential $cred ` - -Format HTML -``` - -**Module Loads**: -```powershell -$script:Report = $ReportConfig.Report -$script:InfoLevel = $ReportConfig.InfoLevel -$script:Options = $ReportConfig.Options -``` - -### Module Manifest - -**File**: `AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1` - -**Key Settings**: -- **Version**: 0.9.11 -- **PowerShellVersion**: 5.1 (minimum, actually PS7 required) -- **CompatiblePSEditions**: Desktop, Core -- **GUID**: 0a3e1c04-13b8-418f-89bc-a5a18da07394 - -**Required Modules**: -- AsBuiltReport.Core (v1.6.2+) -- AsBuiltReport.Chart (v0.2.0+) -- Diagrammer.Core (v0.2.38+) -- PSPKI (v4.3.0+) - ---- - -## 6. EXISTING AI CONFIGS - -**None Found**. No existing files: -- `.cursorrules` ✗ -- `.clinerules` ✗ -- `.windsurfrules` ✗ -- `CLAUDE.md` ✗ -- `AGENTS.md` ✗ -- `CONVENTIONS.md` ✗ - ---- - -## 7. README AND CONTRIBUTING - -### README Key Points - -**Project Purpose**: -- Community-maintained, no Microsoft sponsorship -- Generates as-built documentation for AD (Word/HTML/Text) -- Supports AD 2012/2016/2019/2022/2025 -- **PowerShell 7+ required** (not PS 5.1!) -- Windows only (RSAT dependency) - -**Supported Features**: -- Forest topology & schema info -- Domain configuration & replication -- DNS zones & scavenging -- PKI/Certificate Authority details -- Diagrams (Forest, Replication, Trusts, Sites, CA) -- Health checks for security/best practices -- Multi-language support (en-US, es-ES) - -**Key Disclaimer**: -> This assessment is not exhaustive. All recommendations should be reviewed and implemented by qualified personnel. The author(s) assume no liability for any damages. - -### CONTRIBUTING Guidelines - -**Process**: -1. Fork repo, clone, add remote upstream -2. Create topic branch off dev/main -3. Make changes following project conventions -4. Commit with clear messages -5. Pull upstream dev before pushing -6. Open PR with clear description - -**Requirements**: -- Follow existing code conventions (indentation, comments) -- Include test coverage (reference Pester tests) -- Respect git commit message guidelines -- No copyrighted content -- Agree to project license - -**Key Restriction**: -- Ask before embarking on large features/refactoring -- Don't use issue tracker for personal support - ---- - -## 8. CODE CONVENTIONS SUMMARY - -### PowerShell Code Style - -**Enforced via VSCode + PSScriptAnalyzer**: - -**Formatting** (`.vscode/settings.json`): -- Tab size: 4 spaces (insert spaces, not tabs) -- Line length: 115 characters (ruler configured) -- Trim trailing whitespace: enabled -- Code folding: enabled -- Brace style: - - Opening brace on same line: `if (...) {` - - New line after opening brace: `{\n ...` - - New line after closing brace: disabled -- Whitespace: - - Before open brace: enabled - - Before open paren: enabled - - Around operators: enabled - - After separator (;): enabled - - Around pipe: enabled - -**Linting** (`PSScriptAnalyzerSettings.psd1`): -- No single-character variable names -- No double quotes for constant strings -- Case sensitivity enforced -- No aliases (full cmdlet names) -- Consistent whitespace - -### Naming Conventions - -**Variables**: -- PascalCase for scripts/function names: `$ValidDcFromDomain` -- $script: prefix for module-level vars: `$script:Report`, `$script:InfoLevel` -- Hungarian notation for collections: `$PSSTable`, `$DCStatus` (plural hint) - -**Functions**: -- Verb-Noun format: `Get-AbrADForest`, `Invoke-CommandWithTimeout` -- Approved verbs: Get, New, Invoke, Test, Convert -- Hierarchy: `Get-[Abr][Component][Action]` - -**Constants**: -- `[ordered]` for hash ordering -- `[System.Collections.ArrayList]` for dynamic arrays (preferred over `@()`) -- `[pscustomobject]` for object creation - -### Error Handling - -- Use **try-catch** blocks -- Write warnings via `Write-PScriboMessage -IsWarning` -- Write errors via `Write-Error` or `throw` -- Log activity via `Write-PScriboMessage` -- Show timing via `Show-AbrDebugExecutionTime` - -### Documentation - -- SYNOPSIS, DESCRIPTION, NOTES (version, author, twitter, github) -- .EXAMPLE, .LINK for help -- Inline comments for complex logic -- Parameter documentation with `[Parameter(...)]` attributes - ---- - -## 9. CRITICAL DEVELOPMENT NOTES - -### Must-Know Limitations - -1. **WinRM Requirements**: - - Target must be FQDN (not IP) - - WinRM must be enabled on DC - - Domain-joined machine required to run module - - PowerShell 7+ on Windows only - -2. **Execution Context**: - - Must run `-RunAsAdministrator` - - Cannot run inside PowerShell ISE - - Remote execution via PSSession (not local cmdlets) - -3. **Session Timeout**: - - Default timeout: 900 seconds (15 minutes) - - Configurable via `$Options.JobsTimeOut` - - Long operations may timeout on slow links - -### Development Workflow - -1. **Make changes** to `.ps1` files in `Src/Public` or `Src/Private` -2. **Run tests** locally: `.\Tests\Invoke-Tests.ps1` -3. **Check linting**: PSScriptAnalyzer via VSCode -4. **Push to dev branch** (not master) -5. **CI/CD runs** Pester + PSScriptAnalyzer -6. **Create PR** to merge into master - -### Debugging Tips - -**Execution Timing**: -```powershell -if ($Options.ShowExecutionTime) { - Show-AbrDebugExecutionTime -Start/Stop -TitleMessage 'Section Name' -} -``` - -**Logging Messages**: -```powershell -Write-PScriboMessage -Message "Collecting..." -Write-PScriboMessage -IsWarning "Warning message" -``` - -**Remote Session Debugging**: -```powershell -$session = Get-PSSession -Name 'DC01.contoso.com' -Invoke-Command -Session $session -ScriptBlock { Get-ADForest } -``` - -### Performance Considerations - -- Remote data collection happens sequentially (per domain) -- Large forests (100+ domains) may take 30+ minutes -- CPU-intensive: Schema analysis, trust enumeration -- Network: WinRM traffic, potentially large XML responses -- Disk: HTML/DOCX output can be 50+ MB with diagrams - -### Testing Strategy - -**Unit Tests** (`Tests/AsBuiltReport.Microsoft.AD.Tests.ps1`): -- Module manifest validation -- Function availability -- Module dependency versions -- Export validation - -**Integration Tests** (Not present): -- Would require live AD environment -- Manual testing against test domains recommended - -**Code Coverage**: -- Current: Unknown (50% threshold enforced) -- Recommendation: Add more tests for edge cases - ---- - -## 10. PROJECT-SPECIFIC GUIDANCE FOR AI ASSISTANTS - -### When Making Code Changes - -1. **Respect InfoLevel checks**: Wrap new sections with `if ($InfoLevel.Component -ge N)` -2. **Add HealthCheck conditionals**: Wrap checks with `if ($HealthCheck.Component.Feature)` -3. **Use localization strings**: Reference `$reportTranslate.FunctionName.PropertyName` -4. **Follow try-catch pattern**: Every data gatherer in try-catch with `-IsWarning` -5. **Apply Set-Style**: Mark warning/critical objects for report highlighting -6. **Use OrderedDictionary**: `[ordered] @{}` for property ordering -7. **Pass sessions as parameters**: Don't assume `$TempPssSession` global exists -8. **Document with `.SYNOPSIS`**: All functions need help documentation -9. **Return objects not strings**: Build arrays of `[pscustomobject]` for Table output -10. **Test with `-CodeCoverage`**: Ensure new code is covered by tests - -### Common Tasks - -**Add a new health check:** -1. Add boolean to `AsBuiltReport.Microsoft.AD.json` under `HealthCheck.Component.NewCheck` -2. In Get-Abr* function: `if ($HealthCheck.Component.NewCheck) { ... Set-Style ... }` -3. Add test case to `Tests/AsBuiltReport.Microsoft.AD.Tests.ps1` - -**Add new report section:** -1. Create `Get-AbrNewSection` function in `Src/Private/` -2. Create `Get-AbrNewSectionData` data gatherer -3. Call from main entry point: `if ($InfoLevel.NewComponent -ge 1) { Get-AbrNewSection }` -4. Add InfoLevel config: `"NewComponent": 1` to JSON -5. Add translations to `Language/en-US/MicrosoftAD.psd1` and `es-ES/` - -**Fix a timeout issue:** -1. Increase `$Options.JobsTimeOut` in JSON (default 900) -2. Or reduce data scope (disable HealthChecks or lower InfoLevel) -3. Or optimize remote query (use `-Filter` with better conditions) - -### Module Dependencies to Understand - -- **AsBuiltReport.Core**: Framework for report generation, parameter validation -- **PScribo**: Document markup (Section, Table, Paragraph, Set-Style) -- **ActiveDirectory**: AD cmdlets (Get-ADForest, Get-ADDomain, etc.) - Microsoft module -- **PSPKI**: PKI cmdlets (Get-CertificationAuthority) - community module -- **Diagrammer.Core**: Diagram generation for topology visualization -- **GroupPolicy**: GPO retrieval (Get-GPO, Get-GPOReport) -- **DnsServer**: DNS zone enumeration - ---- - -## 11. QUICK REFERENCE - -### Module Entry Point -- **Location**: `AsBuiltReport.Microsoft.AD/Src/Public/Invoke-AsBuiltReport.Microsoft.AD.ps1` -- **Exports**: Single public function (dot-notation name) -- **Parameters**: `$Target` (FQDN array), `$Credential` (PSCredential) -- **Returns**: Report file (HTML/Word/Text) via PScribo - -### Main Directories -| Directory | Purpose | Files | -|-----------|---------|-------| -| `Src/Public` | Exported functions | 1 file (entry point) | -| `Src/Private` | Internal functions | 88 functions | -| `Language` | Localization | .psd1 per culture | -| `Tests` | Unit/integration tests | Pester framework | -| `.github/workflows` | CI/CD pipelines | 5 YAML files | - -### Key Files -| File | Purpose | Size | -|------|---------|------| -| `AsBuiltReport.Microsoft.AD.psm1` | Module loader | 14 lines | -| `AsBuiltReport.Microsoft.AD.psd1` | Manifest | ~100 lines | -| `AsBuiltReport.Microsoft.AD.json` | Config template | 89 lines | -| `AsBuiltReport.Microsoft.AD.Style.ps1` | Report styling | 20 KB | - -### Test Commands -```powershell -# Basic test run -.\Tests\Invoke-Tests.ps1 - -# With coverage -.\Tests\Invoke-Tests.ps1 -CodeCoverage -OutputFormat NUnitXml - -# Output formats -.\Tests\Invoke-Tests.ps1 -OutputFormat JUnitXml -.\Tests\Invoke-Tests.ps1 -OutputFormat Console -``` - -### Required Modules (Minimum Versions) -```powershell -AsBuiltReport.Core 1.6.2+ -AsBuiltReport.Chart 0.2.0+ -Diagrammer.Core 0.2.38+ -PSPKI 4.3.0+ -Pester 5.0.0+ -PScribo 0.11.1+ -PSScriptAnalyzer 1.0.0+ -``` - -### Function Categories -| Category | Count | Examples | -|----------|-------|----------| -| Get-Abr* (data gathering) | 52 | Get-AbrADForest, Get-AbrADDomain | -| Get-Abr*Section (orchestration) | 4 | Get-AbrForestSection, Get-AbrDNSSection | -| Get-AbrDiag* (diagrams) | 8 | Get-AbrDiagrammer, Get-AbrDiagForest | -| Utility (conversion, helpers) | 24+ | ConvertTo-HashToYN, Invoke-CommandWithTimeout | - ---- - -**Document Version**: 1.0 -**Last Updated**: 2024 -**Project Version**: 0.9.11 -**Target PowerShell**: 7+ -**Platform**: Windows Only - From aa1b8d6033ff83026cfe4c7d9b311efd5705f6c1 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 16:33:58 -0400 Subject: [PATCH 11/18] feat: Add GliderUI support for report generation with a graphical interface fix: Ensure diagram theme generation respects user-selected themes in configuration refactor: Improve multi-language support and documentation clarity for MicrosoftAD.psd1 --- .../AsBuiltReport.Microsoft.AD.json | 5 - .../AsBuiltReport.Microsoft.AD.psd1 | 2 +- .../AsBuiltReport.Microsoft.AD.psm1 | 6 +- .../Src/Private/Diagram/Get-AbrADCaInfo.ps1 | 8 +- .../Private/Diagram/Get-AbrADForestInfo.ps1 | 8 +- .../Private/Diagram/Get-AbrADTrustInfo.ps1 | 6 +- .../Get-AbrDiagCertificateAuthority.ps1 | 12 +- .../Src/Private/Diagram/Get-AbrDiagForest.ps1 | 4 +- .../Diagram/Get-AbrDiagReplication.ps1 | 14 +- .../Src/Private/Diagram/Get-AbrDiagSite.ps1 | 6 +- .../Diagram/Get-AbrDiagSiteInventory.ps1 | 20 +- .../Src/Private/Diagram/Get-AbrDiagTrust.ps1 | 6 +- .../Src/Private/Diagram/New-AbrADDiagram.ps1 | 4 +- .../Private/Gui/Start-AsBuiltReportMSAD.ps1 | 1408 +++++++++++++++++ CHANGELOG.md | 8 + 15 files changed, 1465 insertions(+), 52 deletions(-) create mode 100644 AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json index 88f5b32..4a34316 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.json @@ -79,11 +79,6 @@ "DP": true, "Zones": true, "BestPractice": true - }, - "CA": { - "Status": true, - "Statistics": true, - "BestPractice": true } } } \ No newline at end of file diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 index 24fc28f..58e336b 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 @@ -82,7 +82,7 @@ # 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') + FunctionsToExport = @('Invoke-AsBuiltReport.Microsoft.AD', 'Start-AsBuiltReportMSAD') # 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 = '*' diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psm1 b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psm1 index c27469d..2b78072 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psm1 +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psm1 @@ -3,8 +3,9 @@ $Public = @(Get-ChildItem -Path $PSScriptRoot\Src\Public\*.ps1 -ErrorAction Sile $Diagram = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\Diagram\*.ps1 -ErrorAction SilentlyContinue) $Report = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\Report\*.ps1 -ErrorAction SilentlyContinue) $Tools = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\Tools\*.ps1 -ErrorAction SilentlyContinue) +$Gui = @(Get-ChildItem -Path $PSScriptRoot\Src\Private\Gui\*.ps1 -ErrorAction SilentlyContinue) -foreach ($Module in @($Public + $Report + $Diagram + $Tools)) { +foreach ($Module in @($Public + $Report + $Diagram + $Tools + $Gui)) { try { . $Module.FullName } catch { @@ -15,4 +16,5 @@ foreach ($Module in @($Public + $Report + $Diagram + $Tools)) { Export-ModuleMember -Function $Public.BaseName Export-ModuleMember -Function $Report.BaseName Export-ModuleMember -Function $Diagram.BaseName -Export-ModuleMember -Function $Tools.BaseName \ No newline at end of file +Export-ModuleMember -Function $Tools.BaseName +Export-ModuleMember -Function $Gui.BaseName \ No newline at end of file diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADCaInfo.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADCaInfo.ps1 index 014d8ea..399e2b9 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADCaInfo.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADCaInfo.ps1 @@ -5,7 +5,7 @@ function Get-AbrADCAInfo { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -43,7 +43,7 @@ function Get-AbrADCAInfo { $TempCAInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String "$($rootCA.Name)RootCA" -SpecialChars '\-. ' CAName = $rootCA.Name - Label = Add-NodeIcon -Name $rootCA.Name -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo + Label = Add-NodeIcon -Name $rootCA.Name -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo -FontColor $Fontcolor AditionalInfo = $AditionalInfo IsRoot = $true } @@ -64,7 +64,7 @@ function Get-AbrADCAInfo { $TempCAInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String $RootCAName -SpecialChars '\-. ' CAName = $RootCAName - Label = Add-NodeIcon -Name $RootCAName -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo + Label = Add-NodeIcon -Name $RootCAName -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor AditionalInfo = $AditionalInfo IsRoot = $true } @@ -86,7 +86,7 @@ function Get-AbrADCAInfo { $TempCAInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String $subordinateCA.Name -SpecialChars '\-. ' CAName = $subordinateCA.Name - Label = Add-NodeIcon -Name $subordinateCA.dNSHostName -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo + Label = Add-NodeIcon -Name $subordinateCA.dNSHostName -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -Rows $AditionalInfo -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor AditionalInfo = $AditionalInfo IsRoot = $false } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADForestInfo.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADForestInfo.ps1 index f830c5e..41c1595 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADForestInfo.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADForestInfo.ps1 @@ -5,7 +5,7 @@ function Get-AbrADForestInfo { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -131,9 +131,9 @@ function Get-AbrADForestInfo { $TempForestInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String "$($ChildDomain)ChildDomain" -SpecialChars '\-. ' ChildDomainLabel = $ChildDomain - Label = Add-NodeIcon -Name $ChildDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalDomainInfo -FontSize 18 + Label = Add-NodeIcon -Name $ChildDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalDomainInfo -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor RootDomain = $ForestObj.RootDomain - RootDomainLabel = Add-NodeIcon -Name $ForestObj.RootDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalForestInfo -FontSize 18 + RootDomainLabel = Add-NodeIcon -Name $ForestObj.RootDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalForestInfo -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor ChildDomain = $ChildDomain ParentDomain = Remove-SpecialCharacter -String "$($Childs.Parent)ChildDomain" -SpecialChars '\-. ' AditionalInfo = $AditionalDomainInfo @@ -181,7 +181,7 @@ function Get-AbrADForestInfo { $TempForestInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String "$($ForestObj.Name)RootDomain" -SpecialChars '\-. ' - Label = Add-NodeIcon -Name $ForestObj.RootDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalForestInfo -FontSize 18 + Label = Add-NodeIcon -Name $ForestObj.RootDomain -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -AditionalInfo $AditionalForestInfo -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor AditionalInfo = $AditionalForestInfo } $ForestInfo.Add($TempForestInfo) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADTrustInfo.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADTrustInfo.ps1 index 7d4e407..5b37274 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADTrustInfo.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrADTrustInfo.ps1 @@ -5,7 +5,7 @@ function Get-AbrADTrustsInfo { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -71,9 +71,9 @@ function Get-AbrADTrustsInfo { } $TempTrustsInfo = [PSCustomObject]@{ Name = Remove-SpecialCharacter -String "$($Trust.Target)Trusts" -SpecialChars '\-. ' - Label = Add-NodeIcon -Name $Trust.Target -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -RowsOrdered $AditionalInfo + Label = Add-NodeIcon -Name $Trust.Target -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -RowsOrdered $AditionalInfo -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor Source = $Trust.CanonicalName.split('/')[0] - SourceLabel = Add-NodeIcon -Name $Trust.CanonicalName.split('/')[0] -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug + SourceLabel = Add-NodeIcon -Name $Trust.CanonicalName.split('/')[0] -IconType 'AD_Domain' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor Direction = $TrustDirectionID[[int]$Trust.TrustDirection] } $TrustsInfo.Add($TempTrustsInfo) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 index 20d5e9f..e8e96b5 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagCertificateAuthority { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -32,7 +32,7 @@ function Get-AbrDiagCertificateAuthority { $CAInfo = Get-AbrADCAInfo if ($CAInfo) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = ' ' ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { if ($CAInfo | Where-Object { $_.IsRoot }) { @@ -42,16 +42,16 @@ function Get-AbrDiagCertificateAuthority { $CALabel = $reportTranslate.NewADDiagram.caEntRootCA } - $CARootNodes = Add-HtmlNodeTable -Name CARootNodes -ImagesObj $Images -inputObject ($CAInfo | Where-Object { $_.IsRoot }).CAName -Align 'Center' -iconType 'AD_Certificate' -ColumnSize 4 -IconDebug $IconDebug -MultiIcon -AditionalInfo ($CAInfo | Where-Object { $_.IsRoot }).AditionalInfo -FontSize 18 -TableBorderColor $Edgecolor + $CARootNodes = Add-HtmlNodeTable -Name CARootNodes -ImagesObj $Images -inputObject ($CAInfo | Where-Object { $_.IsRoot }).CAName -Align 'Center' -iconType 'AD_Certificate' -ColumnSize 4 -IconDebug $IconDebug -MultiIcon -AditionalInfo ($CAInfo | Where-Object { $_.IsRoot }).AditionalInfo -FontSize 18 -TableBorderColor $Edgecolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - Node -Name 'RootCA' -Attributes @{Label = (Add-HtmlSubGraph -Name RootCA -ImagesObj $Images -TableArray $CARootNodes -Align 'Center' -IconDebug $IconDebug -Label $CALabel -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -IconType 'AD_PKI_Logo' -FontColor $Fontcolor -FontSize 24 -FontBold -TableBorderColor $Edgecolor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } + Node -Name 'RootCA' -Attributes @{Label = (Add-HtmlSubGraph -Name RootCA -ImagesObj $Images -TableArray $CARootNodes -Align 'Center' -IconDebug $IconDebug -Label $CALabel -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -IconType 'AD_PKI_Logo' -FontColor $Fontcolor -FontSize 24 -FontBold -TableBorderColor $Edgecolor -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } } if ($CAInfo | Where-Object { -not $_.IsRoot }) { - $CASubordinateNodes = Add-HtmlNodeTable -Name CASubordinateNodes -ImagesObj $Images -inputObject ($CAInfo | Where-Object { -not $_.IsRoot }).CAName -Align 'Center' -iconType 'AD_Certificate' -ColumnSize 4 -IconDebug $IconDebug -MultiIcon -AditionalInfo ($CAInfo | Where-Object { -not $_.IsRoot }).AditionalInfo -FontSize 18 -TableBorderColor $Edgecolor + $CASubordinateNodes = Add-HtmlNodeTable -Name CASubordinateNodes -ImagesObj $Images -inputObject ($CAInfo | Where-Object { -not $_.IsRoot }).CAName -Align 'Center' -iconType 'AD_Certificate' -ColumnSize 4 -IconDebug $IconDebug -MultiIcon -AditionalInfo ($CAInfo | Where-Object { -not $_.IsRoot }).AditionalInfo -FontSize 18 -TableBorderColor $Edgecolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - Node -Name 'SubordinateCA' -Attributes @{Label = (Add-HtmlSubGraph -Name SubordinateCA -ImagesObj $Images -TableArray $CASubordinateNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.caEntSubCA -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -IconType 'AD_PKI_Logo' -FontColor $Fontcolor -FontSize 24 -FontBold -TableBorderColor $Edgecolor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } + Node -Name 'SubordinateCA' -Attributes @{Label = (Add-HtmlSubGraph -Name SubordinateCA -ImagesObj $Images -TableArray $CASubordinateNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.caEntSubCA -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -IconType 'AD_PKI_Logo' -FontColor $Fontcolor -FontSize 24 -FontBold -TableBorderColor $Edgecolor -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 index a44e6bc..8c3c83c 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagForest { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -32,7 +32,7 @@ function Get-AbrDiagForest { $ForestInfo = Get-AbrADForestInfo if ($ForestInfo) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = ' ' ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { if ($ForestInfo.ChildDomain ) { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 index bcf6b9a..af21f1e 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagReplication { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -33,7 +33,7 @@ function Get-AbrDiagReplication { Write-Verbose -Message ($reportTranslate.NewADDiagram.buildingReplication -f $($ForestRoot)) $HTMLLegend = ('
{0} {1}
' -f $reportTranslate.NewADDiagram.replIntraSite, $reportTranslate.NewADDiagram.replInterSite) if ($ReplInfo) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = $HTMLLegend ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { # Collect unique sites and DCs from replication data $Sites = ($ReplInfo | Select-Object -ExpandProperty FromSite) + ($ReplInfo | Select-Object -ExpandProperty ToSite) | Select-Object -Unique | Where-Object { $_ -ne 'Unknown' } @@ -49,10 +49,10 @@ function Get-AbrDiagReplication { ($ReplInfo | Where-Object { ($_.FromServer -eq $DC -and $_.FromSite -eq $Site) -or ($_.ToServer -eq $DC -and $_.ToSite -eq $Site) }) } | Select-Object -Unique - SubGraph $SiteNodeName -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $Site -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { + SubGraph $SiteNodeName -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $Site -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { foreach ($DC in $SiteDCs) { $DCNodeName = Remove-SpecialCharacter -String $DC -SpecialChars '\-. ' - Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18); shape = 'plain'; fillColor = 'transparent' } + Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent' } } } } @@ -63,10 +63,10 @@ function Get-AbrDiagReplication { -not ($ReplInfo | Where-Object { ($_.FromServer -eq $DC -and $_.FromSite -ne 'Unknown') -or ($_.ToServer -eq $DC -and $_.ToSite -ne 'Unknown') }) } if ($UnknownSiteDCs) { - SubGraph UnknownSite -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $reportTranslate.NewADDiagram.replUnknownSite -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { + SubGraph UnknownSite -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $reportTranslate.NewADDiagram.replUnknownSite -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { foreach ($DC in $UnknownSiteDCs) { $DCNodeName = Remove-SpecialCharacter -String $DC -SpecialChars '\-. ' - Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18); shape = 'plain'; fillColor = 'transparent' } + Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent' } } } } @@ -74,7 +74,7 @@ function Get-AbrDiagReplication { # No site information - draw all DCs without grouping foreach ($DC in $AllDCs) { $DCNodeName = Remove-SpecialCharacter -String $DC -SpecialChars '\-. ' - Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18); shape = 'plain'; fillColor = 'transparent' } + Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent' } } } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSite.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSite.ps1 index 36bd60f..bd88d2b 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSite.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSite.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagSite { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -32,7 +32,7 @@ function Get-AbrDiagSite { $SitesInfo = Get-AbrADSitesInfo if ($SitesInfo) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = ' ' ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { if ($SitesInfo.Site) { foreach ($SitesObj in $SitesInfo) { @@ -41,7 +41,7 @@ function Get-AbrDiagSite { foreach ($Link in $SitesObj.SiteLink) { # Start - Information for each SiteLink. Example: "Name: (Pharmax-to-Acad) SiteLink (Cost: 10) (Frequency: 15 minutes)" $SiteLink = Remove-SpecialCharacter -String $Link.Name -SpecialChars '\-. ' - Node -Name $SiteLink -Attributes @{Label = (Add-HtmlTable -Name SiteLink -ALIGN 'Center' -IconDebug $IconDebug -Rows ($Link.AditionalInfo.GetEnumerator() | ForEach-Object { "$($_.key): $($_.value)" }) -ColumnSize 1 -FontSize 12); shape = 'plain'; fillColor = 'transparent' } + Node -Name $SiteLink -Attributes @{Label = (Add-HtmlTable -Name SiteLink -ALIGN 'Center' -IconDebug $IconDebug -Rows ($Link.AditionalInfo.GetEnumerator() | ForEach-Object { "$($_.key): $($_.value)" }) -ColumnSize 1 -FontSize 12 -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent' } Edge -From $Site -To $SiteLink @{minlen = 2; arrowtail = 'none'; arrowhead = 'none' } # End - Information for each SiteLink foreach ($SiteLinkSite in $Link.Sites) { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 index 21ae9a7..2f9f905 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagSiteInventory { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -32,7 +32,7 @@ function Get-AbrDiagSiteInventory { $SitesGroups = Get-AbrADSitesInventoryInfo if ($SitesGroups) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor) ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = ' ' ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { if (($SitesGroups | Measure-Object).Count -ge 1) { $ChildSiteSubgraphArray = [System.Collections.Generic.List[object]]::new() @@ -40,23 +40,23 @@ function Get-AbrDiagSiteInventory { if ($SiteGroupOBJ.DomainControllers.DCsArray) { - $ChildDCsNodes = Add-HtmlTable -Name ChildDCsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.DomainControllers.DCsArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 + $ChildDCsNodes = Add-HtmlTable -Name ChildDCsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.DomainControllers.DCsArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 -TableBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $ChildDCsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 18 + $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $ChildDCsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 18 -TableBackgroundColor $MainGraphBGColor } else { - $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteDC -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 22 + $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteDC -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } if ($SiteGroupOBJ.Subnets.SubnetArray) { - $ChildSubnetsNodes = Add-HtmlTable -Name ChildSubnetsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.Subnets.SubnetArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 + $ChildSubnetsNodes = Add-HtmlTable -Name ChildSubnetsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.Subnets.SubnetArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 -TableBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $ChildSubnetsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 + $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $ChildSubnetsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } else { - $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteSubnet -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 + $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteSubnet -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } $ChildSiteSubgraph = [System.Collections.Generic.List[object]]::new() @@ -65,11 +65,11 @@ function Get-AbrDiagSiteInventory { $ChildSiteSubgraph.Add($ChildSubnetsNodesSubgraph) $ChildSiteSubgraphArray.Add( - (Add-HtmlSubGraph -Name ChildSiteSubgraphArray -ImagesObj $Images -TableArray $ChildSiteSubgraph -Align 'Center' -IconType 'AD_Site' -IconDebug $IconDebug -Label $SiteGroupOBJ.Name -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22) + (Add-HtmlSubGraph -Name ChildSiteSubgraphArray -ImagesObj $Images -TableArray $ChildSiteSubgraph -Align 'Center' -IconType 'AD_Site' -IconDebug $IconDebug -Label $SiteGroupOBJ.Name -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor) ) } - Node -Name 'SitesTopology' -Attributes @{Label = (Add-HtmlSubGraph -Name SitesTopology -ImagesObj $Images -TableArray $ChildSiteSubgraphArray -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Sites -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22); shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = 'Segoe Ui' } + Node -Name 'SitesTopology' -Attributes @{Label = (Add-HtmlSubGraph -Name SitesTopology -ImagesObj $Images -TableArray $ChildSiteSubgraphArray -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Sites -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = 'Segoe Ui' } } else { Node -Name NoSites -Attributes @{Label = $reportTranslate.NewADDiagram.NoSites; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 0 } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 index 6cbc704..d623288 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 @@ -5,7 +5,7 @@ function Get-AbrDiagTrust { .DESCRIPTION Build a diagram of the configuration of Microsoft Active Directory to a supported formats using Psgraph. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -32,13 +32,13 @@ function Get-AbrDiagTrust { $TrustsInfo = Get-AbrADTrustsInfo if ($TrustsInfo) { - SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold); fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { + SubGraph ForestSubGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $ForestRoot -IconType 'ForestRoot' -IconDebug $IconDebug -SubgraphLabel -IconWidth 50 -IconHeight 50 -Fontsize 22 -FontName 'Segoe UI' -FontColor $Fontcolor -FontBold -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style ; color = $SubGraphDebug.color } { SubGraph MainSubGraph -Attributes @{Label = ' ' ; fontsize = 24; penwidth = 1.5; labelloc = 't'; style = $SubGraphDebug.style; color = $SubGraphDebug.color } { if (($TrustsInfo.Name | Measure-Object).count -gt 10) { $ChildDomainsNodes = $TrustsInfo.Label - Node -Name 'TrustDestinations' -Attributes @{Label = (Add-HtmlSubGraph -Name TrustDestinations -ImagesObj $Images -TableArray $ChildDomainsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.TrustRelationships -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -FontSize 22 -FontName 'Segoe UI' -TableBorderColor $Edgecolor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } + Node -Name 'TrustDestinations' -Attributes @{Label = (Add-HtmlSubGraph -Name TrustDestinations -ImagesObj $Images -TableArray $ChildDomainsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.TrustRelationships -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -FontSize 22 -FontName 'Segoe UI' -TableBorderColor $Edgecolor -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 18; fontname = 'Segoe Ui' } $ForestRootDomain = Remove-SpecialCharacter -String "$($TrustsInfo.Source[0])ForestRoot" -SpecialChars '\-. ' Node -Name $ForestRootDomain -Attributes @{Label = $TrustsInfo.SourceLabel[0]; shape = 'plain'; fillColor = 'transparent' } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 index c8e9aa8..3896270 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 @@ -71,7 +71,7 @@ function New-AbrADDiagram { .PARAMETER WatermarkColor Allow to specified the color used for the watermark text. Default: #565656. .NOTES - Version: 0.9.12 + Version: 1.0.0 Author(s): Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -511,7 +511,7 @@ function New-AbrADDiagram { Write-Verbose $reportTranslate.NewADDiagram.genDiagramSignature # Main Graph SubGraph - SubGraph MainGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $MainGraphLabel -IconType $CustomLogo -IconDebug $IconDebug -IconWidth 250 -IconHeight 80 -Fontsize 24 -FontName 'Segoe UI Bold' -FontColor $Fontcolor ); fontsize = 22; penwidth = 0; labelloc = 't'; labeljust = 'c' } { + SubGraph MainGraph -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $MainGraphLabel -IconType $CustomLogo -IconDebug $IconDebug -IconWidth 250 -IconHeight 80 -Fontsize 24 -FontName 'Segoe UI Bold' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 22; penwidth = 0; labelloc = 't'; labeljust = 'c' } { Write-Verbose $reportTranslate.NewADDiagram.genDiagramMain $script:ForestRoot = $ADSystem.Name.ToString().ToUpper() diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 new file mode 100644 index 0000000..b7ddb6a --- /dev/null +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 @@ -0,0 +1,1408 @@ +#Requires -RunAsAdministrator + +using namespace GliderUI +using namespace GliderUI.Avalonia +using namespace GliderUI.Avalonia.Controls +using namespace GliderUI.Avalonia.Platform.Storage +using namespace GliderUI.Avalonia.Media + +function Start-AsBuiltReportMSAD { + <# + .SYNOPSIS + GUI launcher for AsBuiltReport.Microsoft.AD — runs entirely in PowerShell 7. + .DESCRIPTION + A PowerShell 7.4+ desktop GUI (GliderUI / Avalonia) that collects connection, + output and report options, then generates the Microsoft AD As-Built Report by + calling New-AsBuiltReport directly — no child PS5.1 process required. + .NOTES + Requirements: + PowerShell 7.4+ — to run this script + GliderUI 0.2.0+ (auto-installed on first run) — Install-PSResource -Name GliderUI -Version 0.2.0 -Scope CurrentUser -TrustRepository + AsBuiltReport.Core — Install-PSResource -Name AsBuiltReport.Core + AsBuiltReport.Microsoft.AD — Install-PSResource -Name AsBuiltReport.Microsoft.AD + #> + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Scope = 'Function')] + + [CmdletBinding()] + param() + + if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 4)) { + throw "Start-AsBuiltReportMSAD requires PowerShell 7.4+. Current version: $($PSVersionTable.PSVersion)" + } + + # ── Bootstrap GliderUI ────────────────────────────────────────────────────── + $requiredGliderUIVersion = [version]'0.2.0' + + if (-not (Get-Module -ListAvailable -Name GliderUI)) { + Write-Host 'GliderUI not found — installing from PSGallery…' -ForegroundColor Cyan + Install-PSResource -Name GliderUI -Version $requiredGliderUIVersion -Scope CurrentUser -TrustRepository + } + + $gliderMod = Get-Module -ListAvailable -Name GliderUI | + Sort-Object Version -Descending | + Select-Object -First 1 + + if ($null -eq $gliderMod -or $gliderMod.Version -lt $requiredGliderUIVersion) { + $found = if ($null -eq $gliderMod) { 'not installed' } else { "v$($gliderMod.Version)" } + Write-Error ("GliderUI v{0} or later is required (found: {1}).`nInstall with: Install-PSResource -Name GliderUI -Version {0} -Scope CurrentUser -TrustRepository`nThen restart PowerShell." -f $requiredGliderUIVersion, $found) + return + } + + Import-Module GliderUI -Force + + # Thread-safe store shared between the main runspace and the report runspace + $syncHash = [Hashtable]::Synchronized(@{ + CancelRequested = $false + IsBusy = $false + }) + + # ── UI Helper Functions ───────────────────────────────────────────────────── + function New-SectionTitle ([string]$Text) { + $tb = [TextBlock]::new() + $tb.Text = $Text + $tb.FontSize = 13 + $tb.FontWeight = 'SemiBold' + $tb.Margin = '0,18,0,6' + return $tb + } + + function New-FormRow ([string]$Label, $Control, [int]$LabelWidth = 185) { + $row = [StackPanel]::new() + $row.Orientation = 'Horizontal' + $row.Spacing = 10 + $row.Margin = '0,3,0,3' + + $lbl = [TextBlock]::new() + $lbl.Text = $Label + $lbl.Width = $LabelWidth + $lbl.VerticalAlignment = 'Center' + $lbl.FontSize = 12 + + $row.Children.Add($lbl) + $row.Children.Add($Control) + return $row + } + + function New-InlineLabel ([string]$Text) { + $tb = [TextBlock]::new() + $tb.Text = $Text + $tb.VerticalAlignment = 'Center' + $tb.Margin = '8,0,0,0' + $tb.FontSize = 12 + return $tb + } + + # Wraps a password TextBox with an eye-toggle button. + function New-PasswordRow ($PasswordTextBox) { + $btn = [Button]::new() + $btn.Content = '👁' + $btn.Padding = '6,2,6,2' + $btn.VerticalAlignment = 'Center' + $btn.AddClick({ + if ($PasswordTextBox.PasswordChar -eq [char]0) { + $PasswordTextBox.PasswordChar = [char]'●' + } else { + $PasswordTextBox.PasswordChar = [char]0 + } + }.GetNewClosure()) + + $row = [StackPanel]::new() + $row.Orientation = 'Horizontal' + $row.Spacing = 6 + $row.Children.Add($PasswordTextBox) + $row.Children.Add($btn) + return $row + } + + function New-DrawerMenuItem ([string]$Title, [string]$IconGeometry, $Page, $NavigationPage) { + $icon = [PathIcon]::new() + $icon.Data = [Geometry]::Parse($IconGeometry) + + $textBlock = [TextBlock]::new() + $textBlock.Text = $Title + $textBlock.VerticalAlignment = 'Center' + + $panel = [StackPanel]::new() + $panel.Orientation = 'Horizontal' + $panel.Spacing = 8 + $panel.Children.Add($icon) + $panel.Children.Add($textBlock) + + $button = [Button]::new() + $button.HorizontalAlignment = 'Stretch' + $button.Padding = 12 + $button.Background = [SolidColorBrush]::new([Colors]::Transparent, 1) + $button.Content = $panel + $button.AddClick({ + param($argumentList) + $targetPage, $navPage = $argumentList + $navPage.ReplaceAsync($targetPage) | Out-Null + }, @($Page, $NavigationPage)) + return $button + } + + # ── Connection Controls ───────────────────────────────────────────────────── + $txtServer = [TextBox]::new() + $txtServer.Width = 240 + $txtServer.Watermark = 'dc01.contoso.com' + + $txtUser = [TextBox]::new() + $txtUser.Width = 200 + $txtUser.Watermark = 'DOMAIN\username or user@domain' + + $txtPass = [TextBox]::new() + $txtPass.Width = 200 + $txtPass.Watermark = 'Password' + try { $txtPass.PasswordChar = [char]'●' } catch { Out-Null } + + # ── Saved Connections ─────────────────────────────────────────────────────── + $savedConnPath = if ($IsWindows) { + [System.IO.Path]::Combine($env:USERPROFILE, 'AsBuiltReport', 'MSAD-SavedConnections.json') + } else { + [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport', 'MSAD-SavedConnections.json') + } + + $loadSavedConns = { + if (Test-Path $savedConnPath) { + try { + $raw = Get-Content -Path $savedConnPath -Raw -Encoding UTF8 | ConvertFrom-Json + if ($null -eq $raw) { return @() } + return @($raw) + } catch { return @() } + } + return @() + }.GetNewClosure() + + $saveSavedConns = { + param ([array]$Connections) + $dir = Split-Path $savedConnPath -Parent + if (-not (Test-Path $dir)) { New-Item -Path $dir -ItemType Directory -Force | Out-Null } + if ($Connections.Count -eq 0) { + '[]' | Set-Content -Path $savedConnPath -Encoding UTF8 + } else { + $Connections | ConvertTo-Json -Depth 3 | Set-Content -Path $savedConnPath -Encoding UTF8 + } + }.GetNewClosure() + + $cboSavedConn = [ComboBox]::new() + $cboSavedConn.Width = 262 + + $refreshSavedConnCombo = { + $cboSavedConn.Items.Clear() + foreach ($c in (& $loadSavedConns)) { + $cboSavedConn.Items.Add("$($c.Server) ($($c.Username))") | Out-Null + } + }.GetNewClosure() + & $refreshSavedConnCombo + + $cboSavedConn.AddSelectionChanged({ + $idx = $cboSavedConn.SelectedIndex + if ($idx -lt 0) { return } + $conns = & $loadSavedConns + if ($idx -ge $conns.Count) { return } + $sel = $conns[$idx] + $txtServer.Text = $sel.Server + $txtUser.Text = $sel.Username + $txtPass.Text = '' + }) + + $btnSaveConn = [Button]::new() + $btnSaveConn.Content = '💾 Save Connection' + $btnSaveConn.AddClick({ + $srv = $txtServer.Text.Trim() + $usr = $txtUser.Text.Trim() + if ([string]::IsNullOrWhiteSpace($srv) -or [string]::IsNullOrWhiteSpace($usr)) { + $syncHash.lblConfigStatus.Text = '⚠ Enter a Domain Controller FQDN and username before saving.' + return + } + $conns = [System.Collections.ArrayList]@() + foreach ($c in (& $loadSavedConns)) { $conns.Add($c) | Out-Null } + $dup = $conns | Where-Object { $_.Server -eq $srv -and $_.Username -eq $usr } + if (-not $dup) { + $conns.Add([PSCustomObject]@{ Server = $srv; Username = $usr }) | Out-Null + & $saveSavedConns -Connections @($conns) + & $refreshSavedConnCombo + $syncHash.lblConfigStatus.Text = "✅ Connection saved: $srv ($usr)" + } else { + $syncHash.lblConfigStatus.Text = "ℹ Connection already exists: $srv ($usr)" + } + }) + + $btnDeleteConn = [Button]::new() + $btnDeleteConn.Content = '🗑 Delete' + $btnDeleteConn.AddClick({ + $idx = $cboSavedConn.SelectedIndex + if ($idx -lt 0) { + $syncHash.lblConfigStatus.Text = '⚠ Select a saved connection to delete.' + return + } + $conns = [System.Collections.ArrayList]@() + foreach ($c in (& $loadSavedConns)) { $conns.Add($c) | Out-Null } + if ($idx -ge $conns.Count) { return } + $removed = $conns[$idx] + $conns.RemoveAt($idx) + & $saveSavedConns -Connections @($conns) + $cboSavedConn.SelectedIndex = -1 + & $refreshSavedConnCombo + $syncHash.lblConfigStatus.Text = "🗑 Deleted: $($removed.Server) ($($removed.Username))" + }) + + $savedConnActionsRow = [StackPanel]::new() + $savedConnActionsRow.Orientation = 'Horizontal' + $savedConnActionsRow.Spacing = 6 + $savedConnActionsRow.Children.Add($btnSaveConn) + $savedConnActionsRow.Children.Add($btnDeleteConn) + + # ── Output Controls ───────────────────────────────────────────────────────── + $chkHTML = [CheckBox]::new(); $chkHTML.Content = 'HTML'; $chkHTML.IsChecked = $true + $chkWord = [CheckBox]::new(); $chkWord.Content = 'Word'; $chkWord.IsChecked = $false + $chkText = [CheckBox]::new(); $chkText.Content = 'Text'; $chkText.IsChecked = $false + + $fmtPanel = [StackPanel]::new() + $fmtPanel.Orientation = 'Horizontal' + $fmtPanel.Spacing = 20 + $fmtPanel.Children.Add($chkHTML) + $fmtPanel.Children.Add($chkWord) + $fmtPanel.Children.Add($chkText) + + $txtOutput = [TextBox]::new() + $txtOutput.Width = 240 + $txtOutput.Text = if ($IsWindows) { + [System.IO.Path]::Combine($env:USERPROFILE, 'Documents', 'AsBuiltReport') + } else { + [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport') + } + + $btnBrowse = [Button]::new() + $btnBrowse.Content = 'Browse…' + $btnBrowse.AddClick({ + try { + $btnBrowse.IsEnabled = $false + $storageProvider = [Window]::GetTopLevel($btnBrowse).StorageProvider + if ($null -eq $storageProvider) { + Write-Host 'Storage provider not available.' -ForegroundColor Yellow + return + } + $options = [FolderPickerOpenOptions]::new() + $options.Title = 'Select Output Folder Path' + $folders = $storageProvider.OpenFolderPickerAsync($options).WaitForCompleted() + if ($folders -and $folders.Count -gt 0) { + $txtOutput.Text = $folders[0].Path.LocalPath + } + } catch { + Write-Host "Folder picker error: $_" -ForegroundColor Red + } finally { + $btnBrowse.IsEnabled = $true + } + }) + + $outputPathRow = [StackPanel]::new() + $outputPathRow.Orientation = 'Horizontal' + $outputPathRow.Spacing = 8 + $outputPathRow.Children.Add($txtOutput) + $outputPathRow.Children.Add($btnBrowse) + + $cboLang = [ComboBox]::new() + $cboLang.Width = 100 + $cboLang.Items.Add('en-US') | Out-Null + $cboLang.Items.Add('es-ES') | Out-Null + $cboLang.SelectedIndex = 0 + + # ── Report Name ───────────────────────────────────────────────────────────── + $txtReportName = [TextBox]::new() + $txtReportName.Width = 300 + $txtReportName.Text = 'Microsoft Active Directory As Built Report' + $txtReportName.Watermark = 'Output filename (without extension)' + + # ── Options Controls ──────────────────────────────────────────────────────── + # Options matching AsBuiltReport.Microsoft.AD.json > Options + $swDiagrams = [ToggleSwitch]::new(); $swDiagrams.IsChecked = $true + $swExportDiagrams = [ToggleSwitch]::new(); $swExportDiagrams.IsChecked = $true + $swTimestamp= [ToggleSwitch]::new(); $swTimestamp.IsChecked = $false + $swWinRMSSL = [ToggleSwitch]::new(); $swWinRMSSL.IsChecked = $false + $swWinRMFallback = [ToggleSwitch]::new(); $swWinRMFallback.IsChecked = $true + + $cboDiagramTheme = [ComboBox]::new() + $cboDiagramTheme.Width = 120 + @('White', 'Black', 'Neon') | ForEach-Object { $cboDiagramTheme.Items.Add($_) | Out-Null } + $cboDiagramTheme.SelectedIndex = 0 + + $cboPSDefaultAuth = [ComboBox]::new() + $cboPSDefaultAuth.Width = 160 + @('Negotiate', 'Kerberos', 'NTLM', 'Default') | ForEach-Object { $cboPSDefaultAuth.Items.Add($_) | Out-Null } + $cboPSDefaultAuth.SelectedIndex = 0 + + # ── InfoLevel Controls — matching AsBuiltReport.Microsoft.AD.json > InfoLevel ─ + function New-LevelCombo { + $cbo = [ComboBox]::new() + $cbo.Width = 160 + @('0 - Off', '1 - Enabled', '2 - Adv Summary', '3 - Detailed') | ForEach-Object { $cbo.Items.Add($_) | Out-Null } + $cbo.SelectedIndex = 1 + return $cbo + } + + $cboLvlForest = New-LevelCombo; $cboLvlForest.SelectedIndex = 2 # default 2 per JSON + $cboLvlDomain = New-LevelCombo; $cboLvlDomain.SelectedIndex = 2 # default 2 per JSON + $cboLvlDNS = New-LevelCombo; $cboLvlDNS.SelectedIndex = 1 # default 1 per JSON + + # ── Progress Bar & Log ────────────────────────────────────────────────────── + $progressBar = [ProgressBar]::new() + $progressBar.IsIndeterminate = $true + $progressBar.IsVisible = $false + $progressBar.Margin = '0,8,0,4' + $syncHash.progressBar = $progressBar + + $txtLog = [TextBox]::new() + $txtLog.IsReadOnly = $true + $txtLog.AcceptsReturn = $true + $txtLog.Height = 220 + $txtLog.FontSize = 16 + $txtLog.TextWrapping = 'Wrap' + $txtLog.Watermark = 'Output log will appear here…' + try { $txtLog.FontFamily = 'Consolas,Courier New,Monospace' } catch { Out-Null } + $syncHash.txtLog = $txtLog + + $chkVerbose = [CheckBox]::new() + $chkVerbose.Content = '🔍Verbose' + $chkVerbose.IsChecked = $false + $chkVerbose.HorizontalAlignment = 'Right' + $chkVerbose.VerticalAlignment = 'Center' + $chkVerbose.Margin = '0,0,8,0' + $syncHash.chkVerbose = $chkVerbose + + # ── Action Buttons ────────────────────────────────────────────────────────── + $btnCancel = [Button]::new() + $btnCancel.Content = '✕ Cancel' + $btnCancel.IsVisible = $false + $btnCancel.Margin = '0,0,0,0' + $btnCancel.AddClick({ + $syncHash.CancelRequested = $true + $rps = $syncHash.reportPS + if ($null -ne $rps) { $rps.Stop() } + }) + $syncHash.btnCancel = $btnCancel + + $btnExportLog = [Button]::new() + $btnExportLog.Content = '💾 Export Log' + $btnExportLog.Margin = '0,0,0,0' + $btnExportLog.AddClick({ + try { + $btnExportLog.IsEnabled = $false + $logText = $syncHash.txtLog.Text + if ([string]::IsNullOrWhiteSpace($logText)) { + $syncHash.lblConfigStatus.Text = '⚠ Log is empty — nothing to export.' + return + } + $storageProvider = [Window]::GetTopLevel($btnExportLog).StorageProvider + if ($null -eq $storageProvider) { return } + $saveOpts = [FilePickerSaveOptions]::new() + $saveOpts.Title = 'Export Output Log' + $saveOpts.SuggestedFileName = "MSAD-AsBuiltReport-$(Get-Date -Format 'yyyyMMdd-HHmmss').log" + $file = $storageProvider.SaveFilePickerAsync($saveOpts).WaitForCompleted() + if ($null -ne $file) { + $logText | Set-Content -Path $file.Path.LocalPath -Encoding UTF8 + $syncHash.lblConfigStatus.Text = "✅ Log exported: $(Split-Path $file.Path.LocalPath -Leaf)" + } + } catch { + $syncHash.lblConfigStatus.Text = "❌ Log export failed: $_" + } finally { + $btnExportLog.IsEnabled = $true + } + }) + + $btnGenerate = [Button]::new() + $btnGenerate.Content = '▶ Generate Report' + $btnGenerate.HorizontalAlignment = 'Stretch' + $btnGenerate.HorizontalContentAlignment = 'Center' + $btnGenerate.FontSize = 14 + $btnGenerate.FontWeight = 'SemiBold' + $btnGenerate.Margin = '0,22,0,0' + $btnGenerate.Classes.Add('accent') + $syncHash.btnGenerate = $btnGenerate + + # ── Generate Callback ──────────────────────────────────────────────────────── + $generateCallback = [EventCallback]::new() + $generateCallback.RunspaceMode = 'RunspacePoolAsyncUI' + $generateCallback.DisabledControlsWhileProcessing = $btnGenerate + + $generateCallback.ArgumentList = @{ + SyncHash = $syncHash + Server = $txtServer + Username = $txtUser + Password = $txtPass + ReportName = $txtReportName + OutPath = $txtOutput + FmtHTML = $chkHTML + FmtWord = $chkWord + FmtText = $chkText + Lang = $cboLang + DiagramTheme = $cboDiagramTheme + PSDefaultAuth = $cboPSDefaultAuth + Diagrams = $swDiagrams + ExportDiagrams = $swExportDiagrams + Timestamp = $swTimestamp + WinRMSSL = $swWinRMSSL + WinRMFallback = $swWinRMFallback + LvlForest = $cboLvlForest + LvlDomain = $cboLvlDomain + LvlDNS = $cboLvlDNS + Verbose = $chkVerbose + # ConfigPath and AbrConfigPath are late-bound below after TextBox creation + } + + $generateCallback.ScriptBlock = { + param ($ui) + + $sh = $ui.SyncHash + if ($sh.IsBusy) { + $sh.lblConfigStatus.Text = '⚠ Another operation is already running. Please wait.' + return + } + $sh.IsBusy = $true + $sh.CancelRequested = $false + $sh.progressBar.IsVisible = $true + $sh.btnCancel.IsVisible = $true + $sh.txtLog.Text = '' + + $verboseEnabled = $ui.Verbose.IsChecked -eq $true + + function Write-Logging ([string]$Msg, [string]$Level = '', [bool]$AddTimestamp = $false) { + $ts = Get-Date -Format 'HH:mm:ss' + if ($Level -eq '') { + if ($AddTimestamp) { + $sh.txtLog.Text += "[$ts] $Msg`n" + } else { + $sh.txtLog.Text += "$Msg`n" + } + } else { + if ($AddTimestamp) { + $sh.txtLog.Text += "[$ts][$Level] $Msg`n" + } else { + $sh.txtLog.Text += "[$Level] $Msg`n" + } + } + $sh.txtLog.CaretIndex = $sh.txtLog.Text.Length + } + + function Build-MSADConfigObject { + param ( + [string]$ReportName, + [string]$Lang, + [string]$Theme, + [bool]$EnableDiagrams, + [bool]$ExportDiagrams, + [string]$PSDefaultAuthentication, + [bool]$WinRMSSL, + [bool]$WinRMFallbackToNoSSL, + [int]$LvlForest, + [int]$LvlDomain, + [int]$LvlDNS + ) + return [ordered]@{ + Report = [ordered]@{ + Name = $ReportName + Version = '1.0' + Status = 'Released' + Language = $Lang + ShowCoverPageImage = $true + ShowTableOfContents = $true + ShowHeaderFooter = $true + ShowTableCaptions = $true + } + Options = [ordered]@{ + ShowExecutionTime = $false + ShowDefinitionInfo = $false + PSDefaultAuthentication = $PSDefaultAuthentication + Exclude = [ordered]@{ Domains = @(); DCs = @() } + Include = [ordered]@{ Domains = @() } + WinRMSSL = $WinRMSSL + WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL + WinRMSSLPort = 5986 + WinRMPort = 5985 + EnableDiagrams = $EnableDiagrams + EnableDiagramDebug = $false + DiagramTheme = $Theme + DiagramObjDebug = $false + DiagramWaterMark = '' + DiagramType = [ordered]@{ + CertificateAuthority = $true + Forest = $true + Replication = $true + Sites = $true + SitesInventory = $true + Trusts = $true + } + ExportDiagrams = $ExportDiagrams + ExportDiagramsFormat = @('pdf') + EnableDiagramSignature = $false + SignatureAuthorName = '' + SignatureCompanyName = '' + JobsTimeOut = 900 + DCStatusPingCount = 2 + } + InfoLevel = [ordered]@{ + Forest = $LvlForest + Domain = $LvlDomain + DNS = $LvlDNS + } + HealthCheck = [ordered]@{ + Domain = [ordered]@{ + GMSA = $true + GPO = $true + Backup = $true + DFS = $true + SPN = $true + DuplicateObject = $true + Security = $true + BestPractice = $true + } + DomainController = [ordered]@{ + Diagnostic = $true + Services = $true + Software = $true + BestPractice = $true + } + Site = [ordered]@{ + Replication = $true + BestPractice = $true + } + DNS = [ordered]@{ + Aging = $true + DP = $true + Zones = $true + BestPractice = $true + } + CA = [ordered]@{ + Status = $true + Statistics = $true + BestPractice = $true + } + } + } + } + + # ── Collect values ──────────────────────────────────────────────────────── + $server = $ui.Server.Text.Trim() + $username = $ui.Username.Text.Trim() + $password = $ui.Password.Text + $reportName = $ui.ReportName.Text.Trim() + $outPath = $ui.OutPath.Text.Trim() + $lang = [string]$ui.Lang.SelectedItem + $configPath = $ui.ConfigPath.Text.Trim() + $abrConfigPath = $ui.AbrConfigPath.Text.Trim() + + $formats = @() + if ($ui.FmtHTML.IsChecked -eq $true) { $formats += 'Html' } + if ($ui.FmtWord.IsChecked -eq $true) { $formats += 'Word' } + if ($ui.FmtText.IsChecked -eq $true) { $formats += 'Text' } + if ($formats.Count -eq 0) { $formats = @('Html') } + + $enableDiagrams = [bool]$ui.Diagrams.IsChecked + $exportDiagrams = [bool]$ui.ExportDiagrams.IsChecked + $addTimestamp = [bool]$ui.Timestamp.IsChecked + $winRMSSL = [bool]$ui.WinRMSSL.IsChecked + $winRMFallback = [bool]$ui.WinRMFallback.IsChecked + $psDefaultAuth = [string]$ui.PSDefaultAuth.SelectedItem + $diagramTheme = [string]$ui.DiagramTheme.SelectedItem + + # Parse InfoLevel (first char = number) + $lvlForest = [int]([string]$ui.LvlForest.SelectedItem).Substring(0, 1) + $lvlDomain = [int]([string]$ui.LvlDomain.SelectedItem).Substring(0, 1) + $lvlDNS = [int]([string]$ui.LvlDNS.SelectedItem).Substring(0, 1) + + # ── Validation ──────────────────────────────────────────────────────────── + if ([string]::IsNullOrWhiteSpace($server)) { + Write-Logging 'Domain Controller FQDN is required.' 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + if ([string]::IsNullOrWhiteSpace($username)) { + Write-Logging 'Username is required.' 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + if ([string]::IsNullOrWhiteSpace($password)) { + Write-Logging 'Password is required.' 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + if ([string]::IsNullOrWhiteSpace($outPath)) { + $outPath = if ($IsWindows) { + [System.IO.Path]::Combine($env:USERPROFILE, 'Documents', 'AsBuiltReport') + } else { + [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport') + } + } + if (-not (Test-Path $outPath)) { + New-Item -Path $outPath -ItemType Directory -Force | Out-Null + Write-Logging "Created output folder: $outPath" + } + if ([string]::IsNullOrWhiteSpace($reportName)) { $reportName = 'Microsoft Active Directory As Built Report' } + if ([string]::IsNullOrWhiteSpace($abrConfigPath)) { + Write-Logging 'AsBuiltReport config file path is required. Use the "⚙️ AsBuiltReport Global Settings" expander to create one.' 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + if (-not (Test-Path $abrConfigPath)) { + Write-Logging "AsBuiltReport config file not found: $abrConfigPath" 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + + Write-Logging "Target : $server" + Write-Logging "User : $username" + Write-Logging "Formats : $($formats -join ', ')" + Write-Logging "Output : $outPath" + + # ── Import modules in this runspace ─────────────────────────────────────── + Write-Logging 'Loading AsBuiltReport modules…' + try { + Import-Module AsBuiltReport.Core, AsBuiltReport.Microsoft.AD -Force -ErrorAction Stop + } catch { + Write-Logging "Failed to load modules: $_" 'ERROR' + $sh.progressBar.IsVisible = $false; $sh.btnCancel.IsVisible = $false; $sh.IsBusy = $false; return + } + + # ── Resolve ReportConfigFilePath ────────────────────────────────────────── + # Use the saved config file from Config Management if provided; + # otherwise build a temp config from the current UI control values. + $tempConfig = $null + if (-not [string]::IsNullOrWhiteSpace($configPath) -and (Test-Path $configPath)) { + $reportConfigFilePath = $configPath + Write-Logging "Using config file: $(Split-Path $configPath -Leaf)" + } else { + $configObj = Build-MSADConfigObject ` + -ReportName $reportName ` + -Lang $lang ` + -Theme $diagramTheme ` + -EnableDiagrams $enableDiagrams ` + -ExportDiagrams $exportDiagrams ` + -PSDefaultAuthentication $psDefaultAuth ` + -WinRMSSL $winRMSSL ` + -WinRMFallbackToNoSSL $winRMFallback ` + -LvlForest $lvlForest ` + -LvlDomain $lvlDomain ` + -LvlDNS $lvlDNS + + $tempConfig = [System.IO.Path]::Combine($env:TEMP, "MSAD_cfg_$(New-Guid).json") + $configObj | ConvertTo-Json -Depth 6 | Set-Content -Path $tempConfig -Encoding UTF8 + $reportConfigFilePath = $tempConfig + Write-Logging 'Using config built from UI controls.' + } + + # ── Invoke New-AsBuiltReport ────────────────────────────────────────────── + try { + if ($sh.CancelRequested) { Write-Logging 'Cancelled before start.' 'WARN'; return } + + Write-Logging 'Starting report generation…' + + $securePassword = ConvertTo-SecureString $password -AsPlainText -Force + $credential = [PSCredential]::new($username, $securePassword) + + $params = @{ + Report = 'Microsoft.AD' + Target = $server + Credential = $credential + OutputFolderPath = $outPath + Format = $formats + ReportConfigFilePath = $reportConfigFilePath + AsBuiltConfigFilePath = $abrConfigPath + } + + if ($addTimestamp) { $params['Timestamp'] = $true } + if ($verboseEnabled) { $params['Verbose'] = $true } + + Write-Logging "Using AsBuiltReport config: $(Split-Path $abrConfigPath -Leaf)" + + New-AsBuiltReport @params *>&1 | ForEach-Object { + $line = if ($_ -is [System.Management.Automation.ErrorRecord]) { + Write-Logging "$($_.Exception.Message)" 'ERROR' + return + } elseif ($_ -is [System.Management.Automation.WarningRecord]) { + Write-Logging "$($_.Message)" 'WARN' + return + } elseif ($_ -is [System.Management.Automation.VerboseRecord]) { + if ($verboseEnabled) { + Write-Logging "$($_.Message)" 'VERBOSE' + } + return + } elseif ($_ -is [System.Management.Automation.InformationRecord]) { + "$($_.MessageData)" + } else { + "$_" + } + if (-not [string]::IsNullOrWhiteSpace($line)) { + Write-Logging $line + } + } + Write-Logging -Msg "✅ Report generation completed. Files saved to: $outPath" -Level '' -AddTimestamp $true + } catch { + Write-Logging $_.Exception.Message 'ERROR' + if ($_.ScriptStackTrace) { Write-Logging $_.ScriptStackTrace 'ERROR' } + } finally { + if ($null -ne $tempConfig) { + Remove-Item -Path $tempConfig -Force -ErrorAction SilentlyContinue + } + $sh.progressBar.IsVisible = $false + $sh.btnCancel.IsVisible = $false + $sh.IsBusy = $false + } + } + + $btnGenerate.AddClick($generateCallback) + + # ── Config Management Controls ─────────────────────────────────────────────── + $txtConfigPath = [TextBox]::new() + $txtConfigPath.Width = 298 + $txtConfigPath.Watermark = 'Path to AsBuiltReport.Microsoft.AD.json (optional)' + $txtConfigPath.Text = if ($IsWindows) { + [System.IO.Path]::Combine($env:USERPROFILE, 'AsBuiltReport', 'AsBuiltReport.Microsoft.AD.json') + } else { + [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport', 'AsBuiltReport.Microsoft.AD.json') + } + + $btnBrowseConfig = [Button]::new() + $btnBrowseConfig.Content = 'Browse…' + $btnBrowseConfig.AddClick({ + try { + $btnBrowseConfig.IsEnabled = $false + $storageProvider = [Window]::GetTopLevel($btnBrowseConfig).StorageProvider + if ($null -eq $storageProvider) { + Write-Host 'Storage provider not available.' -ForegroundColor Yellow + return + } + $options = [FilePickerOpenOptions]::new() + $options.Title = 'Select AsBuiltReport.Microsoft.AD JSON Config File' + $JsonConfigFile = $storageProvider.OpenFilePickerAsync($options).WaitForCompleted() + if ($JsonConfigFile -and $JsonConfigFile.Count -gt 0) { + $txtConfigPath.Text = $JsonConfigFile[0].Path.LocalPath + } + } catch { + Write-Host "File picker error: $_" -ForegroundColor Red + } finally { + $btnBrowseConfig.IsEnabled = $true + } + }) + + $configPathRow = [StackPanel]::new() + $configPathRow.Orientation = 'Horizontal' + $configPathRow.Spacing = 8 + $configPathRow.Children.Add($txtConfigPath) + $configPathRow.Children.Add($btnBrowseConfig) + + $lblConfigStatus = [TextBlock]::new() + $lblConfigStatus.FontSize = 11 + $lblConfigStatus.Margin = '0,4,0,0' + $lblConfigStatus.Text = '' + $syncHash.lblConfigStatus = $lblConfigStatus + + # ── AsBuiltReport Global Config (AsBuiltReport.json) ───────────────────────── + $txtAbrConfigPath = [TextBox]::new() + $txtAbrConfigPath.Width = 298 + $txtAbrConfigPath.Watermark = 'Required: path to AsBuiltReport.json' + + $btnBrowseAbrConfig = [Button]::new() + $btnBrowseAbrConfig.Content = 'Browse…' + $btnBrowseAbrConfig.AddClick({ + try { + $btnBrowseAbrConfig.IsEnabled = $false + $storageProvider = [Window]::GetTopLevel($btnBrowseAbrConfig).StorageProvider + if ($null -eq $storageProvider) { return } + $options = [FilePickerOpenOptions]::new() + $options.Title = 'Select AsBuiltReport.json' + $options.AllowMultiple = $false + $picked = $storageProvider.OpenFilePickerAsync($options).WaitForCompleted() + if ($picked -and $picked.Count -gt 0) { + $txtAbrConfigPath.Text = $picked[0].Path.LocalPath + $syncHash.lblConfigStatus.Text = "📄 AsBuiltReport config: $(Split-Path $txtAbrConfigPath.Text -Leaf)" + } + } catch { + $syncHash.lblConfigStatus.Text = "❌ Browse error: $_" + } finally { + $btnBrowseAbrConfig.IsEnabled = $true + } + }) + + $abrConfigPathRow = [StackPanel]::new() + $abrConfigPathRow.Orientation = 'Horizontal' + $abrConfigPathRow.Spacing = 8 + $abrConfigPathRow.Children.Add($txtAbrConfigPath) + $abrConfigPathRow.Children.Add($btnBrowseAbrConfig) + + # Late-bind after TextBox objects exist + $generateCallback.ArgumentList['ConfigPath'] = $txtConfigPath + $generateCallback.ArgumentList['AbrConfigPath'] = $txtAbrConfigPath + + # ── AsBuiltReport Global Settings (AsBuiltReport.json editor) ──────────────── + $txtAbrCoFullName = [TextBox]::new(); $txtAbrCoFullName.Width = 298; $txtAbrCoFullName.Watermark = 'e.g. Acme Corporation' + $txtAbrCoShortName = [TextBox]::new(); $txtAbrCoShortName.Width = 298; $txtAbrCoShortName.Watermark = 'e.g. ACME' + $txtAbrCoContact = [TextBox]::new(); $txtAbrCoContact.Width = 298; $txtAbrCoContact.Watermark = 'Contact person' + $txtAbrCoPhone = [TextBox]::new(); $txtAbrCoPhone.Width = 298; $txtAbrCoPhone.Watermark = 'e.g. +1-800-555-0100' + $txtAbrCoAddress = [TextBox]::new(); $txtAbrCoAddress.Width = 298; $txtAbrCoAddress.Watermark = 'Street, City, Country' + $txtAbrCoEmail = [TextBox]::new(); $txtAbrCoEmail.Width = 298; $txtAbrCoEmail.Watermark = 'company@example.com' + $txtAbrRptAuthor = [TextBox]::new(); $txtAbrRptAuthor.Width = 298; $txtAbrRptAuthor.Watermark = 'Report author' + $txtAbrMailServer = [TextBox]::new(); $txtAbrMailServer.Width = 298; $txtAbrMailServer.Watermark = 'smtp.example.com' + $txtAbrMailPort = [TextBox]::new(); $txtAbrMailPort.Width = 298; $txtAbrMailPort.Watermark = '587' + $txtAbrMailFrom = [TextBox]::new(); $txtAbrMailFrom.Width = 298; $txtAbrMailFrom.Watermark = 'from@example.com' + $txtAbrMailTo = [TextBox]::new(); $txtAbrMailTo.Width = 298; $txtAbrMailTo.Watermark = 'to@example.com, other@example.com' + $txtAbrMailBody = [TextBox]::new(); $txtAbrMailBody.Width = 298; $txtAbrMailBody.Watermark = 'Email body text' + $swAbrMailUseSSL = [ToggleSwitch]::new(); $swAbrMailUseSSL.IsChecked = $true + $swAbrMailCreds = [ToggleSwitch]::new(); $swAbrMailCreds.IsChecked = $true + $txtAbrFolderPath = [TextBox]::new(); $txtAbrFolderPath.Width = 298; $txtAbrFolderPath.Watermark = '.\AsBuiltReport' + + $loadAbrFields = { + param ([hashtable]$j) + $txtAbrCoFullName.Text = if ($j.Company.FullName) { $j.Company.FullName } else { '' } + $txtAbrCoShortName.Text = if ($j.Company.ShortName) { $j.Company.ShortName } else { '' } + $txtAbrCoContact.Text = if ($j.Company.Contact) { $j.Company.Contact } else { '' } + $txtAbrCoPhone.Text = if ($j.Company.Phone) { $j.Company.Phone } else { '' } + $txtAbrCoAddress.Text = if ($j.Company.Address) { $j.Company.Address } else { '' } + $txtAbrCoEmail.Text = if ($j.Company.Email) { $j.Company.Email } else { '' } + $txtAbrRptAuthor.Text = if ($j.Report.Author) { $j.Report.Author } else { '' } + $txtAbrMailServer.Text = if ($j.Email.Server) { $j.Email.Server } else { '' } + $txtAbrMailPort.Text = if ($j.Email.Port) { $j.Email.Port } else { '' } + $txtAbrMailFrom.Text = if ($j.Email.From) { $j.Email.From } else { '' } + $txtAbrMailTo.Text = if ($j.Email.To) { ($j.Email.To -join ', ') } else { '' } + $txtAbrMailBody.Text = if ($j.Email.Body) { $j.Email.Body } else { '' } + $swAbrMailUseSSL.IsChecked = if ($null -ne $j.Email.UseSSL) { [bool]$j.Email.UseSSL } else { $true } + $swAbrMailCreds.IsChecked = if ($null -ne $j.Email.Credentials) { [bool]$j.Email.Credentials } else { $true } + $txtAbrFolderPath.Text = if ($j.UserFolder.Path) { $j.UserFolder.Path } else { + if ($IsWindows) { [System.IO.Path]::Combine($env:USERPROFILE, 'Documents', 'AsBuiltReport') } else { [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport') } + } + } + + $buildAbrConfig = { + $toList = ([string]$txtAbrMailTo.Text).Trim() -split '\s*,\s*' | Where-Object { $_ -ne '' } + $portRaw = ([string]$txtAbrMailPort.Text).Trim() + $portVal = if ($portRaw -match '^\d+$') { [int]$portRaw } else { $null } + return [ordered]@{ + Company = [ordered]@{ + FullName = ([string]$txtAbrCoFullName.Text).Trim() + Phone = ([string]$txtAbrCoPhone.Text).Trim() + Address = ([string]$txtAbrCoAddress.Text).Trim() + ShortName = ([string]$txtAbrCoShortName.Text).Trim() + Contact = ([string]$txtAbrCoContact.Text).Trim() + Email = ([string]$txtAbrCoEmail.Text).Trim() + } + Email = [ordered]@{ + Credentials = [bool]$swAbrMailCreds.IsChecked + Body = ([string]$txtAbrMailBody.Text).Trim() + From = ([string]$txtAbrMailFrom.Text).Trim() + UseSSL = [bool]$swAbrMailUseSSL.IsChecked + Server = ([string]$txtAbrMailServer.Text).Trim() + To = if ($toList.Count -gt 0) { @($toList) } else { @() } + Port = $portVal + } + Report = [ordered]@{ Author = ([string]$txtAbrRptAuthor.Text).Trim() } + UserFolder = [ordered]@{ Path = ([string]$txtAbrFolderPath.Text).Trim() } + } + }.GetNewClosure() + $syncHash.buildAbrConfig = $buildAbrConfig + + $validateAbrRequired = { + $missing = @() + if ([string]::IsNullOrWhiteSpace($txtAbrCoFullName.Text)) { $missing += 'Full Name' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoShortName.Text)) { $missing += 'Short Name' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoContact.Text)) { $missing += 'Contact' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoEmail.Text)) { $missing += 'Email' } + if ([string]::IsNullOrWhiteSpace($txtAbrRptAuthor.Text)) { $missing += 'Author' } + if ([string]::IsNullOrWhiteSpace($txtAbrFolderPath.Text)) { $missing += 'Path' } + if ($missing.Count -gt 0) { + return "⚠ Required fields missing: $($missing -join ', ')" + } + return $null + }.GetNewClosure() + $syncHash.validateAbrRequired = $validateAbrRequired + + $btnAbrNew = [Button]::new() + $btnAbrNew.Content = '🆕 Create New' + $btnAbrNew.Margin = '0,0,8,0' + $btnAbrNew.AddClick({ + try { + $btnAbrNew.IsEnabled = $false + $storageProvider = [Window]::GetTopLevel($btnAbrNew).StorageProvider + if ($null -eq $storageProvider) { + $syncHash.lblConfigStatus.Text = '⚠ Cannot open save dialog.' + return + } + $saveOpts = [FilePickerSaveOptions]::new() + $saveOpts.Title = 'Create New AsBuiltReport Config File' + $saveOpts.SuggestedFileName = 'AsBuiltReport.json' + $saveOpts.DefaultExtension = 'json' + $file = $storageProvider.SaveFilePickerAsync($saveOpts).WaitForCompleted() + if ($null -eq $file) { return } + if ($null -eq $file.Path) { + $syncHash.lblConfigStatus.Text = '⚠ Could not resolve file path from dialog.' + return + } + $validationError = & $syncHash.validateAbrRequired + if ($null -ne $validationError) { + $syncHash.lblConfigStatus.Text = $validationError + return + } + $dest = $file.Path.LocalPath + $cfg = & $syncHash.buildAbrConfig + $destDir = Split-Path $dest -Parent + if (-not (Test-Path $destDir)) { New-Item -Path $destDir -ItemType Directory -Force | Out-Null } + $cfg | ConvertTo-Json -Depth 4 | Set-Content -Path $dest -Encoding UTF8 + $txtAbrConfigPath.Text = $dest + $syncHash.lblConfigStatus.Text = "✅ Created: $(Split-Path $dest -Leaf)" + } catch { + $syncHash.lblConfigStatus.Text = "❌ Create failed: $_" + } finally { + $btnAbrNew.IsEnabled = $true + } + }) + + $btnAbrLoad = [Button]::new() + $btnAbrLoad.Content = '📂 Load from File' + $btnAbrLoad.Margin = '0,0,8,0' + $btnAbrLoad.AddClick({ + try { + $btnAbrLoad.IsEnabled = $false + $src = if ($txtAbrConfigPath.Text) { $txtAbrConfigPath.Text.Trim() } else { '' } + if ([string]::IsNullOrWhiteSpace($src) -or -not (Test-Path $src)) { + $syncHash.lblConfigStatus.Text = '⚠ Set a valid AsBuiltReport.json path first.' + return + } + $j = Get-Content -Path $src -Raw | ConvertFrom-Json -AsHashtable + & $loadAbrFields $j + $syncHash.lblConfigStatus.Text = "✅ Loaded: $(Split-Path $src -Leaf)" + } catch { + $syncHash.lblConfigStatus.Text = "❌ Load failed: $_" + } finally { + $btnAbrLoad.IsEnabled = $true + } + }) + + $btnAbrSave = [Button]::new() + $btnAbrSave.Content = '💾 Save to File' + $btnAbrSave.AddClick({ + try { + $btnAbrSave.IsEnabled = $false + $validationError = & $syncHash.validateAbrRequired + if ($null -ne $validationError) { + $syncHash.lblConfigStatus.Text = $validationError + return + } + if ([string]::IsNullOrWhiteSpace($txtAbrConfigPath.Text)) { + $syncHash.lblConfigStatus.Text = '❌ Please provide a config file path before saving.' + return + } + $dest = $txtAbrConfigPath.Text.Trim() + $cfg = & $syncHash.buildAbrConfig + $destDir = Split-Path $dest -Parent + if (-not (Test-Path $destDir)) { New-Item -Path $destDir -ItemType Directory -Force | Out-Null } + $cfg | ConvertTo-Json -Depth 4 | Set-Content -Path $dest -Encoding UTF8 + $syncHash.lblConfigStatus.Text = "✅ Saved: $(Split-Path $dest -Leaf)" + } catch { + $syncHash.lblConfigStatus.Text = "❌ Save failed: $_" + } finally { + $btnAbrSave.IsEnabled = $true + } + }) + + $abrActionRow = [StackPanel]::new() + $abrActionRow.Orientation = 'Horizontal' + $abrActionRow.Margin = '0,10,0,0' + $abrActionRow.Children.Add($btnAbrNew) + $abrActionRow.Children.Add($btnAbrLoad) + $abrActionRow.Children.Add($btnAbrSave) + + $abrRequiredNote = [TextBlock]::new() + $abrRequiredNote.Text = '* Required' + $abrRequiredNote.FontSize = 12 + $abrRequiredNote.Margin = '0,0,0,8' + $abrRequiredNote.TextAlignment = 'Right' + + $abrInnerPanel = [StackPanel]::new() + $abrInnerPanel.Spacing = 2 + $abrInnerPanel.Margin = '4,4,4,8' + $abrInnerPanel.Children.Add($abrRequiredNote) + $abrInnerPanel.Children.Add((New-SectionTitle '🏢 Company')) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Full Name' -Control $txtAbrCoFullName)) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Short Name' -Control $txtAbrCoShortName)) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Contact' -Control $txtAbrCoContact)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Phone' -Control $txtAbrCoPhone)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Address' -Control $txtAbrCoAddress)) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Email' -Control $txtAbrCoEmail)) + $abrInnerPanel.Children.Add((New-SectionTitle '📝 Report')) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Author' -Control $txtAbrRptAuthor)) + $abrInnerPanel.Children.Add((New-SectionTitle '📧 Email')) + $abrInnerPanel.Children.Add((New-FormRow -Label 'SMTP Server' -Control $txtAbrMailServer)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Port' -Control $txtAbrMailPort)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'From' -Control $txtAbrMailFrom)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'To (comma-sep.)' -Control $txtAbrMailTo)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Body' -Control $txtAbrMailBody)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Use SSL' -Control $swAbrMailUseSSL)) + $abrInnerPanel.Children.Add((New-FormRow -Label 'Credentials' -Control $swAbrMailCreds)) + $abrInnerPanel.Children.Add((New-SectionTitle '📁 User Folder')) + $abrInnerPanel.Children.Add((New-FormRow -Label '* Path' -Control $txtAbrFolderPath)) + $abrInnerPanel.Children.Add($abrActionRow) + + $abrExpander = [Expander]::new() + $abrExpander.Header = '⚙️ AsBuiltReport Global Settings' + $abrExpander.IsExpanded = $false + $abrExpander.Margin = '0,8,0,0' + $abrExpander.Content = $abrInnerPanel + + # ── Save Config Button ───────────────────────────────────────────────────── + function Build-MSADConfigForSave { + param ( + [string]$ReportName, [string]$Lang, [string]$Theme, + [bool]$EnableDiagrams, [bool]$ExportDiagrams, + [string]$PSDefaultAuthentication, [bool]$WinRMSSL, [bool]$WinRMFallbackToNoSSL, + [int]$LvlForest, [int]$LvlDomain, [int]$LvlDNS + ) + return [ordered]@{ + Report = [ordered]@{ + Name = $ReportName + Version = '1.0' + Status = 'Released' + Language = $Lang + ShowCoverPageImage = $true + ShowTableOfContents = $true + ShowHeaderFooter = $true + ShowTableCaptions = $true + } + Options = [ordered]@{ + ShowExecutionTime = $false + ShowDefinitionInfo = $false + PSDefaultAuthentication = $PSDefaultAuthentication + Exclude = [ordered]@{ Domains = @(); DCs = @() } + Include = [ordered]@{ Domains = @() } + WinRMSSL = $WinRMSSL + WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL + WinRMSSLPort = 5986 + WinRMPort = 5985 + EnableDiagrams = $EnableDiagrams + EnableDiagramDebug = $false + DiagramTheme = $Theme + DiagramObjDebug = $false + DiagramWaterMark = '' + DiagramType = [ordered]@{ + CertificateAuthority = $true + Forest = $true + Replication = $true + Sites = $true + SitesInventory = $true + Trusts = $true + } + ExportDiagrams = $ExportDiagrams + ExportDiagramsFormat = @('pdf') + EnableDiagramSignature = $false + SignatureAuthorName = '' + SignatureCompanyName = '' + JobsTimeOut = 900 + DCStatusPingCount = 2 + } + InfoLevel = [ordered]@{ + Forest = $LvlForest + Domain = $LvlDomain + DNS = $LvlDNS + } + HealthCheck = [ordered]@{ + Domain = [ordered]@{ + GMSA = $true; GPO = $true; Backup = $true; DFS = $true + SPN = $true; DuplicateObject = $true; Security = $true; BestPractice = $true + } + DomainController = [ordered]@{ + Diagnostic = $true; Services = $true; Software = $true; BestPractice = $true + } + Site = [ordered]@{ Replication = $true; BestPractice = $true } + DNS = [ordered]@{ Aging = $true; DP = $true; Zones = $true; BestPractice = $true } + CA = [ordered]@{ Status = $true; Statistics = $true; BestPractice = $true } + } + } + } + + $btnSaveConfig = [Button]::new() + $btnSaveConfig.Content = '💾 Save Config' + $btnSaveConfig.HorizontalAlignment = 'Stretch' + $btnSaveConfig.HorizontalContentAlignment = 'Center' + $btnSaveConfig.Width = 196 + $btnSaveConfig.Margin = '0,0,4,0' + $btnSaveConfig.AddClick({ + $destPath = $txtConfigPath.Text.Trim() + if ([string]::IsNullOrWhiteSpace($destPath)) { + $syncHash.lblConfigStatus.Text = '⚠ Please enter a destination path first.' + return + } + try { + $parent = Split-Path $destPath -Parent + if (-not [string]::IsNullOrEmpty($parent) -and -not (Test-Path $parent)) { + New-Item -Path $parent -ItemType Directory -Force | Out-Null + } + function Get-LevelVal ($cbo) { [int]([string]$cbo.SelectedItem).Substring(0, 1) } + $configObj = Build-MSADConfigForSave ` + -ReportName ($txtReportName.Text.Trim()) ` + -Lang ([string]$cboLang.SelectedItem) ` + -Theme ([string]$cboDiagramTheme.SelectedItem) ` + -EnableDiagrams ([bool]$swDiagrams.IsChecked) ` + -ExportDiagrams ([bool]$swExportDiagrams.IsChecked) ` + -PSDefaultAuthentication ([string]$cboPSDefaultAuth.SelectedItem) ` + -WinRMSSL ([bool]$swWinRMSSL.IsChecked) ` + -WinRMFallbackToNoSSL ([bool]$swWinRMFallback.IsChecked) ` + -LvlForest (Get-LevelVal $cboLvlForest) ` + -LvlDomain (Get-LevelVal $cboLvlDomain) ` + -LvlDNS (Get-LevelVal $cboLvlDNS) + $configObj| ConvertTo-Json -Depth 6 | Set-Content -Path $destPath -Encoding UTF8 + $syncHash.lblConfigStatus.Text = "✅ Config saved: $(Split-Path $destPath -Leaf)" + } catch { + $syncHash.lblConfigStatus.Text = "❌ Save failed: $_" + } + }) + + $btnLoadConfig = [Button]::new() + $btnLoadConfig.Content = '📂 Load Config' + $btnLoadConfig.HorizontalAlignment = 'Stretch' + $btnLoadConfig.HorizontalContentAlignment = 'Center' + $btnLoadConfig.Width = 196 + $btnLoadConfig.Margin = '0,0,4,0' + $btnLoadConfig.AddClick({ + $srcPath = $txtConfigPath.Text.Trim() + if ([string]::IsNullOrWhiteSpace($srcPath) -or -not (Test-Path $srcPath)) { + $syncHash.lblConfigStatus.Text = '⚠ Config file path not found.' + return + } + try { + $j = Get-Content -Path $srcPath -Raw | ConvertFrom-Json + if ($j.Report.Name) { $txtReportName.Text = $j.Report.Name } + if ($j.Report.Language) { $idx = $cboLang.Items.IndexOf($j.Report.Language); if ($idx -ge 0) { $cboLang.SelectedIndex = $idx } } + if ($null -ne $j.Options.EnableDiagrams) { $swDiagrams.IsChecked = [bool]$j.Options.EnableDiagrams } + if ($null -ne $j.Options.ExportDiagrams) { $swExportDiagrams.IsChecked = [bool]$j.Options.ExportDiagrams } + if ($null -ne $j.Options.ShowExecutionTime) { Out-Null } + if ($null -ne $j.Options.ShowDefinitionInfo) { Out-Null } + if ($null -ne $j.Options.WinRMSSL){ $swWinRMSSL.IsChecked = [bool]$j.Options.WinRMSSL } + if ($null -ne $j.Options.WinRMFallbackToNoSSL) { $swWinRMFallback.IsChecked = [bool]$j.Options.WinRMFallbackToNoSSL } + if ($j.Options.DiagramTheme) { $idx = $cboDiagramTheme.Items.IndexOf($j.Options.DiagramTheme); if ($idx -ge 0) { $cboDiagramTheme.SelectedIndex = $idx } } + if ($j.Options.PSDefaultAuthentication) { $idx = $cboPSDefaultAuth.Items.IndexOf($j.Options.PSDefaultAuthentication); if ($idx -ge 0) { $cboPSDefaultAuth.SelectedIndex = $idx } } + if ($null -ne $j.InfoLevel.Forest) { $cboLvlForest.SelectedIndex = [int]$j.InfoLevel.Forest } + if ($null -ne $j.InfoLevel.Domain) { $cboLvlDomain.SelectedIndex = [int]$j.InfoLevel.Domain } + if ($null -ne $j.InfoLevel.DNS) { $cboLvlDNS.SelectedIndex = [int]$j.InfoLevel.DNS } + $syncHash.lblConfigStatus.Text= "✅ Config loaded: $(Split-Path $srcPath -Leaf)" + } catch { + $syncHash.lblConfigStatus.Text = "❌ Load failed: $_" + } + }) + + $btnOpenConfig = [Button]::new() + $btnOpenConfig.Content = '📄 Open File' + $btnOpenConfig.HorizontalAlignment = 'Stretch' + $btnOpenConfig.HorizontalContentAlignment = 'Center' + $btnOpenConfig.Width = 196 + $btnOpenConfig.AddClick({ + $filePath = $txtConfigPath.Text.Trim() + if ([string]::IsNullOrWhiteSpace($filePath) -or -not (Test-Path $filePath)) { + $syncHash.lblConfigStatus.Text = '⚠ Config file not found.' + return + } + try { Start-Process $filePath } catch { $syncHash.lblConfigStatus.Text = "❌ Could not open file: $_" } + }) + + $cfgBtnRow = [StackPanel]::new() + $cfgBtnRow.Orientation = 'Horizontal' + $cfgBtnRow.Margin = '0,4,0,0' + $cfgBtnRow.Children.Add($btnSaveConfig) + $cfgBtnRow.Children.Add($btnLoadConfig) + $cfgBtnRow.Children.Add($btnOpenConfig) + + # ── Assemble Main Panel (Report Page) ─────────────────────────────────────── + $mainPanel = [StackPanel]::new() + $mainPanel.Margin = '28,20,28,24' + $mainPanel.Spacing = 2 + + $headerPanel = [StackPanel]::new() + $headerPanel.HorizontalAlignment = 'Center' + $headerPanel.Spacing = 4 + $headerPanel.Margin = '0,0,0,4' + + $hTitle = [TextBlock]::new() + $hTitle.Text = 'Microsoft Active Directory' + $hTitle.FontSize = 22 + $hTitle.FontWeight = 'Bold' + $hTitle.HorizontalAlignment = 'Center' + + $hSub = [TextBlock]::new() + $hSub.Text = 'As-Built Report Generator' + $hSub.FontSize = 13 + $hSub.HorizontalAlignment = 'Center' + + $headerPanel.Children.Add($hTitle) + $headerPanel.Children.Add($hSub) + $mainPanel.Children.Add($headerPanel) + + # Row 1: Server Connection | Report Output + $topGrid = [Grid]::new() + $topGrid.ColumnDefinitions = [ColumnDefinitions]::Parse('*, *') + $topGrid.ColumnSpacing = 24 + $topGrid.Margin = '0,4,0,0' + + $connPanel = [StackPanel]::new() + $connPanel.Spacing = 2 + $connPanel.Children.Add((New-SectionTitle '🔌 Server Connection')) + $connPanel.Children.Add((New-FormRow -Label 'Saved Connections' -Control $cboSavedConn -LabelWidth 150)) + $connPanel.Children.Add((New-FormRow -Label 'Domain Controller' -Control $txtServer -LabelWidth 150)) + $connPanel.Children.Add((New-FormRow -Label 'Username' -Control $txtUser -LabelWidth 150)) + $connPanel.Children.Add((New-FormRow -Label 'Password' -Control (New-PasswordRow $txtPass) -LabelWidth 150)) + $connPanel.Children.Add((New-FormRow -Label '' -Control $savedConnActionsRow -LabelWidth 150)) + [Grid]::SetColumn($connPanel, 0) + $topGrid.Children.Add($connPanel) + + $outPanel = [StackPanel]::new() + $outPanel.Spacing = 2 + $outPanel.Children.Add((New-SectionTitle '📄 Report Output')) + $outPanel.Children.Add((New-FormRow -Label 'Report Name' -Control $txtReportName -LabelWidth 130)) + $outPanel.Children.Add((New-FormRow -Label 'Format' -Control $fmtPanel -LabelWidth 130)) + $outPanel.Children.Add((New-FormRow -Label 'Output Folder' -Control $outputPathRow -LabelWidth 130)) + $outPanel.Children.Add((New-FormRow -Label 'Language' -Control $cboLang -LabelWidth 130)) + $outPanel.Children.Add((New-FormRow -Label 'Add Timestamp' -Control $swTimestamp -LabelWidth 130)) + [Grid]::SetColumn($outPanel, 1) + $topGrid.Children.Add($outPanel) + + $mainPanel.Children.Add($topGrid) + + # Row 2: Options | Info Level + $bottomGrid = [Grid]::new() + $bottomGrid.ColumnDefinitions = [ColumnDefinitions]::Parse('*, *') + $bottomGrid.ColumnSpacing = 24 + $bottomGrid.Margin = '0,4,0,0' + + $optPanel = [StackPanel]::new() + $optPanel.Spacing = 2 + $optPanel.Children.Add((New-SectionTitle '⚙️ Options')) + $optPanel.Children.Add((New-FormRow -Label 'Enable Diagrams' -Control $swDiagrams -LabelWidth 185)) + $optPanel.Children.Add((New-FormRow -Label 'Export Diagrams' -Control $swExportDiagrams -LabelWidth 185)) + $optPanel.Children.Add((New-FormRow -Label 'Diagram Theme' -Control $cboDiagramTheme -LabelWidth 185)) + $optPanel.Children.Add((New-FormRow -Label 'WinRM SSL' -Control $swWinRMSSL -LabelWidth 185)) + $optPanel.Children.Add((New-FormRow -Label 'WinRM Fallback' -Control $swWinRMFallback -LabelWidth 185)) + $optPanel.Children.Add((New-FormRow -Label 'PS Authentication' -Control $cboPSDefaultAuth -LabelWidth 185)) + [Grid]::SetColumn($optPanel, 0) + $bottomGrid.Children.Add($optPanel) + + $lvlPanel = [StackPanel]::new() + $lvlPanel.Spacing = 2 + $lvlPanel.Children.Add((New-SectionTitle '📊 Info Level')) + $lvlPanel.Children.Add((New-FormRow -Label 'Forest' -Control $cboLvlForest)) + $lvlPanel.Children.Add((New-FormRow -Label 'Domain' -Control $cboLvlDomain)) + $lvlPanel.Children.Add((New-FormRow -Label 'DNS' -Control $cboLvlDNS)) + [Grid]::SetColumn($lvlPanel, 1) + $bottomGrid.Children.Add($lvlPanel) + + $mainPanel.Children.Add($bottomGrid) + + $mainPanel.Children.Add((New-SectionTitle '🗂️ Config Management')) + $mainPanel.Children.Add((New-FormRow -Label '📄 MSAD Config File' -Control $configPathRow)) + $mainPanel.Children.Add($cfgBtnRow) + $mainPanel.Children.Add((New-FormRow -Label '📄 AsBuiltReport Config File' -Control $abrConfigPathRow)) + $mainPanel.Children.Add($abrExpander) + + $mainPanel.Children.Add($btnGenerate) + + # Log area header + $logTitle = [TextBlock]::new() + $logTitle.Text = '📋 Output Log' + $logTitle.FontSize = 13 + $logTitle.FontWeight = 'SemiBold' + $logTitle.VerticalAlignment = 'Center' + + $logHeaderGrid = [Grid]::new() + $logHeaderGrid.Margin = '0,14,0,6' + $logHeaderGrid.ColumnDefinitions.Add( + [ColumnDefinition]::new([GridLength]::new(1, [GridUnitType]::Star))) + $logHeaderGrid.ColumnDefinitions.Add( + [ColumnDefinition]::new([GridLength]::new(0, [GridUnitType]::Auto))) + $logHeaderGrid.ColumnDefinitions.Add( + [ColumnDefinition]::new([GridLength]::new(0, [GridUnitType]::Auto))) + [Grid]::SetColumn($logTitle, 0) + [Grid]::SetColumn($chkVerbose, 1) + [Grid]::SetColumn($btnExportLog, 2) + $logHeaderGrid.Children.Add($logTitle) + $logHeaderGrid.Children.Add($chkVerbose) + $logHeaderGrid.Children.Add($btnExportLog) + + $btnOpenOutputFolder = [Button]::new() + $btnOpenOutputFolder.Content = '📁 Open Output Folder' + $btnOpenOutputFolder.Margin = '0,0,8,0' + $btnOpenOutputFolder.AddClick({ + $path = $txtOutput.Text.Trim() + if ([string]::IsNullOrWhiteSpace($path)) { + $syncHash.lblConfigStatus.Text = '⚠ No output folder set.' + return + } + if (-not (Test-Path $path)) { + $syncHash.lblConfigStatus.Text = "⚠ Output folder not found: $path" + return + } + try { Start-Process $path } catch { $syncHash.lblConfigStatus.Text = "❌ Could not open folder: $_" } + }) + + $logActionsRow = [StackPanel]::new() + $logActionsRow.Orientation = 'Horizontal' + $logActionsRow.HorizontalAlignment = 'Right' + $logActionsRow.Margin = '0,6,0,0' + $logActionsRow.Children.Add($btnOpenOutputFolder) + $logActionsRow.Children.Add($btnCancel) + + $scrollView = [ScrollViewer]::new() + $scrollView.Content = $mainPanel + + # ── Drawer Pages ──────────────────────────────────────────────────────────── + $reportPage = [ContentPage]::new() + $reportPage.Header = 'Report' + $reportPage.Content = $scrollView + + $navigationPage = [NavigationPage]::new() + $navigationPage.Content = $reportPage + + # MDI path geometry for nav icons + $reportGeometry = 'M6,2A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6M6,4H13V9H18V20H6V4M8,12V14H16V12H8M8,16V18H13V16H8Z' + + $btnNavReport = New-DrawerMenuItem -Title 'Report' -IconGeometry $reportGeometry -Page $reportPage -NavigationPage $navigationPage + + $drawerMenuPanel = [StackPanel]::new() + $drawerMenuPanel.Margin = 12 + $drawerMenuPanel.Children.Add($btnNavReport) + + $drawerMenu = [ContentPage]::new() + $drawerMenu.Content = $drawerMenuPanel + + $drawerHeader = [TextBlock]::new() + $drawerHeader.Text = 'Navigation' + $drawerHeader.FontSize = 16 + $drawerHeader.FontWeight = 'SemiBold' + $drawerHeader.VerticalAlignment = 'Center' + $drawerHeader.Padding = '16,10,12,10' + + $drawerPage = [DrawerPage]::new() + $drawerPage.DrawerHeader = $drawerHeader + $drawerPage.Drawer = $drawerMenu + $drawerPage.Content = $navigationPage + + # ── Shared bottom strip (log + status — visible from all drawer pages) ──────── + $sharedBottomPanel = [StackPanel]::new() + $sharedBottomPanel.Margin = '28,4,28,16' + $sharedBottomPanel.Children.Add($progressBar) + $sharedBottomPanel.Children.Add($logHeaderGrid) + $sharedBottomPanel.Children.Add($txtLog) + $sharedBottomPanel.Children.Add($logActionsRow) + $sharedBottomPanel.Children.Add($lblConfigStatus) + + # ── Outer grid: drawer (fills space) above shared log strip ────────────────── + $outerGrid = [Grid]::new() + $outerGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(1, [GridUnitType]::Star))) + $outerGrid.RowDefinitions.Add([RowDefinition]::new([GridLength]::new(0, [GridUnitType]::Auto))) + [Grid]::SetRow($drawerPage, 0) + [Grid]::SetRow($sharedBottomPanel, 1) + $outerGrid.Children.Add($drawerPage) + $outerGrid.Children.Add($sharedBottomPanel) + + # ── Window ────────────────────────────────────────────────────────────────── + $win = [Window]::new() + $win.Title = 'Microsoft AD — As-Built Report Generator' + $win.Width = 1050 + $win.Height = 920 + $win.MinWidth = 880 + $win.MinHeight = 500 + $win.Content = $outerGrid + + $win.Show() + $win.WaitForClosed() +} diff --git a/CHANGELOG.md b/CHANGELOG.md index e9c2836..ae4c61c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.0.0] - 2026-04-?? +### Added + +- Add support for GliderUI to generate the report using a graphical interface instead of command line. The GUI will allow users to select the target domain, customize report options, and initiate the report generation process with a user-friendly experience. + ### :arrows_clockwise: Changed - Improved multi-language support by refactoring localization strings and enhancing documentation clarity in MicrosoftAD.psd1 for English and Spanish languages. @@ -17,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgrade AsBuiltReport.Diagram module to version `1.0.6` - Upgrade AsBuiltReport.Chart module to version `0.3.1` +## :bug: Fixed + +- Fix diagram theme generation not respecting the selected theme in the configuration file, ensuring that diagrams are rendered with the correct visual style as defined by the user. + ## [0.9.12] - 2026-04-02 ### :toolbox: Added From c48185abc09b0d0a9106f9e63dccc394162d402d Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 16:35:01 -0400 Subject: [PATCH 12/18] refactor: Clean up formatting and spacing in Start-AsBuiltReportMSAD.ps1 --- .../Private/Gui/Start-AsBuiltReportMSAD.ps1 | 418 +++++++++--------- 1 file changed, 209 insertions(+), 209 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 index b7ddb6a..42a9b65 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Gui/Start-AsBuiltReportMSAD.ps1 @@ -41,8 +41,8 @@ function Start-AsBuiltReportMSAD { } $gliderMod = Get-Module -ListAvailable -Name GliderUI | - Sort-Object Version -Descending | - Select-Object -First 1 + Sort-Object Version -Descending | + Select-Object -First 1 if ($null -eq $gliderMod -or $gliderMod.Version -lt $requiredGliderUIVersion) { $found = if ($null -eq $gliderMod) { 'not installed' } else { "v$($gliderMod.Version)" } @@ -55,7 +55,7 @@ function Start-AsBuiltReportMSAD { # Thread-safe store shared between the main runspace and the report runspace $syncHash = [Hashtable]::Synchronized(@{ CancelRequested = $false - IsBusy = $false + IsBusy = $false }) # ── UI Helper Functions ───────────────────────────────────────────────────── @@ -318,11 +318,11 @@ function Start-AsBuiltReportMSAD { # ── Options Controls ──────────────────────────────────────────────────────── # Options matching AsBuiltReport.Microsoft.AD.json > Options - $swDiagrams = [ToggleSwitch]::new(); $swDiagrams.IsChecked = $true + $swDiagrams = [ToggleSwitch]::new(); $swDiagrams.IsChecked = $true $swExportDiagrams = [ToggleSwitch]::new(); $swExportDiagrams.IsChecked = $true - $swTimestamp= [ToggleSwitch]::new(); $swTimestamp.IsChecked = $false - $swWinRMSSL = [ToggleSwitch]::new(); $swWinRMSSL.IsChecked = $false - $swWinRMFallback = [ToggleSwitch]::new(); $swWinRMFallback.IsChecked = $true + $swTimestamp = [ToggleSwitch]::new(); $swTimestamp.IsChecked = $false + $swWinRMSSL = [ToggleSwitch]::new(); $swWinRMSSL.IsChecked = $false + $swWinRMFallback = [ToggleSwitch]::new(); $swWinRMFallback.IsChecked = $true $cboDiagramTheme = [ComboBox]::new() $cboDiagramTheme.Width = 120 @@ -345,7 +345,7 @@ function Start-AsBuiltReportMSAD { $cboLvlForest = New-LevelCombo; $cboLvlForest.SelectedIndex = 2 # default 2 per JSON $cboLvlDomain = New-LevelCombo; $cboLvlDomain.SelectedIndex = 2 # default 2 per JSON - $cboLvlDNS = New-LevelCombo; $cboLvlDNS.SelectedIndex = 1 # default 1 per JSON + $cboLvlDNS = New-LevelCombo; $cboLvlDNS.SelectedIndex = 1 # default 1 per JSON # ── Progress Bar & Log ────────────────────────────────────────────────────── $progressBar = [ProgressBar]::new() @@ -428,27 +428,27 @@ function Start-AsBuiltReportMSAD { $generateCallback.DisabledControlsWhileProcessing = $btnGenerate $generateCallback.ArgumentList = @{ - SyncHash = $syncHash - Server = $txtServer - Username = $txtUser - Password = $txtPass - ReportName = $txtReportName - OutPath = $txtOutput - FmtHTML = $chkHTML - FmtWord = $chkWord - FmtText = $chkText - Lang = $cboLang - DiagramTheme = $cboDiagramTheme - PSDefaultAuth = $cboPSDefaultAuth - Diagrams = $swDiagrams - ExportDiagrams = $swExportDiagrams - Timestamp = $swTimestamp - WinRMSSL = $swWinRMSSL - WinRMFallback = $swWinRMFallback - LvlForest = $cboLvlForest - LvlDomain = $cboLvlDomain - LvlDNS = $cboLvlDNS - Verbose = $chkVerbose + SyncHash = $syncHash + Server = $txtServer + Username = $txtUser + Password = $txtPass + ReportName = $txtReportName + OutPath = $txtOutput + FmtHTML = $chkHTML + FmtWord = $chkWord + FmtText = $chkText + Lang = $cboLang + DiagramTheme = $cboDiagramTheme + PSDefaultAuth = $cboPSDefaultAuth + Diagrams = $swDiagrams + ExportDiagrams = $swExportDiagrams + Timestamp = $swTimestamp + WinRMSSL = $swWinRMSSL + WinRMFallback = $swWinRMFallback + LvlForest = $cboLvlForest + LvlDomain = $cboLvlDomain + LvlDNS = $cboLvlDNS + Verbose = $chkVerbose # ConfigPath and AbrConfigPath are late-bound below after TextBox creation } @@ -501,82 +501,82 @@ function Start-AsBuiltReportMSAD { [int]$LvlDNS ) return [ordered]@{ - Report = [ordered]@{ - Name = $ReportName - Version = '1.0' - Status = 'Released' - Language = $Lang - ShowCoverPageImage = $true + Report = [ordered]@{ + Name = $ReportName + Version = '1.0' + Status = 'Released' + Language = $Lang + ShowCoverPageImage = $true ShowTableOfContents = $true - ShowHeaderFooter = $true - ShowTableCaptions = $true + ShowHeaderFooter = $true + ShowTableCaptions = $true } - Options = [ordered]@{ - ShowExecutionTime = $false - ShowDefinitionInfo = $false + Options = [ordered]@{ + ShowExecutionTime = $false + ShowDefinitionInfo = $false PSDefaultAuthentication = $PSDefaultAuthentication - Exclude = [ordered]@{ Domains = @(); DCs = @() } - Include = [ordered]@{ Domains = @() } - WinRMSSL = $WinRMSSL - WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL - WinRMSSLPort = 5986 - WinRMPort = 5985 - EnableDiagrams = $EnableDiagrams - EnableDiagramDebug = $false - DiagramTheme = $Theme - DiagramObjDebug = $false - DiagramWaterMark = '' - DiagramType = [ordered]@{ + Exclude = [ordered]@{ Domains = @(); DCs = @() } + Include = [ordered]@{ Domains = @() } + WinRMSSL = $WinRMSSL + WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL + WinRMSSLPort = 5986 + WinRMPort = 5985 + EnableDiagrams = $EnableDiagrams + EnableDiagramDebug = $false + DiagramTheme = $Theme + DiagramObjDebug = $false + DiagramWaterMark = '' + DiagramType = [ordered]@{ CertificateAuthority = $true - Forest = $true - Replication = $true - Sites = $true - SitesInventory = $true - Trusts = $true + Forest = $true + Replication = $true + Sites = $true + SitesInventory = $true + Trusts = $true } - ExportDiagrams = $ExportDiagrams - ExportDiagramsFormat = @('pdf') - EnableDiagramSignature = $false - SignatureAuthorName = '' - SignatureCompanyName = '' - JobsTimeOut = 900 - DCStatusPingCount = 2 + ExportDiagrams = $ExportDiagrams + ExportDiagramsFormat = @('pdf') + EnableDiagramSignature = $false + SignatureAuthorName = '' + SignatureCompanyName = '' + JobsTimeOut = 900 + DCStatusPingCount = 2 } - InfoLevel = [ordered]@{ + InfoLevel = [ordered]@{ Forest = $LvlForest Domain = $LvlDomain - DNS = $LvlDNS + DNS = $LvlDNS } HealthCheck = [ordered]@{ - Domain = [ordered]@{ - GMSA = $true - GPO = $true - Backup = $true - DFS = $true - SPN = $true + Domain = [ordered]@{ + GMSA = $true + GPO = $true + Backup = $true + DFS = $true + SPN = $true DuplicateObject = $true - Security = $true - BestPractice = $true + Security = $true + BestPractice = $true } DomainController = [ordered]@{ - Diagnostic = $true - Services = $true - Software = $true + Diagnostic = $true + Services = $true + Software = $true BestPractice = $true } - Site = [ordered]@{ - Replication = $true + Site = [ordered]@{ + Replication = $true BestPractice = $true } - DNS = [ordered]@{ - Aging = $true - DP = $true - Zones = $true + DNS = [ordered]@{ + Aging = $true + DP = $true + Zones = $true BestPractice = $true } - CA = [ordered]@{ - Status = $true - Statistics = $true + CA = [ordered]@{ + Status = $true + Statistics = $true BestPractice = $true } } @@ -584,13 +584,13 @@ function Start-AsBuiltReportMSAD { } # ── Collect values ──────────────────────────────────────────────────────── - $server = $ui.Server.Text.Trim() - $username = $ui.Username.Text.Trim() - $password = $ui.Password.Text - $reportName = $ui.ReportName.Text.Trim() - $outPath = $ui.OutPath.Text.Trim() - $lang = [string]$ui.Lang.SelectedItem - $configPath = $ui.ConfigPath.Text.Trim() + $server = $ui.Server.Text.Trim() + $username = $ui.Username.Text.Trim() + $password = $ui.Password.Text + $reportName = $ui.ReportName.Text.Trim() + $outPath = $ui.OutPath.Text.Trim() + $lang = [string]$ui.Lang.SelectedItem + $configPath = $ui.ConfigPath.Text.Trim() $abrConfigPath = $ui.AbrConfigPath.Text.Trim() $formats = @() @@ -599,18 +599,18 @@ function Start-AsBuiltReportMSAD { if ($ui.FmtText.IsChecked -eq $true) { $formats += 'Text' } if ($formats.Count -eq 0) { $formats = @('Html') } - $enableDiagrams = [bool]$ui.Diagrams.IsChecked - $exportDiagrams = [bool]$ui.ExportDiagrams.IsChecked - $addTimestamp = [bool]$ui.Timestamp.IsChecked - $winRMSSL = [bool]$ui.WinRMSSL.IsChecked - $winRMFallback = [bool]$ui.WinRMFallback.IsChecked - $psDefaultAuth = [string]$ui.PSDefaultAuth.SelectedItem - $diagramTheme = [string]$ui.DiagramTheme.SelectedItem + $enableDiagrams = [bool]$ui.Diagrams.IsChecked + $exportDiagrams = [bool]$ui.ExportDiagrams.IsChecked + $addTimestamp = [bool]$ui.Timestamp.IsChecked + $winRMSSL = [bool]$ui.WinRMSSL.IsChecked + $winRMFallback = [bool]$ui.WinRMFallback.IsChecked + $psDefaultAuth = [string]$ui.PSDefaultAuth.SelectedItem + $diagramTheme = [string]$ui.DiagramTheme.SelectedItem # Parse InfoLevel (first char = number) $lvlForest = [int]([string]$ui.LvlForest.SelectedItem).Substring(0, 1) $lvlDomain = [int]([string]$ui.LvlDomain.SelectedItem).Substring(0, 1) - $lvlDNS = [int]([string]$ui.LvlDNS.SelectedItem).Substring(0, 1) + $lvlDNS = [int]([string]$ui.LvlDNS.SelectedItem).Substring(0, 1) # ── Validation ──────────────────────────────────────────────────────────── if ([string]::IsNullOrWhiteSpace($server)) { @@ -697,11 +697,11 @@ function Start-AsBuiltReportMSAD { $credential = [PSCredential]::new($username, $securePassword) $params = @{ - Report = 'Microsoft.AD' - Target = $server - Credential = $credential - OutputFolderPath = $outPath - Format = $formats + Report = 'Microsoft.AD' + Target = $server + Credential = $credential + OutputFolderPath = $outPath + Format = $formats ReportConfigFilePath = $reportConfigFilePath AsBuiltConfigFilePath = $abrConfigPath } @@ -827,70 +827,70 @@ function Start-AsBuiltReportMSAD { $abrConfigPathRow.Children.Add($btnBrowseAbrConfig) # Late-bind after TextBox objects exist - $generateCallback.ArgumentList['ConfigPath'] = $txtConfigPath + $generateCallback.ArgumentList['ConfigPath'] = $txtConfigPath $generateCallback.ArgumentList['AbrConfigPath'] = $txtAbrConfigPath # ── AsBuiltReport Global Settings (AsBuiltReport.json editor) ──────────────── - $txtAbrCoFullName = [TextBox]::new(); $txtAbrCoFullName.Width = 298; $txtAbrCoFullName.Watermark = 'e.g. Acme Corporation' + $txtAbrCoFullName = [TextBox]::new(); $txtAbrCoFullName.Width = 298; $txtAbrCoFullName.Watermark = 'e.g. Acme Corporation' $txtAbrCoShortName = [TextBox]::new(); $txtAbrCoShortName.Width = 298; $txtAbrCoShortName.Watermark = 'e.g. ACME' - $txtAbrCoContact = [TextBox]::new(); $txtAbrCoContact.Width = 298; $txtAbrCoContact.Watermark = 'Contact person' - $txtAbrCoPhone = [TextBox]::new(); $txtAbrCoPhone.Width = 298; $txtAbrCoPhone.Watermark = 'e.g. +1-800-555-0100' - $txtAbrCoAddress = [TextBox]::new(); $txtAbrCoAddress.Width = 298; $txtAbrCoAddress.Watermark = 'Street, City, Country' - $txtAbrCoEmail = [TextBox]::new(); $txtAbrCoEmail.Width = 298; $txtAbrCoEmail.Watermark = 'company@example.com' - $txtAbrRptAuthor = [TextBox]::new(); $txtAbrRptAuthor.Width = 298; $txtAbrRptAuthor.Watermark = 'Report author' - $txtAbrMailServer = [TextBox]::new(); $txtAbrMailServer.Width = 298; $txtAbrMailServer.Watermark = 'smtp.example.com' - $txtAbrMailPort = [TextBox]::new(); $txtAbrMailPort.Width = 298; $txtAbrMailPort.Watermark = '587' - $txtAbrMailFrom = [TextBox]::new(); $txtAbrMailFrom.Width = 298; $txtAbrMailFrom.Watermark = 'from@example.com' - $txtAbrMailTo = [TextBox]::new(); $txtAbrMailTo.Width = 298; $txtAbrMailTo.Watermark = 'to@example.com, other@example.com' - $txtAbrMailBody = [TextBox]::new(); $txtAbrMailBody.Width = 298; $txtAbrMailBody.Watermark = 'Email body text' - $swAbrMailUseSSL = [ToggleSwitch]::new(); $swAbrMailUseSSL.IsChecked = $true - $swAbrMailCreds = [ToggleSwitch]::new(); $swAbrMailCreds.IsChecked = $true - $txtAbrFolderPath = [TextBox]::new(); $txtAbrFolderPath.Width = 298; $txtAbrFolderPath.Watermark = '.\AsBuiltReport' + $txtAbrCoContact = [TextBox]::new(); $txtAbrCoContact.Width = 298; $txtAbrCoContact.Watermark = 'Contact person' + $txtAbrCoPhone = [TextBox]::new(); $txtAbrCoPhone.Width = 298; $txtAbrCoPhone.Watermark = 'e.g. +1-800-555-0100' + $txtAbrCoAddress = [TextBox]::new(); $txtAbrCoAddress.Width = 298; $txtAbrCoAddress.Watermark = 'Street, City, Country' + $txtAbrCoEmail = [TextBox]::new(); $txtAbrCoEmail.Width = 298; $txtAbrCoEmail.Watermark = 'company@example.com' + $txtAbrRptAuthor = [TextBox]::new(); $txtAbrRptAuthor.Width = 298; $txtAbrRptAuthor.Watermark = 'Report author' + $txtAbrMailServer = [TextBox]::new(); $txtAbrMailServer.Width = 298; $txtAbrMailServer.Watermark = 'smtp.example.com' + $txtAbrMailPort = [TextBox]::new(); $txtAbrMailPort.Width = 298; $txtAbrMailPort.Watermark = '587' + $txtAbrMailFrom = [TextBox]::new(); $txtAbrMailFrom.Width = 298; $txtAbrMailFrom.Watermark = 'from@example.com' + $txtAbrMailTo = [TextBox]::new(); $txtAbrMailTo.Width = 298; $txtAbrMailTo.Watermark = 'to@example.com, other@example.com' + $txtAbrMailBody = [TextBox]::new(); $txtAbrMailBody.Width = 298; $txtAbrMailBody.Watermark = 'Email body text' + $swAbrMailUseSSL = [ToggleSwitch]::new(); $swAbrMailUseSSL.IsChecked = $true + $swAbrMailCreds = [ToggleSwitch]::new(); $swAbrMailCreds.IsChecked = $true + $txtAbrFolderPath = [TextBox]::new(); $txtAbrFolderPath.Width = 298; $txtAbrFolderPath.Watermark = '.\AsBuiltReport' $loadAbrFields = { param ([hashtable]$j) - $txtAbrCoFullName.Text = if ($j.Company.FullName) { $j.Company.FullName } else { '' } - $txtAbrCoShortName.Text = if ($j.Company.ShortName) { $j.Company.ShortName } else { '' } - $txtAbrCoContact.Text = if ($j.Company.Contact) { $j.Company.Contact } else { '' } - $txtAbrCoPhone.Text = if ($j.Company.Phone) { $j.Company.Phone } else { '' } - $txtAbrCoAddress.Text = if ($j.Company.Address) { $j.Company.Address } else { '' } - $txtAbrCoEmail.Text = if ($j.Company.Email) { $j.Company.Email } else { '' } - $txtAbrRptAuthor.Text = if ($j.Report.Author) { $j.Report.Author } else { '' } - $txtAbrMailServer.Text = if ($j.Email.Server) { $j.Email.Server } else { '' } - $txtAbrMailPort.Text = if ($j.Email.Port) { $j.Email.Port } else { '' } - $txtAbrMailFrom.Text = if ($j.Email.From) { $j.Email.From } else { '' } - $txtAbrMailTo.Text = if ($j.Email.To) { ($j.Email.To -join ', ') } else { '' } - $txtAbrMailBody.Text = if ($j.Email.Body) { $j.Email.Body } else { '' } - $swAbrMailUseSSL.IsChecked = if ($null -ne $j.Email.UseSSL) { [bool]$j.Email.UseSSL } else { $true } - $swAbrMailCreds.IsChecked = if ($null -ne $j.Email.Credentials) { [bool]$j.Email.Credentials } else { $true } - $txtAbrFolderPath.Text = if ($j.UserFolder.Path) { $j.UserFolder.Path } else { + $txtAbrCoFullName.Text = if ($j.Company.FullName) { $j.Company.FullName } else { '' } + $txtAbrCoShortName.Text = if ($j.Company.ShortName) { $j.Company.ShortName } else { '' } + $txtAbrCoContact.Text = if ($j.Company.Contact) { $j.Company.Contact } else { '' } + $txtAbrCoPhone.Text = if ($j.Company.Phone) { $j.Company.Phone } else { '' } + $txtAbrCoAddress.Text = if ($j.Company.Address) { $j.Company.Address } else { '' } + $txtAbrCoEmail.Text = if ($j.Company.Email) { $j.Company.Email } else { '' } + $txtAbrRptAuthor.Text = if ($j.Report.Author) { $j.Report.Author } else { '' } + $txtAbrMailServer.Text = if ($j.Email.Server) { $j.Email.Server } else { '' } + $txtAbrMailPort.Text = if ($j.Email.Port) { $j.Email.Port } else { '' } + $txtAbrMailFrom.Text = if ($j.Email.From) { $j.Email.From } else { '' } + $txtAbrMailTo.Text = if ($j.Email.To) { ($j.Email.To -join ', ') } else { '' } + $txtAbrMailBody.Text = if ($j.Email.Body) { $j.Email.Body } else { '' } + $swAbrMailUseSSL.IsChecked = if ($null -ne $j.Email.UseSSL) { [bool]$j.Email.UseSSL } else { $true } + $swAbrMailCreds.IsChecked = if ($null -ne $j.Email.Credentials) { [bool]$j.Email.Credentials } else { $true } + $txtAbrFolderPath.Text = if ($j.UserFolder.Path) { $j.UserFolder.Path } else { if ($IsWindows) { [System.IO.Path]::Combine($env:USERPROFILE, 'Documents', 'AsBuiltReport') } else { [System.IO.Path]::Combine($env:HOME, 'AsBuiltReport') } } } $buildAbrConfig = { - $toList = ([string]$txtAbrMailTo.Text).Trim() -split '\s*,\s*' | Where-Object { $_ -ne '' } + $toList = ([string]$txtAbrMailTo.Text).Trim() -split '\s*,\s*' | Where-Object { $_ -ne '' } $portRaw = ([string]$txtAbrMailPort.Text).Trim() $portVal = if ($portRaw -match '^\d+$') { [int]$portRaw } else { $null } return [ordered]@{ - Company = [ordered]@{ - FullName = ([string]$txtAbrCoFullName.Text).Trim() - Phone = ([string]$txtAbrCoPhone.Text).Trim() - Address = ([string]$txtAbrCoAddress.Text).Trim() + Company = [ordered]@{ + FullName = ([string]$txtAbrCoFullName.Text).Trim() + Phone = ([string]$txtAbrCoPhone.Text).Trim() + Address = ([string]$txtAbrCoAddress.Text).Trim() ShortName = ([string]$txtAbrCoShortName.Text).Trim() - Contact = ([string]$txtAbrCoContact.Text).Trim() - Email = ([string]$txtAbrCoEmail.Text).Trim() + Contact = ([string]$txtAbrCoContact.Text).Trim() + Email = ([string]$txtAbrCoEmail.Text).Trim() } - Email = [ordered]@{ + Email = [ordered]@{ Credentials = [bool]$swAbrMailCreds.IsChecked - Body = ([string]$txtAbrMailBody.Text).Trim() - From = ([string]$txtAbrMailFrom.Text).Trim() - UseSSL = [bool]$swAbrMailUseSSL.IsChecked - Server = ([string]$txtAbrMailServer.Text).Trim() - To = if ($toList.Count -gt 0) { @($toList) } else { @() } - Port = $portVal + Body = ([string]$txtAbrMailBody.Text).Trim() + From = ([string]$txtAbrMailFrom.Text).Trim() + UseSSL = [bool]$swAbrMailUseSSL.IsChecked + Server = ([string]$txtAbrMailServer.Text).Trim() + To = if ($toList.Count -gt 0) { @($toList) } else { @() } + Port = $portVal } - Report = [ordered]@{ Author = ([string]$txtAbrRptAuthor.Text).Trim() } + Report = [ordered]@{ Author = ([string]$txtAbrRptAuthor.Text).Trim() } UserFolder = [ordered]@{ Path = ([string]$txtAbrFolderPath.Text).Trim() } } }.GetNewClosure() @@ -898,12 +898,12 @@ function Start-AsBuiltReportMSAD { $validateAbrRequired = { $missing = @() - if ([string]::IsNullOrWhiteSpace($txtAbrCoFullName.Text)) { $missing += 'Full Name' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoFullName.Text)) { $missing += 'Full Name' } if ([string]::IsNullOrWhiteSpace($txtAbrCoShortName.Text)) { $missing += 'Short Name' } - if ([string]::IsNullOrWhiteSpace($txtAbrCoContact.Text)) { $missing += 'Contact' } - if ([string]::IsNullOrWhiteSpace($txtAbrCoEmail.Text)) { $missing += 'Email' } - if ([string]::IsNullOrWhiteSpace($txtAbrRptAuthor.Text)) { $missing += 'Author' } - if ([string]::IsNullOrWhiteSpace($txtAbrFolderPath.Text)) { $missing += 'Path' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoContact.Text)) { $missing += 'Contact' } + if ([string]::IsNullOrWhiteSpace($txtAbrCoEmail.Text)) { $missing += 'Email' } + if ([string]::IsNullOrWhiteSpace($txtAbrRptAuthor.Text)) { $missing += 'Author' } + if ([string]::IsNullOrWhiteSpace($txtAbrFolderPath.Text)) { $missing += 'Path' } if ($missing.Count -gt 0) { return "⚠ Required fields missing: $($missing -join ', ')" } @@ -1052,63 +1052,63 @@ function Start-AsBuiltReportMSAD { [int]$LvlForest, [int]$LvlDomain, [int]$LvlDNS ) return [ordered]@{ - Report = [ordered]@{ - Name = $ReportName - Version = '1.0' - Status = 'Released' - Language = $Lang - ShowCoverPageImage = $true + Report = [ordered]@{ + Name = $ReportName + Version = '1.0' + Status = 'Released' + Language = $Lang + ShowCoverPageImage = $true ShowTableOfContents = $true - ShowHeaderFooter = $true - ShowTableCaptions = $true + ShowHeaderFooter = $true + ShowTableCaptions = $true } - Options = [ordered]@{ - ShowExecutionTime = $false - ShowDefinitionInfo = $false + Options = [ordered]@{ + ShowExecutionTime = $false + ShowDefinitionInfo = $false PSDefaultAuthentication = $PSDefaultAuthentication - Exclude = [ordered]@{ Domains = @(); DCs = @() } - Include = [ordered]@{ Domains = @() } - WinRMSSL = $WinRMSSL - WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL - WinRMSSLPort = 5986 - WinRMPort = 5985 - EnableDiagrams = $EnableDiagrams - EnableDiagramDebug = $false - DiagramTheme = $Theme - DiagramObjDebug = $false - DiagramWaterMark = '' - DiagramType = [ordered]@{ + Exclude = [ordered]@{ Domains = @(); DCs = @() } + Include = [ordered]@{ Domains = @() } + WinRMSSL = $WinRMSSL + WinRMFallbackToNoSSL = $WinRMFallbackToNoSSL + WinRMSSLPort = 5986 + WinRMPort = 5985 + EnableDiagrams = $EnableDiagrams + EnableDiagramDebug = $false + DiagramTheme = $Theme + DiagramObjDebug = $false + DiagramWaterMark = '' + DiagramType = [ordered]@{ CertificateAuthority = $true - Forest = $true - Replication = $true - Sites = $true - SitesInventory = $true - Trusts = $true + Forest = $true + Replication = $true + Sites = $true + SitesInventory = $true + Trusts = $true } - ExportDiagrams = $ExportDiagrams - ExportDiagramsFormat = @('pdf') - EnableDiagramSignature = $false - SignatureAuthorName = '' - SignatureCompanyName = '' - JobsTimeOut = 900 - DCStatusPingCount = 2 + ExportDiagrams = $ExportDiagrams + ExportDiagramsFormat = @('pdf') + EnableDiagramSignature = $false + SignatureAuthorName = '' + SignatureCompanyName = '' + JobsTimeOut = 900 + DCStatusPingCount = 2 } - InfoLevel = [ordered]@{ + InfoLevel = [ordered]@{ Forest = $LvlForest Domain = $LvlDomain - DNS = $LvlDNS + DNS = $LvlDNS } HealthCheck = [ordered]@{ - Domain = [ordered]@{ - GMSA = $true; GPO = $true; Backup = $true; DFS = $true - SPN = $true; DuplicateObject = $true; Security = $true; BestPractice = $true + Domain = [ordered]@{ + GMSA = $true; GPO = $true; Backup = $true; DFS = $true + SPN = $true; DuplicateObject = $true; Security = $true; BestPractice = $true } DomainController = [ordered]@{ Diagnostic = $true; Services = $true; Software = $true; BestPractice = $true } - Site = [ordered]@{ Replication = $true; BestPractice = $true } - DNS = [ordered]@{ Aging = $true; DP = $true; Zones = $true; BestPractice = $true } - CA = [ordered]@{ Status = $true; Statistics = $true; BestPractice = $true } + Site = [ordered]@{ Replication = $true; BestPractice = $true } + DNS = [ordered]@{ Aging = $true; DP = $true; Zones = $true; BestPractice = $true } + CA = [ordered]@{ Status = $true; Statistics = $true; BestPractice = $true } } } } @@ -1143,7 +1143,7 @@ function Start-AsBuiltReportMSAD { -LvlForest (Get-LevelVal $cboLvlForest) ` -LvlDomain (Get-LevelVal $cboLvlDomain) ` -LvlDNS (Get-LevelVal $cboLvlDNS) - $configObj| ConvertTo-Json -Depth 6 | Set-Content -Path $destPath -Encoding UTF8 + $configObj | ConvertTo-Json -Depth 6 | Set-Content -Path $destPath -Encoding UTF8 $syncHash.lblConfigStatus.Text = "✅ Config saved: $(Split-Path $destPath -Leaf)" } catch { $syncHash.lblConfigStatus.Text = "❌ Save failed: $_" @@ -1164,20 +1164,20 @@ function Start-AsBuiltReportMSAD { } try { $j = Get-Content -Path $srcPath -Raw | ConvertFrom-Json - if ($j.Report.Name) { $txtReportName.Text = $j.Report.Name } + if ($j.Report.Name) { $txtReportName.Text = $j.Report.Name } if ($j.Report.Language) { $idx = $cboLang.Items.IndexOf($j.Report.Language); if ($idx -ge 0) { $cboLang.SelectedIndex = $idx } } - if ($null -ne $j.Options.EnableDiagrams) { $swDiagrams.IsChecked = [bool]$j.Options.EnableDiagrams } - if ($null -ne $j.Options.ExportDiagrams) { $swExportDiagrams.IsChecked = [bool]$j.Options.ExportDiagrams } - if ($null -ne $j.Options.ShowExecutionTime) { Out-Null } - if ($null -ne $j.Options.ShowDefinitionInfo) { Out-Null } - if ($null -ne $j.Options.WinRMSSL){ $swWinRMSSL.IsChecked = [bool]$j.Options.WinRMSSL } - if ($null -ne $j.Options.WinRMFallbackToNoSSL) { $swWinRMFallback.IsChecked = [bool]$j.Options.WinRMFallbackToNoSSL } + if ($null -ne $j.Options.EnableDiagrams) { $swDiagrams.IsChecked = [bool]$j.Options.EnableDiagrams } + if ($null -ne $j.Options.ExportDiagrams) { $swExportDiagrams.IsChecked = [bool]$j.Options.ExportDiagrams } + if ($null -ne $j.Options.ShowExecutionTime) { Out-Null } + if ($null -ne $j.Options.ShowDefinitionInfo) { Out-Null } + if ($null -ne $j.Options.WinRMSSL) { $swWinRMSSL.IsChecked = [bool]$j.Options.WinRMSSL } + if ($null -ne $j.Options.WinRMFallbackToNoSSL) { $swWinRMFallback.IsChecked = [bool]$j.Options.WinRMFallbackToNoSSL } if ($j.Options.DiagramTheme) { $idx = $cboDiagramTheme.Items.IndexOf($j.Options.DiagramTheme); if ($idx -ge 0) { $cboDiagramTheme.SelectedIndex = $idx } } if ($j.Options.PSDefaultAuthentication) { $idx = $cboPSDefaultAuth.Items.IndexOf($j.Options.PSDefaultAuthentication); if ($idx -ge 0) { $cboPSDefaultAuth.SelectedIndex = $idx } } if ($null -ne $j.InfoLevel.Forest) { $cboLvlForest.SelectedIndex = [int]$j.InfoLevel.Forest } if ($null -ne $j.InfoLevel.Domain) { $cboLvlDomain.SelectedIndex = [int]$j.InfoLevel.Domain } - if ($null -ne $j.InfoLevel.DNS) { $cboLvlDNS.SelectedIndex = [int]$j.InfoLevel.DNS } - $syncHash.lblConfigStatus.Text= "✅ Config loaded: $(Split-Path $srcPath -Leaf)" + if ($null -ne $j.InfoLevel.DNS) { $cboLvlDNS.SelectedIndex = [int]$j.InfoLevel.DNS } + $syncHash.lblConfigStatus.Text = "✅ Config loaded: $(Split-Path $srcPath -Leaf)" } catch { $syncHash.lblConfigStatus.Text = "❌ Load failed: $_" } From 33cc95268ad52daff1aef1fe78e5764095c19221 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 16:49:00 -0400 Subject: [PATCH 13/18] feat: Add GUI examples and usage instructions to README, including a sample image --- README.md | 13 +++++++++++++ Samples/Sample-Gui.png | Bin 0 -> 440747 bytes 2 files changed, 13 insertions(+) create mode 100644 Samples/Sample-Gui.png diff --git a/README.md b/README.md index 6df76a2..80afbf6 100644 --- a/README.md +++ b/README.md @@ -243,6 +243,19 @@ PS C:\> New-AsBuiltReport -Report Microsoft.AD -Target 'admin-dc-01v.contoso.loc 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 ``` +## :computer: GUI Examples + +The Microsoft AD As Built Report GUI can be used to generate reports without using the console. The GUI provides the same functionality as the console, but with a user-friendly interface. To launch the GUI, run the following command in a PowerShell terminal window: + +```powershell +# Launch the Microsoft AD As Built Report GUI +PS C:\> Start-AsBuiltReportMSAD +``` + +**Beta** versions of the GUI may contain bugs and issues. If you encounter any problems while using the GUI, please report them on the project's GitHub Issues page. + +![alt text](Samples/Sample-Gui.png) + ## :x: Known Issues - **PSWriteWord Module Conflict**: PScribo and the EvotecIT "PSWriteWord" project use conflicting cmdlets. The PSWriteWord module must be uninstalled before generating reports. - **WinRM Dependency**: This report relies heavily on remote connections via WinRM. A Windows 10 client is recommended as a jumpbox for optimal connectivity. diff --git a/Samples/Sample-Gui.png b/Samples/Sample-Gui.png new file mode 100644 index 0000000000000000000000000000000000000000..72b195e888b4b4394e94db454d2414cbfa93dd70 GIT binary patch literal 440747 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�>k-;#vQ5 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

=JVU9S|~UVcgQ(?y2DY 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⁢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

|dtaf(o-LyO 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

8-ZZcYl!H?B99dw8 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 Bc7FitKrEU(;d=(uXMG_V{8AhoZnlqr!R%G zhpYG3{GNO5nD?Lc?RmUMnXCx&k=jbNCQ)gz0C~9GO@pTcRgFE-%v)Lud%ccGYJ)YewZFudD|#QA5+%A4N{d)qT7G zS^F~gm=eMa`EL8kIePCc7T;WGHoNXS*;0P@l=CP?%-&mZwtkP|h{}zbi4db0(P~i9 zj+MvchV$~f9XDQl8T88$_;OQv5NnMiYi)}c7S`tRojQzE=E>U_q zDeJ_mP>M+MJS(rUy|$L^7Oi|x8ISf+X;}g5$L)SWu74+Eu`h4#?dzL*j!-dbC|BYw z;@h`x?sPh-Ktf)_MLa)dy-KXpC)_Wt3(I5-!^I8a5n`0^es`xI z-_>J;ET`c{?@>aw=}UwW;#o{@8g1#dAPf)UT8&HF;ZUZ7fnLSACS)oEd#l&bdNCQ} z-mu2?o_o5j;k{OA|5)jRXO#&`#Vhcu8{&So^IxlbTLmTe5E6Vwe)aPQcqYGk{R>ln z@GG-Y2>ioK@0lO~*h;rye(y6jPDiy8n{lM{!E6L$h8WnrIW+I^lOba2#wob0jm91S zJZ>tmS=(#whRvR|nj5rc!;aZG`lm)M^vn$79yNjDZEAC+%F5Jn(*;%BK8)xDmOQ@=1=Y?1KKoI731in421o3UN|`x&i|${hws_b z>K3H8f#${~Qzhm?kbL6b3l$FXWP%!1{mUBwI$a*amdNOPzjn2GgwSO&zQ|`0Ky>cy z5L|R0g1|)PutgvtqI4@@`sOW{-XI&!PtIi+-T5Mu?wN%)s!x(FQVdEW5XNoIg2g-u&oK zB22i*I`?LPHLoys?Sp0Bp0Ky@t^ZBUl+S8eXI);IK0wiKRML_J1#wA^5S}fK;l&mq zz1j_jc-6&xSlS{JMrb<2(j7J&hyn?10A#xtKBV5f5J%+c4FU;^CoVBzyUfaL%*-@) z$kHF474~Z?N3lUz(>z9<_bxuoQ3e_WU8%jA7K4WiOXgO$toeZ$&Xf z)@IDwqAXLb-wyGWEpBFp4W3SB35tzg)E4Ra+1M;Aui-d(`da$Rqlg6$#~>K=25J*9 z$ZNO^?jmI+jyWp%62?*!k;ZHsQH-G~;lyi`j~ha`akZncww8)>a?ea-LmV;5>q%zL zmWWW{=&TH7Da<~{vDKDwWOnL%Zc5C^-VEQ`XB{6+y?@B{RqaOca}{rvI6{rve; z1rkyYt$rM27#Nq%NK(&C{p-tx2p-(oFO@O)FvL^DW&G(bB9J(JSC0|8+(z`PB%fvJ zjNr{DTguN1BTP7CZMcaeytE-YovvstRk*Qm4bz_f8pQgR<+{Jt{vaEFsZ1@TE$*AI zM$!20L&--W_4K8Cy6Qq|=_Dp6p6YKNbE?-Z=iEuzWo_Yfi?u5$mbhOvebZpma5srV zV?N~L6U*!T;0o0-Y)$xPZP+BI^WJJY2Ak*3^a@$F&g0KgT)7_YcFMOA(;lupwoN%- zmY<;!ZuzsHONd`XS+C7kO!8t@ua@dmr92d3?^GU^uJUBhX*AiGqD>;b+l+d0 zKUj?>FAe9qg)^7x{En#MaBW=(!i>0hgHwIy_? zBk(-m7ngg8_nVvco*!3f*Q;f++IG)xik5nmGQifplixSDFMGK);PGMc`FYuG;V;zS zTa)p@*?WCH5tT8hzYQO^wfA=rN!(k&xz$rmYyYi`&yN4o8us=*8UMWeo8E`b!w-8k zlV^6sD`S6<_@eeidNZEN7;?7jEVyF-Y)+=SeJQPb+OFD=WFcLv`)78%c`)rcAu`sdk9Q{#*FwnV6t>pImMyQfyY26v6rG%yPkZgYbN+kI{{u|$diyw+0Ji`D002ov JPDHLkV1j^3M3w*m literal 0 HcmV?d00001 From 420f801f470df18bfdca2314e8ed194f608e1429 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 16:52:14 -0400 Subject: [PATCH 14/18] refactor: Enhance GliderUI support description in CHANGELOG for clarity and user-friendliness Co-authored-by: Copilot --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae4c61c..217206f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add support for GliderUI to generate the report using a graphical interface instead of command line. The GUI will allow users to select the target domain, customize report options, and initiate the report generation process with a user-friendly experience. +- Add support for GliderUI graphical interface to generate reports via an intuitive user interface instead of command-line execution. The GUI enables users to select target domains, customize report options (InfoLevel, HealthChecks, diagram settings), and initiate report generation with a streamlined, user-friendly experience, reducing friction for non-technical stakeholders. ### :arrows_clockwise: Changed From a0f825e3c2ee327680c0f3803cc6bc10d0ca739e Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Fri, 24 Apr 2026 16:52:44 -0400 Subject: [PATCH 15/18] fix: Update release date for version 1.0.0 in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 217206f..e2335f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ##### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates. -## [1.0.0] - 2026-04-?? +## [1.0.0] - 2026-04-24 ### Added From 98cfa225e41546c94f176ecb11b1ca06642cd5ed Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sat, 2 May 2026 17:20:52 -0400 Subject: [PATCH 16/18] chore: Update module version to 1.0.7 and adjust color properties for diagram nodes --- .../AsBuiltReport.Microsoft.AD.psd1 | 2 +- .../Get-AbrDiagCertificateAuthority.ps1 | 2 +- .../Src/Private/Diagram/Get-AbrDiagForest.ps1 | 4 ++-- .../Private/Diagram/Get-AbrDiagReplication.ps1 | 6 +++--- .../Diagram/Get-AbrDiagSiteInventory.ps1 | 12 ++++++------ .../Src/Private/Diagram/Get-AbrDiagTrust.ps1 | 2 +- .../Src/Private/Diagram/New-AbrADDiagram.ps1 | 6 +++--- .../Report/Get-AbrADDomainController.ps1 | 2 +- .../Private/Report/Get-AbrADDomainObject.ps1 | 18 +++++++++--------- .../Report/Get-AbrADSecurityAssessment.ps1 | 2 +- CHANGELOG.md | 5 +++-- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 index 58e336b..4c25f69 100644 --- a/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 +++ b/AsBuiltReport.Microsoft.AD/AsBuiltReport.Microsoft.AD.psd1 @@ -62,7 +62,7 @@ }, @{ ModuleName = 'AsBuiltReport.Diagram'; - ModuleVersion = '1.0.6' + ModuleVersion = '1.0.7' } ) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 index e8e96b5..3d877f3 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagCertificateAuthority.ps1 @@ -61,7 +61,7 @@ function Get-AbrDiagCertificateAuthority { } } } else { - Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.NoCA; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '5'; height = '3'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = 'gray' } + Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.NoCA; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '5'; height = '3'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = $Edgecolor } } } } catch { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 index 8c3c83c..f6ae0f3 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagForest.ps1 @@ -49,7 +49,7 @@ function Get-AbrDiagForest { Node -Name $ForestInfo.Name -Attributes @{Label = $ForestInfo.Label; shape = 'plain'; fillColor = 'transparent' } - Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.fNoChildDomains; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = 'gray' } + Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.fNoChildDomains; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = $Edgecolor } Edge -From $ForestInfo.Name -To NoDomain @{minlen = 2 } @@ -57,7 +57,7 @@ function Get-AbrDiagForest { } } } else { - Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.fNoChildDomains; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '15'; height = '13'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = 'gray' } + Node -Name NoDomain @{Label = $reportTranslate.NewADDiagram.fNoChildDomains; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '15'; height = '13'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = $Edgecolor } } } } catch { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 index af21f1e..e4d64d2 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagReplication.ps1 @@ -49,7 +49,7 @@ function Get-AbrDiagReplication { ($ReplInfo | Where-Object { ($_.FromServer -eq $DC -and $_.FromSite -eq $Site) -or ($_.ToServer -eq $DC -and $_.ToSite -eq $Site) }) } | Select-Object -Unique - SubGraph $SiteNodeName -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $Site -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { + SubGraph $SiteNodeName -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $Site -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = $Edgecolor } { foreach ($DC in $SiteDCs) { $DCNodeName = Remove-SpecialCharacter -String $DC -SpecialChars '\-. ' Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent' } @@ -63,7 +63,7 @@ function Get-AbrDiagReplication { -not ($ReplInfo | Where-Object { ($_.FromServer -eq $DC -and $_.FromSite -ne 'Unknown') -or ($_.ToServer -eq $DC -and $_.ToSite -ne 'Unknown') }) } if ($UnknownSiteDCs) { - SubGraph UnknownSite -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $reportTranslate.NewADDiagram.replUnknownSite -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = 'gray' } { + SubGraph UnknownSite -Attributes @{Label = (Add-HtmlLabel -ImagesObj $Images -Label $reportTranslate.NewADDiagram.replUnknownSite -IconType 'AD_Site' -IconDebug $IconDebug -SubgraphLabel -IconWidth 35 -IconHeight 35 -Fontsize 18 -FontName 'Segoe UI' -FontColor $Fontcolor -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded'; color = $Edgecolor } { foreach ($DC in $UnknownSiteDCs) { $DCNodeName = Remove-SpecialCharacter -String $DC -SpecialChars '\-. ' Node -Name $DCNodeName -Attributes @{Label = (Add-NodeIcon -Name ($DC.Split('.')[0].ToUpper()) -IconType 'AD_DC' -Align 'Center' -ImagesObj $Images -IconDebug $IconDebug -FontSize 18 -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor); shape = 'plain'; fillColor = 'transparent' } @@ -97,7 +97,7 @@ function Get-AbrDiagReplication { } } else { Write-Verbose ($reportTranslate.NewADDiagram.emptyReplication) - Node -Name NoReplication @{Label = $reportTranslate.NewADDiagram.NoReplication; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = 'gray' } + Node -Name NoReplication @{Label = $reportTranslate.NewADDiagram.NoReplication; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = $Edgecolor } } } } catch { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 index 2f9f905..4ad92a4 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagSiteInventory.ps1 @@ -42,21 +42,21 @@ function Get-AbrDiagSiteInventory { $ChildDCsNodes = Add-HtmlTable -Name ChildDCsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.DomainControllers.DCsArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 -TableBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $ChildDCsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 18 -TableBackgroundColor $MainGraphBGColor + $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $ChildDCsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 18 -TableBackgroundColor $MainGraphBGColor } else { - $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteDC -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 22 -TableBackgroundColor $MainGraphBGColor + $ChildDCsNodesSubgraph = Add-HtmlSubGraph -Name ChildDCsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteDC -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.DomainControllers -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -IconType 'AD_DC' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } if ($SiteGroupOBJ.Subnets.SubnetArray) { $ChildSubnetsNodes = Add-HtmlTable -Name ChildSubnetsNodes -ImagesObj $Images -Rows $SiteGroupOBJ.Subnets.SubnetArray -ALIGN 'Center' -ColumnSize 3 -IconDebug $IconDebug -TableStyle 'dashed,rounded' -NoFontBold -FontSize 18 -TableBackgroundColor $MainGraphBGColor -FontColor $Fontcolor - $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $ChildSubnetsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor + $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $ChildSubnetsNodes -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } else { - $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteSubnet -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor + $ChildSubnetsNodesSubgraph = Add-HtmlSubGraph -Name ChildSubnetsNodesSubgraph -ImagesObj $Images -TableArray $reportTranslate.NewADDiagram.NoSiteSubnet -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Subnets -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -IconType 'AD_Site_Subnet' -FontSize 22 -TableBackgroundColor $MainGraphBGColor } $ChildSiteSubgraph = [System.Collections.Generic.List[object]]::new() @@ -65,11 +65,11 @@ function Get-AbrDiagSiteInventory { $ChildSiteSubgraph.Add($ChildSubnetsNodesSubgraph) $ChildSiteSubgraphArray.Add( - (Add-HtmlSubGraph -Name ChildSiteSubgraphArray -ImagesObj $Images -TableArray $ChildSiteSubgraph -Align 'Center' -IconType 'AD_Site' -IconDebug $IconDebug -Label $SiteGroupOBJ.Name -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor) + (Add-HtmlSubGraph -Name ChildSiteSubgraphArray -ImagesObj $Images -TableArray $ChildSiteSubgraph -Align 'Center' -IconType 'AD_Site' -IconDebug $IconDebug -Label $SiteGroupOBJ.Name -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor) ) } - Node -Name 'SitesTopology' -Attributes @{Label = (Add-HtmlSubGraph -Name SitesTopology -ImagesObj $Images -TableArray $ChildSiteSubgraphArray -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Sites -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor 'gray' -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = 'Segoe Ui' } + Node -Name 'SitesTopology' -Attributes @{Label = (Add-HtmlSubGraph -Name SitesTopology -ImagesObj $Images -TableArray $ChildSiteSubgraphArray -Align 'Center' -IconDebug $IconDebug -Label $reportTranslate.NewADDiagram.Sites -LabelPos 'top' -TableStyle 'dashed,rounded' -TableBorder '1' -ColumnSize 3 -TableBorderColor $Edgecolor -FontColor $Fontcolor -FontSize 22 -TableBackgroundColor $MainGraphBGColor); shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = 'Segoe Ui' } } else { Node -Name NoSites -Attributes @{Label = $reportTranslate.NewADDiagram.NoSites; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 0 } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 index d623288..27e3b7f 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/Get-AbrDiagTrust.ps1 @@ -62,7 +62,7 @@ function Get-AbrDiagTrust { } } } else { - Node -Name NoTrusts @{Label = $reportTranslate.NewADDiagram.NoTrusts; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = 'gray' } + Node -Name NoTrusts @{Label = $reportTranslate.NewADDiagram.NoTrusts; shape = 'rectangle'; labelloc = 'c'; fixedsize = $true; width = '3'; height = '2'; fillColor = 'transparent'; penwidth = 1.5; style = 'dashed'; color = $Edgecolor } } } } catch { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 index 3896270..1180e5d 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Diagram/New-AbrADDiagram.ps1 @@ -379,7 +379,7 @@ function New-AbrADDiagram { $script:NodeDebug = @{color = 'black'; style = 'red' } $script:IconDebug = $true } else { - $SubGraphDebug = @{style = 'invis'; color = 'gray' } + $SubGraphDebug = @{style = 'invis'; color = $Edgecolor } $script:NodeDebug = @{color = 'transparent'; style = 'transparent' } } @@ -496,9 +496,9 @@ function New-AbrADDiagram { if ($Signature) { Write-Verbose 'Generating diagram signature' if ($CustomSignatureLogo) { - $Signature = (Add-HtmlSignatureTable -ImagesObj $Images -Rows "Author: $($AuthorName)", "Company: $($CompanyName)" -TableBorder 2 -CellBorder 0 -Align 'left' -Logo $CustomSignatureLogo -IconDebug $IconDebug) + $Signature = (Add-HtmlSignatureTable -ImagesObj $Images -Rows "Author: $($AuthorName)", "Company: $($CompanyName)" -TableBorderColor $Edgecolor -TableBorder 2 -CellBorder 0 -Align 'left' -Logo $CustomSignatureLogo -IconDebug $IconDebug -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor) } else { - $Signature = (Add-HtmlSignatureTable -ImagesObj $Images -Rows "Author: $($AuthorName)", "Company: $($CompanyName)" -TableBorder 2 -CellBorder 0 -Align 'left' -Logo 'AD_LOGO_Footer' -IconDebug $IconDebug) + $Signature = (Add-HtmlSignatureTable -ImagesObj $Images -Rows "Author: $($AuthorName)", "Company: $($CompanyName)" -TableBorderColor $Edgecolor -TableBorder 2 -CellBorder 0 -Align 'left' -Logo 'AD_LOGO_Footer' -IconDebug $IconDebug -TableBackgroundColor $MainGraphBGColor -CellBackgroundColor $MainGraphBGColor -FontColor $Fontcolor) } } else { Write-Verbose $reportTranslate.NewADDiagram.diagramSignature diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 index 3180504..1b333e2 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 @@ -123,7 +123,7 @@ } try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Category' - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title 'DC vs GC Distribution' -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title 'DC vs GC Distribution' -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning $_.Exception.Message } diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 index f70662a..0c8387b 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainObject.ps1 @@ -5,7 +5,7 @@ function Get-AbrADDomainObject { .DESCRIPTION .NOTES - Version: 0.9.12 + Version: 1.0.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -92,7 +92,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Category' - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.UserObjectsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.UserObjectsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorUserObjectCountChart) $($_.Exception.Message)" } @@ -184,7 +184,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $OutObj - $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfUsersSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 800 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfUsersSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 800 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfUsersAccountsChart) $($_.Exception.Message)" } @@ -270,7 +270,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupCategoriesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupCategoriesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupCategoryObjectChart) $($_.Exception.Message)" } @@ -304,7 +304,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupScopesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title $reportTranslate.GetAbrADDomainObject.GroupScopesSubSection -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorGroupScopesObjectChart) $($_.Exception.Message)" } @@ -774,7 +774,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Name'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } | Sort-Object -Property 'Name' - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.ComputersCount)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Name -Title "$($reportTranslate.GetAbrADDomainObject.ComputersCount)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorComputersObjectCountChart) $($_.Exception.Message)" } @@ -852,7 +852,7 @@ function Get-AbrADDomainObject { } try { $sampleData = $OutObj - $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfComputerAccountsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.$($reportTranslate.GetAbrADDomainObject.Total) -Labels $sampleData.$($reportTranslate.GetAbrADDomainObject.Category) -Title "$($reportTranslate.GetAbrADDomainObject.StatusOfComputerAccountsSection)" -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 400 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($reportTranslate.GetAbrADDomainObject.ErrorStatusOfComputersAccountsChart) $($_.Exception.Message)" } @@ -888,7 +888,7 @@ function Get-AbrADDomainObject { $OutObj.Add([pscustomobject](ConvertTo-HashToYN $inObj)) } if ($HealthCheck.Domain.Security) { - $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2003*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2008*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 95*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 7*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 8 *' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 98*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*XP*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* Vista*' } | Set-Style -Style Critical -Property $reportTranslate.GetAbrADDomainObject.OperatingSystem + $OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2003*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2008*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 95*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 7*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 8*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 10*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 98*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*XP*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* Vista*' } | Set-Style -Style Critical -Property $reportTranslate.GetAbrADDomainObject.OperatingSystem } $TableParams = @{ @@ -900,7 +900,7 @@ function Get-AbrADDomainObject { $TableParams['Caption'] = "- $($TableParams.Name)" } $OutObj | Sort-Object -Property $reportTranslate.GetAbrADDomainObject.OperatingSystem | Table @TableParams - if ($HealthCheck.Domain.Security -and ($OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2003*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2008*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 95*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 7*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 8 *' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 98*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*XP*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* Vista*' })) { + if ($HealthCheck.Domain.Security -and ($OutObj | Where-Object { $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2003*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2008*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* NT*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*2000*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 95*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 7*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 8*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 10*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* 98*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '*XP*' -or $_.$($reportTranslate.GetAbrADDomainObject.OperatingSystem) -like '* Vista*' })) { Paragraph $reportTranslate.GetAbrADDomainObject.HealthCheck -Bold -Underline BlankLine Paragraph { diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 index 9e6f2df..98c7fe0 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADSecurityAssessment.ps1 @@ -81,7 +81,7 @@ function Get-AbrADSecurityAssessment { try { $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = { $_.key } }, @{ Name = 'Value'; Expression = { $_.value } } - $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Category -Title $reportTranslate.GetAbrADSecurityAssessment.UserAccountTitle -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 600 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue + $Chart = New-PieChart -Values $sampleData.Value -Labels $sampleData.Category -Title $reportTranslate.GetAbrADSecurityAssessment.UserAccountTitle -EnableLegend -LegendOrientation Horizontal -LegendAlignment UpperCenter -Width 600 -Height 600 -Format base64 -TitleFontSize 20 -TitleFontBold -EnableCustomColorPalette -CustomColorPalette $AbrCustomPalette -EnableChartBorder -ChartBorderStyle DenselyDashed -ChartBorderColor DarkBlue -LabelFontColor Black -LabelFontSize 14 -LabelBold } catch { Write-PScriboMessage -IsWarning -Message "$($_.Exception.Message) ($($reportTranslate.GetAbrADSecurityAssessment.ErrorUserAccountSecurityAssessmentChart))" } diff --git a/CHANGELOG.md b/CHANGELOG.md index e2335f7..4516a18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,14 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add support for GliderUI graphical interface to generate reports via an intuitive user interface instead of command-line execution. The GUI enables users to select target domains, customize report options (InfoLevel, HealthChecks, diagram settings), and initiate report generation with a streamlined, user-friendly experience, reducing friction for non-technical stakeholders. +- Add support for GliderUI graphical interface to generate reports via an intuitive user interface instead of command-line execution +- Add Windows 10* to the unsupported operating systems list in the Health Check section to reflect the end of support for Windows 10 and encourage users to upgrade to supported operating systems for better security and performance ### :arrows_clockwise: Changed - Improved multi-language support by refactoring localization strings and enhancing documentation clarity in MicrosoftAD.psd1 for English and Spanish languages. This includes improved grammar, punctuation, and readability across various best practice descriptions related to Active Directory configurations - Bump module version to `1.0.0` -- Upgrade AsBuiltReport.Diagram module to version `1.0.6` +- Upgrade AsBuiltReport.Diagram module to version `1.0.7` - Upgrade AsBuiltReport.Chart module to version `0.3.1` ## :bug: Fixed From 0e53d1b0f35d90921cd5944ab2ad95d548ed2e6e Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sat, 2 May 2026 17:24:33 -0400 Subject: [PATCH 17/18] fix: Update release date for version 1.0.0 in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4516a18..60af01e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ##### This project is community maintained and has no sponsorship from Microsoft, its employees or any of its affiliates. -## [1.0.0] - 2026-04-24 +## [1.0.0] - 2026-05-02 ### Added From 6e5a74ea7e8657f0a634d8678e089daa81b2fb42 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sat, 2 May 2026 17:56:22 -0400 Subject: [PATCH 18/18] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Src/Private/Report/Get-AbrADDomainController.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 index 1b333e2..c2f5bc7 100644 --- a/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 +++ b/AsBuiltReport.Microsoft.AD/Src/Private/Report/Get-AbrADDomainController.ps1 @@ -1,4 +1,4 @@ -function Get-AbrADDomainController { +function Get-AbrADDomainController { <# .SYNOPSIS Used by As Built Report to retrieve Microsoft AD Domain Controller information.