User/Get-HawkUserHiddenRule.ps1
# Looks for hidden inbox rules in the mailbox Function Get-HawkUserHiddenRule { param ( [Parameter(Mandatory = $true)] [array]$UserPrincipalName, $EWSCredential ) Test-EXOConnection Send-AIEvent -Event "CmdRun" -Properties @{"cmdlet"="Get-HawkUserHiddenRule"} # Verify our UPN input [array]$UserArray = Test-UserObject -ToTest $UserPrincipalName # Process thru each object recieved foreach ($Object in $UserArray) { # Push the UPN into $user for ease of use $user = $object.UserPrincipalName # Determine if the email address is null or empty # If it is write a warning and skip the rest of the script [string]$EmailAddress = (get-mailbox $user).primarysmtpaddress if ([string]::IsNullOrEmpty($EmailAddress)) { Write-Warning "No SMTP Address found Skipping" Return $null } # If we don't have a credential object then ask for creds and push them into the global scope if ($null -eq $EWSCredential) { Out-LogFile "Please provide credentials that have impersonation rights to the mailbox you are looking to check" $EWSCredential = Get-Credential } # Import the EWS Managed API if (Test-Path 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll') { Out-LogFile "Ews Managed API Found" } else { Write-Error "Please install EWS Managed API 2.2 `nhttp://www.microsoft.com/en-us/download/details.aspx?id=42951" -ErrorAction Stop } # Import the EWS managed API dll Import-Module 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll' # Set up the EWS Connection Write-Host ("Setting up connection for " + $emailaddress) -ForegroundColor Green $exchService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_Sp1) $exchService.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($EWSCredential.username,$EWSCredential.GetNetworkCredential().password); # If we have the global URL for EWS then we just use it since it should all be the same in this case # Otherwise we need to get it via autodiscover if ($null -eq $EWSUrl){ $exchService.AutodiscoverUrl($emailAddress,{$true}) $exchService.url | Set-Variable -name EWSUrl -Scope Global } else { $exchService.url = $EWSUrl } # Set the connection up for impersonation so that we log into the mailbox we want not the one we have creds for $exchService.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$emailAddress); # Add the Anchor mailbox to the http header $exchService.HttpHeaders.Add("X-AnchorMailbox",[string]$EmailAddress) # Using the exchService object connect and retrieve all inbox rules # This DID NOT work since it didn't pull back the hidden rule # $rules = $exchService.GetInboxRules($EmailAddress) # Bind to the inbox folder try { $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox) } catch { # If we don't have rights to impersonate throw in the log file and provide a better error if ($_.Exception.innerexception -like "*permission to impersonate*") { Out-LogFile ("[ERROR] - Account does not have Impersonation Rights on Mailbox: " + $EmailAddress) Out-LogFile "https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-configure-impersonation:" Write-Error $_ -ErrorAction Stop } # If it isn't an impersonation error throw it and stop else { Write-Error $_ -ErrorAction Stop } } # Setup the search $SearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM.Rule.Version2.Message") $Itemview = new-object Microsoft.Exchange.WebServices.Data.ItemView(500) $ItemView.Traversal = [Microsoft.Exchange.Webservices.Data.ItemTraversal]::Associated # Create our property set to view $PR_RULE_MSG_NAME = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EC,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String) $PR_RULE_MSG_PROVIDER = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65EB,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String) $PR_PRIORITY = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x0026,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer) $psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IDOnly,$PR_RULE_MSG_NAME,$PR_RULE_MSG_PROVIDER,$PR_PRIORITY) # Add the property set to the item view $ItemView.PropertySet = $psPropset # Do the search and return the items $ruleResults = $inbox.finditems($SearchFilter,$Itemview) # Null our return arry and populate it [array]$ruleArray = $null $ruleResults | ForEach-Object {[array]$ruleArray += $_} # Set our found flag to false $FoundHidden = $false # Check each rule Foreach ($rule in $ruleArray) { # If either Rule Name or Rule Provider are null then we need to flag it and return the priority of the rule if ([string]::IsNullOrEmpty($rule.ExtendedProperties[0].value) -or [string]::IsNullOrEmpty($rule.ExtendedProperties[1].value)) { $priority = ($rule.ExtendedProperties | Where-Object {$_.propertydefinition.tag -eq 38}).value Out-LogFile ("Possible Hidden Rule found in mailbox: " + $EmailAddress + " -- Rule Priority: " + $priority) -notice $rule | Out-MultipleFileType -FilePrefix "EWS_Inbox_rule" -csv -user $user -append $FoundHidden = $true } } # If the flag wasn't set then we need to log that we didn't find any hidden rules for th euser if ($FoundHidden -eq $false) { Out-LogFile ("No Hidden rules found for mailbox: " + $EmailAddress) } # return $ruleArray } <# .SYNOPSIS Pulls inbox rules for the specified user using EWS. .DESCRIPTION Pulls inbox rules for the specified user using EWS. Searches the resulting rules looking for "hidden" rules. .PARAMETER UserPrincipalName Single UPN of a user, commans seperated list of UPNs, or array of objects that contain UPNs. .PARAMETER EWSCredential Credentials of a user that can impersonate the target user/users. Gather using (get-credential) Does NOT work with MFA protected accounts at this time. .OUTPUTS File: _Investigate.txt Path: \ Description: Adds any hidden rules found here to be investigated File: EWS_Inbox_rule.csv Path: \<User> Description: Inbox rules that were found with EWS .EXAMPLE Get-HawkUserHiddenRules -UserPrincipalName user@contoso.com -EWSCredential (get-credential) Searches user@contoso.com looking for hidden inbox rules using the provided credentials .EXAMPLE Get-HawkUserHiddenRules -UserPrincipalName (get-mailbox -Filter {Customattribute1 -eq "C-level"}) Looks for hidding inbox rules for all users who have "C-Level" set in CustomAttribute1 #> } |