Windows Server Discovery
The Infracast Windows Server plugin connects to Windows hosts using WinRM (Windows Remote Management) to enumerate server roles, Windows services, IIS websites, and SQL Server instances. Authentication supports both NTLM (username/password) and Kerberos (domain join).
How It Works
- Infracast opens a WinRM session to each target host (default port 5985 for HTTP, 5986 for HTTPS)
- System identity information is collected (hostname, OS version, domain membership)
- Installed Windows roles and features are enumerated
- Running and stopped Windows services are inventoried
- IIS site configuration is collected (if the Web Server role is installed)
- SQL Server instances and databases are enumerated (if SQL Server is installed)
Prerequisites
- WinRM must be enabled on each target Windows Server
- TCP/5985 (HTTP) or TCP/5986 (HTTPS) access from the Infracast collector to each target
- A domain or local account with at minimum:
Remote Management Usersgroup membership (for WinRM)- Read access to WMI (
DCOMpermission — see below)
- PowerShell 5.1 or later on target hosts (default on Windows Server 2016+)
Enabling WinRM on Windows Servers
Run the following on each target server (as Administrator):
# Enable WinRM with default settings
winrm quickconfig -q
# Allow remote management from the Infracast collector IP only
winrm set winrm/config/client/auth '@{Basic="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
# Optional: restrict access to specific IPs via firewall rule
New-NetFirewallRule -DisplayName "Infracast WinRM" `
-Direction Inbound -Protocol TCP -LocalPort 5985 `
-RemoteAddress 10.0.100.50 -Action Allow
# For HTTPS (recommended in production)
winrm set winrm/config/listener '@{Address="*";Transport="HTTPS"}'
Creating a Least-Privilege Account
# Create a local account for Infracast
$password = ConvertTo-SecureString "YourSecurePassword!" -AsPlainText -Force
New-LocalUser -Name "infracast" -Password $password -Description "Infracast Discovery"
# Add to Remote Management Users (WinRM access)
Add-LocalGroupMember -Group "Remote Management Users" -Member "infracast"
# Grant WMI read access via DCOM configuration
# (run as admin in Component Services / dcomcnfg, or use this PowerShell snippet)
$dcom = Get-WmiObject -Class Win32_DCOMApplicationSetting -Filter 'AppID="{72DC1FAF-3A47-4D3C-8C11-E0B5FB558AA4}"'
# Grant local activation/launch/execute to infracast user
# (refer to Microsoft docs for full WMI namespace security configuration)
For domain environments, create a domain service account (e.g., CORP\svc-infracast) and add it to the Remote Management Users group via Group Policy Object across all target servers. This avoids managing local accounts on each host.
Registering the Credential in Infracast
# Local or domain account
infracast creds add \
--plugin windows-server \
--name "windows-servers" \
--type winrm-password \
--username "CORP\\svc-infracast" \
--password-file /run/secrets/winrm-password
# With HTTPS (recommended)
infracast creds add \
--plugin windows-server \
--name "windows-servers-https" \
--type winrm-password \
--username "CORP\\svc-infracast" \
--password-file /run/secrets/winrm-password \
--winrm-use-https true \
--ca-cert-file /run/secrets/corp-ca.pem
Configuring the Discovery Job
discovery:
jobs:
- name: windows-servers
plugin: windows-server
credential: windows-servers
schedule: "0 4 * * *" # nightly at 4 AM UTC
config:
# List of hosts to discover (IP or hostname)
hosts:
- "srv-dc01.corp.example.com"
- "srv-app01.corp.example.com"
- "srv-sql01.corp.example.com"
- "10.0.10.20"
# WinRM port (default: 5985 HTTP, 5986 HTTPS)
winrm_port: 5985
winrm_use_https: false
timeout_seconds: 60
# What to collect
collect:
roles: true
services: true
iis_sites: true
sql_instances: true
What Gets Discovered
| Resource Type | Description |
|---|---|
windows.server | Windows Server host (hostname, OS version/build, domain, total RAM, CPU count, install date) |
windows.role | Installed Windows Server role or feature (name, install state, description) |
windows.service | Windows service (name, display name, state, start type, run-as account, path) |
windows.iis_site | IIS website (name, bindings, state, physical path, app pool) |
windows.sql_instance | SQL Server instance (name, version, edition, service account, collation) |
Edges link roles, services, IIS sites, and SQL instances to their parent windows.server node.
Windows DNS Server
On a host that runs the DNS Server role, the plugin can also read its zones and records through the DnsServer PowerShell module (read-only: Get-DnsServerZone, Get-DnsServerResourceRecord). Turn it on with collect_dns: "true"; dns_only: "true" runs only this step.
| Key | Description |
|---|---|
collect_dns | true to read DNS zones from each host (default false) |
dns_only | true to skip roles, services, IIS and SQL |
dns_zones | Only these zones (default: every zone except auto-created ones) |
dns_include_ds_integrated | true to also read AD-integrated zones (default false; the Active Directory plugin owns those, so they are not recorded twice) |
Result: onprem.dns_zone and onprem.dns_record nodes (A, AAAA, CNAME, NS, PTR, MX, SRV, TXT, SOA; other types are kept visible as "not collected" rather than dropped), with dns_source = windows_dns. A zone that cannot be read, or that returns no records at all, is reported as not collected with the reason and produces no nodes — never an empty zone.
The DNS step is tested on output in the shape the script produces, not against a live Windows DNS Server. Compare one zone you know before relying on it.
On the hosted platform, run this through an on-premises relay (the relay carries the plugin and must be on the same build as the platform).
Troubleshooting
Access is denied or WinRM connection refused
Symptom: Error: WinRM connection failed: access denied or connection refused
Checks:
- Verify WinRM is enabled: run
winrm enumerate winrm/config/listeneron the target - Verify the account is in
Remote Management Usersgroup:net localgroup "Remote Management Users" - Check the Windows Firewall allows TCP/5985 from the collector IP
- Test connectivity manually:
# From the collector (Linux with winrm-client tools)
curl -v http://TARGET:5985/wsman
Unauthorized (authentication failure)
Symptom: Error: WinRM auth failed: 401 Unauthorized
Checks:
- Verify the password has not expired (Windows accounts have password expiry by default)
- If using a domain account, confirm the format:
DOMAIN\\username(double backslash in YAML) - If basic auth is disabled, enable it:
winrm set winrm/config/service/auth '@{Basic="true"}'
IIS sites not discovered
Symptom: The server is discovered but windows.iis_site resources are missing
Cause: IIS is not installed, or the account lacks access to IIS WMI namespaces.
Checks:
- Verify IIS is installed:
Get-WindowsFeature Web-Serveron the target - Ensure the
infracastaccount has access toroot/WebAdministrationWMI namespace
SQL instances not found
Symptom: SQL Server is installed but no windows.sql_instance resources appear
Checks:
- Verify SQL Server is running:
Get-Service MSSQL* - The
infracastaccount needsVIEW ANY DEFINITIONat minimum in SQL Server, or public role access tosys.databases