There isn’t yet an official Ansible module for managing Windows Defender exclusions. If you’re committed to idempotency, and not sure how to add a path to Windows Defender’s exclusions list, read on!
I’ll get straight into the task:
- name: Exclude directories from Windows Defender
ansible.windows.win_powershell:
script: |
$Ansible.Changed = $false
# Check if the folder is already excluded
$excluded = Get-MpPreference | Select-Object -ExpandProperty ExclusionPath | Where-Object { $_ -eq "{{ item }}" }
if ($null -eq $excluded) {
# Add the folder to the exclusion list
try {
Add-MpPreference -ExclusionPath "{{ item }}"
$Ansible.Changed = $true
} catch {
$Ansible.Failed = $true
}
}
loop:
- C:\foo\bar.exe
- H:\baz\qux
To break it down:
loop
: Pass the file/directory paths that you wish to exclude, as a list.Add-MpPreference
does not accept wildcards, so you may need to be verbose, or add exclusions at the directory level rather than file level. These are the “target exclusions” referred to below.ansible.windows.win_powershell
: This module gives us the ability with custom PowerShell scripts to tell Ansible explicitly whether the task failed or resulted in a change.$Ansible.Changed = $false
: Ansible uses this variable to detect whether or not the task resulted in a change. We initialise it to$false
, since no change has occurred yet.Get-MpPreference
: This PowerShell cmdlet retrieves lots of Windows Defender configuration imformation.Select-Object -ExpandProperty ExclusionPath
: Get the existing exclusions from the previous command, as a list.Where-Object { $_ -eq "{{ item }}" }
: Look for our target exclusion in the list.if ($null -eq $excluded) {
: If we didn’t find the target exclusion, run the next bit of code. If we did find the exclusion, we don’t execute any more code. the script will end with$Ansible.Changed
still set to$false
, which is what we want, to preserve idempotency.try { ... } catch { ... }
: If we fail to add the exclusion, PowerShell throws an error, so we wrap this intry..catch
so we can handle that failure.Add-MpPreference -ExclusionPath "{{ item }}"
: Add the target exclusion to Windows Defender’s exclusions list. Note that if this fails, PowerShell will immediately jump to the code in thecatch
block.$Ansible.Changed = $true
: We’ll only reach this line if (a) the target exclusion wasn’t already in the list and (b) adding the exclusion succeeded. Hence we set$Ansible.Changed
to$true
.$Ansible.Failed = $true
: We reach this code ifAdd-MpPreference
failed, hence we set$Ansible.Failed
to$true
.
I hope this is helpful! If you know of a better or more elegant way of doing this, let me know in the comments. 🙂