Skip to main content

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​

  1. Infracast opens a WinRM session to each target host (default port 5985 for HTTP, 5986 for HTTPS)
  2. System identity information is collected (hostname, OS version, domain membership)
  3. Installed Windows roles and features are enumerated
  4. Running and stopped Windows services are inventoried
  5. IIS site configuration is collected (if the Web Server role is installed)
  6. 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 Users group membership (for WinRM)
    • Read access to WMI (DCOM permission — 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)
tip

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​

infracast.yaml
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 TypeDescription
windows.serverWindows Server host (hostname, OS version/build, domain, total RAM, CPU count, install date)
windows.roleInstalled Windows Server role or feature (name, install state, description)
windows.serviceWindows service (name, display name, state, start type, run-as account, path)
windows.iis_siteIIS website (name, bindings, state, physical path, app pool)
windows.sql_instanceSQL 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.

KeyDescription
collect_dnstrue to read DNS zones from each host (default false)
dns_onlytrue to skip roles, services, IIS and SQL
dns_zonesOnly these zones (default: every zone except auto-created ones)
dns_include_ds_integratedtrue 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.

Not verified against a live server

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:

  1. Verify WinRM is enabled: run winrm enumerate winrm/config/listener on the target
  2. Verify the account is in Remote Management Users group: net localgroup "Remote Management Users"
  3. Check the Windows Firewall allows TCP/5985 from the collector IP
  4. 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:

  1. Verify the password has not expired (Windows accounts have password expiry by default)
  2. If using a domain account, confirm the format: DOMAIN\\username (double backslash in YAML)
  3. 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:

  1. Verify IIS is installed: Get-WindowsFeature Web-Server on the target
  2. Ensure the infracast account has access to root/WebAdministration WMI namespace

SQL instances not found​

Symptom: SQL Server is installed but no windows.sql_instance resources appear

Checks:

  1. Verify SQL Server is running: Get-Service MSSQL*
  2. The infracast account needs VIEW ANY DEFINITION at minimum in SQL Server, or public role access to sys.databases