Migration of receive connectors from Exchange 2007/2010 to Exchange 2013

I have recently came to a need to migrate many receive connectors from Exchange 2010 to Exchange 2013. I helped myself by creating a function, which migrates all connectors from one server to another. Connectors with same settings (bindings, Remote IP ranges and port) are skipped. Function doesn’t automatically grant anonymous relay permission, because I think it is worth setting manually after check of migrated connectors, since almost all environments are messy :).

Don’t forget, that there is major architecture change in Exchange 2013! All external e-mails should flow via FrontEndTransport service! The detailed description with consequences is mentioned here:

http://blogs.technet.com/b/rischwen/archive/2013/03/13/exchange-2013-mail-flow-demystified-hopefully.aspx

Description:

  • Connectors are listed from selected server
  • Default connectors are skipped
  • If you use server name in FQDN for some reason, please check FQDN manually after transfer
  • Connectors are being created with WhatIf parameter to keep admin informed of the changes
  • Admin can confirm, that connectors should be created if output is OK, if not, admin can skip
  • All tasks are recorded in Transcript (default location)
function Transfer-ReceiveConnectors ($source, $destination, $bindings, $transportrole){
$OldServer = $source
$NewServer = $destination
Write-Host "Transrtipt will be started."  -foregroundcolor "yellow"
start-transcript

Write-Host "Getting receive connectors..."  -foregroundcolor "yellow"
[array]$ReceiveConnectors = Get-ReceiveConnector -Server $OldServer | Where {$_.Name -notlike "Default $($OldServer)" -and $_.Name -notlike "Client $($OldServer)"} 

Write-Host "Testing creation of receive connectors..."  -foregroundcolor "yellow"
$ReceiveConnectors | foreach {
Write-Host "Testing: $($_.name)"  -ForegroundColor "blue" -BackgroundColor "White"
                New-ReceiveConnector -MaxAcknowledgementDelay $_.MaxAcknowledgementDelay -FQDN $_.fqdn -TransportRole $transportrole -Bindings $bindings -Name $_.Name -AuthMechanism $_.AuthMechanism -RemoteIPRanges $_.RemoteIPRanges -Banner $_.Banner -ChunkingEnabled $_.ChunkingEnabled -DefaultDomain $_.DefaultDomain -DeliveryStatusNotificationEnabled $_.DeliveryStatusNotificationEnabled -EightBitMimeEnabled $_.EightBitMimeEnabled -DomainSecureEnabled $_.DomainSecureEnabled -LongAddressesEnabled $_.LongAddressesEnabled -OrarEnabled $_.OrarEnabled -Comment $_.Comment -Enabled $_.Enabled -ConnectionTimeout $_.ConnectionTimeout -ConnectionInactivityTimeout $_.ConnectionInactivityTimeout -MessageRateLimit $_.MessageRateLimit -MaxInboundConnection $_.MaxInboundConnection -MaxInboundConnectionPerSource $_.MaxInboundConnectionPerSource -MaxInboundConnectionPercentagePerSource $_.MaxInboundConnectionPercentagePerSource -MaxHeaderSize $_.MaxHeaderSize -MaxHopCount $_.MaxHopCount -MaxLocalHopCount $_.MaxLocalHopCount -MaxLogonFailures $_.MaxLogonFailures -MaxMessageSize $_.MaxMessageSize -MaxProtocolErrors $_.MaxProtocolErrors -MaxRecipientsPerMessage $_.MaxRecipientsPerMessage -PermissionGroups $_.PermissionGroups -PipeliningEnabled $_.PipeLiningEnabled -ProtocolLoggingLevel $_.ProtocolLoggingLevel -RequireEHLODomain $_.RequireEHLODomain -RequireTLS $_.RequireTLS -EnableAuthGSSAPI $_.EnableAuthGSSAPI -ExtendedProtectionPolicy $_.ExtendedProtectionPolicy -SizeEnabled $_.SizeEnabled -TarpitInterval $_.TarpitInterval -Server $NewServer -WhatIf
        } 
Write-Host "If output is expected and you want to create connectors, please type Y."  -foregroundcolor "yellow"
$Continue = read-host "Please confirm: "
if ($continue -eq "Y"){
        $ReceiveConnectors | foreach {
                New-ReceiveConnector -MaxAcknowledgementDelay $_.MaxAcknowledgementDelay -FQDN $_.fqdn -TransportRole $transportrole -Bindings $bindings -Name $_.Name -AuthMechanism $_.AuthMechanism  -RemoteIPRanges $_.RemoteIPRanges -Banner $_.Banner -ChunkingEnabled $_.ChunkingEnabled -DefaultDomain $_.DefaultDomain -DeliveryStatusNotificationEnabled $_.DeliveryStatusNotificationEnabled -EightBitMimeEnabled $_.EightBitMimeEnabled -DomainSecureEnabled $_.DomainSecureEnabled -LongAddressesEnabled $_.LongAddressesEnabled -OrarEnabled $_.OrarEnabled -Comment $_.Comment -Enabled $_.Enabled -ConnectionTimeout $_.ConnectionTimeout -ConnectionInactivityTimeout $_.ConnectionInactivityTimeout -MessageRateLimit $_.MessageRateLimit -MaxInboundConnection $_.MaxInboundConnection -MaxInboundConnectionPerSource $_.MaxInboundConnectionPerSource -MaxInboundConnectionPercentagePerSource $_.MaxInboundConnectionPercentagePerSource -MaxHeaderSize $_.MaxHeaderSize -MaxHopCount $_.MaxHopCount -MaxLocalHopCount $_.MaxLocalHopCount -MaxLogonFailures $_.MaxLogonFailures -MaxMessageSize $_.MaxMessageSize -MaxProtocolErrors $_.MaxProtocolErrors -MaxRecipientsPerMessage $_.MaxRecipientsPerMessage -PermissionGroups $_.PermissionGroups -PipeliningEnabled $_.PipeLiningEnabled -ProtocolLoggingLevel $_.ProtocolLoggingLevel -RequireEHLODomain $_.RequireEHLODomain -RequireTLS $_.RequireTLS -EnableAuthGSSAPI $_.EnableAuthGSSAPI -ExtendedProtectionPolicy $_.ExtendedProtectionPolicy -SizeEnabled $_.SizeEnabled -TarpitInterval $_.TarpitInterval -Server $NewServer -verbose
                }
       Write-Host "Completed!"  -foregroundcolor "green"
}else {Write-Host "Aborted!"  -foregroundcolor "red"}
Stop-TranScript
}

