Scenario: If you want to verify membership of a Exchange dynamic distribution group, run the following:
$DDG = Get-DynamicDistributionGroup All_Mbx
Get-Recipient -RecipientPreviewFilter $DDG.RecipientFilter
Scenario: If you want to verify membership of a Exchange dynamic distribution group, run the following:
$DDG = Get-DynamicDistributionGroup All_Mbx
Get-Recipient -RecipientPreviewFilter $DDG.RecipientFilter
Scenario: We migrated (offboarded) a mailbox from Exchange Online to Exchange On-Premises. Although the mailbox was successfully migrated to On-Premises, the Exchange Online mailbox (which should have been deprovisioned) was still available in the cloud with the following error found in the Users:
Exchange: Failed to disable the mailbox <GUID> due to a conflict in directory settings. To disable this mailbox, first run Enable-RemoteMailbox on-premises. After the next Dirsync sync cycle, run Disable-RemoteMailbox on-premises to disable this mailbox in the datacenter.; Exchange: An unknown error has occurred.
The issue is that we cannot Enable-RemoteMailbox On-Premises because a Mailbox already exists for the user account On-Premises. Also we already disabled the Exchange Online license for that account. Its just not working, MICROSOFT!
Instead we got around the issue by doing this:
Solution: In ADSIEdit, we cleared the value for msExchRemoteRecipientType. Originally this value was set to a ‘8’ (DeprovisionMailbox ). By clearing this value, the mailbox and the error are no longer present in Exchange Online and everything is good. There had to be an error in the process of the sync or the mailbox conversion, but after clearing the error there are no issues with the mailbox.
Scenario: A user no longer has fullaccess to a shared mailbox BUT the shared mailbox still attempts to reconnect via Autodiscover in the Outlook profile.
Solution: The following scriptlets will detect the autodiscover links associated with the problem mailbox and attempt to remove them. Note, you can remove all backlinks, or specific backlinks.
$u = "Steve"
$u_DN = Get-ADUser $u | select -ExpandProperty DistinguishedName
$d = Get-ADUser $u -Properties msExchDelegateListBL | select msExchDelegateListBL
#To remove all backLinks
$d.msexchdelegatelistBL | %{Set-ADUser $_ -Remove @{msExchDelegateListLink = "$u_dn"}}
#To Remove specific BackLinks
$SharedMailboxToRemove
$d | Where msexchdelegatelistBL -like "*$SharedMailboxToRemove*" | Select -ExpandProperty msexchdelegatelistBL | %{Set-ADUser $_ -Remove @{msExchDelegateListLink = "$u_dn"}}
Scenario: Users are reporting that their Mac Mail and Outlook for Mac email clients continuously disconnect and then reconnect making their mail client unreliable and unstable. EWS is the only mail protocol that is affected, all other protocols are fine.
Troubleshooting: We noticed the following (the timing for each item found was at the same time or really close together):
Event Viewer: We found the following events in the Application logs that tied together errors with ASP.Net and the crashing/restarting of the MSExchange Web Services app pool:
Wireshark: We saw connection Resets (RST) being issued from the server to the client, meaning it was the server that was the cause of disconnecting clients to the server. Wireshark Filter: (ip.dst==10.1.1.2 or ip.src==10.1.1.2) and tcp.flags.reset ==1
AuthConfig: Troubleshooting the ASP.NET error and the message: missing signing certificate, we realized that the certificate currently being used for server authentication was expired. (ExPowershell: Get-authconfig)
Solution: ASP.NET was breaking as a result of the certificate used for AuthConfig. When ASP.NET broke, so did EWS. We created/deployed a new certificate and this fixed our issue.
We created a new certificate:
New-ExchangeCertificate -KeySize 2048 -PrivateKeyExportable $true -SubjectName “cn=Microsoft Exchange Server Auth Certificate” -FriendlyName “Microsoft Exchange Server Auth Certificate” -DomainName “contoso.com”
Then we exported the new cert and imported to each Ex Server:
Export-ExchangeCertificate -Thumbprint E5AAEBA3DCB406331949D3FB5E108FC7EF3B0B62 -FileName “\ExSrv1C$authcert.pfx” -BinaryEncoded -Password (ConvertTo-SecureString -String ‘password’ -AsPlainText -Force)
$Servers = get-exchangeserver
$servers.name | %{
“$_”
Import-ExchangeCertificate -Server $_ -FileName “\ExSrv1C$authcert.pfx” -Password (ConvertTo-SecureString -String ‘password’ -AsPlainText -Force)
}
Next we set the AuthConfig to the new certificate:
Set-AuthConfig -NewCertificateThumbprint E5AAEBA3DCB406331949D3FB5E108FC7EF3B0B62 -NewCertificateEffectiveDate (Get-Date)
Next we Published the Cert:
Set-AuthConfig –PublishCertificate
Since this issue was a result of ASP.NET errors, this made the errors go right away. I followed up with Restarting the Web App Pools for the following just in case:
Restart-WebAppPool MSExchangeOWAAppPool
Restart-WebAppPool MSExchangeECPAppPool
Restart-WebAppPool MSexchangeServicesAppPool
Scenario: We found that using Microsoft’s spider script (the script that determines all mailbox permissions and delegates found here) was slow and would eat RAM (like Cookie Monster eats cookies) causing our Exchange servers to error out. So we developed a newer, faster, but more raw version of the spider script.
Script: Edit the global variables and then copy and paste in normal Windows Powershell. You want the scriptlet pretty and easy to read, copy and paste into PowerShell ISE. This is not meant to run as a .ps1, we like to see everything….
<#Script Notes:
0. Output of the file will display FullAccess, SendAs, SendOnBehalf, and Calendar Permissions (Reviewer,Editor, ect.)
1. Open a normal Windows Powershell with an account with Exchange Permissions (Run-As)
2. Take a list of all Exchange On-Premises Mailboxes (get-mailbox -resultsize unlimited | Select Alias | export-csv C:tempAll_mbx.csv. All we need is the alias column (keep the header alias), nothing else.
3. This script requires the ActiveDirectory Module
4. In the New-OnPremExchangeSession it will randomly select one of our Exchange servers to process the remote PowerShell Commands. After 500 mailboxes, it will randomly select another.
5. If you have to start over, open a brand new normal Windows Powershell with an account with Exchange Permission (Run-As)
End_ScriptNotes #>
#Global Variables############################################################################################
$m = import-csv “C:tempAll_Mbx.csv” #Import a list of all your Mailboxes. If you have not done this yet, feel free to run the following command inside a Exchange PowerShell: get-mailbox -resultsize unlimited | Export-csv C:tempAll_mbx.csv
$outfile = “C:tempAll_Mbx_Spider_Results.csv” #Final Spider Results Export
$report_Final = @() #Used to capture all spider rights within the script
$count = 0 #The Count starts the counter for each mailbox processed
$CounterSleep = 500 #This offset countersleep allows the script to sleep after 500 Mailboxes and pickup a new Exchange server to connect to to avoid hardware/resource problems
$ExchangeServers = “ExSrv1.domain.com”,”ExSrv2.domain.com”,”ExSrv3.domain.com” #Exchange server pool that your Powershell session with connect to after the CounterSleep hits
$domainForUsername = “domain” #Replace the domain with the domain name used for sign ins. Example: If you login is domainusername: contososteve make the value “contoso”
$dom = $env:userdomain;$usr = $env:username #Just for fun in the script
$DisplayName = ([adsi]”WinNT://$dom/$usr,user”).fullname #Just for fun in the script
#End_Global Variables############################################################################################
#This is where the MAGIC HAPPENS
#Import Module####################################################################################################
#Required for AD Permissions
Import-Module ActiveDirectory
#End_Import Module#####################################################################################################
#Functions required##################################################################################################################################
#Gets nested group members
function Get-DistributionGroupMemberRecursive ($GroupIdentity) {
$member_list = Get-DistributionGroupMember -Identity $GroupIdentity
foreach ($member in $member_list) {
if ($member.RecipientType -like ‘*Group*’) {
Get-DistributionGroupMemberRecursive -GroupIdentity $member.Identity
} else {
$member
}
}
}
#Connects to Exchange remote Powershell on servers randomly
Function New-OnPremExchangeSession(){
#close any old remote session. We don’t need it. Don’t want it.
Get-PSSession | Remove-PSSession -Confirm:$false
For ($i=60; $i -gt 1; $i–-) {
Write-Progress -Activity “$DisplayName made me fall asleep.” -SecondsRemaining $i
Start-Sleep 1
}
Do{
#get-random number for exchange server
$ex_srv = get-random $ExchangeServers
$ex_ps = “http://”+$ex_srv +”/powershell/”
#start a new remote session
“Attempting to connect to Remote Powershell on esgmtwex$ex_i”
$OnPremsession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ex_ps -Authentication Kerberos
$OnPrem = Import-PSSession $OnPremSession
#check for session
$opensession = Get-PSSession | Where {($_.Configurationname -eq “Microsoft.Exchange”) -and ($_.State -eq “Opened”)}
}While($opensession -eq $null)
}
#End_Functions##############################################################################################
#Connect to Exchange##############################################################################################################################
New-OnPremExchangeSession
#END_ConnecttoExchange##############################################################################################################################
#Loop Each Mailbox#################################################################################################################################################################
$m.alias | sort | %{
#Define InLoop Variables
$u = $_
#write-it so you can see it.
Write-host “$U – $count/$($m.count – 1)” -ForegroundColor green
$count++
If($count -eq $CounterSleep){
New-OnPremExchangeSession $OnPremCredentials
$CounterSleep = $CounterSleep + 500
“CounterSleep now set to $CounterSleep”
}
[int]$percentComplete = [int](($Count/$($M.count * 100)))
Write-Progress -Activity “Connected to $((Get-PSSession | Where {($_.Configurationname -eq “Microsoft.Exchange”) -and ($_.State -eq “Opened”)}).computername)” -PercentComplete “$percentComplete” -Status (“Processing Mailbox: $($U) – $($Count) of $($m.count – 1 )”)
“————————”
#Check Mbx
$error.clear()
$mbx = get-mailbox $u
If($error[0].exception -like “*The I/O operation has been aborted*”){“I/O Error Operation found, sleeping 3 minutes”;sleep 180; $mbx=get-mailbox $u}
If($mbx -ne $null){
#here we go!!!!!
#Collect SendOnBehalf permissions##############################################################################################
” Checking SendOnBehalf for $U”
$SendOnBehalf = $mbx.grantsendonbehalfto
If($SendOnBehalf -ne $null){
$SendOnBehalf | %{
$sob_name = $_
$sob_name = ($sob_name -split ‘/’)[-1]
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value $sob_name
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “SendOnBehalf”
$Report_final += $obj
}
}else{
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value “None”
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “SendOnBehalf”
$Report_final += $obj
}
$SendOnBehalf = $null
#End_Calendar##################################################################################################################
#Collect Calendar permissions##############################################################################################
” Checking Calendar for $U”
$cal_var = ($mbx.alias).tostring() +”:calendar”
$Calendar_Perm = get-mailboxfolderpermission $cal_Var | Where {($_.User -notlike “*Default*”) -and ($_.user -notlike “*anonymous*”)}
If($Calendar_Perm -ne $Null){
$calendar_Perm | %{
$cal_user_name = $_.user.adrecipient.name
If($cal_user_name -ne $null){
$cal_user_right = $_ | Select -ExpandProperty AccessRights
#”$Cal_user_name – $Cal_user_right”
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value $cal_user_name
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “Calendar:$cal_user_right”
$Report_final += $obj
}
}
}else{
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value None
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “Calendar”
$Report_final += $obj
}
#Clear FullAccess
$Cal_Var = $null
$Calendar_Perm = $null
$Cal_user_name = $null
$Cal_user_right = $null
#End_Calendar##################################################################################################################
#Collect SendAs permissions##############################################################################################
#This method does not perform a get-adpermission because its slow.
#Why does Microsoft want us to run slow commands when the offer faster commands.
” Checking Sendas for $U”
$SendAs_Perm = (Get-acl -path “AD:$($mbx.distinguishedname)”).access |where {($_.ActiveDirectoryRights -like “*ExtendedRight*”) -and ($_.IsInherited -like “*false*”) -and ($_.IdentityReference -like “$domainForUsername*”) -and ($_.ObjectType -eq “ab721a54-1e2f-11d0-9819-00aa0040529b”)}
#$SendAs = $mbx | Get-ADPermission | Where extendedrights -like send-as | Where User -notlike “Nt AuthoritySelf”
If($SendAs_Perm -ne $Null){
$SendAs_users = @()
$Sendas_Perm.IdentityReference.Value |%{
#Format User Name
$object = $_
$object = $object -replace “$domainForUsername\”,””
#ADCheck
$AD_Chk = Get-adobject -filter {samaccountname -eq $object}
#Write-host ” $($AD_Chk | Select name, objectclass)” -ForegroundColor yellow
#ObjectClass Check based off ADObject $AD_CHK
If($AD_Chk.objectclass -eq “User”){$SendAs_users += $AD_CHK | Select -ExpandProperty Name}
If($AD_Chk.objectclass -eq “Group”){$SendAs_users += Get-DistributionGroupMemberRecursive $($AD_Chk | Select -ExpandProperty Name) | Select -ExpandProperty Name}
$Sendas_users | select -Unique | %{
$delegate = $_
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value $delegate
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “SendAs”
$Report_final += $obj
}
}
}else{
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value None
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “SendAs”
$Report_final += $obj
}
#Clear SendAsVariables
$SendAs_Perm = $null
$Sendas_users = $null
$object = $null
$AD_Chk = $null
$delegate = $null
#End_SendAs##################################################################################################################
#Collect MBX permissions##############################################################################################
” Checking FullAccess for $U”
$FullAccess_Perm = $mbx | get-mailboxpermission | Where {($_.IsInherited -eq $false) -and ($_.User -notlike “NT Auth*”) -and ($_.Deny -eq $false)}
If($FullAccess_Perm -ne $Null){
$fullAccess_Users = @()
$fullAccess_Perm.user | %{
#$fullAccess_Perm.user.securityidentifier | %{
#Format User Name
$object = $_
$object = $object -replace “$domainForUsername\”,””
#ADCheck
#$AD_Chk = Get-adobject -filter {objectsid -eq $object}
$AD_Chk = Get-adobject -filter {samaccountname -eq $object}
#ObjectClass Check based off ADObject $AD_CHK
If($AD_Chk.objectclass -eq “User”){$FullAccess_users += $AD_CHK | Select -ExpandProperty Name}
If($AD_Chk.objectclass -eq “Group”){$FullAccess_users += Get-DistributionGroupMemberRecursive $($AD_Chk | Select -ExpandProperty Name) | Select -ExpandProperty Name}
$FullAccess_users | select -Unique | %{
$delegate = $_
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value $delegate
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “FullAccess”
$Report_final += $obj
}
}
}else{
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value None
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “FullAccess”
$Report_final += $obj
}
#Clear FullAccess
$FullAccess_Perm = $null
$FullAccess_users = $null
$object = $null
$AD_Chk = $null
$delegate = $null
#End_FullAccess##################################################################################################################
}else{
Write-Host “No Mbx for $u” -ForegroundColor Magenta
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -Name Mbx -Value $u
$obj | Add-Member -membertype noteproperty -Name Delegate -Value None
$obj | Add-Member -membertype noteproperty -Name AccessRight -Value “No_Mbx_Found”
$Report_final += $obj}
#Clear InLoop Variables.
#Wash, Rinse, Repeat
$u = $null
$mbx = $null
}
#END_Loop Each Mailbox#################################################################################################################################################################
#View the Report##################################################################################################################################################################
#$report_Final
#$report_Final | out-gridview
$Report_Final | export-csv $outfile
#View the Report##################################################################################################################################################################
Scenario – You want to see what Management Roles and Commands a user can run from Exchange PowerShell
Scriptlet:
#Determine management role assignments for an account
$1= Get-ManagementRoleAssignment -RoleAssignee <username>
$1 | Select Role
#Determine what commands are associated with that account
#For a Single Role
Get-ManagementRole Monitoring | FL
Get-ManagementRole Monitoring | Select -ExpandProperty RoleEntries | Select Name
Get-ManagementRole Monitoring | Select -ExpandProperty RoleEntries |Sort Name | Select name
#For Multiple Roles from $1
$Roles = @()
$1.role.name | %{
$n = $_
$temp = Get-managementrole $n | Select -ExpandProperty RoleEntries |Sort Name | Select -expandproperty name
$temp | %{
$c = $_
$ServerObj = New-Object PSObject
$ServerObj | Add-Member NoteProperty -Name “ManagementRole” -value $n
$ServerObj | Add-member NoteProperty -Name “Command” -Value $c
$Roles += $ServerObj
}
$n = $null
$c = $null
}
#Display $roles
$roles | Sort Command | Select Command, ManagementRole
Scenario: You want to pull in values/output from other commands into the output of a different command. In Exchange we know not all uniquely identifiable properties are attached to each exchange command:
Example: The Alias can be found in get-mailbox, but is not tied to the output of a get-mailboxstatistics command.
In the scriptlet below, we are going to tie together the following properties in a single one-liner using expressions within the Select-Object statement:
Scriptlet:
Get-mailboxstatistics steve | Select Displayname,`
Total*Size,`
@{Name=”User_Email”;Expression={$u = $_.LegacyDN; (@(get-mailbox “$u”)).primarysmtpaddress}},`
@{Name=”Alias”;Expression={$u = $_.LegacyDN; (@(get-mailbox “$u”)).alias}}, `
@{Name=”HasActiveSyncDevicePartnership”;Expression={$u = $_.LegacyDN; (@(get-casmailbox “$u”)).HasActiveSyncDevicePartnership}}, `
@{Name=”MobileDeviceCount”;Expression={$u = $_.LegacyDN; (@(get-mobiledevice -mailbox “$u”)).count}}
Another example: Pulling the Get-mailboxfolderpermission for the calendar, but including the primarysmtpaddress in the Select statement of the delegated user:
get-mailboxfolderpermission steve:calendar | Select FolderName,`
User,`
@{Name=”User_Email”;Expression={$u = $_.user; (@(get-mailbox “$u”)).primarysmtpaddress}},`
AccessRights
Scenario: Although RegEx searches are not supported within the Exchange toolset, here is an EWS Script that will perform two kinds of RegEx searches; Patterns AND exact matches (not case sensitive).
The script below is going to do the following:
Scripts:
#Finding items With RegEx
#Variables
$cred = Get-credential #credentials will fullaccess to access the mailbox
$mailboxname = “stevetest25@domain.com” #The Mailbox you wish to perform the query and restore on
$EWS_DLL = “C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll”
$EWS_URL = “https://domain/ews/exchange.asmx”
#Configure connection to EWS
Import-Module -Name $EWS_DLL
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2013)
$service.Url = new-object System.Uri($EWS_URL)
$service.UseDefaultCredentials = $false
$service.Credentials = $cred.GetNetworkCredential()
#Find all Mailbox folders
$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)
#Bind to BadFolders for RegEx and Terms
$BADfolder_Reg = $findFolderResults | Where displayname -like “BadFolder_Reg”
$BADfolder_Term = $findFolderResults | Where displayname -like “BadFolder_Term”
If($BadFolder_Reg -eq $null){
#Create a Folder called BAD on the Root
“Bad folder doesnt exist, creating it now”
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailboxname)
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = “BadFolder_reg”
$NewFolder.Save($Folder.id)
$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
#Find all folders in the mailbox
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)
$BADfolder_Reg = $findFolderResults | Where displayname -like “BadFolder_Reg”
}
If($BadFolder_Term -eq $null){
#Create a Folder called BAD on the Root
“Bad folder doesnt exist, creating it now”
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailboxname)
$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = “BadFolder_Term”
$NewFolder.Save($Folder.id)
$MailboxRootid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MailboxRoot=[Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$MailboxRootid)
#Find all folders in the mailbox
$FolderList = new-object Microsoft.Exchange.WebServices.Data.FolderView(1000)
$FolderList.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$findFolderResults = $MailboxRoot.FindFolders($FolderList)
$BADfolder_Term = $findFolderResults | Where displayname -like “BadFolder_Term”
}
#Create Variables for Search
$ItemPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$i = 0
$i_end = $findfolderResults.item.count
$reg = @()
$reg += “[1-9][0-9]{2}-[0-9]{2}-[0-9]{4}^d”
$reg += “(^|D)(d{3}-d{2}-d{4})(D|$)”
$DownloadDirectory = “\servershare$attachments”
$term = ” test123 “,” steve “,” batman “,” superman ”
#Loop each mail folder and perform the search
Do{
If(($findFolderResults.Folders[$i]).DisplayName -notlike “Badfolder*”){
“Checking Folder: $(($findFolderResults.Folders[$i]).DisplayName)”
$ItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
Do{
$AqsString = “System.Message.DateReceived:01/01/2000..12/31/2099”
$fiItems = $findFolderResults.Folders[$i].FindItems($AqsString,$ItemView)
$ItemView.offset += $fiItems.Items.Count
[Void]$service.LoadPropertiesForItems($fiItems , $ItemPropset)
foreach($Item in $fiItems.Items){
“Checking on $($Item.Subject)”
#Check for attachments#########################
If($item.Hasattachments -eq $true){
“Attachment Detected on $($Item.Subject)”
foreach($attach in $Item.Attachments){
$attach.Load()
$fiFile = new-object System.IO.FileStream(($downloadDirectory + “” + $attach.Name.ToString()), [System.IO.FileMode]::Create)
$fiFile.Write($attach.Content, 0, $attach.Content.Length)
$fiFile.Close()
write-host “Downloaded Attachment : ” + (($downloadDirectory + “” + $attach.Name.ToString()))
}
}
#^Check for attachments#########################
#Check for Reg#########################
$reg_result = $false
$b_temp = $Item.body.text
#Loop regex
$reg | %{
$r = $b_temp -match “$_”
“Result: $r”
if($r -eq $true){“Setting $reg_result to $r”;$reg_result = $true}
}
#display
“$Reg_result – The MSG with Subject: $($Item.subject) ”
If($reg_result -eq $true){
“Moving $($Item.Subject) to BadFolder_reg”
[VOID]$Item.Move($BadFolder_reg.Id)}
#^Check for Reg##################################################
#Check for Terms#########################
$Term_result = $false
$b_temp = $Item.body.text
#Loop term
$term | %{
$rr = $b_temp -match $_
“Result: $rr”
if($rr -eq $true){“Setting $term_result to $rr”;$term_result = $true}
$term_temp = $null
}
#display
“$term_result – The MSG with Subject: $($Item.subject) ”
If($term_result -eq $true){
“Moving $($Item.Subject) to BadFolder_term”
[VOID]$Item.Move($BadFolder_term.Id)}
#^Check for Terms##################################################
#clean var
$r = $null
$b_temp = $null
}
}While($fiItems.moreavailable -eq $true)
}
$i++
“FolderID Counter $i”
}While ($i -le $i_end)
Scenario: You are going to install the latest CU for Exchange, but you want to check the AD Schema levels to see if they need to be upgraded before the CU install
Command Line: Using CMD line, run the following: (Everything in bold needs to be edited to reflect your Exchange organization OR your domain)
dsquery * "cn=Enterprise Exchange,cn=Microsoft Exchange,cn=services,cn=configuration,dc=root,dc=domain,dc=com" -scope base -attr msExchProductID dsquery * "cn=Enterprise Exchange,cn=Microsoft Exchange,cn=services,cn=configuration,dc=root,dc=domain,dc=com" -scope base -attr objectVersion dsquery * "CN=Microsoft Exchange System Objects,DC=child,DC=root,DC=domain,DC=com" -scope base -attr objectVersion dsquery * cn=ms-Exch-Schema-Version-Pt,cn=schema,cn=configuration,dc=root,dc=domain,dc=com -scope base -attr rangeUpper
Scenario: When performing a New-MailboxImportRequest, you receive the following error:
QuotaExceededException
Error: Cannot save changes made to an item to store. –> MapiExceptionShutoffQuotaExceeded: Unable to save changes.
Solution: Increase the Quotas on the mailbox. It was the Recoverable quotas that were giving me an issue.
Set-Mailbox mailbox -RecoverableItemsWarningQuota 100GB -RecoverableItemsQuota 100GB -UseDatabaseQ
uotaDefaults $false -IssueWarningQuota unlimited -ProhibitSendQuota unlimited -ProhibitSendReceiveQuota unlimited