Skip to content

Add computer name targeting to AD domain state#2002

Open
soulemike wants to merge 1 commit into
maester365:mainfrom
soulemike:codex/create-branch-for-issue-1974
Open

Add computer name targeting to AD domain state#2002
soulemike wants to merge 1 commit into
maester365:mainfrom
soulemike:codex/create-branch-for-issue-1974

Conversation

@soulemike

@soulemike soulemike commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

📑 Description

Adds an optional param for the target of the caching commands with a default of the current domain. May need future mapping in other commands.

Allow callers to target a specific domain controller or DNS server when collecting AD domain state so sub-commands that require a host can be directed explicitly.
Preserve existing behavior by falling back to the collected domain object's DNS root when no computer name is supplied.
Ensure cached domain state is separated per target host to avoid overwriting or reusing results collected for a different server.
Description
Added an optional ComputerName parameter and updated the command help with examples describing its use.
Build @adServerParameters when -ComputerName is provided and splat it to supported Get-AD* calls so those queries target the specified AD Server.
Introduced resolvedComputerName = if ($ComputerName) { $ComputerName } else { $domainState.Domain.DNSRoot } and use it for DNS and LDAP sub-commands, including Get-DnsServerZone, Get-DnsServerResourceRecord, and the LDAP:// search root for DirectorySearcher.
Use a cache key that includes the ComputerName (DomainState:$ComputerName) when a target host is specified so targeted collections do not clash with the default cache.

Closes #1974

✅ Checks

  • My pull request adheres to the code style of this project.
  • My code requires changes to the documentation.
  • I have updated the documentation as required.
  • The build and unit tests pass after running /powershell/tests/pester.ps1 locally.

ℹ️ Additional Information

Summary by CodeRabbit

  • New Features

    • Added an optional -ComputerName parameter to collect Active Directory and DNS state from a specific domain controller or DNS server.
    • Expanded server targeting across schema, trusts, organizational units, printer objects, DFS-R, LAPS, and permission data collection.
    • Added examples and documentation for using the new parameter.
  • Bug Fixes

    • Improved session caching and ensured queries consistently use the selected server.

@soulemike
soulemike requested a review from a team as a code owner July 25, 2026 21:30
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Get-MtADDomainState now accepts an optional -ComputerName, scopes caching per target, and directs Active Directory, DNS, schema, and LDAP queries to the resolved server.

Changes

Targeted domain-state collection