Function can be called by the following cmdlet:

Transfer-ReceiveConnectors <SOURCE_SERVER> <TARGET_SERVER> <BINDINGS> <ExchangeTransportRole>

Examples:

Transfer-ReceiveConnectors EX2010 EX2013 0.0.0.0:25,[::]:25 FrontEndTransport
Transfer-ReceiveConnectors EX2010 EX2013 192.168.1.25:25 HubTransport
Advertisements

How to backup Exchange 2013 database on Windows Server 2012

Exchange backup limitations

  • Only Full backup is possible with log truncation (incremental backups do not flush logs)
  • Normal backup performance option does always full backup, but only differences are stored in the disk, while using file block mode.

After initial full backup every other backup of the same volume to the same target is incremental unless the following two conditions are fulfilled:

Configuring Windows backup

Installation

Windows Server Backup feature is not installed by default on Windows 2012 server. To gather status use the following Powershell command:

Get-windowsfeature | where {$_.name -like "*backup*"}

Backup_feature_not_installed

To install Windows Server Backup features run the following commands from Powershell. These commands will install needed features to run Exchange backup via command line tool Wbadmin.

Add-WindowsFeature "Windows-Server-Backup"

after-installation

In backup/restore of Exchange servers we will use Powershell commands. In comparison with previous version of Windows server there is no need to add pssnapin for backup to Exchange Powershell session.

Add new disk for Exchange backups. In script there used “Backup Disk” as volume name. (Depends on the HW you use so no further notice here)

Configuration

To successfully configure Windows Server Backup we must first define backup policy:

