ADMappingToolkit Hybrid SI mapping — AD inventory + active network scan

PowerShell 5.1+ ActiveDirectory Module Network Scan

ADMappingToolkit is a hybrid SI mapping toolkit. Classic AD-based inventory only sees machines it already knows. In any real enterprise network, AD is structurally incomplete: unmanaged devices, IoT, printers, Linux servers, NAS, and shadow IT never register in AD. ADMappingToolkit closes this visibility gap by combining AD queries with active network probing in a single unified report.

Three runner scripts cover the three most common scopes: all machines, servers only, or clients only. Each script is a thin wrapper around the module functions and exposes the full parameter set directly from the command line.

AD correlation chain

When scanning a raw IP target, the tool does not just report "this IP responded". It runs a full correlation chain:

  1. Reverse DNS lookup (Resolve-DnsName -Type PTR) to retrieve the FQDN
  2. AD lookup by DNSHostName or Name to find a match
  3. If found: entry enriched with OS, OU, LastLogon, and all AD metadata
  4. If not found: a synthetic object is created — the device is flagged as non-AD

A single subnet scan returns both your managed Windows fleet and every unmanaged device on the same network in one report.

Architecture

ADMappingToolkit/
  ADMappingToolkit.psm1       # Module — all functions
  scripts/
    Check-All.ps1             # Wrapper: Get-MachineInventory (all OS)
    Check-Servers.ps1         # Wrapper: Get-ServerInventory (Server OS)
    Check-Clients.ps1         # Wrapper: Get-ClientInventory (Client OS)
  tools/
    Invoke-PSEncoder.py       # Base64 UTF-16LE encoder for -EncodedCommand
    Sign-Scripts.ps1          # Authenticode signing with RFC 3161 timestamp

The module exports three inventory functions. Get-MachineInventory queries all AD computers. Get-ServerInventory and Get-ClientInventory are thin wrappers that pre-filter by OS family before passing the target list to the shared inventory engine.


Installation

Requirements

  • PowerShell 5.1 or PowerShell 7+
  • RSAT ActiveDirectory module (Import-Module ActiveDirectory)
  • Domain-joined machine or explicit -Credential

Clone

# Clone the repo
git clone https://github.com/franckferman/ADMappingToolkit.git
cd ADMappingToolkit

# Unblock if downloaded from the internet
Get-ChildItem -Recurse *.ps1,*.psm1 | Unblock-File

Import the module directly

Import-Module .\ADMappingToolkit.psm1 -Force

The runner scripts import the module automatically from their parent directory. You do not need to import manually when using the scripts.


Quick Start

# 1. Discover all reachable machines in the domain
.\scripts\Check-All.ps1 -OnlyReachable -Stats

# 2. Probe servers for SMB, RDP, WinRM
.\scripts\Check-Servers.ps1 -TcpCheck -Ports 445,3389,5985 -OnlyReachable

# 3. Flag end-of-support workstations
.\scripts\Check-Clients.ps1 -CheckEOS -ShowOU -AutoCsv

# 4. Export full inventory to CSV
.\scripts\Check-All.ps1 -OutCsv inventory.csv

Check-All.ps1

Wrapper for Get-MachineInventory. Queries all AD computer accounts regardless of OS. Use this for full-domain discovery.

.\scripts\Check-All.ps1 [parameters...]

Common invocations

# Reachable machines only, print stats
.\scripts\Check-All.ps1 -OnlyReachable -Stats

# Top 20 port scan, turbo mode (PS7+)
.\scripts\Check-All.ps1 -TcpCheck -Ports Top20 -Turbo

# Unconstrained delegation check
.\scripts\Check-All.ps1 -ADOnly -CheckUnconstrained -ShowOU

# Inactive hosts (not seen in 90 days)
.\scripts\Check-All.ps1 -MinDaysInactive 90 -ADOnly

Check-Servers.ps1

Wrapper for Get-ServerInventory. Pre-filters to AD computers with a Windows Server OS before scanning. Ideal for targeting domain controllers, file servers, and application servers.

.\scripts\Check-Servers.ps1 [parameters...]

Common invocations

# SMB + RDP + WinRM probe
.\scripts\Check-Servers.ps1 -TcpCheck -Ports 445,3389,5985 -OnlyReachable

