tools_WD_clean.ps1 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. ################################################################################
  2. #
  3. # Microsoft WindowsDefender exclusions cleaner
  4. # Espressif Systems, 2019
  5. #
  6. ################################################################################
  7. #
  8. # - cleans all Windows Defender process exclusions containing given path (both Process and Path)
  9. # - 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)
  10. # minimum requirements: Windows XP SP3, PowerShell 2.0, Windows Defender with relevant PS cmdlets
  11. # - Returns 0 on success or -1 on failure
  12. #
  13. ################################################################################
  14. Param
  15. (
  16. [String]$RmExclPath,
  17. [String]$logFile
  18. )
  19. function Check-Command($cmdname)
  20. {
  21. return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue)
  22. }
  23. function Log-Msg($msg, $logF = $null)
  24. {
  25. if( ![string]::IsNullOrEmpty($logF) ) { Write-Output $msg *>> $logF }
  26. else { Write-Output $msg }
  27. [Console]::Out.Flush()
  28. }
  29. $retVal = 1
  30. Try
  31. {
  32. Import-Module Defender
  33. #self-elevation support
  34. $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
  35. $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
  36. $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
  37. if( -not $myWindowsPrincipal.IsInRole($adminRole) ) {
  38. $params = ""
  39. foreach($key in $PSBoundParameters.keys) {
  40. $params = -join( $params, "-", $key, " `"", $PSBoundParameters[$key], "`"" )
  41. }
  42. #running elevated and logFile not set
  43. if( [string]::IsNullOrEmpty($logFile) ) {
  44. $tempFileName = Get-Date -UFormat "%Y%m%d%H%M%s"
  45. $lf = Join-Path -Path $env:TEMP -ChildPath "WDEspLog$tempFileName.log"
  46. }
  47. $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell"
  48. $newProcess.Arguments = "-ExecutionPolicy ByPass -File " + $script:MyInvocation.MyCommand.Definition + " " + $params + " -logFile $lf"
  49. $newProcess.Verb = "RunAs"
  50. $newProcess.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
  51. $proc = [System.Diagnostics.Process]::Start($newProcess)
  52. $proc.WaitForExit()
  53. if (Test-Path -Path $lf ) {
  54. foreach($line in Get-Content $lf) {
  55. Log-Msg -msg $line
  56. }
  57. Remove-Item $lf
  58. }
  59. exit $proc.ExitCode
  60. }
  61. Log-Msg -msg "Getting Windows Defender process exclusions..." -logF $logFile
  62. $Preferences = Get-MpPreference
  63. #ExclusionProcess
  64. $cnt = $Preferences.ExclusionProcess.Count
  65. $cntRemoved = 0
  66. $cntRemovedTotal = 0
  67. $cntMissed = 0
  68. $cntMissedTotal = 0
  69. $bRmPath = ![string]::IsNullOrEmpty($RmExclPath)
  70. if( $bRmPath ) { Log-Msg -msg "Exclusion path: $RmExclPath" -logF $logFile }
  71. Log-Msg -msg " Found total $cnt of ExclusionProcess items" -logF $logFile
  72. foreach( $pref in $Preferences.ExclusionProcess ) {
  73. if( $bRmPath ) { $bGoAhead = $pref.Contains($RmExclPath) }
  74. else { $bGoAhead = $true }
  75. if( $bGoAhead ) {
  76. Log-Msg -msg " removing $pref" -logF $logFile
  77. Try
  78. {
  79. Remove-MpPreference -ExclusionProcess $pref
  80. $cntRemoved++
  81. }
  82. Catch
  83. {
  84. if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
  85. Write-Error -Exception $_.Exception
  86. $cntMissed++
  87. }
  88. }
  89. }
  90. if( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionProcess list" -logF $logFile }
  91. else { Log-Msg -msg " WARNING: Only $cntRemoved out of $(cntRemoved+cntMissed) relevant items removed from ExclusionProcess list" -logF $logFile }
  92. #ExclusionPath
  93. $cnt = $Preferences.ExclusionPath.Count
  94. $cntRemovedTotal = $cntRemoved
  95. $cntRemoved = 0
  96. $cntMissedTotal = $cntMissed
  97. $cntMissed = 0
  98. Log-Msg -msg " Found total $cnt of ExclusionPath items" -logF $logFile
  99. foreach( $pref in $Preferences.ExclusionPath ) {
  100. if( $bRmPath ) { $bGoAhead = $pref.Contains($RmExclPath) }
  101. else { $bGoAhead = $true }
  102. if( $bGoAhead ) {
  103. Log-Msg -msg " removing $pref" -logF $logFile
  104. Try
  105. {
  106. Remove-MpPreference -ExclusionPath $pref
  107. $cntRemoved++
  108. }
  109. Catch
  110. {
  111. if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
  112. Write-Error -Exception $_.Exception
  113. $cntMissed++
  114. }
  115. }
  116. }
  117. if( $cntMissed -eq 0 ) { Log-Msg -msg " $cntRemoved relevant items removed from ExclusionPath list" -logF $logFile }
  118. else { Log-Msg -msg " WARNING: Only $cntRemoved out of $(cntRemoved+cntMissed) relevant items removed from ExclusionPath list" -logF $logFile }
  119. #TOTAL
  120. $cntRemovedTotal += $cntRemoved
  121. $cntMissedTotal += $cntMissed
  122. Log-Msg -msg "============================" -logF $logFile
  123. if( $cntMissedTotal -eq 0 ) { Log-Msg -msg "OK: Processed all $cntRemovedTotal items" -logF $logFile }
  124. else { Log-Msg -msg "WARNING: Processed only $cntRemovedTotal out of $(cntRemovedTotal+cntMissedTotal) relevat items" -logF $logFile }
  125. Log-Msg -msg "`nDone" -logF $logFile
  126. $retVal = 0
  127. }
  128. Catch
  129. {
  130. if( ![string]::IsNullOrEmpty($logFile) ) { Write-Error -Exception $_.Exception *>> $logFile }
  131. Write-Error -Exception $_.Exception
  132. [Environment]::Exit($retVal)
  133. }
  134. Finally
  135. {
  136. [Environment]::Exit($retVal)
  137. }