$WBPolicyFull = New-WBPolicy									# Create new WB policy object
$WhatToBackup = New-WBFileSpec –FileSpec E:\				# Define what to backup
Add-WBFileSpec –Policy $WBPolicyFull –FileSpec $WhatToBackup 	# Adding what to backup to backup policy
$WBTarget = New-WBbackupTarget –NetworkPath "\\Servername\sharename\path" 	# Selected backup disk will be set as target
Add-WBBackupTarget –Policy $WBPolicyFull -Target $WBTarget 		# Adding target to WB policy
Set-WBVssBackupOptions -Policy $WBPolicyFull -VssFullBackup			# Set method to use WSS Full Backup

Check

To check policy:

$WBPolicyFull

Policy configured in previous step might be started directly

Start-WBBackup -Policy $WBPolicyFull

Or scheduled

Set-WBSchedule –Policy $WBPolicyFull –Schedule 21:00

List backup sets

To list backup sets:

Get-WBBackupSet

Example 1

$WBPolicyFull = New-WBPolicy
$WhatToBackup = New-WBFileSpec –FileSpec E:\
Add-WBFileSpec –Policy $WBPolicyFull –FileSpec $WhatToBackup 
$WBTarget = New-WBbackupTarget –Networkpath "\\Ex13node2\g$\Full"
Add-WBBackupTarget –Policy $WBPolicyFull -Target $WBTarget
Set-WBVssBackupOptions -Policy $WBPolicyFull -VssFullBackup
Start-WBBackup -Policy $WBPolicyFull
Set-WBSchedule –Policy $WBPolicyFull –Schedule 21:00

or create a task

Example 2

Example can be downloaded on My Skydrive (E2013BackupW12.zip)

ZIP file contains:

  • *.PS1 file – script to perform backup
  • *.XML file – windows task file example

This Example creates backup of single mailbox database to local drive and then copies it to network drive.

$dat = get-date
start-transcript "C:\ExchangeScripts\Backups\DB_Backup_$($dat.day)_$($dat.month)_$($dat.year)_report.txt"
write-host "started"
new-item -ItemType Directory -path "G:\Full\$($dat.dayofweek)" -erroraction SilentlyContinue
New-PSDrive –Name “G” –PSProvider FileSystem –Root “\\fileserver\data\ExchangeBackup” –Persist
$target = "\\Ex13node2\d$\ExchangeBackup"
#$target = "\\fileserver\data\Full\$($dat.dayofweek)\ExchangeBackup"
$drive = "G:\Full\$($dat.dayofweek)"
$cleanup = $drive + "\WindowsImageBackup"
Remove-Item -Recurse -Force $cleanup
write-host $target
$policy = New-WBPolicy
$co_zalohovat= New-WBFileSpec -filespec F:\
Add-WBFileSpec -Policy $policy -FileSpec $co_zalohovat
$backuplocation = New-WBBackupTarget -networkpath $target
Add-WBBackupTarget -Policy $policy -Target $backuplocation
Set-WBVssBackupOptions -Policy $policy -VssFullBackup
Start-WBBackup -Policy $policy -force
get-wbjob -previous 1
Get-ChildItem –path $($target) -Recurse | Foreach-Object  { copy-item -Path $_.fullname -Destination $($drive) }
stop-transcript

Result of example

Example_run

This solution works only, when running backup from active database copy on member of DAG, which hosts only active DB copies.

Exchange 2010 – Get-MailboxDatabaseStatistics (your customization)

The function Get-MailboxDatabaseStatistics has been created due to a reporting purpose. I was focused mainly on script output and customization. It means that the most part of script code is related to the output and its attributes. Well it would be quite easy to modify the output attributes based on your needs.

Script prerequisites

  • Exchange Server 2010
  • Exchange Management Shell run-space
  • Organization Management (RBAC)

Script inputs

The function requires one of these inputs: DatabaseName, ServerName, AllDatabases. It means that we can call the function for example like:

Get-MailboxDatabaseStatistics -DatabaseName mbx11

Get-MailboxDatabaseStatistics -DatabaseName mbx11,mbx12

Get-MailboxDatabaseStatistics -DatabaseName (Get-MailboxDatabase|?{$_.Server -like "*exch10*"})

Get-MailboxDatabaseStatistics -ServerName exch10ser01

Get-MailboxDatabaseStatistics -AllDatabases

