Create Configuration Manager Antimalware Policies with PowerShell

As I spend time working in many different Configuration Manager environments, I find myself regularly needing to create Antimalware Policies. Most of the settings in the antimalware policies can be configured quickly, however the setting that always takes me the most time is the Exclusion Settings.

There needs to be different policies with different exclusion settings for different types of devices. Each of these separate policies have 3 different areas for adding file paths, file types, and processes. And for some reason, unknown to me, the dialog window for adding exclusions has a 260 character limit. This means that even if all the exclusion settings are in a list, you can’t just copy the whole list in at once. All this adds up to make this process time consuming and inconsistent.

I figured PowerShell could be the answer to this problem (as it usually is). I saw that there are PowerShell cmdlets for working with antimalware policies, specifically New-CMAntimalwarePolicy and Set-CMAntimalwarePolicy. I used these cmdlets and wrote a PowerShell script.

Note: The script needs to be run from a computer that has the Configuration Manager console installed, so the ConfigurationManager.psd1 module can be imported.

<#
    .DESCRIPTION
        This script can be used to automatically add exclusion settings
        to a new or existing antimalware policy in Configuration Manager.
	
    .PARAMETER SiteCode
        Site Code of the target Configuration Manager envrionment
	
    .PARAMETER SiteServer
        Name of the Configuration Manager primary site server
	
    .PARAMETER CsvPath
        Path to the CSV file that contains the antimalware exclusions
    
    .PARAMETER PolicyName
        Name of the anitmalware policy to create or modify
	
    .EXAMPLE
        Create_Exclusions.ps1 -SiteCode PS1 -SiteServer cm.example.local -CsvPath "C:\Temp\Exchange.csv" -PolicyName "Exchange AV Exclusions"
	
    .NOTES
        Created by: Jon Anderson
        Reference: https://www.configjon.com/create-configuration-manager-antimalware-policies-with-powershell/
#>

#Parameters
param(
    [Parameter(Mandatory=$true)][ValidateLength(3,3)][string]$SiteCode,
    [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$SiteServer,
    [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$CsvPath,
    [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$PolicyName
)

#Get the current working directory
$OriginalLocation = Get-Location | Select-Object -ExpandProperty Path

#Check if the Configuration Manager console is installed
$DriveLetter = Get-Volume | Select-Object -ExpandProperty DriveLetter
ForEach ($Letter in $DriveLetter){
    $ModulePath = "$($Letter):\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
    If (Test-Path $ModulePath){Break}
    $ModulePath = "$($Letter):\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1"
    If (Test-Path $ModulePath){Break}
    Clear-Variable -Name "ModulePath"
}
If ($NULL -eq $ModulePath) {
    Throw "Could not find \Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1. This script should be run from a computer with the Configuration Manager console installed."
}

#Connect to the Configuration Manager site
If (!(Test-Path $SiteCode":")) {
    Import-Module $ModulePath
    New-PSDrive -Name $SiteCode -PSProvider "AdminUI.PS.Provider\CMSite" -Root $SiteServer
}
Set-Location $SiteCode":"

#Create the specified policy object if it does not already exist
If (!(Get-CMAntimalwarePolicy -Name $PolicyName)) {
    New-CMAntimalwarePolicy -Name $PolicyName -Policy ExclusionSettings
}

#Declare the array objects
$FilePath = @()
$FileType = @()
$Process = @()

#Import CSV data into the arrays
Import-Csv $CsvPath | ForEach-Object {
    $FilePath += $_.FilePath
    $FileType += $_.FileType
    $Process += $_.Process
}

#Remove blank lines from the arrays
$FilePath = $filePath | Where-Object {$_}
$FileType = $fileType | Where-Object {$_}
$Process = $process | Where-Object {$_}

#If the array is not empty, add the file paths to the specified antimalware policy
If ($FilePath.count -gt 0) {
    Set-CMAntimalwarePolicy -Name $PolicyName -ExcludeFilePath $FilePath
}

#If the array is not empty, add the file types to the specified antimalware policy
If ($FileType.count -gt 0) {
    Set-CMAntimalwarePolicy -Name $PolicyName -ExcludeFileType $FileType
}

#If the array is not empty, add the processes to the specified antimalware policy
If ($Process.count -gt 0) {
    Set-CMAntimalwarePolicy -Name $PolicyName -ExcludeProcess $Process
}

#Set the working directory back to the original location
Set-Location $OriginalLocation

This script takes a CSV file as input. This allows me to maintain a few CSV files with all the common exclusion settings for various types of devices. I can then use this script to quickly and consistently import these exclusion settings into Configuration Manager. The CSV files need to have 3 headings (FilePath, FileType, Process). These 3 headings should be there even if one of the columns is blank.

The script has 4 mandatory parameters.

  • SiteCode – The site code of the Configuration Manager environment
  • SiteServer – The name of the Configuration Manager primary site server
  • CsvPath – The full path to the CSV file containing the exclusion settings
  • PolicyName – The name of the antimalware policy to either create or edit

Here is an example of the script being run with the parameters specified.

Create_Exclusions.ps1 -SiteCode PS1 -SiteServer cm.example.local -CsvPath "C:\Temp\Exchange.csv" -PolicyName "Exchange AV Exclusions"

I have uploaded the script as well as some example CSV files to my GitHub. The CSV files contain generic exclusion recommendations collected from these sites. (Configuration Manager, Domain Controller, Exchange Server) You will need to modify these exclusion settings to work with your own environment.