Layer / File(s) Summary
Target selection and cache scoping
powershell/public/Get-MtADDomainState.ps1
Adds -ComputerName, per-server cache keys, shared AD server parameters, and related help examples.
Targeted domain and DNS collection
powershell/public/Get-MtADDomainState.ps1
Passes the selected server to domain object, DFS-R, trust, OU, DNS zone, and DNS record queries.
Targeted schema and LDAP collection
powershell/public/Get-MtADDomainState.ps1
Targets schema, printer, LAPS, and DACL LDAP queries using the resolved server.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant Get-MtADDomainState
  participant ActiveDirectory
  participant DNSServer
  Caller->>Get-MtADDomainState: call with optional ComputerName
  Get-MtADDomainState->>ActiveDirectory: query targeted AD data
  Get-MtADDomainState->>DNSServer: query zones and records on resolved server
  ActiveDirectory-->>Get-MtADDomainState: return AD state
  DNSServer-->>Get-MtADDomainState: return DNS state
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly summarizes the main change: adding ComputerName targeting to AD domain state collection.
Description check ✅ Passed The PR description follows the template, includes the closing issue, completed checks, and a brief behavior summary.
Linked Issues check ✅ Passed The changes add host-targeted AD/DNS collection and cache separation, addressing the linked issue’s DNS and config collection needs.
Out of Scope Changes check ✅ Passed The changes stay focused on AD domain state targeting and related docs/examples, with no unrelated scope evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@powershell/public/Get-MtADDomainState.ps1`:
- Line 75: Update the resolved computer name and DACL binding logic around
$resolvedComputerName so omitting -ComputerName preserves the serverless
LDAP://$domainDN path. Only construct an explicit LDAP://$ComputerName/$domainDN
DirectoryEntry with AuthenticationTypes.ServerBind when -ComputerName is
supplied, and apply the same adjustment to the corresponding logic around the
referenced additional locations.
- Around line 15-17: Update the ComputerName documentation in
Get-MtADDomainState to state that it must identify an Active Directory domain
controller or AD DS server, not a DNS-only server. Clarify that DNS collection
uses the same target only when it also supports the required DNS management
access, or introduce separate AD and DNS target parameters if the implementation
supports that scope.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 05d0ce35-7a80-481b-98fc-22a15458718a

📥 Commits

Reviewing files that changed from the base of the PR and between 50595be and 298cc0f.

📒 Files selected for processing (1)
  • powershell/public/Get-MtADDomainState.ps1

Comment on lines +15 to +17
.PARAMETER ComputerName
Specifies the domain controller or DNS server to use when collecting Active Directory and DNS data.
If not specified, commands that require a computer name use the DNS root from the collected domain object.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)Get-MtADDomainState\.ps1$|powershell/public/Get-MtADDomainState\.ps1' || true

echo "== outline =="
ast-grep outline powershell/public/Get-MtADDomainState.ps1 --view compact || true

echo "== relevant lines =="
cat -n powershell/public/Get-MtADDomainState.ps1 | sed -n '1,120p'

echo "== search ComputerName/Server usage =="
rg -n "ComputerName|Select-String|Split-Path|New-Object|Get-ADDomain|Get-ADForest|Get-ADObject|Get-ADComputer|Get-ADUser|Get-ADGroup|Try|Catch|ComputerName" powershell/public/Get-MtADDomainState.ps1

Repository: maester365/maester

Length of output: 11212


🌐 Web query:

Microsoft Learn Get-ADDomain -Server parameter ADDomainController directory server Active Directory module

💡 Result:

The Get-ADDomain cmdlet in the Active Directory PowerShell module does not have a parameter named ADDomainController [1]. To retrieve information about an Active Directory domain, you use Get-ADDomain [1]. If you need to specify which domain controller to query, you use the -Server parameter instead [1]. For example, to retrieve domain information from a specific domain controller, you would use: Get-ADDomain -Server "DCName.domain.com" If you are looking for domain controllers themselves, the correct cmdlet is Get-ADDomainController [2]. This separate cmdlet is designed to retrieve, filter, and list Active Directory domain controllers [2][3]. The two cmdlets serve different purposes: - Get-ADDomain: Retrieves information about an Active Directory domain (e.g., domain functional level, SIDs, FSMO roles) [1][4]. - Get-ADDomainController: Retrieves information about specific domain controller objects (e.g., IP addresses, site names, available services) [2][3].

Citations:


🌐 Web query:

Microsoft Learn Get-DnsServerZone -ComputerName remote DNS server module DnsServer

💡 Result:

The Get-DnsServerZone cmdlet is part of the DnsServer PowerShell module, which is used to manage Domain Name System (DNS) servers on Windows Server [1][2]. This cmdlet allows you to retrieve details about zones hosted on a DNS server [1]. To use Get-DnsServerZone to query a remote DNS server, you can utilize the -ComputerName parameter [1]. When this parameter is specified, it targets the remote DNS server by its IP address, FQDN, host name, or NetBIOS name [1]. If -ComputerName is omitted, the command defaults to the local system [1]. Key information regarding the cmdlet: - Module: DnsServer [1][2] - Requirement: To use these cmdlets, you must have either the DNS Server role installed or the DNS Server Tools (part of Remote Server Administration Tools, or RSAT) installed on your system [2]. - Key Parameter: -ComputerName specifies the remote DNS server to query [1]. - Other Parameters: Supports common parameters like -CimSession, as well as -Name (to specify particular zones) and -VirtualizationInstance (for virtualized DNS partitions) [1]. Example usage to query a remote server: Get-DnsServerZone -ComputerName "RemoteServer01.contoso.com" This command retrieves all zones configured on the DNS server named "RemoteServer01.contoso.com" [1].

Citations:


🌐 Web query:

Microsoft Learn DnsServer module Get-DnsServerZone error Access denied non-DNS Server role remote server

💡 Result:

The "Access denied" error when running Get-DnsServerZone against a remote server is typically caused by insufficient permissions for the user account performing the remote operation, or misconfigured WinRM/CIM session settings [1][2][3]. This error often occurs even if the account is in the DnsAdmins group, because managing DNS remotely via PowerShell requires specific privileges on the remote Windows Management Instrumentation (WMI/CIM) service, not just within the DNS service itself [2]. Recommended troubleshooting steps include: 1. Verify Group Memberships: Ensure the account is a member of the DnsAdmins security group on the remote DNS server [1][2]. Additionally, the account may need to be added to the Remote Management Users group on the target server to allow PowerShell/WinRM access [2]. 2. Verify CIM/WinRM Permissions: Because the DnsServer module relies on CIM sessions, the account must have remote access permissions for WMI/CIM [2][3]. You can verify if the user can manage DNS via the DNS Manager snap-in (GUI) to rule out basic authentication or connectivity issues [1]. 3. Check Zone-Level Permissions: In some environments, simply being in DnsAdmins is insufficient if the specific DNS zone object has restricted access. Ensure the service account has appropriate read/write permissions on the DNS zone objects within Active Directory (for AD-integrated zones) or on the zone files on the disk [2]. 4. Administrative Privilege (Elevation): PowerShell remoting commands often require the process to be run with elevated (Administrator) privileges on the source machine, even if the target account has sufficient rights [4]. 5. Verify Target Configuration: Confirm the target server has the DNS Server role correctly installed and configured [5][6]. The "non-DNS Server role" error message can sometimes indicate that the remote system does not have the necessary DNS provider components registered or active for the CIM session [2]. If you are using implicit remoting or a script, ensure that the -ComputerName parameter is correctly specified in your command, as omitting it may cause the cmdlet to attempt to run locally instead of against the intended remote server [7].

Citations:


🌐 Web query:

Microsoft Learn Active Directory RSAT Remote Server Administration Tools Get-ADDomain Server non domain controller

💡 Result:

To use Active Directory PowerShell cmdlets like Get-ADDomain from a computer that is not a domain controller, you must install the Active Directory module, which is part of the Remote Server Administration Tools (RSAT) [1][2]. The module allows you to manage Active Directory remotely by interacting with the Active Directory Web Services (ADWS) running on a domain controller [2][3]. Installation on Windows 10/11 RSAT is included as a "Feature on Demand" in modern Windows versions [1][4]. You can install only the necessary AD tools using the following methods: 1. Windows Settings: Go to Settings > Apps (or System) > Optional features. Search for "RSAT" and select "RSAT: Active Directory Domain Services and Lightweight Directory Services Tools" [4][5][6]. 2. PowerShell: Run the following command in an elevated PowerShell window [5][7]: Add-WindowsCapability -Online -Name "Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0" Installation on Windows Server (as a Member Server) On Windows Server, you can install the module via Server Manager or PowerShell [8]: - Server Manager: Navigate to Add Roles and Features > Features and select "Active Directory module for Windows PowerShell" under "Remote Server Administration Tools" [8]. - PowerShell: Run the following command in an elevated window [8]: Add-WindowsFeature RSAT-AD-PowerShell Usage and Connectivity Once installed, you can use Get-ADDomain to query your environment [9]. - Default Behavior: The module automatically attempts to connect to the nearest domain controller [2][10]. - Targeting Specific Servers: You can explicitly specify a domain controller using the -Server parameter if you need to target a specific domain or rule out connectivity issues with the automatically discovered DC [2][9][11]. - Requirements: Ensure that the domain controller is running Active Directory Web Services (ADWS) and that TCP port 9389 is open through any firewalls [2][3]. If you receive errors regarding the server, you can verify connectivity with Test-NetConnection -ComputerName -Port 9389 [2].

Citations:


Document that ComputerName targets domain controllers, not DNS-only servers.

ComputerName is passed as Get-AD* -Server, which requires an Active Directory directory server / AD DS host. A DNS-only target can cause the initial AD collection to fail, while Get-DnsServerZone -ComputerName has separate DNS-management permissions/access requirements. Update the help/example to reflect this or expose separate AD and DNS target parameters.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@powershell/public/Get-MtADDomainState.ps1` around lines 15 - 17, Update the
ComputerName documentation in Get-MtADDomainState to state that it must identify
an Active Directory domain controller or AD DS server, not a DNS-only server.
Clarify that DNS collection uses the same target only when it also supports the
required DNS management access, or introduce separate AD and DNS target
parameters if the implementation supports that scope.