Database queries (code)

The function expects database name/names declared via input parameters. After input validation process, the function can process particular database name in a loop. The loop is uses for the following queries:

  • $query1 = Get-MailboxDatabase -Identity $db -Status
  • $query2 = Get-Mailbox -Database $db
  • $query3 = $query2 |%{if($_.Identity -ne $null){Get-MailboxStatistics -identity $_.identity}}

As can be seen above, here is the first thing for consideration/customization. Because the script processing time depends primarily on amount and severity of particular query. So the processing time can be decreased by query optimization (e.g. omit  Get-Mailbox etc.).

Output attributes (code)

The loop fills query variables ($query1, $query2, $query3) and those variables are used for declaration of attributes into output brick.  Due to this reason the brick can contain original values as same as a variation of values from all queries at once. Attributes are added into the brick through simple function addResultAttribute:

function addResultAttribute ($propertyName,$propertyValue){
$result | add-member -Type NoteProperty -name $propertyname -value $propertyValue
}

Just for example we can create attribute DatabaseName by using query1 (Get-MailboxDatabase -Status) and its parameter Name:

  • DatabaseName : DB01
addResultAttribute DatabaseName $query1.Name

Another example is attribute  RecipientTypeStatus which keeps amount of mailboxes based on  RecipientTypeDetails:

  • RecipientTypeStatus: {158-UserMailbox, 36-SharedMailbox, 1-DiscoveryMailbox, 3-ArbitrationMailbox}
addResultAttribute RecipientTypeStatus (($query2|Group-Object -Property RecipientTypeDetails|%{$_.Count,$_.Name -join ("-")}) -join (",")).ToString()

Feel free to modify brick attributes. The function contains only attributes regarding my scenario.

Scrip output

The output is brick wall as collection. It contains the brick with declared attributes for each database which was processed by the function. So it can looks like:

DatabaseName                     : DB01
DatabaseSize                     : 171 GB (183,619,878,912 bytes)
AvailableNewMailboxSpace         : 12.3 GB (13,204,750,336 bytes)
CircularLoggingEnabled           : False
LogFolderPath                    : E:\DB01
EdbFilePath                      : E:\DB01\DB01.edb
IssueWarningQuota                : 2.876 GB (3,088,056,320 bytes)
ProhibitSendQuota                : 3 GB (3,221,225,472 bytes)
ProhibitSendReceiveQuota         : 3.276 GB (3,517,972,480 bytes)
LastFullBackup                   : 5.4.2013 15:01:15
LastIncrementalBackup            : 7.4.2013 15:01:13
DatabaseCopiesCount              : 2
DatabaseCopiesServer             : {exch10Ser01, exch10Ser01}
TotalMailboxCount                : 198
RecipientTypeStatus              : {158-UserMailbox, 36-SharedMailbox, 1-DiscoveryMailbox, 3-ArbitrationMailbox}
MailboxWithDatabaseQuotaCount    : 189
ArchiveMailboxCount              : 130
SoftDeletedMailboxCount          : 
DisconectedMailboxCount          : 4
MailboxTotalItemSizeSumMB        : 138996
MailboxTotalDeletedItemSizeSumMB : 4931
MailboxTotalSizeSumMB            : 143927
MailboxTotalItemCount            : 1426074
Top3LargestMailboxSize           : {2.935 GB (3,151,719,330 bytes), 2.904 GB (3,118,361,061 bytes), 2.897 GB (3,110,582,421 bytes)}
Top3LargestMailboxName           : {Kasaj Filip, Salon Zbynek, Namjman Lukas}
MailboxLimitStatus               : {187-BelowLimit, 6-NoChecking, 4-IssueWarning}

Of course that we can use the function also:

[PS] C:\> $rep = Get-MailboxDatabaseStatistics -DatabaseName db01
[PS] C:\> $rep.MailboxTotalDeletedItemSizeSumMB
4916

[PS] C:\> $rep2 = Get-MailboxDatabaseStatistics -DatabaseName db01,db02
[PS] C:\> $rep2 | fl RecipientTypeStatus
RecipientTypeStatus : {158-UserMailbox, 36-SharedMailbox, 1-DiscoveryMailbox, 3-ArbitrationMailbox}
RecipientTypeStatus : {151-UserMailbox, 52-SharedMailbox}

