Skip to main content

Windows WMI Scanner Technical Documentation

This document provides comprehensive technical documentation for the NopeSight v3 Windows WMI scanner, covering all WMI classes, data collection methods, network protocols, authentication mechanisms, and security considerations.

Overview

The WMI scanner (wmi_scanner.py) performs comprehensive Windows system discovery using Windows Management Instrumentation (WMI) protocol. It collects hardware specifications, software inventory, network configurations, user accounts, and active network connections to build a complete Windows infrastructure inventory.

The scanner includes an intelligent fallback mechanism using PAExec when WMI ports are blocked by firewalls, ensuring data collection in restrictive network environments.

Core WMI Classes Used

System Information Classes

Win32_ComputerSystem

Purpose: Collects basic system hardware and domain information

Query: Win32_ComputerSystem()

Data Collected:

  • Name: Computer hostname
  • Model: Hardware model designation
  • Manufacturer: System manufacturer (Dell, HP, Lenovo, etc.)
  • Domain: Active Directory domain or workgroup name
  • PartNumber: Hardware part number (when available)
  • NumberOfProcessors: Physical processor count
  • TotalPhysicalMemory: Total system RAM in bytes
  • DomainRole: Domain controller status (0-5 scale)

Win32_ComputerSystemProduct

Purpose: Retrieves friendly model names for hardware identification

Query: Win32_ComputerSystemProduct()

Data Collected:

  • Version: Friendly model name (e.g., "ThinkPad X1 Carbon")
  • Used when manufacturer-specific model names are more descriptive than generic model field

BIOS Information Classes

Win32_BIOS

Purpose: Collects system BIOS and firmware information

Query: Win32_BIOS()

Data Collected:

  • Manufacturer: BIOS manufacturer
  • Version: BIOS version string
  • SerialNumber: System serial number
  • SMBIOSBIOSVersion: SMBIOS BIOS version
  • ReleaseDate: BIOS release date

Operating System Classes

Win32_OperatingSystem

Purpose: Comprehensive OS information and system state

Query: Win32_OperatingSystem()

Data Collected:

  • Caption: OS name (e.g., "Windows Server 2019")
  • Version: OS version number
  • BuildNumber: OS build number
  • OSArchitecture: System architecture (x64, x86)
  • ServicePackMajorVersion: Service pack level
  • SerialNumber: OS product ID
  • InstallDate: OS installation timestamp
  • LastBootUpTime: System last boot time
  • LocalDateTime: Current system time

Hardware Information Classes

Win32_Processor

Purpose: Detailed CPU specifications and capabilities

Query: Win32_Processor()

Data Collected:

  • Name: CPU model name
  • Manufacturer: CPU manufacturer (Intel, AMD)
  • Description: CPU description
  • NumberOfCores: Physical core count
  • NumberOfLogicalProcessors: Logical processor count (includes hyperthreading)
  • MaxClockSpeed: Maximum clock speed in MHz
  • SocketDesignation: CPU socket information
  • L2CacheSize: L2 cache size in KB
  • L3CacheSize: L3 cache size in KB

Win32_PhysicalMemory

Purpose: Physical memory module specifications

Query: Win32_PhysicalMemory()

Data Collected:

  • Capacity: Memory module capacity in bytes
  • Manufacturer: Memory manufacturer
  • Speed: Memory speed in MHz
  • PartNumber: Memory part number
  • DeviceLocator: Physical slot location
  • BankLabel: Memory bank designation
  • MemoryType: Memory type identifier

Storage Classes

Win32_DiskDrive

Purpose: Physical disk drive information

Query: Win32_DiskDrive()

Data Collected:

  • Caption: Drive caption/name
  • Description: Drive description
  • DeviceID: Physical device identifier
  • InterfaceType: Interface type (SATA, NVMe, etc.)
  • Manufacturer: Drive manufacturer
  • Model: Drive model
  • Name: Drive name
  • SerialNumber: Drive serial number
  • Size: Drive capacity in bytes
  • Status: Drive operational status

Win32_LogicalDisk

Purpose: Logical drive and filesystem information

