05 August 2016

SCCM Automated Endpoint Full System Scan upon Infection with Email Notification

While helping to manage Microsoft Endpoint, a former colleague suggested that I setup Endpoint to automatically run a full system scan each time an infection is detected. I Googled the blog posting on it and although it is a great post, I figured it could streamlined even more by just using SCCM alone to achieve the same outcome. It is nice when you are out of the office and your backup might not have the time to keep an eye on the antivirus infections. It is also beneficial if you are in an environment where the office is closed overnight and on weekends. If an infection takes place, this can help remediate it without your presence.

This is the third edition. The first edition just initiated a full system scan upon infection. The second edition initiated a full system scan plus would send an email to the designated email address. The third edition now combines the first two and allows for them to be designated using parameters. The code has also been optimized.

I decided to use the SCCM custom application detection to query a system and see if a full system scan has been performed in the event of an infection logged in the event viewer. I first started out by writing a PowerShell script that would perform a WMI query on the SCCM server for the status of the system the application detection was being run on. The problem I ran across was that the application is being run under system credentials, which would require me to pass network credentials within the script. Instead of having to do this, I decided to query the event viewer logs on the local machine to look for the last infection date/time, which is event 1116. I also found that event 1001 and provider name Microsoft Antimalware designate are used when a system scan has been performed. Here are the steps SCCM and PowerShell go through:

  1. SCCM deploys the package to the system.
  2. The application detection queries the event viewer logs for the last 1116 ID (infection).
  3. The application detection queries the event viewer logs for the last 1001 ID and "Microsoft Antimalware" provider name.
  4. If a system 1001 ID does not exist since the last infection, the custom detection method will exit out as a failure.
  5. If the custom detection failed, the AntiVirusScanEmail.ps1 file will be executed on the machine.
  6. An email is sent that tells a scan was performed on %COMPUTERNAME% with the virus details in the body if -Email switch was specified
  7. Once the scan is complete, an application deployment evaluation cycle is initiated to update the SCCM server with the status of the system.
  8. The application detection is initiated again to confirm the scan occurred.
If you desire emails be sent alerting you of an infection and system scan, then you will need to download and place PsExec.exe in the same directory as this script. The next thing will be to define the Installation program in SCCM using psexec.exe. This allows the PowerShell script to be executed under a domain account, thereby giving it the ability to use the send-mailmessage commandlet.  Here is how to do this:

psexec.exe \\%computername% -u <domain>\<username> -p <password> -h cmd.exe /c "echo . | powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1"

Do not change %computername%. The only parts of the psexec.exe command line that need to be changed are <domain>, <username>, and <password>. 

If you do not want emails sent, then you can use the following command line parameter:

powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -FullScan
or
powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -QuickScan

This is setup in SCCM as a normal application deployment. The only thing that differs from a standard deployment is the application detection method. The ApplicationVirusDetectionMethodEmail.ps1 script is imported in for the detection method. The AntiVirusScanEmail.ps1 file is setup as the installation program. I have mine entered like this:

powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -FullScan

You can see the settings in this video:




If you also want it to email you, then refer to the section above on using psexec.exe and the example to enter in as the installation program. 

One more thing is that I have the application hidden from the software center. There really isn't a need for it to be seen by the end-users. 

In order for this to work in a timely manor, you will need to change the software deployment frequency under the client settings. I have mine set at every 8 hours, or three times a day.



You can download the application and application detection files from the following links:



ApplicationVirusDetectionMethodEmail.ps1

1:  <#       
2:       .NOTES  
3:       ===========================================================================  
4:        Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.127  
5:        Created on:       8/5/2016 11:11 AM  
6:        Created by:       Mick Pletcher  
7:        Organization:         
8:        Filename:         ApplicationVirusDetectionMethod.ps1  
9:       ===========================================================================  
10:       
11:  #>  
12:    
13:    
14:  $LastInfection = get-winevent -filterhashtable @{ logname = 'system'; ID = 1116 } -maxevents 1 -ErrorAction SilentlyContinue  
15:  $LastScan = Get-WinEvent -FilterHashtable @{ logname = 'system'; ProviderName = 'Microsoft Antimalware'; ID = 1001 } -MaxEvents 1  
16:  If ($LastScan.TimeCreated -lt $LastInfection.TimeCreated) {  
17:       #No scan since last infection  
18:       Start-Sleep -Seconds 5  
19:       exit 0  
20:  } else {  
21:       #No infection since last scan  
22:       Write-Host "No Infection"  
23:       Start-Sleep -Seconds 5  
24:       exit 0  
25:  }  
26:    


AntiVirusScanEmail.ps1

