Automate Milestone XProtect Updates: PowerShell Script for Windows Defender Anti-Virus Exclusions

In this tutorial, I'll share how I leveraged ChatGPT to create a PowerShell script that automates one of these tedious tasks: setting up Windows Defender antivirus exclusions. These exclusions are crucial to ensure that the antivirus doesn't interfere with XProtect servers' performance or disrupt video recordings.
Table of Contents

Let’s talk (rant) about Milestone Upgrades for a second. The repetition involved in mind-numbingly boring and you know how I feel about boring tasks (hint: I don’t like them). 

However, they are a necessary evil so when I was recently tasked with performing Milestone upgrades, I turned to ChatGPT to help me create some PowerShell scripts that could help speed up some of these tedious tasks.

I’ll be the first to admit that PowerShell is no magic wand. It has its own challenges and is far from simple BUT I find it to be much less time-consuming and more predictable than performing each change one at a time via the Windows user interface.

This script focuses on a crucial step: adding antivirus exclusions for XProtect in Windows Defender. These exclusions are essential to ensure that antivirus scans don’t interfere with the performance of XProtect servers.

Why Anti-Virus Exclusions Matter

Before diving into the script, let’s quickly touch on why these exclusions are so important. 

Windows Defender, like any antivirus software, scans files and processes in real-time to catch potential threats. 

However, this real-time scanning can consume resources and potentially interfere with the performance of your XProtect servers. 

By setting exclusions, we tell Windows Defender to skip scanning certain files, folders, or processes, which helps maintain smooth and uninterrupted server performance.

PowerShell Script to Add AV Exclusions for XProtect in Windows Defender

This PowerShell script automates the process of adding necessary antivirus exclusions for XProtect, ensuring that all required directories, file types, and processes are excluded from Windows Defender scans.

👉 I am not responsible for any mishaps that may happen with your update. Do your own research, testing, and critical thinking. I am merely a human with a passion for security solutions that wants to share my knowledge and experience with you in hopes it helps make your job a little less boring.

Here is the script:

				
					# Script to add AV exclusions for XProtect in Windows Defender

# Directories to exclude - to be entered by user
$directories = @()

# Prompt user for directories
Write-Output "Please enter the directories for the video database folders. Press Enter without typing a directory to finish."
while ($true) {
    $dir = Read-Host "Enter directory"
    if ([string]::IsNullOrWhiteSpace($dir)) {
        break
    } else {
        $directories += $dir
    }
}

# Predefined directories to exclude
$predefinedDirectories = @(
    "C:\Program Files\Milestone\",
    "C:\Program Files (x86)\Milestone\",
    "C:\ProgramData\Milestone\"
)

# Combine user input directories with predefined directories
$directories += $predefinedDirectories

# File types to exclude
$fileTypes = @(".blk", ".idx", ".pic", ".pqz", ".sts", ".ts")

# Processes to exclude
$processes = @(
    "VideoOS.Recorder.Service.exe",
    "VideoOS.Server.Service.exe",
    "VideoOS.Administration.exe",
    "VideoOS.Event.Server.exe",
    "VideoOS.Failover.Service.exe",
    "RecordingServer.exe",
    "ImageServer.exe",
    "ManagementApplication.exe",
    "ImageImportService.exe",
    "RecordingServerManager.exe",
    "VideoOS.ServiceControl.Service.exe",
    "VideoOS.MobileServer.Service.exe",
    "VideoOS.LPR.Server.exe"
)

# Function to check if a process exists
function Test-Process {
    param (
        [string]$ProcessName
    )
    $process = Get-Process -Name $ProcessName -ErrorAction SilentlyContinue
    if ($process) {
        return $true
    } else {
        return $false
    }
}

# Function to check if a directory exclusion already exists
function Test-DirectoryExclusion {
    param (
        [string]$Directory
    )
    $exclusions = Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
    if ($exclusions -contains $Directory) {
        return $true
    } else {
        return $false
    }
}

# Function to check if a file type exclusion already exists
function Test-FileTypeExclusion {
    param (
        [string]$FileType
    )
    $exclusions = Get-MpPreference | Select-Object -ExpandProperty ExclusionExtension
    if ($exclusions -contains $FileType) {
        return $true
    } else {
        return $false
    }
}

# Function to check if a process exclusion already exists
function Test-ProcessExclusion {
    param (
        [string]$Process
    )
    $exclusions = Get-MpPreference | Select-Object -ExpandProperty ExclusionProcess
    if ($exclusions -contains $Process) {
        return $true
    } else {
        return $false
    }
}

# Adding directory exclusions
foreach ($dir in $directories) {
    if (Test-DirectoryExclusion -Directory $dir) {
        Write-Output "Directory exclusion already exists: $dir"
    } else {
        Add-MpPreference -ExclusionPath $dir
        if ($?) {
            Write-Output "Successfully excluded directory: $dir"
        } else {
            Write-Output "Failed to exclude directory: $dir"
        }
    }
}

# Adding file type exclusions
foreach ($fileType in $fileTypes) {
    if (Test-FileTypeExclusion -FileType $fileType) {
        Write-Output "File type exclusion already exists: $fileType"
    } else {
        Add-MpPreference -ExclusionExtension $fileType
        if ($?) {
            Write-Output "Successfully excluded file type: $fileType"
        } else {
            Write-Output "Failed to exclude file type: $fileType"
        }
    }
}

# Adding process exclusions if they exist
foreach ($process in $processes) {
    $processName = $process -replace ".exe", ""
    if (Test-Process -ProcessName $processName) {
        if (Test-ProcessExclusion -Process $process) {
            Write-Output "Process exclusion already exists: $process"
        } else {
            Add-MpPreference -ExclusionProcess $process
            if ($?) {
                Write-Output "Successfully excluded process: $process"
            } else {
                Write-Output "Failed to exclude process: $process"
            }
        }
    } else {
        Write-Output "Process not found: $process"
    }
}

Write-Output "All exclusions have been processed successfully."
				
			

This script takes the laborious task of adding antivirus exclusions for numerous directories, file types, and processes and makes it a one-time setup that you can run whenever needed. By automating these steps, you save time and ensure consistency across your XProtect installations.

Using this PowerShell script to automate antivirus exclusions for XProtect servers helps maintain their performance by preventing unnecessary antivirus scans. This automation not only saves you time but also minimizes the risk of human error. 

I hope this script makes your upgrades smoother and your work a little less boring. 

It’s the newsletter security professionals use to work smarter. We promise you’ll learn stuff and enjoy a few blissful moments of productive procrastination.

Team Boring

Your go-to XProtect eXPerts. We learn the technical stuff that will save you time and make it less boring.

Team Boring

Your go-to XProtect eXPerts. We learn the technical stuff that will save you time and make it less boring.

You Might Also Enjoy…