Query: Win32_LogicalDisk()

Data Collected:

  • Name: Drive letter (C:, D:, etc.)
  • Description: Drive description
  • FileSystem: Filesystem type (NTFS, FAT32)
  • Size: Total capacity in bytes
  • FreeSpace: Available space in bytes
  • VolumeName: Volume label

Network Classes

Win32_NetworkAdapter

Purpose: Network interface hardware information

Query: Win32_NetworkAdapter()

Data Collected:

  • Name: Adapter name
  • NetConnectionID: Connection name (e.g., "Ethernet")
  • Description: Adapter description
  • Manufacturer: Network adapter manufacturer
  • MACAddress: MAC address
  • AdapterType: Adapter type designation
  • Speed: Interface speed in bits per second
  • PhysicalAdapter: Boolean indicating physical vs virtual adapter

Win32_NetworkAdapterConfiguration

Purpose: Network interface IP configuration

Query: Win32_NetworkAdapterConfiguration(Index=adapter_index)

Data Collected:

  • IPAddress: Array of IP addresses
  • IPSubnet: Array of subnet masks
  • DefaultIPGateway: Default gateway addresses
  • DHCPEnabled: DHCP configuration status
  • DHCPServer: DHCP server address
  • DNSServerSearchOrder: DNS server list

Network Connection Classes

MSFT_NetTCPConnection (Modern Systems)

Purpose: Active TCP network connections (Windows 8/Server 2012+)

Namespace: root\StandardCimv2
Query: MSFT_NetTCPConnection()

Data Collected:

  • LocalAddress: Local IP address
  • LocalPort: Local port number
  • RemoteAddress: Remote IP address
  • RemotePort: Remote port number
  • State: Connection state (1=CLOSED, 2=LISTEN, 5=ESTABLISHED, etc.)
  • OwningProcess: Process ID owning the connection

Win32_TCPConnection (Legacy Fallback)

Purpose: TCP connections for older Windows systems

Query: Win32_TCPConnection()

Data Collected:

  • LocalIPAddress: Local IP address
  • LocalPort: Local port number
  • RemoteIPAddress: Remote IP address
  • RemotePort: Remote port number
  • ConnectionState: Connection state string
  • ProcessId: Owning process ID

Process Information Classes

Win32_Process

Purpose: Running process information for connection mapping

Query: Win32_Process()

Data Collected:

  • ProcessId: Process identifier
  • Name: Process executable name
  • ExecutablePath: Full path to executable

Display Classes

Win32_VideoController

Purpose: Graphics adapter information

Query: Win32_VideoController()

Data Collected:

  • Name: Graphics adapter name
  • AdapterCompatibility: Adapter compatibility
  • AdapterRAM: Video memory in bytes
  • DriverVersion: Graphics driver version
  • VideoProcessor: Video processor type
  • VideoMemoryType: Memory type
  • CurrentRefreshRate: Current refresh rate
  • MaxRefreshRate: Maximum refresh rate
  • MinRefreshRate: Minimum refresh rate
  • CurrentHorizontalResolution: Current horizontal resolution
  • CurrentVerticalResolution: Current vertical resolution

User Account Classes

Win32_UserAccount

Purpose: Local user account information

Query: Win32_UserAccount WHERE LocalAccount = True

Data Collected:

  • Name: Username
  • FullName: Full display name
  • Caption: Account caption
  • Description: Account description
  • Disabled: Account disabled status
  • LocalAccount: Local vs domain account flag
  • Lockout: Account lockout status
  • PasswordChangeable: Password change permission
  • PasswordExpires: Password expiration policy
  • SID: Security identifier

Win32_SystemUsers (Domain Controllers)

Purpose: Lightweight user enumeration for domain controllers

Query: Win32_SystemUsers()

Data Collected:

  • PartComponent: User reference path containing username

Registry-Based Software Inventory

Registry Paths Queried

The scanner uses registry queries instead of Win32_Product for performance reasons:

Uninstall Registry Keys

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

Registry Provider (StdRegProv)

Purpose: Direct registry access for software inventory

Provider: StdRegProv
Methods: EnumKey(), GetStringValue()