# LDAP availability check
.\scripts\Check-Servers.ps1 -CheckLDAP -OnlyReachable

# Check WinRM connectivity
.\scripts\Check-Servers.ps1 -CheckWinRM -OnlyReachable

# EOS + unconstrained delegation
.\scripts\Check-Servers.ps1 -ADOnly -CheckEOS -CheckUnconstrained -ShowOU

Check-Clients.ps1

Wrapper for Get-ClientInventory. Pre-filters to AD computers with a Windows client OS (Windows 10/11/7/XP etc.) before scanning.

.\scripts\Check-Clients.ps1 [parameters...]

Common invocations

# Flag end-of-support workstations
.\scripts\Check-Clients.ps1 -CheckEOS -ShowOU -ADOnly

# RDP exposure on clients
.\scripts\Check-Clients.ps1 -Report OpenRDP

# Inactive clients (no logon in 60 days)
.\scripts\Check-Clients.ps1 -MinDaysInactive 60 -ADOnly

# Export all clients to CSV
.\scripts\Check-Clients.ps1 -AutoCsv -ADOnly

Parameters Reference

All three scripts accept the same parameter set.

AD Query

ParameterDefaultDescription
-SearchBase""LDAP OU/DN to scope the AD query. Empty = entire domain.
-IncludeDisabledoffInclude disabled computer accounts in results.
-OnlyDisabledoffReturn only disabled computer accounts.
-MinDaysInactive0Filter to computers inactive for at least N days (0 = no filter).
-TargetsOverride AD query: supply hostnames, IPs, CIDR, ranges, or wildcards.

Network Probing

ParameterDefaultDescription
-NoIcmpoffSkip ICMP ping. Use TCP check or AD-only mode instead.
-PingCount1Number of ICMP echo requests per host.
-TimeoutMs1200TCP connect timeout in milliseconds.
-TcpCheckoffProbe TCP ports defined by -Ports.
-Ports445,3389,5985Comma-separated ports or Top5/Top10/Top20/Top50/Top100 keyword.
-CheckLDAPoffProbe TCP 389 and 636 (LDAP / LDAPS).
-CheckWinRMoffTest WinRM connectivity (Test-WSMan).
-CheckPSSessionoffAttempt New-PSSession to verify remote PS access.
-ResolveDnsoffReverse-resolve IP targets to hostnames for AD correlation.
-ADOnlyoffSkip all network probes, return AD attributes only.

Filtering

ParameterDefaultDescription
-OnlyReachableoffReturn only hosts that responded to ICMP or TCP.
-OnlyUnreachableoffReturn only hosts that did NOT respond.

Performance

ParameterDefaultDescription
-TurbooffEnable ForEach-Object -Parallel scanning. Requires PowerShell 7+. Mutually exclusive with -Stealth.
-Threads50Thread count for Turbo mode (capped at 1000).
-StealthoffSequential scan with random delay between hosts. Disables Turbo automatically.
-StealthDelay2,10Min/max random delay in seconds for Stealth mode. E.g. -StealthDelay 5,20.

AD Enrichment

ParameterDefaultDescription
-CheckUnconstrainedoffRetrieve TrustedForDelegation attribute. Flag machines with unconstrained delegation.
-CheckEOSoffFlag end-of-support OS (Windows XP, 7, 2003, 2008, etc.).
-ShowOUoffInclude OU path in output.
-ShowDescriptionoffInclude AD computer description field.
-ShowEnabledoffInclude Enabled column.
-CredentialPSCredential for AD queries and WinRM checks.

Output

ParameterDefaultDescription
-Properties*Select specific columns from the result set.
-RawOutputoffReturn raw PSObject array (pipeline-friendly). Suppresses table formatting.
-StatsoffPrint summary line: total / reachable / unreachable / reachability %.
-AutoCsvoffAuto-generate timestamped CSV filename and export.
-OutCsv""Export results to specified CSV path.

Reports

ParameterDefaultDescription
-ReportNamed report: Inactive or OpenRDP.
-ReportDays30Lookback window in days for the Inactive report.

Port Keywords

Pass a keyword to -Ports instead of a manual list. Setting a Top keyword automatically enables -TcpCheck.

