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 🙂

Twan van Beers

Twan is a senior consultant with over 20 years of experience. He has a wide range of skills including Messaging, Active Directory, SQL, Networking and Firewalls. Twan loves to write scripts and get deep and dirty into debugging code, in order to understand and resolve the most complex of problems.

Leave a Reply

Your email address will not be published. Required fields are marked *

Search