Registry Values Retrieved

  • DisplayName: Software product name
  • Publisher: Software vendor/publisher
  • DisplayVersion: Software version
  • InstallDate: Installation date
  • InstallLocation: Installation directory path

Registry Constants:

  • HKEY_LOCAL_MACHINE = 0x80000002

Network Ports and Protocols

Primary WMI Ports

Port 135 - RPC Endpoint Mapper

  • Protocol: TCP
  • Purpose: Initial RPC endpoint resolution
  • Required: Yes (for WMI connection establishment)
  • Direction: Scanner → Target
  • Security: Often blocked by firewalls

Dynamic RPC Ports (49152-65535)

  • Protocol: TCP
  • Purpose: WMI data transfer after endpoint mapping
  • Required: Yes (for actual WMI queries)
  • Direction: Scanner → Target
  • Security: Frequently blocked, causes most WMI failures

Fallback Protocol Ports

Port 445 - SMB/CIFS

  • Protocol: TCP
  • Purpose: PAExec fallback when WMI ports blocked
  • Required: Only for PAExec fallback
  • Direction: Scanner → Target
  • Security: More commonly allowed than RPC ports

Optional Ports

Port 139 - NetBIOS Session Service

  • Protocol: TCP
  • Purpose: Legacy NetBIOS support
  • Required: No
  • Direction: Scanner → Target

Port 5985 - WinRM HTTP

  • Protocol: TCP
  • Purpose: Windows Remote Management (not used by current scanner)
  • Required: No
  • Direction: Scanner → Target

Port 5986 - WinRM HTTPS

  • Protocol: TCP
  • Purpose: Secure Windows Remote Management (not used by current scanner)
  • Required: No
  • Direction: Scanner → Target

Authentication Methods

Credential Format Support

The scanner attempts multiple credential formats automatically:

Domain\Username Format

# Primary format for domain accounts
credential_format = f"{domain}\\{username}"

Use Case: Active Directory domain authentication Example: CONTOSO\administrator

Username@Domain Format

# Alternative domain format
credential_format = f"{username}@{domain}"

Use Case: UPN-style domain authentication Example: administrator@contoso.com

Username Only Format

# Local account format
credential_format = username

Use Case: Local account authentication Example: administrator

WMI Connection Parameters

Standard WMI Connection

connection = wmi.WMI(
computer=ip,
user=formatted_username,
password=password,
impersonation_level='impersonate'
)

Connection Without Credentials

# Attempted when no credentials provided
connection = wmi.WMI(computer=ip)

Authentication Error Handling

Common WMI Error Codes

  • 0x80070005: Access Denied - Insufficient permissions
  • 0x800706BA: RPC Server Unavailable - Cannot connect to remote computer
  • 0x800706BE: Remote Procedure Call Failed
  • 0x800706D9: Windows Firewall is blocking
  • 0x80070721: Credential conflict
  • 0x80041003: WMI access specifically denied
  • 0x80070035: Network Path Not Found

PAExec Fallback Mechanism

When PAExec is Triggered

PAExec fallback activates when WMI connection fails with RPC-related errors:

Error Indicators

rpc_error_indicators = [
'rpc', 'endpoint', 'port', 'firewall',
'0x800706ba', # RPC server unavailable
'0x800706be', # Remote procedure call failed
'0x800706d9', # Windows Firewall is blocking
'0x80070721', # Credential conflict
'rpc server is unavailable',
'-2147023174', # RPC_S_SERVER_UNAVAILABLE
'-2147023447', # EPT_S_NOT_REGISTERED
'x_wmi', # General WMI connection error
'access is denied',
'0x80070005' # Access denied
]

PAExec Operation

Connection Establishment

from pypsexec.client import Client as PAExecClient

client = PAExecClient(ip, username=username, password=password)
client.connect()
client.create_service()

Command Execution Pattern

stdout, stderr, rc = client.run_executable(
"cmd.exe",
arguments="/c wmic [wmi_class] get [properties] /format:csv"
)

PAExec Data Collection

WMIC Commands Used