KeywordPorts
Top521, 22, 80, 443, 3389
Top10Top5 + 25, 53, 135, 139, 445
Top20Top10 + 110, 143, 389, 1433, 3306, 5900, 5985, 8080, 8443
Top50Top20 + 23, 69, 88, 111, 119, 161, 162, 179, 199, …
Top100Top50 + 1025, 1194, 1521, 1723, 2000, 2049, 4444, 5432, …

Target Formats

The -Targets parameter bypasses the AD query and accepts mixed input:

FormatExampleBehavior
Hostname / AD nameDC01Queried directly in AD by name.
WildcardSRV-*AD filter: Name -like 'SRV-*'.
Single IP192.168.1.10Probed directly; optional PTR reverse lookup.
CIDR192.168.1.0/24All host IPs in range (capped at 65536).
IP range192.168.1.1-50Short range: resolves to .1 through .50.
IP range (full)10.0.0.1-10.0.0.100Full range between two IPs.
# Mixed: wildcard + CIDR
.\scripts\Check-All.ps1 -Targets SRV-*, 192.168.10.0/24 -TcpCheck -Ports 445,3389

# IP range with DNS reverse lookup
.\scripts\Check-All.ps1 -Targets 10.0.0.1-50 -ResolveDns -TcpCheck

Reports

Inactive

Returns machines whose last logon is older than -ReportDays days (default 30).

.\scripts\Check-All.ps1 -Report Inactive -ReportDays 90 -ADOnly

OpenRDP

Returns machines with TCP 3389 open. Automatically enables -TcpCheck and adds port 3389 to the probe list if missing.

.\scripts\Check-Clients.ps1 -Report OpenRDP
.\scripts\Check-Servers.ps1 -Report OpenRDP -OnlyReachable

AD Recon Examples

# Full domain inventory, AD attributes only
.\scripts\Check-All.ps1 -ADOnly -ShowOU -ShowDescription -ShowEnabled

# Find computers with unconstrained delegation
.\scripts\Check-All.ps1 -ADOnly -CheckUnconstrained -ShowOU

# Scope to a specific OU
.\scripts\Check-Servers.ps1 -SearchBase "OU=Servers,DC=corp,DC=local" -ADOnly

# Hosts inactive for 30+ days, export CSV
.\scripts\Check-All.ps1 -Report Inactive -ReportDays 30 -ADOnly -AutoCsv

# Use alternate credentials
$cred = Get-Credential
.\scripts\Check-All.ps1 -ADOnly -Credential $cred

Network Scan Examples

# Ping sweep + TCP Top20
.\scripts\Check-All.ps1 -TcpCheck -Ports Top20 -OnlyReachable -Stats

# LDAP availability on all servers
.\scripts\Check-Servers.ps1 -CheckLDAP -OnlyReachable

# WinRM + PSSession check
.\scripts\Check-Servers.ps1 -CheckWinRM -CheckPSSession -OnlyReachable

# Pure IP range scan (no AD)
.\scripts\Check-All.ps1 -Targets 192.168.1.0/24 -TcpCheck -Ports 445,3389 -Turbo

# RDP exposure report across all clients
.\scripts\Check-Clients.ps1 -Report OpenRDP -Stats

Stealth Examples

Note: -Stealth disables Turbo automatically. Sequential probes with random delay reduce detection surface at the cost of scan speed.
# Slow sweep, 5-15 s random delay between hosts
.\scripts\Check-All.ps1 -Stealth -StealthDelay 5,15 -OnlyReachable

# Stealth + no ICMP (TCP-only, even less noise)
.\scripts\Check-All.ps1 -Stealth -NoIcmp -TcpCheck -Ports 445

# Stealth on a specific target range
.\scripts\Check-All.ps1 -Targets SRV-* -Stealth -StealthDelay 10,30

Export Examples

# Auto-generate timestamped CSV
.\scripts\Check-All.ps1 -AutoCsv

# Explicit output path
.\scripts\Check-Servers.ps1 -OutCsv C:\Audit\servers.csv -TcpCheck -Ports 445,3389,5985

# Select specific columns
.\scripts\Check-All.ps1 -ADOnly -Properties Name,OS,LastLogon,OU -OutCsv names.csv

# Pipeline: filter and export in PS
$r = .\scripts\Check-All.ps1 -RawOutput -TcpCheck -Ports 3389
$r | Where-Object { $_.TCP_3389 } | Export-Csv rdp-exposed.csv -NoTypeInformation