[PS] C:\> Get-MailboxDatabaseStatistics -AllDatabases | Export-Csv -Delimiter "," -Encoding unicode -Path "C:rep.txt"

How to load the function

  • Save function as ps1 file.
  • Import the file into Exchange Management Shell.
  • That’s it.

07-04-2013 19-45-27Download: 

Get-MailboxDatabaseStatistics.ps1

IMAP pst file import problems – folders containing IMAP items (IPF.Imap) type are not displayed in Exchange 2010 / 2013 OWA

Problem description

I have been solving problem in my friends Exchange 2013 environment. After migration (from IMAP profile) some folders were not visible in his OWA while those were visible in Outlook.
After research I have found, that every folder is “Different in properties” as seen in result Picture below.

wrong properties

Hmm, what now? I dont wanna use MFCMapi, since my friend has many folders. EWS? OK, but how?

Solution

Theory

  • As far as I understand Exchange, there are several kind of permissions and properties and mailbox folder properties belong to MAPI and those can be edited via MFC Mapi (ExFolders) (http://mfcmapi.codeplex.com/) or via EWS Managed API (http://www.microsoft.com/en-us/download/details.aspx?id=30141)
  • Yes. Exchange Web Services Managed API allows you to write custom applications, but I am not a programmer. I have downloaded a script from (http://gsexdev.blogspot.cz/2012/02/ews-managed-api-and-powershell-how-to.html), which I want to say thanks for and made additions to it.
  • Behind the scenes I have found nice technet discussion about how to change folder class so, that it will be visible in OWA, because OWA doesnt show folders with IMAP items. The goal is to change IPF.Imap class to IPF.Note. After changing via EWS you will see the diference as in picture below and after refresh OWA will work as needed.

Correct properties

  • As administrator I am not keen in C# so I will use my domain. Powershell (3.0) as I do the script on Exchange 2013 server

Prerequisites

  • Before you even start to play with EWS, you need to install EWS Managed API fom the link: http://www.microsoft.com/en-us/download/details.aspx?id=30141 or newer version (Link is from Fall 2012)
  • After downloading install it to directory, from which you run the script. Note, that you will need to make reference for “Microsoft.Exchange.WebServices.dll” which is key component of EWS managed API. Example from my script is below:

$dllpath =“d:ExchangeScriptsEWSmanagedAPIMicrosoft.Exchange.WebServices.dll”  

  • Next step is to add your user name full access to mailbox, which will be checked and impersonate role, which will allow impersonation of mailbox under your user as you were owner of the mailbox. Commands are as follows:

New-ManagementRoleAssignment -Name Impersonation -User administrator -Role ApplicationImpersonation

Script

Script can be downloaded from Skydrive

 
$dllpath = "d:ExchangeScriptsEWSmanagedAPIMicrosoft.Exchange.WebServices.dll" #Define DLL Path

[void][Reflection.Assembly]::LoadFile($dllpath) #Load DLL

$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2) #Define EWS Service and version

$service.Url = New-Object System.Uri("https://email.domain.cz/EWS/Exchange.asmx") #Define uri for EWS VDir

$MBXID = "mailbox.identity" #Define mailboxID

foreach ($MailboxIdentity in $MBXID) {

Write-Host "Searching for $MailboxIdentity"

$MailboxName = (Get-Mailbox -Identity $MailboxIdentity).PrimarySmtpAddress.ToString()

$MailboxDName = (Get-Mailbox -Identity $MailboxIdentity).DisplayName

$ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId -ArgumentList ([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress),$MailboxName #Define impersonation

$service.ImpersonatedUserId = $ImpersonatedUserId #Impersonate service under userID

$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName) #MsgFolderRoot selection and creation of new root folder object

$f1 = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, $MailboxName) #Binding folder under mailbox identity

$fold = get-mailboxfolderstatistics $MailboxIdentity #Getting complete list of selected mailbox

foreach ($mbxfolder in $fold){

#Define Folder View Really only want to return one object

$fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(100) #page size for displayed folders

$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep; #Search traversal selection Deep = recursively

#Define a Search folder that is going to do a search based on the DisplayName of the folder

$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::Displayname,$MBXFolder.name) #for each folder in mailbox define search

$findFolderResults = $service.FindFolders($folderid,$SfSearchFilter,$fvFolderView) #for each folder in mailbox define folder view (this is online task for store.exe) and perform search

if ($findFolderResults.TotalCount -eq 0){ "Folder Doesn't Exist" } #Info if folder still exist

else {"Folder Exist"

ForEach ($Folder in $findFolderResults.Folders) { #for each folder in folder results perform check of folder class

$folder.folderclass #Info about folder class

if ($Folder.folderclass -eq "IPF.Imap"){ #If folder class is target type, do change and update

$Folder.folderclass = "IPF.Note" #Folder class change in variable

Write-Host "Updating folder $folder.name to correct type IPF.Note. Folder will start to be visible in OWA"

$Folder.update() #Folder class update in mailbox via EWS

}

}

}

}

}