Source: MCP tools

CollectionTime = Get-Date
}

$resolvedComputerName = if ($ComputerName) { $ComputerName } else { $domainState.Domain.DNSRoot }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file list candidates =="
fd -a 'Get-MtADDomainState.ps1|Get-MtADDomainState\.ps1' . || true

echo "== target file excerpt =="
file="$(fd 'Get-MtADDomainState.ps1' . | head -n 1)"
if [ -n "${file:-}" ]; then
  wc -l "$file"
  sed -n '1,120p' "$file" | cat -n
  echo "== relevant later excerpt =="
  sed -n '180,240p' "$file" | cat -n
fi

echo "== related LDAP searchroot usages =="
rg -n "LDAP://|SearchRoot|AuthenticationTypes|DirectoryEntry|DNSRoot|Domain\.(DN|DNSRoot|DomainGuid)" -S .

Repository: maester365/maester

Length of output: 14232


🌐 Web query:

Microsoft ADSI DirectoryEntry server-qualified LDAP path ServerBind authentication

💡 Result:

When using the Microsoft ADSI DirectoryEntry class with a server-qualified LDAP path, you should include the AuthenticationTypes.ServerBind flag in your authentication options [1][2][3]. This flag informs ADSI that a specific server has been explicitly defined in the ADsPath, allowing the system to bypass unnecessary and time-consuming network operations such as DNS or WINS lookups that would otherwise be performed to locate a domain controller [2][4]. Key considerations include: - Usage: The ServerBind flag is intended specifically for use when the ADsPath contains a server name (e.g., LDAP://server01/DC=fabrikam,DC=com) [1][2][5]. - Restrictions: It should not be used for serverless paths (e.g., LDAP://DC=fabrikam,DC=com) or paths that include a domain name instead of a server name [1][2][3]. - Performance: Omitting this flag when a server is specified forces ADSI to attempt to resolve the server name using various discovery mechanisms, which often results in significant delays (often several seconds) during the initialization or binding process [2][4]. - Implementation Example (C#): DirectoryEntry entry = new DirectoryEntry("LDAP://server01/CN=Users,DC=fabrikam,DC=com", username, password, AuthenticationTypes.ServerBind); In unmanaged ADSI development, the equivalent flag is ADS_SERVER_BIND, used within the dwReserved parameter of the IADsOpenDSObject::OpenDSObject method [6][7]. Always prioritize using a fully qualified DNS server name (e.g., server01.fabrikam.com) over flat NetBIOS names to ensure reliable Kerberos authentication [6][7].

Citations:


Restore serverless DACL binding when -ComputerName is omitted.

With DNSRoot now used for $resolvedComputerName, the DACL search creates LDAP://<DNSRoot>/<domainDN> without -ComputerName. That replaces the previous serverless path and can break DACL collection when the DNS server is not an LDAP/DC target; keep LDAP://$domainDN for the default path, and use DirectoryEntry with AuthenticationTypes.ServerBind only when constructing an explicit LDAP://$ComputerName/... path.

Proposed binding adjustment
-                $searchRootPath = if ($resolvedComputerName) { "LDAP://$resolvedComputerName/$domainDN" } else { "LDAP://$domainDN" }
-                $searcher.SearchRoot = [ADSI]$searchRootPath
+                $searchRootPath = if ($ComputerName) { "LDAP://$ComputerName/$domainDN" } else { "LDAP://$domainDN" }
+                $searchRoot = if ($ComputerName) {
+                    New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList @(
+                        $searchRootPath, $null, $null,
+                        [System.DirectoryServices.AuthenticationTypes]::ServerBind
+                    )
+                } else {
+                    [ADSI]$searchRootPath
+                }
+                $searcher.SearchRoot = $searchRoot

Also applies to: 214-215

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@powershell/public/Get-MtADDomainState.ps1` at line 75, Update the resolved
computer name and DACL binding logic around $resolvedComputerName so omitting
-ComputerName preserves the serverless LDAP://$domainDN path. Only construct an
explicit LDAP://$ComputerName/$domainDN DirectoryEntry with
AuthenticationTypes.ServerBind when -ComputerName is supplied, and apply the
same adjustment to the corresponding logic around the referenced additional
locations.

Source: MCP tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🪲 AD tests. Missing DNS and Config informations

1 participant