Use Cases

For security teams / RSSI

NeedHow
How many machines are on the network?-Targets 10.0.0.0/24 -ResolveDns -Turbo
Do we have end-of-support OS?-CheckEOS flags XP, Vista, 7, 2003, 2008, 2012
Which servers have RDP exposed?-Report OpenRDP
Ghost machines inactive for 90+ days?-MinDaysInactive 90 -ADOnly
Can we remotely administer a host?-CheckWinRM -CheckPSSession
Kerberos unconstrained delegation risk?-CheckUnconstrained
ISO 27001 / ANSSI asset inventory?Full subnet scan + -AutoCsv for timestamped evidence
Shadow IT / unmanaged devices?Non-AD objects returned as synthetic entries in same report

Real-world results

Scan of a /24 subnet (254 hosts) in a production environment:

CategoryCountDetails
Total responding hosts126Out of 254 scanned
Windows machines (AD-matched)~50Workstations and servers enriched with OS, OU, LastLogon
Non-AD devices~76Printers, Raspberry Pi, NAS, Linux servers, IoT, appliances, smartphones
EOS servers detected2Windows Server 2012 R2, Windows Server 2008 R2

In one command: a complete 360-degree view of the network — managed and unmanaged alike.


Security Context

Unconstrained Kerberos Delegation (-CheckUnconstrained)

Unconstrained delegation (TrustedForDelegation = True) is a Kerberos configuration that allows a service to impersonate any authenticated user to any other service in the domain. When a user authenticates to a host configured with unconstrained delegation, the domain controller embeds a full copy of the user's TGT (Ticket Granting Ticket) in the service ticket. The receiving host can then use that TGT to request service tickets on behalf of the user — without restriction.

Attack path: if an attacker compromises a host with unconstrained delegation and forces a privileged account (e.g., a Domain Controller computer account) to authenticate to it — via printer bug, PetitPotam, or coercion — the attacker captures a TGT for that account. A DC TGT enables a DCSync attack and full domain compromise.

Detection: -CheckUnconstrained queries TrustedForDelegation from AD. Any non-DC computer with this flag set is a high-risk finding. Domain Controllers legitimately carry this attribute — filter them out. Remediation: switch to constrained delegation (msDS-AllowedToDelegateTo) or resource-based constrained delegation (RBCD).

End-of-Support Operating Systems (-CheckEOS)

Microsoft end-of-support (EOS) dates mark the point after which no security patches are issued for a product. EOS systems accumulate unpatched CVEs indefinitely. The vulnerability surface grows with every new public disclosure while the system remains permanently exposed.

OSEnd of SupportKnown CVE exposure
Windows XPApril 2014MS17-010 (EternalBlue), MS08-067, dozens of unpatched RCEs
Windows VistaApril 2017EternalBlue, EternalRomance, multiple privilege escalations
Windows 7January 2020EternalBlue, PrintNightmare (partial), BlueKeep (CVE-2019-0708)
Windows Server 2003July 2015MS17-010, MS08-067, multiple unpatched RPC and SMB RCEs
Windows Server 2008 (R2)January 2020EternalBlue, PrintNightmare, Zerologon (CVE-2020-1472)
Windows Server 2012 (R2)October 2023Growing unpatched CVE backlog post-EOL
EOS machines are often high-value targets for initial access and lateral movement precisely because exploitation is trivial and reliable — the vulnerability is permanent and public. ISO 27001 and ANSSI guidelines both require tracking and remediating EOS systems.

RDP Exposure (-Report OpenRDP)

TCP 3389 (Remote Desktop Protocol) exposed on workstations and servers is one of the most targeted attack surfaces in enterprise environments. RDP brute-force, credential stuffing, and unauthenticated pre-auth vulnerabilities (BlueKeep, CVE-2019-0708; DejaBlue, CVE-2019-1181/1182) have driven widespread ransomware deployments.

The OpenRDP report identifies all hosts with TCP 3389 open and reachable, regardless of whether they are in AD. This includes workstations with RDP inadvertently enabled, servers with RDP exposed to internal segments, and legacy hosts.

Remediation priorities: restrict RDP access via firewall rules or Windows Firewall GPO, enforce NLA (Network Level Authentication), disable RDP on hosts that do not require it, and audit all machines with RDP open against an authorized list.