The script will generate some output to host:

converting via script

Reference

Email Address Policy and Capital Letters – Exchange 2007

05.01.2013

I worked on a request to omit capitals letters in email address (WindowsEmailAddress attribute). Nice to see how can be this request solved. If you have granted email address like  Ficility@windowslive.com you cannot update value (WindowsEmailAddress or PrimarySMTPAddress attribute) within ficility@windowslive.com through EMS or EMC. The value is still Ficility@windowslive.com. As I heard from clever guys many times Exchange and RFC 2821 (SMTP) is not so tantamount “The local-part of a mailbox
MUST BE treated as case sensitive. Therefore, SMTP implementations
MUST take care to preserve the case of mailbox local-parts.“. Additionally, we do not have a restriction for the case in Exchange mail-flow, but how can we change the value while the address is still same (with capital letters). Just rename it e.g. _Ficility@windowslive.com and after that you can apply lower format ficility@windowslive.com without problem. Unfortunately mentioned fact is the same as for Email Address Policy. We cannot change granted capital letters in WindowsEmailAddress or PrimarySMTPAddress by the policy for existing objects.

Basic related management ragarding to Email Address Policy is described in following article: http://www.msexchange.org/articles-tutorials/exchange-server-2007/management-administration/managing-email-address-policies.html.

The main declaration elements are:

%g - Used for given name (first name)
%i - Used for middle initial
%s - Used for surname (last name)
%d - Used for display name
%m - Used for Exchange alias
%xs - Uses the x number of letters of the surname. For example if x=2, then the first two letters of the surname are used.
%xg - Uses the x number of letters of the given name. For example, if x=2, then the first two letters of the given name are used.

But I have used most frequently element %r as replace factor: %rÄa%rÖo%rÅa%räa%röo%råa%rÜu%rüu%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz

Original policy was updated by:

Get-EmailAddressPolicy -identity "Defaulr Policy" | Set-EmailAddressPolicy -EnabledEmailAddressTemplates "smtp:%m@contoso.com","SMTP:%rÄa%rÖo%rÅa%räa%röo%råa%rÜu%rüu%rAa%rBb%rCc%rDd%rEe%rFf%rGg%rHh%rIi%rJj%rKk%rLl%rMm%rNn%rOo%rPp%rQq%rRr%rSs%rTt%rUu%rVv%rWw%rXx%rYy%rZz%g.%i.%s@contoso.com"

After that each new mailbox do not have capital letters in its email address. I changed also old addresses with capital letters by a script – HERE – but the script is customized for my a purpose so ask if anything.

Mailbox quotas change based on Custom Attribute

  • Exchange 2010 / 2013 can be designed so, that multiple mailbox tiers can be placed within one database. In this case there is not easy way how to control mailbox limits for bigger companies. I wrote the script, which can help managing limits based on single value in Custom attribute 12.

How it works

  • Change custom attribute 12 for maiblox users to value Tier1, Tier2 ….Tier5
  • Plan to run the script on daily basis via task manager
  • Script will change the limits to correct values and check if the limits are still OK for existing mailboxes
  • If limits have changed for some reason. Script will set correct ones
  • For non existing value or deviated one: for example “Tier 1” the default tier will be set

