Windows Remote
The Windows Remote Collector gathers various Windows basic metrics and objects remotely via WMI or SNMP, and uploads the data to help monitor and analyze Windows system anomalies.
Configuration¶
Prerequisites¶
- Windows 2008 R2 or later
- For SNMP collection:
- SNMP service must be enabled on Windows (Only SNMP v2c is supported by the collector)
Enabling Windows SNMP Service¶
Complete steps to install the SNMP service, configure access permissions, and firewall rules via PowerShell. Full commands:
# Install service
Install-WindowsFeature -Name 'SNMP-Service'
# Configure community string
$regPath = "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\ValidCommunities"
New-ItemProperty -Path $regPath -Name "datakit" -PropertyType DWord -Value 4 -Force
# Configure allowed hosts
$allowedHostsPath = "HKLM:\SYSTEM\CurrentControlSet\services\SNMP\Parameters\PermittedManagers"
New-ItemProperty -Path $allowedHostsPath -Name "1" -PropertyType String -Value "192.168.1.0" -Force
# Configure firewall
netsh advfirewall firewall add rule name="datakit-snmp" dir=in action=allow protocol=UDP localport=161
# Restart service
Restart-Service SNMP
Key Notes:
- Must be executed in PowerShell with Administrator privileges
- Community string must match
inputs.windows_remote.snmp.community
in the collector's configuration file. Recommended value:datakit
- Replace
192.168.1.0
with actual client IP/subnet (e.g.,10.10.1.0/24
). To allow all IPs: Use-Name "*"
- Firewall rule: Opens UDP port 161 (standard SNMP port). Rule name
datakit-snmp
can be customized - Restart service to apply configurations
Use the following PowerShell commands to validate configurations:
# Check service status (ensure status is "Running")
Get-Service -Name "SNMP Service"
# View firewall rules
netsh advfirewall firewall show rule name="datakit-snmp"
# Optional: Verify connectivity using SNMP client tools
snmpwalk -v 2c -c datakit <Local_IP> .1.3.6.1.2.1.1.1.0
"In conf.d/windows_remote.conf
, set the mode
configuration option to snmp
to enable the SNMP collector functionality."
Collector Configuration¶
Go to the conf.d/windows_remote
directory under the DataKit installation directory, copy windows_remote.conf.sample
and name it windows_remote.conf
. Examples are as follows:
[[inputs.windows_remote]]
## Network discovery configuration
ip_list = [ ] # e.g. ["127.0.0.1"]
cidrs = [ ] # e.g. ["10.100.1.0/24"]
scan_interval = "10m"
## Set to 'true' to enable election.
election = true
## Maximum number of workers. Default value is calculated as datakit.AvailableCPUs * 2 + 1.
worker_num = 0
## Select mode 'wmi' or 'snmp'
mode = "wmi"
## WMI Collection Module
[inputs.windows_remote.wmi]
port = 135 # Port for WMI (DCOM 135)
log_enable = true
## Authentication configuration
[inputs.windows_remote.wmi.auth]
username = "user"
password = "password"
## SNMP Collection Module (Independent configuration)
[inputs.windows_remote.snmp]
ports = [ 161 ] # SNMP ports (default 161)
community = "datakit"
[inputs.windows_remote.tags]
# "some_key" = "some_value"
After configuration, restart DataKit.
The collector can now be turned on by configMap injection collector configuration.
WMI Collection Guide¶
1 Prerequisites
Ensure the following services are running:
- Service name for Windows Management Instrumentation (WMI):
winmgmt
- Service name for Remote Procedure Call (RPC):
RpcSs
- PowerShell version is 4.0 or above.
- The Windows Server version from which data is collected is 2008 or above.
- The Windows server used for installing the DataKit collector must be
2012R2
or above.
2 Firewall Configuration
Run PowerShell as Administrator and execute these commands:
# Allow WMI DCOM communication
New-NetFirewallRule -DisplayName "WMI_DCOM" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow -Program "%SystemRoot%\system32\svchost.exe" -Service rpcss
# Allow WMI service communication (dynamic ports)
New-NetFirewallRule -DisplayName "WMI_Service" -Direction Inbound -Protocol TCP -LocalPort Any -Action Allow -Program "%SystemRoot%\system32\svchost.exe" -Service winmgmt
# Allow WMI Unsecured Application communication
New-NetFirewallRule -DisplayName "WMI_UnsecApp" -Direction Inbound -Action Allow -Program "%SystemRoot%\system32\wbem\unsecapp.exe"
3 User Permission Setup
Run this PowerShell script to create a dedicated user and grant WMI access:
<#
Copy and modify from https://github.com/grbray/PowerShell/blob/main/Windows/Set-WMINameSpaceSecurity.ps1
#>
$UserName = "datakit"
$password = "xxxxxxxxxxxxx" | ConvertTo-SecureString -AsPlainText -Force
$namespaces = "root/cimv2", "root/wmi"
$allowInherit = $false
$deny = $false
$computerName = "."
<#delete datakit user#>
try {
$ExistingUser = Get-LocalUser -Name $UserName -ErrorAction SilentlyContinue
if ($ExistingUser) {
Write-Host "[1] delete $UserName ..."
Remove-LocalUser -Name $UserName -Confirm:$false
Start-Sleep -Seconds 1
}
} catch {
throw "delete user err: $_"
}
<#create user datakit.#>
New-LocalUser -Name $UserName -Password $password -Description "user datakit for remote_wmi" -AccountNeverExpires
<# Add groups.#>
Add-LocalGroupMember -Group "Administrators" -Member $UserName
Write-Host "Member Of Administrators"
Add-LocalGroupMember -Group "Distributed COM Users" -Member $UserName
Write-Host "Member Of DCOM"
Add-LocalGroupMember -Group "Performance Monitor Users" -Member $UserName
Write-Host "Member Of Perform"
Add-LocalGroupMember -Group "Event Log Readers" -Member $UserName
Write-Host "Member Of log"
if ($PSBoundParameters.ContainsKey("Credential")) {
$remoteparams = @{ComputerName=$computerName;Credential=$credential}
} else {
$remoteparams = @{ComputerName=$computerName}
}
$computerName = (Get-WmiObject @remoteparams Win32_ComputerSystem).Name
<#1:Enable, 2:MethodExecute, 0x20:RemoteAccess#>
$accessMask = 0x23
$domain = $computerName
<# add wmi namespace #>
foreach ($namespace in $namespaces){
$invokeparams = @{Namespace=$namespace;Path="__systemsecurity=@"} + $remoteParams
$output = Invoke-WmiMethod @invokeparams -Name GetSecurityDescriptor
if ($output.ReturnValue -ne 0) {
throw "GetSecurityDescriptor failed: $($output.ReturnValue)"
}
$acl = $output.Descriptor
$OBJECT_INHERIT_ACE_FLAG = 0x1
$CONTAINER_INHERIT_ACE_FLAG = 0x2
$getparams = @{Class="Win32_Account";Filter="Domain='$domain' and Name='$UserName'"}
$win32account = Get-WmiObject @getparams
if ($win32account -eq $null) {
throw "Account was not found: $UserName"
}
$ace = (New-Object System.Management.ManagementClass("win32_Ace")).CreateInstance()
$ace.AccessMask = $accessMask
Write-Host "add Enable,MethodExecute,RemoteAccess for ns:'${namespace}' user:'${UserName}'"
if ($allowInherit) {
$ace.AceFlags = $CONTAINER_INHERIT_ACE_FLAG
} else {
$ace.AceFlags = 0
}
$trustee = (New-Object System.Management.ManagementClass("win32_Trustee")).CreateInstance()
$trustee.SidString = $win32account.Sid
$ace.Trustee = $trustee
$ACCESS_ALLOWED_ACE_TYPE = 0x0
$ACCESS_DENIED_ACE_TYPE = 0x1
if ($deny) {
$ace.AceType = $ACCESS_DENIED_ACE_TYPE
} else {
$ace.AceType = $ACCESS_ALLOWED_ACE_TYPE
}
$acl.DACL += $ace.psobject.immediateBaseObject
$setparams = @{Name="SetSecurityDescriptor";ArgumentList=$acl.psobject.immediateBaseObject} + $invokeParams
$output = Invoke-WmiMethod @setparams
if ($output.ReturnValue -ne 0) {
throw "SetSecurityDescriptor failed: $($output.ReturnValue)"
}
}
4 Connectivity Verification
Run this command to test WMI access:
✅ Expected Result: Returns the target host's Name
information.
At this point, the machine being collected has been configured.
DataKit Deployment¶
1. Create User Permissions¶
Objective: Create a dedicated user datakit
with WMI permissions to serve as the service startup account.
-
Execute the User Creation Script
After running the provided script, the system will automatically create the userdatakit
and grant it WMI operation permissions. -
Verify User Permissions
Ensure the user has the following permissions:
- Remote WMI access permissions
- "Log on as a service" permission (to be configured in later steps)
2. Installation and Configuration¶
Objective: Complete DataKit installation and configure WMI collection mode.
-
Install via Official Script
After executing the installation command, DataKit will be deployed by default to:
C:\Program Files\datakit
-
Modify Collector Configuration
Edit the configuration file:
C:\Program Files\datakit\conf.d\windows_remote\windows_remote.conf
3. Configure Service Permissions¶
Key Notes:
The DataKit service must be started using the dedicated account datakit
, which requires the "Log on as a service" permission.
Method 1: GUI
- Open Services Manager (
services.msc
) - Find
datakit.ext
→ Right-click Properties - Go to Log On tab → Select This account • Account format:
.\datakit
(local) orDomain\User
- Enter the password and confirm
Method 2: PowerShell
Add user : Log On as a service
, and change datakit
server:
$username = ".\datakit"
$password = 'xxxxxxxxx'
$service = Get-WmiObject win32_service -filter "DisplayName like 'datakit'"
Set-ExecutionPolicy Bypass -Scope Process
function Add-ServiceLogonRight {
param (
[Parameter(Mandatory)]
[string]$Username
)
try {
$tempPath = [System.IO.Path]::GetTempFileName()
$tmpFile = New-Item -Path $tempPath -ItemType File -Force
secedit /export /cfg "$tmpFile.inf" | Out-Null
$content = Get-Content "$tmpFile.inf" -Encoding ASCII
if ($content -match "^SeServiceLogonRight\s*=") {
$content = $content -replace "^SeServiceLogonRight\s*=.*", "`$0, $Username"
} else {
$content += "`r`nSeServiceLogonRight = $Username"
}
$content | Set-Content "$tmpFile.inf" -Encoding ASCII
secedit /import /cfg "$tmpFile.inf" /db "$tmpFile.sdb" | Out-Null
secedit /configure /db "$tmpFile.sdb" /cfg "$tmpFile.inf" | Out-Null
Write-Host " user $Username add to Log on as a server"
}
catch {
Write-Error " error: $_"
}
finally {
Remove-Item "$tmpFile*" -Force -ErrorAction SilentlyContinue
}
}
Add-ServiceLogonRight -Username "datakit"
# Stop the service if it's running
if ($service.State -eq "Running") {
Write-Host "Stopping service $($service.DisplayName)..."
$stopResult = $service.StopService()
if ($stopResult.ReturnValue -eq "0") {
Write-Host "$($service.DisplayName) stopped successfully."
} else {
Write-Warning "Failed to stop $($service.DisplayName). Return Value: $($stopResult.ReturnValue). Proceeding with credential change."
}
# Wait a short time after stopping
Start-Sleep -Seconds 15
}
Start-Sleep -Seconds 3 # Wait before attempting to change
$returnValue = $service.Change($Null,$Null,$Null,$Null,$Null,$Null,$username,$password,$Null,$Null,$Null)
Write-Host "return value is $($returnValue.ReturnValue)"
if ($returnValue.ReturnValue -eq "0") {
Write-Host "Successfully changed credentials for $($service.DisplayName)"
} elseif ($returnValue.ReturnValue -eq "15") {
Write-Warning "Service database is locked for $($service.DisplayName). Retrying in 10 seconds..."
Start-Sleep -Seconds 10
$returnValue = $service.Change($Null,$Null,$Null,$Null,$Null,$Null,$username,$password)
if ($returnValue.ReturnValue -eq "0") {
Write-Host "Successfully changed credentials for $($service.DisplayName) after retry"
} else {
Write-Error "Failed to change credentials for $($service.DisplayName) after retry. Return Value: $($returnValue.ReturnValue)"
}
} else {
Write-Error "Failed to change credentials for $($service.DisplayName). Return Value: $($returnValue.ReturnValue)"
}
$service.StartService()
Verify Deployment Results¶
- Check Service Status
Confirm that the service status is Running.
- View Collected Metrics
The output should include WMI-related metrics (e.g., data from the windows_remote
collector).
- Troubleshoot with Logs
Inspect the log files at:
C:\Program Files\datakit\log
Appendix¶
When querying host performance metrics via the WMI (Windows Management Instrumentation) protocol, the following classes are utilized:
Class Name | DataKit | type |
---|---|---|
Win32_PerfFormattedData_PerfOS_Processor | cpu | metric |
win32_Processor | host_object cpu | object |
Win32_LogicalDisk | host_object disk | object |
Win32_OperatingSystem | host_object system | object |
Win32_OperatingSystem | mem | object |
Win32_PerfFormattedData_Tcpip_NetworkInterface | net | metric |
Win32_PerfFormattedData_PerfDisk_PhysicalDisk | diskio | metric |
Win32_PerfFormattedData_PerfProc_Process | host_processes | object |
Win32_Process | host_processes | object |
Win32_NTLogEvent | log | logging |
Query these classes to verify metrics:
# Retrieve CPU metric information
Get-CimInstance -ClassName Win32_PerfFormattedData_PerfOS_Processor | Select-Object *
# Retrieve System information
Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object *
# And so on...
Special queries for metrics:
- When querying
Win32_NetworkAdapterConfiguration
, use the query parameterwhere IPEnabled = TRUE
to ensure the network adapter status. - When querying
Win32_LogicalDisk
, specify local disks withwhere DriveType=3
. - When querying disk performance metrics from
Win32_PerfFormattedData_PerfDisk_PhysicalDisk
, usewhere Name = '_Total'
. - For CPU performance metrics from
Win32_PerfFormattedData_PerfOS_Processor
, usewhere Name = '_Total'
.
All queries are executed within the namespace root\cimv2
.