Stealth Mode and Detection Evasion (-Stealth)

Standard sequential network scanning generates predictable, high-volume traffic patterns. ICMP sweeps produce a burst of echo requests from a single source IP to sequential destinations — a trivial signature for IDS, SIEM correlation rules, and NDR (Network Detection and Response) products.

Stealth mode applies two mitigations:

  • Random scan order (Sort-Object { Get-Random }): avoids the sequential sweep signature that IDS/SIEM rules commonly alert on
  • Random inter-host delay (-StealthDelay): reduces packets-per-second rate, staying below typical threshold-based alerting

Turbo mode (parallel scanning) is intentionally incompatible with Stealth — the two objectives are irreconcilable. OPSEC takes priority: if both are set, Turbo is disabled with an explicit warning.

MITRE ATT&CK Mapping

TechniqueIDADMappingToolkit feature
Remote System DiscoveryT1018AD enumeration, -Targets subnet/range scan
Network Service ScanningT1046-TcpCheck, -CheckLDAP, -CheckWinRM, -CheckPSSession
System Network Configuration DiscoveryT1016-ResolveDns, IPv4Address, DNSHostName enumeration
Account Discovery: Domain AccountT1087.002AD computer account enumeration via Get-ADComputer
Domain Trust DiscoveryT1482-CheckUnconstrained (TrustedForDelegation)
Steal or Forge Kerberos TicketsT1558Unconstrained delegation detection context

Invoke-PSEncoder.py

Generates PowerShell -EncodedCommand oneliners from a PS1 file or a raw string. The encoded command is Base64 UTF-16LE, which bypasses Restricted and AllSigned execution policies because PowerShell treats it as an in-memory string, not a file read from disk.

# Encode a script file
python3 tools/Invoke-PSEncoder.py scripts/Check-All.ps1

# Encode a raw command string
python3 tools/Invoke-PSEncoder.py -c ".\scripts\Check-All.ps1 -OnlyReachable -Stats"

# Add flags
python3 tools/Invoke-PSEncoder.py scripts/Check-All.ps1 --hidden --bypass

# Quiet mode (oneliner only, no decoration)
python3 tools/Invoke-PSEncoder.py -q -c ".\scripts\Check-All.ps1 -TcpCheck -Ports Top20"

# Copy to clipboard on Linux
python3 tools/Invoke-PSEncoder.py scripts/Check-All.ps1 | xclip -selection clipboard
FlagDescription
filePath to a PS1 file to encode.
-c / --commandInline PowerShell command string to encode.
--hiddenAppend -WindowStyle Hidden.
--bypassAppend -ExecutionPolicy Bypass.
--32Use 32-bit PowerShell (SysWOW64).
--noexitAppend -NoExit.
-q / --quietOutput only the oneliner.

Sign-Scripts.ps1

Signs all scripts in scripts/ and ADMappingToolkit.psm1 with Authenticode + RFC 3161 timestamp. The countersignature keeps signatures valid after certificate expiry.

Authenticode signing reduces detection surface: signed scripts bypass AllSigned execution policy without -ExecutionPolicy Bypass, and a valid signature lowers static heuristic scores in EDRs and AV engines that weigh unsigned scripts more aggressively.

# Auto-generate temporary self-signed cert, sign, then remove cert
.\tools\Sign-Scripts.ps1

# Use an existing cert by thumbprint
.\tools\Sign-Scripts.ps1 -CertThumbprint "AB12CD..."

# Use a different timestamp server
.\tools\Sign-Scripts.ps1 -TimestampServer "http://timestamp.sectigo.com"

Cert type comparison

Cert typeExecution policySmartScreenEDR static score
NoneRequires -ExecutionPolicy BypassFlaggedHigher risk weight
Self-signedPasses AllSigned if cert is trusted locallyStill flaggedSlight improvement
OV code-signingPasses AllSignedReduced warningsLower risk weight
EV code-signingPasses AllSignedInstant reputationBest reduction
For meaningful evasion improvement, use an OV or EV certificate (DigiCert, Sectigo, GlobalSign). EV certs provide instant SmartScreen reputation and the strongest reduction in static detection. Self-signed certs only help with execution policy enforcement, not publisher trust.