Sysmon Configuration with DSC

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 🙂