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 🙂