# Basic system information
wmic computersystem get Name,Model,Manufacturer,Domain,PartOfDomain,NumberOfProcessors,TotalPhysicalMemory /format:csv

# BIOS information
wmic bios get manufacturer,version,serialnumber,smbiosbiosversion,releasedate /format:csv

# Operating system
wmic os get caption,version,buildnumber,osarchitecture,servicepackmajorversion,serialnumber,installdate,lastbootuptime /format:csv

# Processor information
wmic cpu get name,manufacturer,description,numberofcores,numberoflogicalprocessors,maxclockspeed,socketdesignation,l2cachesize,l3cachesize /format:csv

# Physical memory
wmic memorychip get capacity,manufacturer,speed,partnumber,devicelocator,banklabel /format:csv

# Network adapters
wmic nic where "NetConnectionID is not null" get name,netconnectionid,description,manufacturer,macaddress,speed /format:csv

# Disk drives
wmic diskdrive get caption,description,deviceid,interfacetype,manufacturer,model,name,serialnumber,size,status /format:csv

# Logical disks
wmic logicaldisk where "size is not null" get name,description,filesystem,size,freespace,volumename /format:csv

# Display adapters
wmic path win32_videocontroller get name,adaptercompatibility,adapterram,driverversion,videoprocessor,currentrefreshrate,currenthorizontalresolution,currentverticalresolution /format:csv

# User accounts
wmic useraccount where "localaccount=true" get name,fullname,caption,description,disabled,lockout,passwordchangeable,passwordexpires,sid /format:csv

Network Connection Analysis

Connection State Mapping

MSFT_NetTCPConnection States

state_map = {
1: 'CLOSED',
2: 'LISTEN',
3: 'SYN_SENT',
4: 'SYN_RECEIVED',
5: 'ESTABLISHED',
6: 'FIN_WAIT1',
7: 'FIN_WAIT2',
8: 'CLOSE_WAIT',
9: 'CLOSING',
10: 'LAST_ACK',
11: 'TIME_WAIT',
12: 'DELETE_TCB'
}

Connection Filtering Logic

Server vs Workstation Behavior

def _is_server_os(self, os_info):
"""Determine if the OS is a server version"""
server_patterns = [
'server', 'datacenter', 'enterprise',
'standard', 'essential', 'hyper-v'
]
# Check OS name against server patterns

Connection Collection Rules

  • ESTABLISHED connections: Collected for all systems
  • LISTEN connections: Collected only for server operating systems
  • Local connections: Intentionally included (captures database connections, IPC)

Process-to-Connection Mapping

Process Information Collection

processes = {}
for process in connection.Win32_Process():
processes[process.ProcessId] = {
'name': process.Name,
'path': getattr(process, 'ExecutablePath', '') or ''
}

Connection Data Structure

connection_data = {
'protocol': 'TCP',
'local_address': local_address,
'local_port': local_port,
'remote_address': remote_address,
'remote_port': remote_port,
'state': state,
'process_id': pid,
'process_name': process_info['name'],
'process_path': process_info['path']
}

Security Considerations

Required Permissions

WMI Permissions

  • Distributed COM Users: User must be member of this group
  • WMI Permissions: Explicitly granted in WMI security settings
    • Enable Account permission
    • Remote Enable permission
  • Local Security Policy: "Log on as a service" right may be required

Registry Access

  • Read access to HKEY_LOCAL_MACHINE registry hive
  • Remote Registry service must be running (for software inventory)

Firewall Requirements

Target Windows System

# Enable WMI through Windows Firewall
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)"

# Or manually open ports
New-NetFirewallRule -DisplayName "WMI-In-TCP-135" -Direction Inbound -Protocol TCP -LocalPort 135
New-NetFirewallRule -DisplayName "WMI-In-TCP-Dynamic" -Direction Inbound -Protocol TCP -LocalPort 49152-65535

Scanner System

  • Outbound access to target ports 135, 445, and dynamic RPC range
  • Firewall exceptions for Python WMI process

Credential Security

Credential Handling

  • Credentials stored encrypted using Windows DPAPI
  • No plaintext credential storage
  • Credentials transmitted over encrypted WMI channel