What do you need to customize

  • Where to put report file (line 9)
  • Define tiers (Number for size, Unit for multiplier MB,GB etc)
  • You can specify unlimited value as well, unit value then is empty “”

Work left for service desk

  • Add tier info to CustomAttribute12 or leave it empty for default tier assignment
  • change CustomAttribute12 value once mailbox user requests change of mailbox limits

Script

 # Author: zbynek.salon@salonovi.cz
 # Version 3.0
 # Purpose: 1/ Changing limits based on tier value inside CustomAttribute12
 #
 #######################################################################################################################################################
 # Date and report definitions
 $dat = get-date | select day,month,year
 $date = "$($dat.day)_$($dat.month)_$($dat.year)"
 $file = "d:report_$date.txt"
 $report = "started at $($date) - Task 1/ Changing limits based on tier value inside CustomAttribute12"
 $report | out-file "$($file)" -width 2000000 -Append
 #######################################################################################################################################################
 # Tier definition W-Warning, S-ProhibitSend, R-ProhibitSendReceive, WU-Warning Unit, SU-Send Unit, RU-Receive Unit, TI - TierInfo
 $t = [PSCustomObject]@{
 T1 =[PSCustomObject]@{
 W="950"
 S="1024"
 R="1250"
 WU="MB"
 SU="MB"
 RU="MB"
 TI="Limit 1024MB"
 }
 T2 = [PSCustomObject]@{
 W="450"
 S="500"
 R="650"
 WU="MB"
 SU="MB"
 RU="MB"
 TI="Limit 500MB"
 }
 T3 = [PSCustomObject]@{
 W="130"
 S="150"
 R="200"
 WU="MB"
 SU="MB"
 RU="MB"
 TI="Limit 150MB"
 }
 T4 = [PSCustomObject]@{
 W="8192"
 S="10240"
 R="unlimited"
 WU="MB"
 SU="MB"
 RU=""
 TI="Business demand 8GB"
 }
 T5 = [PSCustomObject]@{
 W="2048"
 S="2548"
 R="3072"
 WU="MB"
 SU="MB"
 RU="MB"
 TI="Temporarily increased - for cleanup 2,5GB"
 }
 }
 #######################################################################################################################################################
 # Function
 function Limit ($mb,$ti,$rep){
 $res=0
 if ($mb.issuewarningquota.isunlimited -eq $true)
 {
 if ("unlimited" -ne $ti.w){$res=1}
 }
 else{
 if ($mb.issuewarningquota.value.toMB() -ne $ti.w){$res=1}
 }
 if ($mb.prohibitsendquota.isunlimited -eq $true)
 {
 if ("unlimited" -ne $ti.s){$res=1}
 }
 else{
 if ($mb.prohibitsendquota.value.toMB() -ne $ti.s){$res=1}
 }
 if ($mb.prohibitsendreceivequota.isunlimited -eq $true)
 {
 if ("unlimited" -ne $ti.r){$res=1}
 }
 else{
 if ($mb.prohibitsendreceivequota.value.toMB() -ne $ti.r){$res=1}
 }
 if ($res -eq 1){
 Write-Host "$($ti.TI)"
 $report = "$($mb.alias);$($mb.ExchangeGuid);$($mb.customattribute12);$($mb.issuewarningquota);$($mb.prohibitsendquota);$($mb.prohibitsendreceivequota);Will be set to correct limits"
 $report | out-file "$($rep)" -width 2000000 -Append
 set-mailbox "$($mb.exchangeguid)" -usedatabasequotadefaults $false -Prohibitsendquota "$($ti.s)$($ti.SU)" -prohibitsendreceivequota "$($ti.r)$($ti.RU)" -issuewarningquota "$($ti.w)$($ti.WU)"
 }
 else{
 Write-Host "$($ti.TI)"
 $report = "$($mb.alias);$($mb.ExchangeGuid);$($mb.customattribute12);$($mb.issuewarningquota);$($mb.prohibitsendquota);$($mb.prohibitsendreceivequota);Mailbox OK"
 $report | out-file "$($rep)" -width 2000000 -Append
 }
 }
########################################################################################################################################
 # Main program
 $a = $null
 $a = @()
 $a += get-mailbox -resultsize unlimited | select *quota*,customattribute12,alias,Exchangeguid
 foreach ($line in $a){
 if ($line.exchangeguid -ne $null){
 $tier=$null
 switch ($line.customattribute12) {
 "Tier1"{
 $tier = $t.t1
 Limit $line $tier $file
 }
 "Tier2"{
 $tier = $t.t2
 Limit $line $tier $file
 }
 "Tier3"{
 $tier = $t.t3
 Limit $line $tier $file
 }
 "Tier4"{
 $tier = $t.t4
 Limit $line $tier $file
 }
 "Tier5"{
 $tier = $t.t5
 Limit $line $tier $file
 }
 "$null"{
 $tier = $t.t3
 Limit $line $tier $file
 }
 default{
 $tier = $t.t3
 Limit $line $tier $file
 }
 }
 }
 }

How to backup Exchange 2013 mailbox database on Windows Server 2008 R2 SP1

It is possible to backup Exchange 2013 mailbox databases with Windows backup, however, there are some limitations in functionality. For normal LAB or small bussiness it is fine solution.

Exchange Backup limitations

  • Only Full backup is possible with log truncation (incremental backups do not flush logs)
  • Normal backup performance option does always full backup, but only differences are stored in the disk, while using file block mode.
  • After initial full backup every other backup of the same volume to the same target is incremental unless the following two conditions are fulfilled:
  • 14 incremental backups have occurred since the last full backup
  • More than 14 days have passed since the last full backup ( http://technet.microsoft.com/en-us/library/dd759145.aspx )

Configuring Windows backup

Installation

Windows Server Backup feature is not installed by default on W2k8 R2 SP1 server.

  • To gather status use the following Powershell command:
Get-windowsfeature | where {$_.name -like "*backup*"}
  • To install Windows Server Backup features run the following commands from Powershell. These commands will install needed features to run Exchange backup via command line tool Wbadmin.
Add-WindowsFeature "Backup-Features" Add-WindowsFeature "Backup-Tools"

  • In backup/restore of Exchange servers we will use Powershell commands. Run the following command to import WB command to Powershell session.
add-pssnapin windows.serverbackup
  • Add new disk for Exchange backups. In script there is used “Backup Disk” as volume name. (Depends on the HW you use, please use your HW guidance)

  • To succesfully configure Windows Server Backup we must first define backup policy:
$WBPolicyFull = New-WBPolicy         # Create new WB policy object
$WhatToBackup = New-WBFileSpec –FileSpec E:    # Define what to backup
Add-WBFileSpec –Policy $WBPolicyFull –FileSpec $WhatToBackup  # Adding what to backup to backup policy
$WBTarget = New-WBbackupTarget –NetworkPath "\Servernamesharenamepath"  # Selected backup disk will be set as target
Add-WBBackupTarget –Policy $WBPolicyFull -Target $WBTarget   # Adding target to WB policy
Set-WBVssBackupOptions -Policy $WBPolicyFull -VssFullBackup   # Set method to use WSS Full Backup
  • To check policy:
$WBPolicyFull
  • Status of mailbox database before initial full backup
Get-MailboxDatabase <identity> -Status

  • Policy configured in previous step might be started directly
Start-WBBackup -Policy $WBPolicyFull

  • Or scheduled
Set-WBSchedule –Policy $WBPolicyFull –Schedule 21:00
  • After initial full backup the mailbox database is changed

  • To list backup sets:
Get-WBBackupSet
  • To list job result:
Get-WBJob -previous 1

Example

add-pssnapin windows.serverbackup
$WBPolicyFull = New-WBPolicy
$WhatToBackup = New-WBFileSpec –FileSpec E:
Add-WBFileSpec –Policy $WBPolicyFull –FileSpec
$WhatToBackup $WBTarget = New-WBbackupTarget –Networkpath "\backend1g$Full"
Add-WBBackupTarget –Policy $WBPolicyFull -Target
$WBTarget Set-WBVssBackupOptions -Policy
$WBPolicyFull -VssFullBackup
Start-WBBackup -Policy $WBPolicyFull

Results