Quantcast
Channel: Practical 365
Viewing all 506 articles
Browse latest View live

Get Exchange Install Path Using PowerShell

$
0
0

I was recently dealing with a scenario where I needed to determine the Exchange install path via PowerShell script so that I could copy a scripting agent config XML file to all servers automatically.

After coming up with a solution I asked my fellow Exchange Server MVPs Steve Goodman and Michael van Horenbeeck if they had any better methods that they use. PowerShell being what it is, and no two scenarios being exactly the same, it turns out we each had different approaches.

Michael points out that a script running locally on an Exchange server can simply reference the environment variable that stores the Exchange install path.

PS C:\> $env:exchangeinstallpath
C:\Program Files\Microsoft\Exchange Server\V14\

Finding the Exchange install path of a remote server requires a different approach. I came up with a whole bunch of code to query registry keys and output a report of the install paths for all servers. The results look like this (that warning is for the Edge Transport server):

PS C:\Scripts> .\Get-ExchangeInstallPaths.ps1
Checking HO-EX2010-MB1
Checking HO-EX2010-MB2
Checking BR-EX2010-MB
Checking HO-EX2010-PF
Checking HO-EX2010-EDGE
WARNING: Exception calling "OpenRemoteBaseKey" with "2" argument(s): "Attempted to perform an unauthorized operation."
Server Name                                                 Install Path
-----------                                                 ------------
HO-EX2010-MB1                                               C:\Program Files\Microsoft\Exchange Server\V14\
HO-EX2010-MB2                                               C:\Program Files\Microsoft\Exchange Server\V14\
BR-EX2010-MB                                                C:\Program Files\Microsoft\Exchange Server\V14\
HO-EX2010-PF                                                C:\Program Files\Microsoft\Exchange Server\V14\
HO-EX2010-EDGE                                              Unable to connect to registry

The script itself is as follows:

#requires -version 2
#...................................
# Initialize
#...................................
#Add Exchange snapin if not already loaded
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"}))
{
	Write-Verbose "Loading the Exchange 2010 snapin"
	try
	{
		Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP
	}
	catch
	{
		#Snapin not loaded
		Write-Warning $_.Exception.Message
		EXIT
	}
	. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
	Connect-ExchangeServer -auto -AllowClobber
}
$exchangeservers = Get-ExchangeServer
$report = @()
foreach ($srv in $exchangeservers)
{
    $server = $srv.Name
    if ($srv.AdminDisplayVersion -match "Version 14") {$ver = "V14"}
    if ($srv.AdminDisplayVersion -match "Version 15") {$ver = "V15"}
    Write-Host "Checking $server"
    $installpath = $null
    $reg = $null
	try {
        $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$server)
    }
    catch
    {
        Write-Warning $_.Exception.Message
        $installpath = "Unable to connect to registry"
    }
    if (!($installpath))
    {
	    $installpath = $reg.OpenSubKey("SOFTWARE\Microsoft\ExchangeServer\$ver\Setup").GetValue("MsiInstallPath")
    }
    $serverObj = New-Object PSObject
	$serverObj | Add-Member NoteProperty -Name "Server Name" -Value $server
	$serverObj | Add-Member NoteProperty -Name "Install Path" -Value $installpath
    $report += $serverObj
}
$report

As it turns out, Michael has another idea for remote servers, using remoting. Working his tip into the same script looks like this:

#requires -version 2
#...................................
# Initialize
#...................................
#Add Exchange snapin if not already loaded
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"}))
{
	Write-Verbose "Loading the Exchange 2010 snapin"
	try
	{
		Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP
	}
	catch
	{
		#Snapin not loaded
		Write-Warning $_.Exception.Message
		EXIT
	}
	. $env:ExchangeInstallPath\bin\RemoteExchange.ps1
	Connect-ExchangeServer -auto -AllowClobber
}
$exchangeservers = Get-ExchangeServer
$report = @()
foreach ($srv in $exchangeservers)
{
    $server = $srv.Name
    Write-Host "Checking $server"
    $installpath = $null
	try {
        $installpath = Invoke-Command –Computername $server -ScriptBlock {$env:ExchangeInstallPath} -ErrorAction STOP
    }
    catch
    {
        Write-Warning $_.Exception.Message
        $installpath = "Unable to connect to server"
    }
    $serverObj = New-Object PSObject
	$serverObj | Add-Member NoteProperty -Name "Server Name" -Value $server
	$serverObj | Add-Member NoteProperty -Name "Install Path" -Value $installpath
    $report += $serverObj
}
$report

The resulting output is the same, though it seemed to run a little slower and also failed on my servers that didn’t have remoting already enabled. That is a quick fix, but not a problem I ran into with the remote registry query method.

So there you have it. Multiple methods for retrieving the Exchange install path in PowerShell scripts. If you’ve got another technique you use feel free to share in the comments below.


This article Get Exchange Install Path Using PowerShell is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com


Pros and Cons of Using Separate Security and Distribution Groups

$
0
0

Something I have noticed over the years is a tendency for organizations to duplicate effort by having separate security and distribution groups for the same people.

For example, in one organization a security group is used to grant permissions to register new devices with the BYOD mobile email service. A staff member who wishes to get their work email on their iPhone is added to that security group so that they can enrol their device.

In addition to that, another group exists for notifications to be sent to BYOD users, for example when there is upcoming planned maintenance.

The help desk for this organization has to manage the memberships of two groups that will, in all likelihood, always be exactly the same. The reason they have two groups is because the security group follows an IT-centric naming standard, such as “SEC_MobileDevice_BYOD“, whereas the distribution group has a more user friendly name such as “BYOD Mobile Device Users” that looks nicer in the global address list.

If the only reason for having two groups is for naming purposes then you can solve that by changing the display name of the distribution group.

To demonstrate, I have a universal security group in Active Directory called App_Tier2_ABCDEF.

exchange-group-display-name-01

When I mail-enable the group using the New Distribution Group wizard, it still has the name App_Tier2_ABCDEF, and that is how it will appear in the GAL.

However, if I then use the Exchange management console to change the display name of the group to ABCDEF Users, then that is how it will appear in the GAL (note: you may need to wait for the offline address book to update before you see this change. If in doubt, use OWA to verify it).

exchange-group-display-name-02

exchange-group-display-name-03

Now the help desk would only need to manage membership of a single group to serve both purposes.

However, this does not suit every situation. In one organization I have worked with there was a group used for this dual purpose. One day an administrator was looking to grant a group of people access to a resource. Reviewing the existing groups with access to that resource they decided to nest the new group in the existing one. However they did not realise that both groups were also mail-enabled, so in effect they had just added thousands of people to a mailing list that was not relevant to them.

Of course one day this situation blew up when an harmless group email was sent out, and a few thousand people who weren’t interested in it also received it, kicking off one of those glorious “reply all” storms as a handful of people request to be removed from the list, and then others begin replying all to scold them for replying all, and so on and so on.

So as you can see, although this approach can be used to reduce administrative overhead, you also need to be cautious of situations where it will cause even bigger problems. My view is that fewer groups to manage are better, and most of the risks can be avoided by good admin processes that avoid reckless actions like nesting of groups where the relationship between them is not understood.

 


This article Pros and Cons of Using Separate Security and Distribution Groups is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

PowerShell Script to Distribute Scripting Agent Configuration File to Exchange Servers

$
0
0

One of the components of the Exchange Server scripting agent is the scripting agent config file itself.

This file, named ScriptingAgentConfig.xml, needs to exist on all of the Exchange servers in your organization if the scripting agent is enabled. Ideally you would also keep the file consistent across all of the servers as it gets updated with new actions.

Manual file copy is tedious. Scripting is the ideal approach to a problem like this, but the location where the file needs to be stored will vary depending on the install path for the Exchange Server application.

In a recent post I demonstrated using PowerShell to retrieve the install path of Exchange for remote servers. Extending on that I have written a script to handle the distribution of the scripting agent config file as well.

This script will:

  • Determine the install path of Exchange on the remote server, and use that to determine the path where the config file should be copied
  • Rename the existing ScriptingAgentConfig.xml file if it exists
  • Copy the new ScriptingAgentConfig.xml file from the same directory where the script is running to the remote server
  • Display a report so that success/failure can be identified

The script and config file just need to be located in the same folder. The script also requires the Exchange management tools to be installed, however it can be launched from regular PowerShell and will load the snapin automatically for you.

push-scripting-agent-config-script

Example output (the warning is caused by my Edge Transport server):

PS C:\Scripts\ScriptingAgentConfig> .\PushScriptingAgentConfig.ps1
WARNING: Exception calling "OpenRemoteBaseKey" with "2" argument(s): "Attempted to perform an unauthorized operation."
Server Name        : HO-EX2010-MB1
Config UNC Path    : \\HO-EX2010-MB1\C$\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\Scripting
                     AgentConfig.xml
File Rename Result : Success
File Copy Result   : Success
File Check Result  : Found
Server Name        : HO-EX2010-MB2
Config UNC Path    : \\HO-EX2010-MB2\C$\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\Scripting
                     AgentConfig.xml
File Rename Result : Success
File Copy Result   : Success
File Check Result  : Found
Server Name        : BR-EX2010-MB
Config UNC Path    : \\BR-EX2010-MB\C$\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingA
                     gentConfig.xml
File Rename Result : Success
File Copy Result   : Success
File Check Result  : Found
Server Name        : HO-EX2010-PF
Config UNC Path    : \\HO-EX2010-PF\C$\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents\ScriptingA
                     gentConfig.xml
File Rename Result : Success
File Copy Result   : Success
File Check Result  : Found
Server Name        : HO-EX2010-EDGE
Config UNC Path    : n/a
File Rename Result : n/a
File Copy Result   : n/a
File Check Result  : n/a

For more detailed output use the -Verbose parameter.

PS C:\Scripts\ScriptingAgentConfig> .\PushScriptingAgentConfig.ps1 -Verbose

Download the script file here: PushScriptingAgentConfig.ps1 (downloaded 49 times so far)

Feedback is welcome in the comments below.


This article PowerShell Script to Distribute Scripting Agent Configuration File to Exchange Servers is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

How to Automatically Enable Mailbox Audit Logging in Exchange Server

$
0
0

If your organization uses mailbox audit logging you will probably find it useful to automatically enable it when new mailboxes are created. This avoids the potential problem of mailboxes not being enabled manually when they are created by your help desk, and avoids you having to run regular scheduled scripts to enable auditing for new mailboxes.

This is achieved using the Scripting Agent, one of the cmdlet extension agents in Exchange Server 2013 and 2010.

If you have not already enabled the Scripting Agent you can find steps here. Don’t forget to distribute a ScriptingAgentConfig.xml file to all Exchange servers first.

To enable audit logging for new mailboxes create and distribute a ScriptingAgentConfig.xml file containing the following:

scriptingagentconfig

The important part is these lines, that will fire if the New-Mailbox or Enable-Mailbox cmdlet completes successfully. You can see that all it is really doing is running Set-Mailbox to enable auditing, just as you would manually in the Exchange management shell.

  If ($succeeded)
  {
  	$Alias= $provisioningHandler.UserSpecifiedParameters["Alias"]
	$mailbox = Get-Mailbox $Alias
	Set-Mailbox $mailbox -AuditEnabled:$true
  }

This config uses the Alias attribute of the mailbox, which is populated when a new mailbox is created.

exchange-2013-mailbox-audit-logging-01

When the mailbox creation process has completed you can verify that auditing has been enabled.

[PS] C:\>Get-Mailbox Alannah.Shaw | fl auditenabled
AuditEnabled : True

And that is basically it. As you can see using the Scripting Agent to automate this task is quite simple, yet powerful, and saves you a lot of administrative burden.


This article How to Automatically Enable Mailbox Audit Logging in Exchange Server is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

How Much Database Storage Does Mailbox Audit Logging Consume?

$
0
0

Mailbox audit logging is a useful feature but some administrators become concerned when they learn that the audit logs are stored in the mailbox itself.

Does add a significant amount of data to the mailbox?

It really depends a lot on which audit options you’ve turned on, and how many mailbox in your organization are shared mailbox or have a lot of delegates performing actions on them.

What I can say is that my experience has been that mailbox audit logging, using the default 90 days retention and other audit settings, adds about 1-2% to the size of the mailbox. Of course, you should not take that as definitive and should perform some testing and analysis yourself, but I hope that my experience at least helps remove some of the uncertainty when it comes to storage impact of mailbox audit logging.

If you have turned on mailbox audit logging for a mailbox, and you know that actions are being logged already, you can check the size of the audits folder to see what kind of impact it is having.

[PS] C:\>get-mailbox Alan.Reid | Get-MailboxFolderStatistics -FolderScope RecoverableItems | fl name,foldersize
Name       : Recoverable Items
FolderSize : 5.804 MB (6,085,852 bytes)
Name       : Audits
FolderSize : 71.67 KB (73,394 bytes)
Name       : Deletions
FolderSize : 429.2 KB (439,483 bytes)
Name       : Purges
FolderSize : 0 B (0 bytes)
Name       : Versions
FolderSize : 0 B (0 bytes)

In the example above the Audits folder is just 71KB in size, for a mailbox of about 1Gb in total size. This mailbox has just a small amount of delegate activity though. Other mailboxes in the same organization have upwards of 2-3MB of audit data, which is still not very much compared to total mailbox sizes of several gigabytes.

If mailbox audit logging has been widely deployed you can also use a simple script to collect these stats from all mailbox. This example will list all mailboxes with their mailbox size and audit log size, and then export the stats for all of them to a CSV file at the end.

$report = @()
$mailboxes = @(Get-Mailbox -Resultsize Unlimited)
foreach ($mailbox in $mailboxes)
{
    $name = $mailbox.Name
    $auditsfolder = "$($mailbox.Identity)\Audits"
    $foldersize = ($mailbox | Get-MailboxFolderStatistics -FolderScope RecoverableItems | Where {$_.Name -eq "Audits"}).FolderSize
    if ($foldersize)
    {
        $foldersize = "{0:N2}" -f $foldersize.ToMB()
    }
    else
    {
        $foldersize = 0
    }
    $mailboxsize = (Get-MailboxStatistics $mailbox).TotalItemSize.Value.ToMB()
    $reportObj = New-Object PSObject
	$reportObj | Add-Member NoteProperty -Name "Name" -Value $name
    $reportObj | Add-Member NoteProperty -Name "Mailbox Size (MB)" -Value $mailboxsize
    $reportObj | Add-Member NoteProperty -Name "Audits Size (MB)" -Value $foldersize
    $report += $reportObj
    Write-Host "$name, $mailboxsize, $foldersize"
}
$report | Export-CSV AuditLogOverhead.csv -NoTypeInformation

You could easily customize that for your own environment if you have the need.


This article How Much Database Storage Does Mailbox Audit Logging Consume? is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Using the Scripting Agent in Exchange Server 2013

$
0
0

The Scripting Agent is one of the cmdlet extension agents in Exchange Server 2013 (and 2010 for that matter). You can read more about cmdlet extension agents here, but in short they allow administrators to extend the functionality of PowerShell cmdlets by creating additional actions that are performed when a cmdlet is used.

One of the best examples, as well as being a common use, of the Scripting Agent is to extend the New-Mailbox and Enable-Mailbox cmdlets to automatically perform additional configuration tasks for new mailboxes as they are created.

For example, when a new mailbox is created automatically enable mailbox audit logging, or automatically disabled protocols such as POP and IMAP.

Enabling the Script Agent takes effect for the entire Exchange organization, so the first step is to deploy the Script Agent configuration file to each of your Exchange servers. This is a simple task if you use the PowerShell script that I’ve made available here.

If you need a placeholder config file before you’ve configured any actual actions this simple three line XML will do the trick.

exchange-2013-mailbox-audit-logging-02

The next step is to enable the Scripting Agent. You can view the existing cmdlet extension agent configuration using Get-CmdletExtensionAgent.

[PS] C:\>Get-CmdletExtensionAgent | ft name,enabled -auto
Name                               Enabled
----                               -------
Admin Audit Log Agent                 True
Scripting Agent                      False
Mailbox Resources Management Agent    True
OAB Resources Management Agent        True
Query Base DN Agent                   True
Provisioning Policy Agent             True
Rus Agent                             True
Mailbox Creation Time Agent           True

To enable the Scripting Agent use Enable-CmdletExtensionAgent.

[PS] C:\>Enable-CmdletExtensionAgent "Scripting Agent"

For an example of Script Agent config files check out how to enable mailbox audit logging automatically for new mailboxes.


This article Using the Scripting Agent in Exchange Server 2013 is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Using Exchange Server 2013 Mailbox Audit Logging

$
0
0

In many organizations the Exchange Server administrator will encounter a situation where there is a need to determine who took action on an item in a mailbox. This will most often be about actions taken by delegates of a person’s mailbox, or people who use a shared mailbox.

For example:

  • An email message from a customer was never responded to, and the manager of the customer service team wants to know which person in the team move or deleted the message from the shared mailbox
  • Information sent to an executive via email has leaked, and there is an investigation into which of the executive’s delegates read the email message

Note that in these situations it is assumed that delegates or a team of people already have full access to the mailbox, or read-only access to the mailbox. Based on that assumption the focus is now on which of those people took action on specific mail items.

Exchange Server 2013 can log access to mailboxes by the owner, delegates, and administrators, using a feature called mailbox audit logging.

How Mailbox Audit Logging Works

When mailbox audit logging is enabled for a mailbox, audit log entries are stored in the Recoverable Items folder of the mailbox, which is not visible to the mailbox user via Outlook or other client interfaces.

Log entries are written for actions taken by the mailbox owner, delegates, or by administrators, depending on the audit logging configuration applied to the mailbox. The mailbox audit log entries are then retained for a configurable period of time.

Mailbox audit logging has the following default configuration in Exchange Server 2013:

  • Mailbox audit logging is disabled
  • Audit log entries are retained for 90 days
  • No owner actions are logged
  • Some delegate and administrator actions are logged

A default mailbox audit logging configuration for an Exchange 2013 mailbox looks like this:

[PS] C:\>Get-Mailbox alan.reid | fl *audit*
AuditEnabled     : False
AuditLogAgeLimit : 90.00:00:00
AuditAdmin       : {Update, Move, MoveToDeletedItems, SoftDelete, HardDelete, FolderBind, SendAs, SendOnBehalf, Create}
AuditDelegate    : {Update, SoftDelete, HardDelete, SendAs, Create}
AuditOwner       : {}

Note: The AuditAdmin settings refer to access via mechanisms such as eDiscovery searches, mailbox import/export operations, or tools such as MFCMAPI. If an administrator is granted permission to a mailbox and accesses it then those actions will be logged according to the AuditDelegate settings.

Enabling/Disabling Mailbox Audit Logging

For mailboxes in your organization that you wish to enable audit logging on you can do so using the Set-Mailbox cmdlet.

[PS] C:\>Set-Mailbox alan.reid -AuditEnabled $true

Typical candidates for mailbox audit logging are executives or VIPs who handle sensitive information, and who have delegates, or shared mailboxes used by teams of people.

In some organizations it may be preferable to enable mailbox audit logging for large numbers of mailbox users, or perhaps even all mailbox users. You can pipe the output of any Get-Mailbox query into Set-Mailbox to enable mailbox audit logging.

[PS] C:\>Get-Mailbox -ResultSize Unlimited | Set-Mailbox -AuditEnabled:$true

If you need to ensure that mailbox audit logging is automatically enabled for all new mailboxes when they are created then you achieve that using the Scripting Agent.

For more information see:

Impact of Audit Logging on Mailbox Size

Mailbox audit log data is stored in a folder named Audits under the Recoverable Items folder of the mailbox, so it is hidden from the user. The default retention is 90 days, and some administrators may be concerned about the storage overhead for all of that audit logging data.

For more information on this see How Much Database Storage Does Mailbox Audit Logging Consume?

Searching Mailbox Audit Logs

In these further articles I will demonstrate some methods for searching and using the mailbox audit logging data.


This article Using Exchange Server 2013 Mailbox Audit Logging is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

How to Grant Send As Permissions for a Mailbox in Exchange Server 2013

$
0
0

In Exchange Server 2013 there are multiple methods you can use for granting Send As permissions for a mailbox.

Send As permissions can be granted using the Exchange admin center. Navigate to Recipients, then choose the type of recipient you want to grant Send As right for (in this example I am using a shared mailbox called “Help Desk”). Click the Edit button to open the properties of the mailbox.

exchange-2013-send-as-01

Select Mailbox Delegation, then click the + button for the Send As permissions and choose who you are granting the permissions to. Click Add then OK, and then Save to complete the task.

exchange-2013-send-as-02

Note: You can add a user or group here. To use a group to grant Send As permissions, which may be easier in the long run, the group simply needs to be a Universal Security group. It does not need to be mail-enabled. However you will need to use PowerShell to configure the permissions when adding a group.

To grant Send As permissions using PowerShell we use the Add-AdPermission cmdlet. Using PowerShell allows either a user or Universal Security group to be given Send As permissions.

[PS] C:\>Get-Mailbox "Help Desk" | Add-ADPermission -User "Help Desk Team" -ExtendedRights "Send As"
Identity             User                 Deny  Inherited
--------             ----                 ----  ---------
exchange2013demo.... E2013DEMO\Help De... False False

Remember if you’re setting up a group for Send As permissions, new members of that group will need to log off and back on again before they can send as the mailbox.


This article How to Grant Send As Permissions for a Mailbox in Exchange Server 2013 is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com


Using Exchange Server Mailbox Audit Logs to Find the Sender of an Email from a Shared Mailbox

$
0
0

In all my years as an Exchange Server administrator the most common “whodunnit” scenario is being asked to find out who sent a specific message from a shared mailbox.

Consider a scenario where a shared “Help Desk” mailbox is used by a reasonably large team of IT staff, and they all have Send As permissions for the mailbox (for legitimate purposes such as sending out system outage and maintenance notifications).

One day a help desk operator has a brain fart and sends an email to the whole organization that causes some bad feedback.

exchange-server-audit-logging-send-as

Youve been tasked with finding the culprit and there are a few angles of investigation that you’re considering, such as finding the IP address that submitted the message and tracing that back to a workstation, trawling through sent items of help desk staff, or even just flat out asking people (this one works sometimes, don’t rule it out).

It would be a lot easier if Exchange could just tell you who sent the message.

The good news is that Exchange Server can tell you this (in Exchange 2010 SP1 or later, and Exchange 2013), using a feature called mailbox audit logging. The bad news (if you can call it that) is that the feature is not enabled by default, and needs to be turned on *before* the email is sent to capture the action in the audit log.

So, assuming mailbox audit logging is already enabled for the Help Desk mailbox, we can perform an audit log search to find out who took the Send As action at that time.

Performing Mailbox Audit Log Searches Using the Exchange Admin Center

In the Exchange admin center navigate to Compliance Management and choose Auditing. There are several items in that section but we’re interested in “Run a non-owner mailbox access report” in this case.

exchange-2013-mailbox-audit-log-search-01

Set the date range you’re interested in, and then click on Select Mailboxes to add the specific mailbox you want to search. Finally, set the search type to “All non-owners”, and then click Search to begin.

exchange-2013-mailbox-audit-log-search-02

After a few moments your search results should appear. If you’ve picked a large date range, or a mailbox with a lot of non-owner activity, then you may have quite a lot of results to scroll through.

But for this example we can see that someone has in fact performed a “Send As” on the date in question, with the matching subject line of the email that causes all the fuss to begin with. So it seems we have our culprit, caught red handed, thanks to mailbox audit logging.

Performing Mailbox Audit Log Searches Using the Exchange Management Shell

Naturally we can also perform this search using PowerShell and the Search-MailboxAuditLog cmdlet.

For example, to search the “Help Desk” mailbox audit logs between the 13th and 15th of January 2014, the following command is used.

[PS] C:\>Search-MailboxAuditLog -Identity "Help Desk" -LogonTypes Delegate -StartDate 1/14/2014 -EndDate 1/15/2014
RunspaceId               : d8142847-166a-488a-b668-f7b84c3f3ceb
MailboxGuid              : a0f10db1-5268-47a5-8f71-d1e65f55c653
MailboxResolvedOwnerName : Help Desk
LastAccessed             : 14/01/2014 9:31:08 PM
Identity                 : exchange2013demo.com/Company/Resources/Help Desk
IsValid                  : True
ObjectState              : New

We can see a result, and the time stamp matches the email message that was sent, but little else is shown about the event. To see more we need to use the -ShowDetails parameter.

[PS] C:\>Search-MailboxAuditLog -Identity "Help Desk" -LogonTypes Delegate -StartDate 1/14/2014 -EndDate 1/15/2014 -Sho
Details
RunspaceId                    : d8142847-166a-488a-b668-f7b84c3f3ceb
Operation                     : SendAs
OperationResult               : Succeeded
LogonType                     : Delegate
ExternalAccess                : False
DestFolderId                  :
DestFolderPathName            :
FolderId                      :
FolderPathName                :
ClientInfoString              : Client=MSExchangeRPC
ClientIPAddress               : 192.168.0.181
ClientMachineName             :
ClientProcessName             : OUTLOOK.EXE
ClientVersion                 : 15.0.4551.1004
InternalLogonType             : Owner
MailboxOwnerUPN               : Sarah.Jones@exchange2013demo.com
MailboxOwnerSid               : S-1-5-21-2175008225-1847283934-4039955522-1471
DestMailboxOwnerUPN           :
DestMailboxOwnerSid           :
DestMailboxGuid               :
CrossMailboxOperation         :
LogonUserDisplayName          : Sarah Jones
LogonUserSid                  : S-1-5-21-2175008225-1847283934-4039955522-1471
SourceItems                   : {}
SourceFolders                 : {}
SourceItemIdsList             :
SourceItemSubjectsList        :
SourceItemFolderPathNamesList :
SourceFolderIdsList           :
SourceFolderPathNamesList     :
ItemId                        :
ItemSubject                   : Wheeee!
DirtyProperties               :
OriginatingServer             : E15MB1 (15.00.0775.022)
MailboxGuid                   : a0f10db1-5268-47a5-8f71-d1e65f55c653
MailboxResolvedOwnerName      : Help Desk
LastAccessed                  : 14/01/2014 9:31:07 PM
Identity                      : RgAAAAD2fF/dZobvQoWbbV7P6N7eBwD7Y5OF+DDRQZRz1a4+yUyzAABaldDBAAD7Y5OF+DDRQZRz1a4+yUyzAAB
                                aldDCAAAJ
IsValid                       : True
ObjectState                   : New

As you can see we get the same information that reveals the sender of the email message, as well as some extra info that may be useful as well.

Summary

In this article I’ve used a common scenario to demonstrate the value of mailbox audit logging, as well as demonstrating how to perform simple mailbox audit log searches. Hopefully by now you can see the value of mailbox audit logging and are considering enabling it in your organization, even if only for your most important/shared mailboxes.


This article Using Exchange Server Mailbox Audit Logs to Find the Sender of an Email from a Shared Mailbox is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Get-DailyBackupAlerts.ps1 v1.04 is Available

$
0
0

It’s been a while since Get-DailyBackupAlerts.ps1 had an update, but thanks to some feedback and bug reports I have made a few changes this week.

I’ve just uploaded v1.04 to the Insiders member area (free registration here).

This new version has the following improvements:

  • Databases with only one mailbox will now display as 1 instead of 0
  • Mailboxes for excluded databases are no longer retrieved for mailbox count calculations, which improves performance in very large environments
  • The “Backup currently in progress” field now displays as Yes/No instead of True/False (which I call “manager-friendly mode”)
  • Some minor formatting changes to make larger reports easier to read

Download v1.04 here.


This article Get-DailyBackupAlerts.ps1 v1.04 is Available is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Start-MailGen.ps1 – Test Lab Email Generator PowerShell Script Updated to V1.01

$
0
0

I’ve just uploaded an update to the Start-MailGen.ps1 script, which is a free PowerShell script that you can use to generate email traffic within a test lab environment.

This new version has the following updates and improvements:

  • Updated to use Exchange Web Services Managed API 2.0
  • Tested on Exchange Server 2010 and 2013
  • Fixes bug where last mailbox in alphabetical order would never be picked as a sender or recipient
  • Added code for Exchange snap-in to load to simplify running script as a scheduled task
  • Distribution groups are now included as possible recipients of emails
  • Recipient list is refreshed on every loop so that newly created recipients are included
  • Messages are now sent to a random number of recipients between 1 and 5 instead of only single recipients (you can increase this if you like)
  • Messages will now randomly include a file attachment chosen from the \Attachments folder. This will happen about 30% of the time. You can add your own attachments to that folder if you want more variety as well.

Usage instructions and download link are here.


This article Start-MailGen.ps1 – Test Lab Email Generator PowerShell Script Updated to V1.01 is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Using Log Parser and Protocol Logs to Analyze Send Connector Usage

$
0
0

An Exchange organization may have send connectors that are believed to be no longer in use, for example a send connector used for shared SMTP namespace.

However when you are planning the removal of a send connector there is the concern that some email traffic may still be using that send connector, and so you want to investigate this further before making your change.

One way of determining send connector usage is to analyze protocol logs. If you’re not already familiar with protocol logging I wrote an article about it here that is a good starting place.

To begin with you should check whether your send connector has protocol logging enabled.

[PS] C:\>Get-SendConnector "Name of Send Connector" | fl ProtocolLoggingLevel
ProtocolLoggingLevel : Verbose

There are two possible values; None (off) or Verbose (on). If protocol logging is not already set to Verbose you can turn it on using Set-SendConnector.

[PS] C:\>Set-SendConnector "Name of Send Connector" -ProtocolLoggingLevel Verbose

A default protocol logging configuration will retain 30 days worth of logs, but you can start analyzing them after a day or so if that is all the time you think you will need to discover any systems still using the connector. Obviously for less used connectors the longer you wait the more chance you’ll capture something.

Using Log Parser to View Send Connector Hits in Protocol Logs

We can use a Log Parser query to search through the protocol logs and count the “hits” for each connector, because one of the fields in the log file is the “connector-id”.

SELECT connector-id,
       Count(*) as Hits
from *.log
WHERE data LIKE '%EHLO%'
GROUP BY connector-id
ORDER BY Hits DESC

To run this query open Log Parser, navigate to the folder containing the send connector protocol logs (C:\Program Files\Microsoft\Exchange\V14\TransportRoles\Logs\ProtocolLog\SmtpSend by default on an Exchange 2010 server. Refer to the protocol logging article if you need more help finding the path on your server), and then run the command:

"C:\Program Files (x86)\Log Parser 2.2\logparser.exe" "SELECT connector-id,Count(*) as Hits from *.log WHERE data LIKE '%EHLO%' GROUP BY connector-id ORDER BY Hits DESC" -i:CSV -nSkipLines:4 -rtp:-1
connector-id          Hits
--------------------- -----
Internet              70556
Shared Domains        152
Fax Gateway           4
Statistics:
-----------
Elements processed: 1469279
Elements output:    4
Execution time:     4.52 seconds

Using Log Parser to Analyze Email Traffic on a Send Connector

As you can see in the output above the “Shared Domains” connector has registered a small number of hits. To dig into that further we can use Log Parser again to query the logs for information such as the “RCPT TO” command being used in the SMTP transaction, which will tell us the recipient email address.

SELECT data,
       Count(*) as Hits
from *.log
WHERE connector-id = 'Shared Domains'
AND data LIKE '%RCPT TO%'
GROUP BY data
ORDER BY Hits DESC

Again, running from Log Parser after navigating to the SmtpSend folder:

"C:\Program Files (x86)\Log Parser 2.2\logparser.exe" "SELECT data,Count(*) as Hits from *.log WHERE connector-id = 'Shared Domains' AND data LIKE '%RCPT TO%' GROUP BY data ORDER BY Hits DESC" -i:CSV -nSkipLines:4 -rtp:-1

You should see output similar to this.

data                                                                                        Hits
------------------------------------------------------------------------------------------- ----
RCPT TO:                                                             18
RCPT TO: ORCPT=rfc822;david@domain.com.au                              6
RCPT TO: ORCPT=rfc822;peter@domain.com.au                              5
RCPT TO: ORCPT=rfc822;cathy@domain.com.au                              4
RCPT TO: ORCPT=rfc822;michael@domain.com.au                          4
RCPT TO: ORCPT=rfc822;michelle@domain.com.au                        4
RCPT TO: ORCPT=rfc822;donna@domain.com.au                              3
RCPT TO: ORCPT=rfc822;jacinta@domain.com.au                          3

Knowing which recipients are still receiving email that is going over a particular send connector can be very useful in tracking down any stragglers among the mailboxes or applications that the connector was originally set up for, but that have not been migrated properly.

You could do the same analysis using a search for “MAIL FROM” instead, which will show you the senders of the emails, which is also useful in some cases.

"C:\Program Files (x86)\Log Parser 2.2\logparser.exe" "SELECT data,Count(*) as Hits from *.log WHERE connector-id = 'Shared Domains' AND data LIKE '%MAIL FROM%' GROUP BY data ORDER BY Hits DESC" -i:CSV -nSkipLines:4 -rtp:-1

Summary

As you can see in the examples above there is some very useful information contained within protocol logging that can help you determine whether a send connector is still being used in your Exchange Server organization.


This article Using Log Parser and Protocol Logs to Analyze Send Connector Usage is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Exchange Server FAQ: Does Message Tracking Include Bcc Recipients?

$
0
0

I’ve been asked by more than a few people recently whether Exchange Server message tracking also includes emails sent to Bcc recipients.

I guess the purpose of Bcc would lead some to assume that those emails are not logged by message tracking.

However if you consider it from the perspective that all email travels through the transport pipeline no matter whether they are To, Cc, or Bcc recipients, and that the idea of untraceable email passing through your Exchange servers should be a scary thought, it makes sense that these messages are in fact logged in the message tracking logs.

I realise an actual demonstration may be necessary to convince some people of this, so here it is.

This email is sent to two recipients; one in the To field and one a Bcc.

exchange-message-tracking-bcc

I’ve only just sent the email so a quick search of the last 10 minutes of message tracking logs is all I need to run.

[PS] C:\>$msgs = Get-ExchangeServer | Get-MessageTrackingLog -Sender Alan.Reid@exchangeserverpro.net -Start (Get-Date).A
ddMinutes(-10)

Now let’s take a look at the results.

[PS] C:\>$msgs | sort timestamp
EventId  Source   Sender                            Recipients                        MessageSubject
-------  ------   ------                            ----------                        --------------
SUBMIT   STORE... Alan.Reid@exchangeserverpro.net   {}                                A test email
RECEIVE  STORE... Alan.Reid@exchangeserverpro.net   {Ana.Williams@exchangeserverpr... A test email
TRANSFER ROUTING  Alan.Reid@exchangeserverpro.net   {Mahera.Bawa@exchangeserverpro... A test email
DELIVER  STORE... Alan.Reid@exchangeserverpro.net   {Mahera.Bawa@exchangeserverpro... A test email
DELIVER  STORE... Alan.Reid@exchangeserverpro.net   {Ana.Williams@exchangeserverpr... A test email
SUBMIT   STORE... Alan.Reid@exchangeserverpro.net   {}                                A test email
RECEIVE  STORE... Alan.Reid@exchangeserverpro.net   {Ana.Williams@exchangeserverpr... A test email
TRANSFER ROUTING  Alan.Reid@exchangeserverpro.net   {Mahera.Bawa@exchangeserverpro... A test email
DELIVER  STORE... Alan.Reid@exchangeserverpro.net   {Mahera.Bawa@exchangeserverpro... A test email
DELIVER  STORE... Alan.Reid@exchangeserverpro.net   {Ana.Williams@exchangeserverpr... A test email

As you can see, both recipients are visible in the results.

But now let’s take a closer look, as some of you may be wondering how you can tell from the message tracking logs whether a recipient was in the Bcc of the email message.

[PS] C:\>$msgs | sort timestamp | select eventid,recipients,recipientstatus
EventId                                 Recipients                              RecipientStatus
-------                                 ----------                              ---------------
SUBMIT                                  {}                                      {}
RECEIVE                                 {Ana.Williams@exchangeserverpro.net,... {To, Bcc}
TRANSFER                                {Mahera.Bawa@exchangeserverpro.net}     {}
DELIVER                                 {Mahera.Bawa@exchangeserverpro.net}     {}
DELIVER                                 {Ana.Williams@exchangeserverpro.net}    {}

Notice on the RECEIVE event that the RecipientStatus field indicates whether the recipient was a To or a Bcc. Here’s that same event formatted slightly differently for clarity.

EventId         : RECEIVE
Recipients      : {Ana.Williams@exchangeserverpro.net, Mahera.Bawa@exchangeserverpro.net}
RecipientStatus : {To, Bcc}

Of course, with just two recipients you wouldn’t be 100% sure from this log event which one was the To and which one was the Bcc. So let’s take a look at another test email, this time with a different recipient mix.

exchange-message-tracking-bcc-03

Here is the RECEIVE event details for that message.

EventId         : RECEIVE
Recipients      : {Mahera.Bawa@exchangeserverpro.net, John.Tilleray@exchangeserverpro.net, Ana.Williams@exchangeserverp
                  ro.net}
RecipientStatus : {To, To, Bcc}

Notice how the recipients and recipient statuses are listed in a matching order (not alphabetical order)?

In other words, for that specific message:

  • Mahera Bawa = To
  • John Tilleray = To
  • Ana Williams = Bcc

So in conclusion, yes message tracking includes Bcc recipients, and yes you can even use message tracking logs to determine whether a recipient was in the To, Cc, or Bcc field of the email message.

If you’d like to learn more about message tracking in Exchange Server check out Mastering Message Tracking.


This article Exchange Server FAQ: Does Message Tracking Include Bcc Recipients? is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Optimizing Offline Address Book Schedules in Exchange Server 2010

$
0
0

In an Exchange Server 2010 organization it is normal for there to be some delay before administrative changes appear in the address book for Outlook users.

For example, a staff member changes surnames and the help desk updates their Active Directory account with the new name. The staff member may notice that when the address book is viewed in Outlook their name remains unchanged, and may do so for 24-48 hours.

A common reason for this is the offline address book (OAB) schedules that are in place for the environment.

Consider the following process:

  1. A change is made in Active Directory (eg, the user’s surname)
  2. The OAB generation process occurs (5am daily by default)
  3. The OAB file distribution process runs (every 8 hours by default)
  4. The OAB is downloaded to the Outlook client (at startup)

exchange-2010-oab-distribution

So in real world conditions that process may actually look like this.

  1. At 9am the help desk changes the user’s surname
  2. At 5am the next day the OAB generation process runs
  3. Up to 8 hours later (ie as late as 1pm) the OAB file distribution process runs
  4. The OAB is updated at next Outlook startup the day after that

So it is easy to understand why changes may not appear in the address book for cached-mode Outlook users for 24-48 hours after the change is actually made.

Note: a good way to verify whether an inconsistency is OAB-related or not is to use Outlook Web App to look up the person in the address book. If OWA shows the correct details, and cached-mode Outlook does not, then it is likely an OAB-related issue whether that is simply a normal delay as shown above, or possibly an OAB problem of some kind.

So what can we do to optimize this process?

Well first of all, consider whether you should take any action at all. A delay for changes appearing in the OAB may be perfectly acceptable to some organizations. And additional load from OAB generation and distribution cycles running more frequently may be undesirable to some administrators.

But, assuming you do want to improve this situation in your environment, here is what you can do about it.

Modify the OAB Generation Schedule

The first item to consider is a change to the OAB generation schedule. If you know that your administrators are only making changes up until 6pm each day, then waiting until 5am the next day to update the OAB is probably unnecessary.

In the Exchange Management Console navigate to Organization Configuration -> Mailbox and select the Offline Address Book tab.

exchange-2010-oab-generation-01

Open the Properties of the OAB you want to modify and look at the Update Schedule.

exchange-2010-oab-generation-02

The default schedule runs daily at 5am, and there are some other pre-configured schedules you can choose as well. If none of those suit your needs you can choose a custom schedule and then customize it to run at one more times on each day.

exchange-2010-oab-generation-03

Modify the OAB File Distribution Schedule

OAB files are distributed to Exchange Server 2010 Client Access servers where they are made available for web-distribution to Outlook clients.

exchange-2010-oab-distribution-02

Each OAB virtual directory included in the web-distribution list for an OAB polls for changes on a configurable interval. The default is 480 minutes (8 hours).

exchange-2010-oab-distribution-03

I find PowerShell to be a little easier to use for managing this setting.

[PS] C:\>Get-OabVirtualDirectory | Select Server,Name,PollInterval
Server        Name                   PollInterval
------        ----                   ------------
BR-EX2010-MB  OAB (Default Web Site)          480
HO-EX2010-MB2 OAB (Default Web Site)          480
HO-EX2010-MB1 OAB (Default Web Site)          480

If you want to ensure that the OAB web-distribution points are updated before most Outlook users begin logging on in the morning then you would may need to change this polling interval.

Let’s look at two examples:

  1. With the OAB generation schedule modified earlier to also run at 7pm an OAB file distribution interval of  8 hours means the web-distribution points will likely be up to date at 3am. So in this case there may be no need to make a change.
  2. With the default OAB generation schedule of 5am daily you may want to lower the polling interval to 1 or 2 hours so that the web-distribution point is up to date by 7am.

For that second scenario we can update the interval either via the OAB virtual directory properties (shown above) or using Set-OABVirtualDirectory.

[PS] C:\>Get-OabVirtualDirectory | Set-OabVirtualDirectory -PollInterval 120
[PS] C:\>Get-OabVirtualDirectory | Select Server,Name,PollInterval
Server        Name                   PollInterval
------        ----                   ------------
BR-EX2010-MB  OAB (Default Web Site)          120
HO-EX2010-MB2 OAB (Default Web Site)          120
HO-EX2010-MB1 OAB (Default Web Site)          120

Summary

The default OAB generation and distribution schedules work just fine for many organizations, but some will find they are not suitable and are causing support issues when changes are made that do not appear in the address book until 24-48 hours later.

In those cases the Exchange Server administrator can consider making adjustments to the OAB generation and distribution schedules to suit their environment better.


This article Optimizing Offline Address Book Schedules in Exchange Server 2010 is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Get-EASDeviceReport.ps1 V1.01 Available

$
0
0

The Get-EASDeviceReport.ps1 PowerShell script has been updated to V1.01.

This update includes the following changes:

  • Added SMTP parameters for emailing the report
  • Added an “age” parameter to set a threshold for last sync age
  • Numerous bug fixes and improvements

So now you can, for example, run a report that shows ActiveSync devices that have not attempted sync in the last 30 days, and have that report emailed to you as a CSV file.

get-easdevicereport-email

See more details and download the script here.


This article Get-EASDeviceReport.ps1 V1.01 Available is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com


Restoring Exchange Server 2013 Databases Using Windows Server Backup

$
0
0

We’ve already looked at how to backup Exchange Server 2013 using Windows Server Backup. Now let’s take a look at the scenario where we restore the Exchange Server 2013 application using Windows Server Backup.

This mailbox user, Paul Cunningham, has items received up to 8:07pm.

exchange-2013-paulcunningham-before

The last backup for the server was 8:00am.

[PS] E:\DB01>Get-MailboxDatabase -Status | fl name,*last*backup
Name                           : DB01
SnapshotLastFullBackup         : True
SnapshotLastIncrementalBackup  :
SnapshotLastDifferentialBackup :
SnapshotLastCopyBackup         :
LastFullBackup                 : 12/02/2014 8:00:33 AM
LastIncrementalBackup          :
LastDifferentialBackup         :
LastCopyBackup                 :
Name                           : DB02
SnapshotLastFullBackup         : True
SnapshotLastIncrementalBackup  :
SnapshotLastDifferentialBackup :
SnapshotLastCopyBackup         :
LastFullBackup                 : 12/02/2014 8:00:33 AM
LastIncrementalBackup          :
LastDifferentialBackup         :
LastCopyBackup                 :

So, there are items in the mailbox that have been received since the last backup. Are those items at risk of being lost if there is a failure? Let’s see.

Now let’s cause the database to be lost. To simulate this I’ve dismounted the DB01 database and then deleted the database’s EDB file.

[PS] C:\>Get-MailboxDatabase DB01 -Status | fl name,mounted
Name    : DB01
Mounted : False
[PS] C:\>Get-MailboxDatabase DB01 | Test-MAPIConnectivity
MailboxServer      Database           Result    Error
-------------      --------           ------    -----
E15MB1             DB01               *FAILURE* Database is dismounted.

The database file is gone, and to get back the data it needs to be recovered from the last backup.

Note: because I am using Windows Server Backup to recover the Exchange Server application I cannot choose to only restore a specific database, so any other databases hosted on that volume will also be restored.

This server hosts two databases, DB01 and DB02. Only DB01 has been lost and needs recovering, DB02 is fine. And DB02 also contains mailboxes, such as Alan Reid’s, that have items in there that arrived after the last backup was taken.

exchange-2013-alan-reid-before

Are these items in DB02 mailboxes at risk if we do a restore from Windows Server Backup to recover DB01? Let’s see.

In Windows Server Backup launch the Recover… wizard.

exchange-2013-restore-database-02

In this example the backup is stored on this server.

exchange-2013-restore-database-step-01

Choose the date and time for the backup you wish to use for the recovery.

exchange-2013-restore-database-step-02

Choose the recovery type of Applications.

exchange-2013-restore-database-step-03

Choose the “Exchange” application. Note the tick box for choosing whether to *not* perform a roll-forward recovery of the application databases. Because we *do* want a roll-forward recovery to be performed in this case (ie, replay the transaction logs for transactions that occurred since the last backup, since they are still available on the server) we will leave this tick box *unticked*.

exchange-2013-restore-database-step-04

Leave the selection as “Recover to original location”.

exchange-2013-restore-database-step-05

Finally, click Recover to begin the restore. Note that this will cause an outage for all of the databases on the server, even the ones that are healthy, because the application recovery process can’t restore single databases. That said, it will restore them one at a time, so in this example DB02 stays online while DB01 is being recovered, then DB02 is taken offline after that.

Wait while the restore operation completes.

exchange-2013-restore-database-step-06

After the restore has completed users on both DB01 (Paul Cunningham) and DB02 (Alan Reid) can access all of their mail items, even the ones that were sent/received after the backup was taken, because the recovery process replays the transaction logs that are still intact on the server to bring the database right up to date.

As you can see even though Windows Server Backup is not the most flexible and feature packed backup software, it is still perfectly capable of backing up and recovering your Exchange Server 2013 Mailbox servers.


This article Restoring Exchange Server 2013 Databases Using Windows Server Backup is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

How to Decommission a Shared SMTP Namespace in Exchange Server

$
0
0

In a previous article I demonstrated how to setup a shared SMTP namespace in Exchange Server.

A shared SMTP namespace may be a permanent situation for some organizations, but for others it is only temporary while a migration is occurring (eg, during a merger of two companies).

When that temporary need no longer exists the shared SMTP namespace can be decommissioned. While this may not be strictly necessary, it is a good idea for neatness and efficiency in the Exchange organization.

For this scenario I recommend an approach like this.

Analyze the Send Connector(s) to Verify They Are Not Being Used

Part of the shared SMTP namespace configuration is a send connector to route emails from organization A to organization B.

You can use protocol logs to confirm that the send connector no longer has email traffic passing through it. Theoretically no traffic would be passing through the send connector but there are situations where some non-essential traffic is still passing through.

For example, organization B may have some old mailboxes that you decided did not need to be migrated to organization A, so any stray emails sent to those mailboxes will still show up in the protocol logs.

Either way, the protocol log data will help you find and fix (or choose to ignore) any remaining email traffic.

Remove the Send Connector

After confirming the send connector is no longer in use you can remove it.

I like to make note of the details of the send connector for future reference, just in case I need to reverse the change and re-establish the connector again.

[PS] C:\>Get-SendConnector oldcompany.com | fl
AddressSpaces                : {SMTP:*.oldcompany.com;1}
AuthenticationCredential     :
Comment                      :
ConnectedDomains             : {}
ConnectionInactivityTimeOut  : 00:10:00
DNSRoutingEnabled            : False
DomainSecureEnabled          : False
Enabled                      : True
ErrorPolicies                : Default
ForceHELO                    : False
Fqdn                         :
HomeMTA                      : Microsoft MTA
HomeMtaServerId              : HO-EX2010-MB1
Identity                     : oldcompany.com
IgnoreSTARTTLS               : False
IsScopedConnector            : False
IsSmtpConnector              : True
LinkedReceiveConnector       :
MaxMessageSize               : 10 MB (10,485,760 bytes)
Name                         : oldcompany.com
Port                         : 25
ProtocolLoggingLevel         : None
RequireOorg                  : False
RequireTLS                   : False
SmartHostAuthMechanism       : None
SmartHosts                   : {[10.10.10.10]}
SmartHostsString             : [10.10.10.10]
SmtpMaxMessagesPerConnection : 20
SourceIPAddress              : 0.0.0.0
SourceRoutingGroup           : Exchange Routing Group (DWBGZMFD01QNBJR)
SourceTransportServers       : {HO-EX2010-MB1, HO-EX2010-MB2}
TlsAuthLevel                 :
TlsDomain                    :
UseExternalDNSServersEnabled : False

Then remove the send connector with the Remove-SendConnector cmdlet.

[PS] C:\>Remove-SendConnector oldcompany.com
Confirm
Are you sure you want to perform this action?
Removing Send connector "oldcompany.com".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): y

Change the Accepted Domain to Authoritative

With no send connectors to route the formerly shared domain to other organizations you can change the accepted domain from InternalRelay to Authoritative.

[PS] C:\>Set-AcceptedDomain oldcompany.com -DomainType Authoritative

Also, you may want to enable address book lookups for the domain so that non-existent recipients can be rejected by recipient filtering (more info on that here).

[PS] C:\>Set-AcceptedDomain oldcompany.com -AddressBookEnabled $true

Update Email Address Policies (Optional)

Depending on your organization’s needs you may also need to change the primary SMTP address for migrated users, eg to align with the new company name/brand after a merger.

You can read more about using email address policies here.

Summary

As you can see decommissioning a shared SMTP namespace is not a complex process, at least for scenarios that were not highly complex to begin with. I’ve seen a few organizations over the years that left shared SMTP namespace configurations in place long after they were no longer required. While this doesn’t necessarily cause serious problems it is certainly worth decommissioning them for neatness and efficiency.


This article How to Decommission a Shared SMTP Namespace in Exchange Server is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Using PowerShell Custom Objects in Exchange Server Reporting Scripts

$
0
0

I often receive questions from people who are looking at some PowerShell examples here on Exchange Server Pro but want to know how to combine the output from different examples into a single script or report.

This is something I do in almost all of the PowerShell scripts I’ve published here, and you’re free to look at the code in them and use it elsewhere or customize it for your own needs. But I also wanted to give you a simple demonstration of the technique here.

Let’s say you want to write a script that will tell you the name, department, database name, and mailbox storage quota info for a mailbox.

Those are all pieces of information we can get from different PowerShell cmdlets:

  • Name can come from Get-Mailbox, Get-Recipient, or Get-MailboxStatistics (and others for that matter)
  • Department can come from Get-Recipient
  • Database name can come from Get-Mailbox or Get-MailboxStatistics
  • Get-Mailbox will also tell us if the mailbox is configured to use the database default quota values
  • The storage limit status (above or below quota limit) comes from Get-MailboxStatistics
  • The quota levels themselves can come from Get-Mailbox or Get-MailboxDatabase, depending on whether the mailbox is using database quota defaults or not

So as you can see the data we’re interested in can come from multiple cmdlets.

So now let’s build a simple script that fetches the data using those multiple PowerShell cmdlets, and then uses a PowerShell custom object to combine it all for output.

First, let’s fetch the data (my script has a parameter -Mailbox, hence the $mailbox in the example here).

#Fetch the various bits of data we're interested in
$mbx = Get-Mailbox $Mailbox
$recipient = Get-Recipient $mailbox
$mbxstats = Get-MailboxStatistics $mailbox
$database = Get-MailboxDatabase $mbx.Database

Next, we can create a custom object. Where I’m using $MailboxObject you can really use anything you like. I often simply use $ReportObj.

#Create the custom object
$MailboxObject = New-Object PSObject

Now let’s start adding properties and values to the custom object.

#Begin adding the values to the custom object properties
$MailboxObject | Add-Member NoteProperty -Name "Name" -Value $mbx.Name
$MailboxObject | Add-Member NoteProperty -Name "Department" -Value $recipient.Department
$MailboxObject | Add-Member NoteProperty -Name "Storage Limit Status" -Value $mbxstats.StorageLimitStatus
$MailboxObject | Add-Member NoteProperty -Name "Database" -Value $mbx.Database
$MailboxObject | Add-Member NoteProperty -Name "Uses Database Quota Defaults" -Value $mbx.UseDatabaseQuotaDefaults

As you can see it is as simple as giving each property a unique name, such as “Department”, and then assigning the value for that property such as $recipient.Department (remember that $recipient is what I fetched earlier with Get-Recipient).

You don’t need to match the property names and values precisely. I could just as easily use this instead:

$MailboxObject | Add-Member NoteProperty -Name "Dept" -Value $recipient.Department

But obviously for neatness and readability it pays to use property names that make sense.

Now comes the only “tricky” part of this script. If the mailbox is configured to use the database quota defaults, then we want to grab those values from the database. However if the mailbox is not using the default quota values, then we want to grab those values from the mailbox.

#If the mailbox is configured to use the database quota defaults, we collect those values from the database
if ($($mbx.UseDatabaseQuotaDefaults) -eq $true)
{
    $MailboxObject | Add-Member NoteProperty -Name "Warning Quota" -Value $database.IssueWarningQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Quota" -Value $database.ProhibitSendQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Receive Quota" -Value $database.ProhibitSendReceiveQuota
}
#Otherwise, we want the quota values from the mailbox itself
else
{
    $MailboxObject | Add-Member NoteProperty -Name "Warning Quota" -Value $mbx.IssueWarningQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Quota" -Value $mbx.ProhibitSendQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Receive Quota" -Value $mbx.ProhibitSendReceiveQuota
}

Finally, output the custom object.

#Output the results
$MailboxObject

Here is the complete script code, including the -Mailbox parameter that is used when running the script.

#
# Check-QuotaStatus.ps1
#
#requires -version 2
[CmdletBinding()]
param (
	[Parameter( Mandatory=$true)]
	[string]$Mailbox
	)
#Fetch the various bits of data we're interested in
$mbx = Get-Mailbox $Mailbox
$recipient = Get-Recipient $mailbox
$mbxstats = Get-MailboxStatistics $mailbox
$database = Get-MailboxDatabase $mbx.Database
#Create the custom object
$MailboxObject = New-Object PSObject
#Begin adding the values to the custom object properties
$MailboxObject | Add-Member NoteProperty -Name "Name" -Value $mbx.Name
$MailboxObject | Add-Member NoteProperty -Name "Department" -Value $recipient.Department
$MailboxObject | Add-Member NoteProperty -Name "Storage Limit Status" -Value $mbxstats.StorageLimitStatus
$MailboxObject | Add-Member NoteProperty -Name "Database" -Value $mbx.Database
$MailboxObject | Add-Member NoteProperty -Name "Uses Database Quota Defaults" -Value $mbx.UseDatabaseQuotaDefaults
#If the mailbox is configured to use the database quota defaults, we collect those values from the database
if ($($mbx.UseDatabaseQuotaDefaults) -eq $true)
{
    $MailboxObject | Add-Member NoteProperty -Name "Warning Quota" -Value $database.IssueWarningQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Quota" -Value $database.ProhibitSendQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Receive Quota" -Value $database.ProhibitSendReceiveQuota
}
#Otherwise, we want the quota values from the mailbox itself
else
{
    $MailboxObject | Add-Member NoteProperty -Name "Warning Quota" -Value $mbx.IssueWarningQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Quota" -Value $mbx.ProhibitSendQuota
    $MailboxObject | Add-Member NoteProperty -Name "Send Receive Quota" -Value $mbx.ProhibitSendReceiveQuota
}
#Output the results
$MailboxObject

Now let’s see the result when we run the script against some mailboxes.

[PS] C:\Scripts>.\Check-QuotaStatus.ps1 -Mailbox alan.reid
Name                         : Alan.Reid
Department                   : Finance Office
Storage Limit Status         : BelowLimit
Database                     : MB-HO-04
Uses Database Quota Defaults : True
Warning Quota                : 18.99 GB (20,394,803,200 bytes)
Send Quota                   : 20 GB (21,474,836,480 bytes)
Send Receive Quota           : 23 GB (24,693,964,800 bytes)
[PS] C:\Scripts>.\Check-QuotaStatus.ps1 -Mailbox alex.heyne
Name                         : Alex.Heyne
Department                   :
Storage Limit Status         : BelowLimit
Database                     : MB-BR-01
Uses Database Quota Defaults : False
Warning Quota                : 7.813 GB (8,388,608,000 bytes)
Send Quota                   : 8.789 GB (9,437,184,000 bytes)
Send Receive Quota           : unlimited

I hope that helps you understand how you can use PowerShell custom objects in your scripting tasks. If you have any questions or would like to see this concept covered in more depth please feel free to leave a comment below.


This article Using PowerShell Custom Objects in Exchange Server Reporting Scripts is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Restore an Exchange Server 2013 Database to a Recovery Database

$
0
0

In a previous article I demonstrated how to restore Exchange Server 2013 databases using Windows Server Backup. In that scenario an entire database that had been lost needed to be recovered.

However in other recovery scenarios you may only want to recover one or several mailboxes, or even specific mailbox items, from a point in time without having to overwrite the entire database.

In Exchange Server 2013 we can do this with recovery databases, which operate basically the same as Exchange Server 2010 recovery databases. A recovery database allows us to mount a copy of a database on an Exchange server without having any impact on the live copy of that same database. In fact we can even use recovery databases to mount copies of databases from other servers within the same Exchange organization, thanks to database portability.

When a recovery database is mounted we can inspect it and restore items or mailboxes from it, but no clients can connect to it. So as the name suggests it can only be used for recovery purposes, not for active mailbox functionality.

Restoring an Exchange Server 2013 Database Using Windows Server Backup

Some backup applications have the capability to handle some or all of the process of creating a recovery database, restoring the database files, and extracting the desired mailboxes or items to a destination.

When using Windows Server Backup to perform a recovery you need to do pretty much all of the work yourself, so it is a good exercise for learning how to recovery Exchange 2013 databases.

In Windows Server Backup click Recover to start a new recovery.

exchange-2013-recovery-database-01

Choose the location where the backup is stored. In this example my backups are stored on the same server.

exchange-2013-recovery-database-02

Choose the backup date and time that you wish to restore.

exchange-2013-recovery-database-03

When recovering entire databases we would normally choose “Applications” and restore every database that was backed up on the server. However when working with recovery databases we can choose Files and folders and only restore the specific database and log files we need.

exchange-2013-recovery-database-04

Browse through the tree of available items and choose the database and log files you want to restore. I am restoring DB02 in this example. Note that restoring the database and logs will be two separate restore jobs if they are located in folders where you can’t select both at the same time.

exchange-2013-recovery-database-05

Choose to restore to Another location, and select a folder that has enough free space to hold the restored data.

exchange-2013-recovery-database-06

Confirm your selections and click Recover to begin the restore.

exchange-2013-recovery-database-07

You can close the progress window if you like and the job will continue running in the background.

exchange-2013-recovery-database-08

I’ve also run a second recovery job to restore the log files for DB02.

After you’ve completed your file restores the next step is making the database mountable.

Making the Restored Database Mountable

So far we’ve restored the database and transaction log files from a recent backup, but haven’t created the actual recovery database yet. If we created the recovery database right now, pointing it at the restored database and log files, and then tried to mount it, the database would fail to mount.

The reason for this is that the restored database is in a “dirty shutdown” state, which you can see by navigating to the restored database folder and running eseutil.exe.

F:\RecoveryDB>eseutil /mh DB02.edb
Extensible Storage Engine Utilities for Microsoft(R) Exchange Server
Version 15.00
Copyright (C) Microsoft Corporation. All Rights Reserved.
Initiating FILE DUMP mode...
         Database: DB02.edb
            State: Dirty Shutdown

I have abbreviated the output of the above command, but basically you are looking for the “State” shown in the command output.

So we need to get the database file to a “clean shutdown” state before it can be mounted.

In my example I have:

  • A database file named DB02.edb in F:\RecoveryDB
  • Transaction logs with the filename prefix E01 in F:\RecoveryLogs

So my eseutil “soft recovery” command line will be:

F:\RecoveryDB>eseutil /r E01 /l F:\RecoveryLogs /d F:\RecoveryDB

What that command means:

  • /r for “recovery” mode
  • E01 for the log file name  prefix
  • /l (lower-case L) to specify the path to the log files
  • /d to specify the path to the database file (but do not include the name of the file itself)
F:\RecoveryDB>eseutil /r E01 /l F:\RecoveryLogs /d F:\RecoveryDB
Extensible Storage Engine Utilities for Microsoft(R) Exchange Server
Version 15.00
Copyright (C) Microsoft Corporation. All Rights Reserved.
Initiating RECOVERY mode...
    Logfile base name: E01
            Log files: F:\RecoveryLogs
         System files:
   Database Directory: F:\RecoveryDB
Performing soft recovery...
                      Restore Status (% complete)
          0    10   20   30   40   50   60   70   80   90  100
          |----|----|----|----|----|----|----|----|----|----|
          ...................................................
Operation completed successfully in 2.359 seconds.

After the command has completed check the state of the database with eseutil /mh again.

F:\RecoveryDB>eseutil /mh DB02.edb
Extensible Storage Engine Utilities for Microsoft(R) Exchange Server
Version 15.00
Copyright (C) Microsoft Corporation. All Rights Reserved.
Initiating FILE DUMP mode...
         Database: DB02.edb
            State: Clean Shutdown

If soft recovery does not bring the database to a clean shutdown state you may consider a hard recovery, which will make the database mountable but risks some data loss in the process.

F:\RecoveryDB>eseutil /p DB02.edb

exchange-2013-recovery-database-09

When the database is in a clean shutdown state you can create the recovery database.

Creating a Recovery Database in Exchange Server 2013

Creating a recovery database is performed using the New-MailboxDatabase cmdlet with the -Recovery switch. Notice that in this example I am using the same database and log file locations as my restored data.

[PS] C:\>New-MailboxDatabase -Server E15MB1 -Name RecoveryDB -Recovery -EdbFilePath F:\RecoveryDB\DB02.edb -LogFolderPath F:\RecoveryLogs
WARNING: Recovery database 'RecoveryDB' was created using existing file F:\RecoveryDB\DB02.edb. The database must be
brought into a clean shutdown state before it can be mounted.
Name                           Server          Recovery        ReplicationType
----                           ------          --------        ---------------
RecoveryDB                     E15MB1          True            None
WARNING: Please restart the Microsoft Exchange Information Store service on server E15MB1 after adding new mailbox
databases.

For more information about the warning to restart the Information Store service read this article. For a recovery database that you are only mounting for a short period of time an Information Store service restart may not be necessary.

Mount the recovery database.

[PS] C:\>Mount-Database RecoveryDB

Working with Recovery Databases

With the recovery database mounted you can use Get-MailboxStatistics to confirm that it contains mailbox database.

[PS] C:\>Get-MailboxStatistics -Database RecoveryDB | ft -auto
DisplayName                                                      ItemCount StorageLimitStatus          LastLogonTime
-----------                                                      --------- ------------------          -------------
SystemMailbox{849e4450-d32d-4a1b-90cf-5d0ca8109884}              239
Administrator                                                    102                           6/02/2014 11:06:56 PM
Discovery Search Mailbox                                         3
Aisha Bhari                                                      14996                          7/02/2014 2:05:18 AM
Alison Lindsay                                                   5848                          7/02/2014 12:04:59 AM
Ambrine Berry                                                    5849                           7/02/2014 1:01:17 AM
Ann Parker                                                       6107                           7/02/2014 1:01:34 AM
Bina Faria                                                       15055                          7/02/2014 2:03:36 AM
...snip...

After you have confirmed that data is available for restore you can begin your mailbox or item recovery.

In the next articles in this series we’ll cover different mailbox and item recovery scenarios.


This article Restore an Exchange Server 2013 Database to a Recovery Database is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Exchange Server 2013 Error: An Inconsistency in the Active Directory Was Detected

$
0
0

While creating a new mailbox database in Exchange Server 2013 you may encounter the following error.

[PS] C:\>New-MailboxDatabase DB07 -Server E15MB1 -EdbFilePath E:\DB07\DB07.edb -LogFolderPath F:\DB07

An inconsistency in the Active Directory was detected: Database ‘DB07′ is expected to be in a database availability
group but the value for its MasterServerOrAvailabilityGroup property (‘E15MB1′) is not valid. This may be a defect in
the product and this should be reported to Microsoft Product Support.
+ CategoryInfo : InvalidOperation: (DB07:MailboxDatabase) [New-MailboxDatabase], InconsistentADException
+ FullyQualifiedErrorId : [Server=E15MB1,RequestId=b008e2ed-bbd4-465e-9681-b8b64b734db0,TimeStamp=16/02/2014 1:07:
18 PM] 8006979E,Microsoft.Exchange.Management.SystemConfigurationTasks.NewMailboxDatabase
+ PSComputerName : e15mb1.exchange2013demo.com

This appears to be a bug that, at least in my specific case, occurs when an Exchange 2013 mailbox server has been removed as a member of a database availability group, and then a mailbox database is created on that mailbox server.

Despite the error message the database object is created in Active Directory, however the database and log folder paths are not created on the server and the database itself can’t be mounted.

[PS] C:\>Mount-Database DB07
Failed to mount database "DB07". Error: An Active Manager operation failed with a transient error. Please retry the
operation. Error: Database action failed with transient error. Error: A transient error occurred during a database
operation. Error: An error occurred while preparing to mount database 'DB07'. Error: An I/O error occurred while
attempting to enumerate log files in directory 'F:\DB07'. Error 0x3 (The system cannot find the path specified) from
Windows API 'FindFirstFile'. [Database: DB07, Server: E15MB1.exchange2013demo.com]
    + CategoryInfo          : InvalidOperation: (DB07:ADObjectId) [Mount-Database], InvalidOperationException
    + FullyQualifiedErrorId : [Server=E15MB1,RequestId=a930a445-11de-4fba-a648-881662a8e5f7,TimeStamp=16/02/2014 1:11:
   38 PM] FC4C3D31,Microsoft.Exchange.Management.SystemConfigurationTasks.MountDatabase
    + PSComputerName        : e15mb1.exchange2013demo.com

In my testing I found that the database creation error would not appear if I first re-added the mailbox server to a DAG (any DAG, not necessarily the one it was previously a member of). Obviously that is not an ideal solution, so fortunately it also appears that the new database will be mountable if you manually create the log folder path on the server.

[PS] C:\>New-Item -Type Directory -Path (Get-MailboxDatabase DB07).LogFolderPath

After creating the log folder path the database should mount successfully.

[PS] C:\>Mount-Database DB07
[PS] C:\>Get-MailboxDatabase DB07 | Test-MAPIConnectivity
MailboxServer      Database           Result    Error
-------------      --------           ------    -----
E15MB1             DB07               Success

I am not sure exactly which versions of Exchange Server 2013 would exhibit this behaviour, as I only have Exchange 2013 CU3 available to me at the moment.


This article Exchange Server 2013 Error: An Inconsistency in the Active Directory Was Detected is © 2014 ExchangeServerPro.com

Get more Exchange Server tips at ExchangeServerPro.com

Viewing all 506 articles
Browse latest View live