Authentication Flow

  1. Initial RPC connection to port 135
  2. Endpoint mapper returns dynamic port
  3. Authenticated WMI session established
  4. DCOM authentication for each WMI query

Error Handling and Diagnostics

Common Failure Scenarios

RPC/Firewall Issues

# Detected by error message analysis
has_rpc_error = any(indicator in error_str.lower()
for indicator in rpc_error_indicators)

Resolution: Triggers PAExec fallback automatically

Authentication Failures

# Multiple credential formats attempted
formats_to_try = [
f"{domain}\\{username}",
f"{username}@{domain}",
username
]

Resolution: Tries all supported formats before failing

COM Initialization

def _initialize_com(self):
"""Initialize COM for the current thread"""
pythoncom.CoInitialize()

Purpose: Required for each thread using WMI

Performance Optimizations

User Account Limits

max_users = 20  # Standard limit
if domain_role >= 4: # Domain controller
max_users = 5 # Reduced limit

Software Inventory Method

  • Registry-based: Used instead of Win32_Product (much faster)
  • Batch processing: All software enumerated in single registry query

Domain Controller Handling

# Use Win32_SystemUsers for domain controllers (faster)
if domain_role >= 4:
system_users = connection.Win32_SystemUsers()

Troubleshooting Guide

Port Testing Commands

Windows Target System

# Test WMI service status
Get-Service Winmgmt

# Test RPC service status
Get-Service RpcSs

# Test specific port connectivity
Test-NetConnection -ComputerName scanner_ip -Port 135

# Check firewall rules
Get-NetFirewallRule -DisplayGroup "Windows Management Instrumentation*"

Scanner System

# Use built-in WMI tester
python test_wmi_connectivity.py target_ip -u username -p password -d domain

Configuration Fixes

Target System (Run as Administrator)

# Enable WMI through firewall
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)"

# Restart WMI service
Restart-Service Winmgmt -Force

# Check WMI repository integrity
winmgmt /verifyrepository

# Rebuild WMI repository if corrupted
Stop-Service Winmgmt -Force
Remove-Item -Path C:\Windows\System32\wbem\Repository -Recurse -Force
Start-Service Winmgmt

WMI Permissions Configuration

  1. Run wmimgmt.msc as Administrator
  2. Right-click "WMI Control (Local)" → Properties
  3. Security tab → Root → Security
  4. Add scanning user account
  5. Grant "Enable Account" and "Remote Enable" permissions

PAExec Prerequisites

Required Components

  • pypsexec Python package installed
  • paexec.exe executable bundled with scanner
  • Port 445 open between scanner and target

PAExec Service Management

# Service creation on target
client.create_service()

# Command execution
client.run_executable("cmd.exe", arguments="/c command")

# Cleanup
client.remove_service()
client.disconnect()

Integration with NopeSight Platform

Data Upload Format

Scan Result Structure

{
"basic_info": { ... },
"bios": { ... },
"operating_system": { ... },
"processor": { ... },
"physical_memory": [ ... ],
"network_adapters": [ ... ],
"physical_disks": [ ... ],
"logical_disks": [ ... ],
"displays": [ ... ],
"installed_software": [ ... ],
"user_accounts": [ ... ],
"network_connections": [ ... ],
"scan_time": "timestamp"
}

Upload Endpoint

  • URL: https://api.nopesight.com/api/discovery/scan-data
  • Method: POST
  • Authentication: Bearer token
  • Content-Type: application/json

Performance Metrics

Typical Scan Times

  • Workstation (WMI): 30-60 seconds
  • Server (WMI): 45-90 seconds
  • Domain Controller (WMI): 60-120 seconds
  • PAExec Fallback: 90-180 seconds

Resource Usage

  • Memory: 50-100 MB per concurrent scan
  • CPU: Low (I/O bound operations)
  • Network: 1-5 MB data transfer per system

This comprehensive documentation provides system administrators and security analysts with the technical details needed to understand, configure, and troubleshoot the Windows WMI scanner component of the NopeSight v3 platform.