Modules/ADEHM.ActiveDirectory.psm1
|
#requires -Version 5.1 <# ADEHM.ActiveDirectory.psm1 Active Directory-specific checks: service state (NTDS, DNS, DFSR, Netlogon, KDC, ADWS), SYSVOL/NETLOGON share availability, and site/domain information. This module does not require the RSAT ActiveDirectory module: it relies solely on CIM and lightweight LDAP queries (RootDSE) to minimize prerequisites on the execution host. #> function Get-ADEHMServiceStatus { <# .SYNOPSIS Queries the state of a list of services through the open CIM session. #> [CmdletBinding()] param( [Parameter(Mandatory)] [Microsoft.Management.Infrastructure.CimSession]$CimSession, [Parameter(Mandatory)] [string[]]$ServiceNames ) $filter = ($ServiceNames | ForEach-Object { "Name='$_'" }) -join ' OR ' $services = Get-CimInstance -CimSession $CimSession -ClassName Win32_Service -Filter $filter -ErrorAction Stop $result = @{} foreach ($name in $ServiceNames) { $svc = $services | Where-Object { $_.Name -eq $name } if ($svc) { $result[$name] = [PSCustomObject]@{ Name = $svc.Name State = $svc.State StartMode = $svc.StartMode Running = ($svc.State -eq 'Running') } } else { # Note: on hardened systems a service may be INVISIBLE (not just # stopped) when its security descriptor denies read access to the # caller. See Docs/PERMISSIONS.md, delegation #5. $result[$name] = [PSCustomObject]@{ Name = $name State = 'NotFound' StartMode = $null Running = $false } } } return $result } function Test-ADEHMShare { <# .SYNOPSIS Checks that a network share (e.g. SYSVOL, NETLOGON) is reachable. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$ComputerName, [Parameter(Mandatory)] [string]$ShareName ) $path = '\\{0}\{1}' -f $ComputerName, $ShareName try { return [bool](Test-Path -LiteralPath $path -ErrorAction Stop) } catch { return $false } } function Get-ADEHMDomainInfo { <# .SYNOPSIS Retrieves the domain (via LDAP RootDSE) and the Active Directory site (via nltest) of a domain controller, with no dependency on the RSAT ActiveDirectory module. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$ComputerName ) $domain = $null try { $rootDse = [ADSI]"LDAP://$ComputerName/RootDSE" $dn = $rootDse.Properties['defaultNamingContext'][0] if ($dn) { $domain = (($dn -split ',') | ForEach-Object { $_ -replace '^DC=', '' }) -join '.' } } catch { $domain = $null } $site = $null try { $nltestOutput = & nltest.exe /server:$ComputerName /dsgetsite 2>$null if ($LASTEXITCODE -eq 0 -and $nltestOutput) { $site = ($nltestOutput | Select-Object -First 1).ToString().Trim() } } catch { $site = $null } return [PSCustomObject]@{ Domain = $domain Site = $site } } Export-ModuleMember -Function Get-ADEHMServiceStatus, Test-ADEHMShare, Get-ADEHMDomainInfo |