Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- This script will prompt the user for sender and subject line for a Spam or Phishing email and remove it from all mailboxes in the organization
- .DESCRIPTION
- This script requires you to have Exchange 2010 Management Shell installed to your computer before it will work.
- .EXAMPLE
- delete-email.ps1 -Sender <email address> -Subject <text> -O365user <user@domain.com> -O365pass <password> -ExchUser <domain\user> -ExchPass <password> -MoveMsg <boolean flag, set true if present>
- .REQUIRES -Version 3.0
- .REQUIRES -PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
- .REQUIRES -Run this command as admin before running this script for the first time on a system: New-EventLog -LogName Application -Source "Email Deletion"
- #>
- param(
- [Parameter(Mandatory=$false)][string]$Sender = "",
- [Parameter(Mandatory=$false)][string]$Subject = "",
- [parameter(Mandatory=$false)][string]$O365User,
- [Parameter(Mandatory=$false)][string]$O365Pass,
- [Parameter(Mandatory=$false)][string]$ExchUser,
- [Parameter(Mandatory=$false)][string]$ExchPass
- )
- #################################################################################
- #
- # Gather Input & check provided parameters for validity
- #
- #################################################################################
- Write-Verbose "This script will ask you for sender email address and email subject line of an email to remove from all maiboxes."
- $SubjectRequired = $false
- # Ask user for the sender email address and verify via regex that it is a valid email address. Re-prompt user for valid address until user gets it right.
- Do {
- if((-not $sender) -or ($match -ne $true)) {
- $Sender = Read-Host -Prompt "Please input the senders email address"
- }
- if( $Sender -match "^[a-zA-Z0-9._%+-=]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") {
- $match = $true
- }
- else{
- Write-Host "You did not enter a properly formatted email address. Please try again" -ForegroundColor Red
- }
- }while($match -ne $true)
- $match = "" #clear the $match variable for reuse
- #Check if sender address provided is an internal address, if so - require a subject line.
- if( $sender -match "long list of our email domains") {
- $SubjectRequired = $true
- }
- # Prompt user for subject line of email to search for, prompt user repeatedly until they enter a subject, if it's required.
- Do {
- if([string]::IsNullOrWhiteSpace($Subject)) {
- $Subject = Read-Host -Prompt "Please input the email subject line"
- }
- if( [string]::IsNullOrWhiteSpace($Subject) -and $SubjectRequired ) {
- write-host "You must enter a subject line when dealing with a Carilion Internal sender." -ForegroundColor Red
- }
- } while ($SubjectRequired -and [string]::IsNullOrWhiteSpace($Subject) )
- #Build a string to send to Event Log, and send an Application Event log entry
- $logtext = "Script ran by: $env:userdomain\$env:username`r`nSender address: $Sender`r`nSubject line: $Subject"
- Write-EventLog -LogName Application -Source "Email Deletion" -EntryType Information -EventId 65535 -Message $logtext
- #################################################################################
- #
- # Begin Office 365 Connectivity & cleanup
- #
- #################################################################################
- # Prompt user for O365 login credentials
- if((-not $O365User) -or (-not $O365Pass)) {
- $O365Credential = Get-Credential -Message "Please enter your Office365 credentials <user@domain.org> format."
- }
- try{
- write-verbose "Loading Office 365 Powershell Connection ..."
- $O365Sess = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid -Credential $O365Credential -Authentication Basic -AllowRedirection -ErrorAction Stop
- Import-PSSession $O365Sess -AllowClobber -DisableNameChecking -ErrorAction Stop
- write-verbose "Office 365 Security and Compliance center Powershell connection loaded."
- }
- catch{
- write-host "Loading Office 365 Powershell Connection failed. Please connect your internet connectivity, credentials provided or O365 portal status." -ForegroundColor Red
- exit
- }
- # Create O365 Content Search to locate the message. Uses the current date and the spam sender's address as a name for the
- $date = Get-Date -displayhint datetime
- $compsearchname = "$date - $Sender"
- $user = $env:USERNAME
- write-verbose "Creating Content search in O365 based on provided information."
- write-verbose "Spam sender email address: $Sender"
- write-verbose "Spam email subject line: $Subject"
- #Runs one search command if there is a subject line present, another if there is no subject line present.
- if(-not $Subject) {
- New-ComplianceSearch -Name $compsearchname -Description "Searching for Spam/Phishing message from $Sender. Search created by $user" -ExchangeLocation all -ContentMatchQuery "from: `"$Sender`""
- }
- else {
- New-ComplianceSearch -Name $compsearchname -Description "Searching for Spam/Phishing message from $Sender. Search created by $user" -ExchangeLocation all -ContentMatchQuery "subject:`"$Subject`" AND from: `"$Sender`""
- }
- Start-ComplianceSearch -Identity $compsearchname
- write-verbose "Content search created & started."
- Get-PSSession | Remove-PSSession #Removes O365 session so there is no confusion between commands from on-prem Exchange and O365 Exchange.
- #################################################################################
- #
- # Import Exchange 2010 snap ins & begin On Prem cleanup
- #
- #################################################################################
- write-verbose "Importing Exchange 2010 PowerShell SnapIn"
- # Attempt importing Exchange 2010 snap ins. Fail and exit script if not found.
- if((-not $ExchUser) -or (-not $ExchPass)) {
- $ExchCred = Get-Credential -Message "Please enter your On-Prem Exchange Admin credentials. <domain\username> format."
- }
- try{
- Write-Verbose "Loading Exchange 2010 Powershell Snapins ..."
- $ExchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://exch-prd-htcas1/powershell/ -Authentication Kerberos -Credential $ExchCred
- Import-PSSession $ExchSession
- }
- catch{
- Write-Host "Incorrect password or you do not have Exchange 2010 Management Shell installed. Please install before running this script" -ForegroundColor Red
- exit
- }
- # Get on-prem mailbox servers. Regex assumes they are all named "DAG--" with the last character being A or B, and third to last being any number.
- # The DAG server naming is likely unique to my org, they all end like DAG1A, DAG1B, etc.
- # We only have to do regex here because my orgs DAGs all have 3 members named A, B and C. The C items are only there for backup reasons and do not contain live mailboxes
- $MailboxServers = @()
- $MailboxServers = get-mailboxserver | where { $_.Name -match "DAG\w[AB]"}
- # Get on-prem CAS servers.
- # My org has 8 mailbox servers and 8 CAS servers. To spread workload, we connect powershell session to each CAS and run deletion script against one mailbox server per CAS.
- $HTCASServers = @()
- $HTCASServers = Get-ClientAccessServer
- write-verbose "We will now loop through the following Exchange Mailbox servers to remove the message from all on-prem mailboxes. This may take some time"
- write-verbose "$MailboxServers"
- $count = 0 #counter to incrememt which CAS server to connect to. This portion of script relies on org having an equal number of MBX and CAS servers
- foreach ($mbxsrv in $MailboxServers){
- $HTCAS = $HTCASServers[$count] # Select array item to pass to start-job block
- # Start-Job block allows parallel running of the cleanup task, which is essential as it reduces the time to process greatly.
- Start-Job -Name $mbxsrv -scriptblock {
- param (
- [Parameter()][string]$mbxsrv,
- [Parameter()][string]$Sender,
- [Parameter()][string]$Subject,
- [Parameter()][System.Management.Automation.PSCredential]$ExchCred,
- [Parameter()][String]$HTCAS
- )
- try {
- # Connects the background PS job to a CAS server.
- $ExchSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$HTCAS/powershell/" -Authentication Kerberos -Credential $ExchCred -ErrorAction Stop
- Import-PSSession $ExchSession -ErrorAction Stop
- }
- catch {
- write-host "Failed to connect to local exchange environment."
- exit
- }
- # Run a search logging the results, then a search deleting the results. Still trying to combine into one search.
- # Seperate commands depending on if the Subject line is present or not.
- if(-not $Subject) {
- Get-Mailbox -Server "$mbxsrv" -ResultSize Unlimited | Search-Mailbox -SearchQuery From:"$Sender" -targetmailbox contentfilter -targetfolder searchlog -loglevel full -logonly
- Get-Mailbox -Server "$mbxsrv" -ResultSize Unlimited | Search-Mailbox -SearchQuery From:"$Sender" -DeleteContent -force
- }
- else {
- Get-Mailbox -Server "$mbxsrv" -ResultSize Unlimited | Search-Mailbox -SearchQuery From:"$Sender",Subject:"$Subject" -targetmailbox contentfilter -targetfolder searchlog -loglevel full -logonly
- Get-Mailbox -Server "$mbxsrv" -ResultSize Unlimited | Search-Mailbox -SearchQuery From:"$Sender",Subject:"$Subject" -DeleteContent -force
- }
- } -ArgumentList $mbxsrv, $Sender, $Subject, $ExchCred, $HTCAS #args to send into the start-job scriptblock.
- $count += 1 # increments to select the next CAS server
- }
- get-job | wait-job # get created jobs, wait for completion, remove them.
- write-verbose "Spam message successfully removed from all on-prem mailboxes."
- Get-PSSession | Remove-PSSession #Removes local exchange session so there is no confusion between commands from on-prem Exchange and O365 Exchange.
- #################################################################################
- #
- # Check O365 Search & finalize cleanup
- #
- #################################################################################
- # Re-connect to O365 powershell
- write-verbose "Checking status of O365 Content Search."
- $O365Sess = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid -Credential $O365Credential -Authentication Basic -AllowRedirection -ErrorAction Stop
- Import-PSSession $O365Sess -AllowClobber -DisableNameChecking -ErrorAction Stop
- # Check compliance search status. Pause for 30s and check again if not Completed
- $search = Get-ComplianceSearch -Identity $compsearchname
- while($search.Status -ne "Completed") {
- write-host "O365 Content Search not yet completed. Waiting 30s" -ForegroundColor Red
- Start-Sleep -Seconds 30
- $search = Get-ComplianceSearch -Identity $compsearchname
- }
- write-verbose "Content search is complete."
- $found = (get-compliancesearch -identity $compsearchname).Items # get count of found items
- write-verbose "$found items found in O365"
- if($found -gt 0) { # if >0 found items, delete them all.
- write-verbose "Removing spam message from O365 mailboxes."
- New-ComplianceSearchAction -SearchName $compsearchname -Purge -Force #force flag seems to not be recognized; still prompts for deletion confirmation.
- Write-host "Removed $found matching emails in O365 mailboxes."
- }
- write-host "Spam message removed from all mailboxes, on-premesis and O365." -ForegroundColor Green
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement