2019-08-20 06:37:45 +00:00
################################################################################
#
# Microsoft WindowsDefender exclusions cleaner
# Espressif Systems, 2019
#
################################################################################
#
# - cleans all Windows Defender process exclusions containing given path (both Process and Path)
# - run as Administrator, eg: PowerShell -ExecutionPolicy ByPass -File tools_WD_clean.ps1 -RmExclPath "C:\Program Files\Espressif\ESP-IDF Tools". If not running with admin privileges, the script tries to elevate itself (new process, output grabbed on exit)
# minimum requirements: Windows XP SP3, PowerShell 2.0, Windows Defender with relevant PS cmdlets
# - Returns 0 on success or -1 on failure
#
################################################################################
Param
(
2019-11-22 10:55:42 +00:00
[ String ] $RmExclPath ,
[ String ] $logFile
2019-08-20 06:37:45 +00:00
)
function Check-Command($cmdname )
{
2019-11-22 10:55:42 +00:00
return [ bool ] ( Get-Command -Name $cmdname -ErrorAction SilentlyContinue )
2019-08-20 06:37:45 +00:00
}
function Log-Msg($msg , $logF = $null )
{
2019-11-22 10:55:42 +00:00
if ( ! [ string ] :: IsNullOrEmpty ( $logF ) ) { Write-Output $msg * > > $logF }
else { Write-Output $msg }
[ Console ] :: Out . Flush ( )
2019-08-20 06:37:45 +00:00
}
2019-11-22 10:55:42 +00:00
$retVal = 1
2019-08-20 06:37:45 +00:00
Try
2019-11-22 10:55:42 +00:00
{
#check the Defender module availability
if ( ! ( Get-Module " Defender " ) ) {
Write-Output " Windows Defender module not available, aborting "
[ Environment ] :: Exit ( 0 )
}
Import-Module Defender
#self-elevation support
$myWindowsID = [ System.Security.Principal.WindowsIdentity ] :: GetCurrent ( )
$myWindowsPrincipal = new-object System . Security . Principal . WindowsPrincipal ( $myWindowsID )
$adminRole = [ System.Security.Principal.WindowsBuiltInRole ] :: Administrator
if ( -not $myWindowsPrincipal . IsInRole ( $adminRole ) ) {
$params = " "
foreach ( $key in $PSBoundParameters . keys ) {
$params = -join ( $params , " - " , $key , " `" " , $PSBoundParameters [ $key ] , " `" " )
}
#running elevated and logFile not set
if ( [ string ] :: IsNullOrEmpty ( $logFile ) ) {
$tempFileName = Get-Date -UFormat " %Y%m%d%H%M%s "
$lf = Join-Path -Path $env:TEMP -ChildPath " WDEspLog $tempFileName .log "
#Write-Output "Logfile: $lf"
}
$newProcess = new-object System . Diagnostics . ProcessStartInfo " PowerShell "
$newProcess . Arguments = " -ExecutionPolicy ByPass -File " + $script:MyInvocation . MyCommand . Definition + " " + $params + " -logFile $lf "
$newProcess . Verb = " RunAs "
$newProcess . WindowStyle = [ System.Diagnostics.ProcessWindowStyle ] :: Hidden
$proc = [ System.Diagnostics.Process ] :: Start ( $newProcess )
$proc . WaitForExit ( )
if ( Test-Path -Path $lf ) {
foreach ( $line in Get-Content $lf ) {
Log-Msg -msg $line
}
Remove-Item $lf
}
#Write-Output "Process finished with code " $proc.ExitCode
exit $proc . ExitCode
}
Log-Msg -msg " Getting Windows Defender process exclusions... " -logF $logFile
$Preferences = Get-MpPreference
#ExclusionProcess
$cnt = $Preferences . ExclusionProcess . Count
$cntRemoved = 0
$cntRemovedTotal = 0
$cntMissed = 0
$cntMissedTotal = 0
$bRmPath = ! [ string ] :: IsNullOrEmpty ( $RmExclPath )
if ( $bRmPath ) { Log-Msg -msg " Exclusion path: $RmExclPath " -logF $logFile }
Log-Msg -msg " Found total $cnt of ExclusionProcess items " -logF $logFile
foreach ( $pref in $Preferences . ExclusionProcess ) {
if ( $bRmPath ) { $bGoAhead = $pref . Contains ( $RmExclPath ) }
else { $bGoAhead = $true }
if ( $bGoAhead ) {
Log-Msg -msg " removing $pref " -logF $logFile
Try
{
Remove-MpPreference -ExclusionProcess $pref
$cntRemoved + +
}
Catch
{
if ( ! [ string ] :: IsNullOrEmpty ( $logFile ) ) { Write-Error -Exception $_ . Exception * > > $logFile }
Write-Error -Exception $_ . Exception
$cntMissed + +
}
}
}
if ( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionProcess list " -logF $logFile }
else { Log-Msg -msg " WARNING: Only $cntRemoved out of $( cntRemoved + cntMissed ) relevant items removed from ExclusionProcess list " -logF $logFile }
#ExclusionPath
$cnt = $Preferences . ExclusionPath . Count
$cntRemovedTotal = $cntRemoved
$cntRemoved = 0
$cntMissedTotal = $cntMissed
$cntMissed = 0
Log-Msg -msg " Found total $cnt of ExclusionPath items " -logF $logFile
foreach ( $pref in $Preferences . ExclusionPath ) {
if ( $bRmPath ) { $bGoAhead = $pref . Contains ( $RmExclPath ) }
else { $bGoAhead = $true }
if ( $bGoAhead ) {
Log-Msg -msg " removing $pref " -logF $logFile
Try
{
Remove-MpPreference -ExclusionPath $pref
$cntRemoved + +
}
Catch
{
if ( ! [ string ] :: IsNullOrEmpty ( $logFile ) ) { Write-Error -Exception $_ . Exception * > > $logFile }
Write-Error -Exception $_ . Exception
$cntMissed + +
}
}
}
if ( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionPath list " -logF $logFile }
else { Log-Msg -msg " WARNING: Only $cntRemoved out of $( cntRemoved + cntMissed ) relevant items removed from ExclusionPath list " -logF $logFile }
#TOTAL
$cntRemovedTotal + = $cntRemoved
$cntMissedTotal + = $cntMissed
Log-Msg -msg " ============================ " -logF $logFile
if ( $cntMissedTotal -eq 0 ) { Log-Msg -msg " OK: Processed all $cntRemovedTotal items " -logF $logFile }
else { Log-Msg -msg " WARNING: Processed only $cntRemovedTotal out of $( cntRemovedTotal + cntMissedTotal ) relevat items " -logF $logFile }
Log-Msg -msg " `n Done " -logF $logFile
$retVal = 0
2019-08-20 06:37:45 +00:00
}
Catch
{
2019-11-22 10:55:42 +00:00
if ( ! [ string ] :: IsNullOrEmpty ( $logFile ) ) { Write-Error -Exception $_ . Exception * > > $logFile }
Write-Error -Exception $_ . Exception
[ Environment ] :: Exit ( $retVal )
}
Finally
{
[ Environment ] :: Exit ( $retVal )
2019-08-20 06:37:45 +00:00
}