Add computer name targeting to AD domain state#2002
Conversation
📝 WalkthroughWalkthrough
ChangesTargeted domain-state collection
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
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Up to standards ✅🟢 Issues
|
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
powershell/public/Get-MtADDomainState.ps1
| .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. |
There was a problem hiding this comment.
🎯 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.ps1Repository: 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:
- 1: https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-addomain?view=windowsserver2025-ps
- 2: https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-addomaincontroller?view=windowsserver2025-ps
- 3: https://activedirectorypro.com/list-all-domain-controllers-with-powershell/
- 4: https://kyou00.gitbook.io/xyz/commands/view/windows/get-addomain
🌐 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:
- 1: https://learn.microsoft.com/en-us/powershell/module/dnsserver/get-dnsserverzone?view=windowsserver2025-ps
- 2: https://learn.microsoft.com/en-us/powershell/module/dnsserver/?view=windowsserver2025-ps
🌐 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:
- 1: https://learn.microsoft.com/en-us/answers/questions/840790/powershell-remote-dns-server-commands-access-denie
- 2: https://learn.microsoft.com/en-us/archive/msdn-technet-forums/b748d1bb-fa97-4c30-a626-145dfbc40873
- 3: https://stackoverflow.com/questions/26565319/powershell-4-0-remoting-dns-module-from-win-7-pc-to-win-8-1-pc
- 4: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting?view=powershell-7.6
- 5: https://archworks.co/docs/windows-dns-server/
- 6: https://computingforgeeks.com/install-and-configure-dns-server-in-windows-server/
- 7: win_dns_record access is denied because .ps1 is missing -ComputerName ansible-collections/community.windows#303
🌐 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:
- 1: https://learn.microsoft.com/en-us/powershell/module/activedirectory/?view=windowsserver2025-ps
- 2: https://woshub.com/powershell-active-directory-module/
- 3: https://stackoverflow.com/questions/33271201/querying-ad-from-powershell
- 4: https://learn.microsoft.com/en-us/troubleshoot/windows-server/system-management-components/remote-server-administration-tools
- 5: https://theitbros.com/install-and-import-powershell-active-directory-module/
- 6: https://www.digitalcitizen.life/how-to-install-rsat-tools-on-windows-11/
- 7: https://woshub.com/install-rsat-remote-server-admin-tools-windows/
- 8: https://petri.com/install-active-directory-powershell-module-member-server/
- 9: https://learn.microsoft.com/en-us/powershell/module/activedirectory/get-addomain?view=windowsserver2025-ps
- 10: https://stackoverflow.com/questions/78887454/which-dc-do-the-powershell-activedirectory-cmdlets-use-if-none-is-specified
- 11: https://learn.microsoft.com/en-us/archive/msdn-technet-forums/f8eb3d11-6a79-4c0b-a59a-8c90b65557cf
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 } |
There was a problem hiding this comment.
🎯 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:
- 1: https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.authenticationtypes?view=windowsdesktop-9.0
- 2: https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/ldap-session-takes-longer-target-host-names
- 3: https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.authenticationtypes?view=net-11.0-pp
- 4: https://stackoverflow.com/questions/45381486/delay-in-directoryentry-refreshcache
- 5: https://source.dot.net/System.DirectoryServices/System/DirectoryServices/AuthenticationTypes.cs.html
- 6: https://learn.microsoft.com/en-us/windows/win32/adsi/ldap-adspath
- 7: https://learn.microsoft.com/en-us/windows/win32/api/iads/nf-iads-iadsopendsobject-opendsobject
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 = $searchRootAlso 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
📑 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
/powershell/tests/pester.ps1locally.ℹ️ Additional Information
Summary by CodeRabbit
New Features
-ComputerNameparameter to collect Active Directory and DNS state from a specific domain controller or DNS server.Bug Fixes