Sysmon Configuration with DSC
As part of a project I’m working on I was asked to install and configure Sysmon on all servers using DSC (Azure Automation DSC in this case) After a bit of effort I came up with the following
Configuration xSysmon { param ( [string] $SourcePath = "", [string] $LocalPath = "", [string] $ConfigFileName = "" )
The name of the configuration (composite) and the parameters it accepts
Service sysmonService { Name = "Sysmon" State = "Running" DependsOn = "[Script]sysmonScriptInstall" }
A check to make sure that the sysmon service is running, if not it will put it into a running state (and will run the sysmonScriptInstall directive first)
Script sysmonScriptUpgrade { GetScript = { Get-FileHash "C:\Windows\sysmon.exe", "$($Using:LocalPath)\current-$($Using:ConfigFileName)" } TestScript = { # check if there is a newer version of sysmon $hash = Get-FileHash "C:\Windows\sysmon.exe", "$($Using:LocalPath)\sysmon64.exe" if ($hash[0].hash -eq $hash[1].hash) { # check if there is a newer version of the configuration if( Test-Path "$($Using:LocalPath)\current-$($Using:ConfigFileName)" ) { $hash = Get-FileHash "$($Using:LocalPath)\current-$($Using:ConfigFileName)", "$($Using:LocalPath)\$($Using:ConfigFileName)" if ($hash[0].hash -eq $hash[1].hash) { return $true } } } return $false } SetScript = { try { & "$($Using:LocalPath)\sysmon64.exe" -u } catch { } & "$($Using:LocalPath)\sysmon64.exe" -i "$($Using:LocalPath)\$($Using:ConfigFileName)" -accepteula Copy-Item "$($Using:LocalPath)\$($Using:ConfigFileName)" "$($Using:LocalPath)\current-$($Using:ConfigFileName)" -Force } DependsOn = "[Script]sysmonScriptInstall" }
A section that will ensure that the sysmon64.exe and the configuration file are up to date. If they’re not (due to a hash difference) then it will reinstall sysmon with the new configuration. It will again run the sysmonScriptInstall section first to ensure that sysmon is actually installed.
Script sysmonScriptInstall { GetScript = { (Get-Service Sysmon -ErrorAction SilentlyContinue) } TestScript = { return ( ((Get-Service Sysmon -ErrorAction SilentlyContinue) -ne $null) -and ((fltmc | findstr /i sysmondrv) -ne $null) ) } SetScript = { if( (Get-Service Sysmon -ErrorAction SilentlyContinue) ) { & "$($Using:LocalPath)\sysmon64.exe" -u } & "$($Using:LocalPath)\sysmon64.exe" -i "$($Using:LocalPath)\$($Using:ConfigFileName)" -accepteula Copy-Item "$($Using:LocalPath)\$($Using:ConfigFileName)" "$($Using:LocalPath)\current-$($Using:ConfigFileName)" -Force } DependsOn = "[File]sysmonFiles" }
A section to install sysmon on a newly managed server, or to reinstall it on a server where the filter drive has been unloaded. It depends on sysmonFiles which copies the required sysmon64.exe and config files locally
File sysmonFiles { DestinationPath = $LocalPath SourcePath = $SourcePath Recurse = $true Checksum = 'SHA-256' MatchSource = $true Force = $true Ensure = 'Present' }
Finally a section to copy the required files to the local server and keep them up to date
}
Close the Configuration to get a valid composite DSC config
For ease of use I’ve bundled the above along with xBGInfo, xLAPS, xMMAgent and xNetbios into a DSC Module xServerConfiguration which you can find on GitHub. Feel free to contribute or comment as desired 🙂