1:  <#  
2:       .SYNOPSIS  
3:            EndPoint Virus Scan  
4:         
5:       .DESCRIPTION  
6:            This script will initiate a full or quick scan, whichever switch is selected at the command line. Once the scan is completed, it will check the event viewer logs for a scan completed entry to verify the scan successfully completed. If the Email switch is designated at the command line, then an email is sent to the specified recipient. It is suggested the $EmailRecipient, $EmailSender, and $SMTPServer be predefined in the parameter field. I have also included a trigger of the application deployment evaluation cycle to expedite the process.  
7:         
8:       .PARAMETER FullScan  
9:            Initiate a full system scan  
10:         
11:       .PARAMETER QuickScan  
12:            Initiate a quick scan  
13:         
14:       .PARAMETER Email  
15:            Select if you want an email report sent to the specified email address  
16:         
17:       .PARAMETER EmailRecipient  
18:            Receipient's email address  
19:         
20:       .PARAMETER EmailSender  
21:            Sender's email address  
22:         
23:       .PARAMETER SMTPServer  
24:            SMTP server address  
25:         
26:       .EXAMPLE  
27:            Initiate a Quickscan  
28:            powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -QuickScan  
29:              
30:            Initiate a Fullscan  
31:            powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -FullScan  
32:              
33:            Initiate a Fullscan and send email report. To, From, and SMTP parameters are pre-defined  
34:            powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1 -FullScan -Email  
35:         
36:       .NOTES  
37:            ===========================================================================  
38:            Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.2.127  
39:            Created on:       8/5/2016 11:11 AM  
40:            Created by:       Mick Pletcher  
41:            Organization:  
42:            Filename:         AntiVirusScanEmail.ps1  
43:            ===========================================================================  
44:  #>  
45:  param  
46:  (  
47:       [switch]  
48:       $FullScan,  
49:       [switch]  
50:       $QuickScan,  
51:       [switch]  
52:       $Email,  
53:       [string]  
54:       $EmailRecipient = '',  
55:       [string]  
56:       $EmailSender = '',  
57:       [string]  
58:       $SMTPServer = ''  
59:  )  
60:    
61:  #Import the Endpoint Provider module  
62:  Import-Module $env:ProgramFiles"\Microsoft Security Client\MpProvider\MpProvider.psd1"  
63:  #Get the relative execution path of this script  
64:  $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
65:  #Find the last infection entry in the event viewer logs  
66:  $LastInfection = get-winevent -filterhashtable @{ logname = 'system'; ID = 1116 } -maxevents 1 -ErrorAction SilentlyContinue  
67:  #Full Scan  
68:  If ($FullScan.IsPresent) {  
69:       #Initiate a full system scan  
70:       Start-MProtScan -ScanType "FullScan"  
71:       #Commented area only there if you want to manually execute this script to watch it execute  
72:  <#     cls  
73:       Write-Warning "Error: $_"  
74:       Write-Host $_.Exception.ErrorCode  
75:  #>       
76:       #Get the last event viewer log written by Endpoint to check if the full system scan has finished  
77:       $LastScan = Get-WinEvent -FilterHashtable @{ logname = 'system'; ProviderName = 'Microsoft Antimalware'; ID = 1001 } -MaxEvents 1  
78:       #  
79:       If ($LastScan.Message -like '*Microsoft Antimalware scan has finished*') {  
80:            $EmailBody = "An Endpoint antimalware full system scan has been performed on" + [char]32 + $env:COMPUTERNAME + [char]32 + "due to the virus detection listed below." + [char]13 + [char]13 + $LastInfection.Message  
81:       } else {  
82:            $EmailBody = "An Endpoint antimalware full system scan did not complete on" + [char]32 + $env:COMPUTERNAME + [char]32 + "due to the virus detection listed below." + [char]13 + [char]13 + $LastInfection.Message  
83:       }  
84:  }  
85:  #Quick Scan  
86:  If ($QuickScan.IsPresent) {  
87:       #Initiate a quick system scan  
88:       Start-MProtScan -ScanType "QuickScan"  
89:       #Commented area only there if you want to manually execute this script to watch it execute  
90:  <#     cls  
91:       Write-Warning "Error: $_"  
92:       Write-Host $_.Exception.ErrorCode  
93:  #>       
94:       #Get the last event viewer log written by Endpoint to check if the quick system scan has finished  
95:       $LastScan = Get-WinEvent -FilterHashtable @{ logname = 'system'; ProviderName = 'Microsoft Antimalware'; ID = 1001 } -MaxEvents 1  
96:       #  
97:       If ($LastScan.Message -like '*Microsoft Antimalware scan has finished*') {  
98:            $EmailBody = "An Endpoint antimalware quick system scan has been performed on" + [char]32 + $env:COMPUTERNAME + [char]32 + "due to the virus detection listed below." + [char]13 + [char]13 + $LastInfection.Message  
99:       } else {  
100:            $EmailBody = "An Endpoint antimalware quick system scan did not complete on" + [char]32 + $env:COMPUTERNAME + [char]32 + "due to the virus detection listed below." + [char]13 + [char]13 + $LastInfection.Message  
101:       }  
102:  }  
103:  #Email Infection Report  
104:  If ($Email.IsPresent) {  
105:       $Subject = "Microsoft Endpoint Infection Report"  
106:       $EmailSubject = "Virus Detection Report for" + [char]32 + $env:COMPUTERNAME  
107:       Send-MailMessage -To $EmailRecipient -From $EmailSender -Subject $Subject -Body $EmailBody -SmtpServer $SMTPServer  
108:  }  
109:  #Initiate Application Deployment Evaluation Cycle  
110:  $WMIPath = "\\" + $env:COMPUTERNAME + "\root\ccm:SMS_Client"  
111:  $SMSwmi = [wmiclass]$WMIPath  
112:  $strAction = "{00000000-0000-0000-0000-000000000121}"  
113:  [Void]$SMSwmi.TriggerSchedule($strAction)  
114:    

7 comments:

  1. Hi Mike, Thanks from NJ, USA!

    ReplyDelete
    Replies
    1. My apology for messing up your name Mick!

      Delete
    2. I keep getting the "script is not signed" error although -bypass parameter is specified

      Delete
    3. That sounds like a policy issues on your domain. Have you done a get-executionpolicy?

      Delete
    4. Hi Mick thanks for your response it was set to RemoteSigned...doh! :)

      Delete
  2. So the command for email report will be

    psexec.exe \\%computername% -u \ -p -h cmd.exe /c "echo . | powershell.exe -executionpolicy bypass -file AntiVirusScanEmail.ps1" -FullScan -Email

    Will have to just change domain\xxx and -p password

    ReplyDelete