The following script runs a custom Windows Defender scan on multiple drives with exclusions.
👉 NOTE: Since this is a long-running script, be sure to turn off the Sleep setting for your computer before you run it.
- Navigate to Settings > System > Power & sleep
- Click the drop-down setting for Sleep and change it to Never
#requires -RunAsAdministrator
Import-Module Defender
Function Start-CustomScan
{
<# .DESCRIPTION
Runs Custom Windows Defender Scan on Multiple Drives with Exclusions
#>
[CmdletBinding()]
Param(
[Parameter()]
[Microsoft.Management.Infrastructure.CimInstance[]]$volumes
)
$ErrorActionPreference = 'Stop'
ForEach ($volume in $volumes)
{
$drive = "$($volume.DriveLetter):\"
$exclusions = (Get-MpPreference).ExclusionExtension
$friendlyName = "$($volume.FileSystemLabel)"
$logFile = "CustomScan-Drive-$($volume.DriveLetter).csv"
$message = "{0} CustomScan on Drive $drive"
$LogMessage = @{
LogFile = $logFile
Message = $message -f 'BEGIN'
}
Write-Log @LogMessage
try {
Start-MpScan -ScanPath $drive -ScanType CustomScan
$LogMessage.Message = "Volume $friendlyName exclusions: $exclusions"
$LogMessage.Severity = 'Information'
} catch {
$LogMessage.Message = $_.Exception.Message
$LogMessage.Severity = 'Error'
}
Write-Log @LogMessage
$result = "$(Get-Date -f g) Drive $drive scan completed {0}."
if ($LogMessage.Severity -ne 'Error') {
$result = $result -f 'successfully'
} else {
$result = $result -f 'with error(s)'
$LogMessage.Severity = 'Information'
}
$LogMessage.Message = $message -f '*END*'
Write-Log @LogMessage
Write-Output $result
}
}
Function Write-Log
{
# REF: https://adamtheautomator.com/powershell-log-function/
[CmdletBinding()]
Param(
[Parameter()]
[string]$LogDirectory = "$([Environment]::GetFolderPath("Desktop"))\Logs",
[Parameter()]
[string]$LogFile = 'LogFile.csv',
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information','Warning','Error')]
[string]$Severity = 'Information'
)
if (-not(Test-Path -Path $LogDirectory -PathType Container)) {
$null = New-Item -ItemType Directory -Path $LogDirectory -ErrorAction STOP
}
$LogPath = Join-Path -Path $LogDirectory -ChildPath $LogFile
[PSCustomObject] @{
# REF: https://social.technet.microsoft.com/wiki/contents/articles/32274.powershell-get-date-format.aspx
Time = (Get-Date -f g)
Message = $Message
Severity = $Severity
} | Export-Csv -Path $LogPath -Append -NoTypeInformation
}
echo "Windows Defender Last Updated Date and Age"
echo "=========================================="
(Get-MpComputerStatus | Select-Object *LastUpdated,*SignatureAge | Out-String).Trim()
# Setup for Custom Scan with Exclusions; CHANGE $exclusions FOR YOUR NEEDS
$exclusions = @('*.ffu','*.iso','*.m4a','*.mp3','*.wav','*.wim')
Set-MpPreference -CheckForSignaturesBeforeRunningScan $true
Set-MpPreference -ExclusionExtension $exclusions
Start-CustomScan (Get-Volume |
Where-Object {$_.DriveLetter -ne $null -and $_.OperationalStatus -eq 'OK'} |
Sort-Object DriveLetter)
$events = Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-Windows Defender/Operational'
Level = 2
}
if ($events) {
$events | Out-GridView -Title 'Windows Defender Errors' -Wait
}
if (($Host.Name -eq 'ConsoleHost') -and (-not $env:WT_SESSION)) {
Write-Host "`nPress any key to close this window . . ." -NoNewline
$Host.UI.RawUI.ReadKey('NoEcho, IncludeKeyDown') | Out-Null
}