• 1. London, UK
  • 2. New York, NY
  • 3. Sydney, Australia
  • 4. Melbourne, Australia
  • 5. San Francisco, CA
  • 6. Chicago, IL
  • 7. Toronto, Canada
  • 8. Moscow, Russia
  • 9. Houston, TX
  • 10. Amsterdam, Netherlands
Bharat Suneja

Bizarre RSS Feed issue with FeedBurner?

The site's having some issues with the Feedburner RSS feed— it's stuck in a time warp and refuses to move on from the post dated June 15th, 2008 (the one titled What is an Azalia controller?).
Every day it moves forward by one day, so we're at June 17 in Firefox today. You may or may not run into it. To see it for yourself, try visiting the RSS feed URL in Firefox and in Internet Explorer. IE shows the updated feed.

If you're using FireFox, please use the atom feed meanwhile.

Recent Posts

Tuesday, July 29, 2008

Users consider email to be a reliable communication mechanism - not as reliable as the dial tone, but pretty close. Most users expect mail to be delivered within minutes, if not seconds.

Many organizations, including those operating in the financial & banking sectors, have strict SLAs for mail delivery which specify mail delivery times granularly— for mail within a particular location (that is, within a Routing Group in Exchange 2003 and within an AD Site in Exchange 2007), between two locations, and to/from the internet.

Exchange Server sends a delay notification to inform the sender if delivery of a message is delayed beyond a configured timeout. The default delay notification timeout in Exchange Server 2003 is 12 hours. This has been reduced to a (comparatively) more realistic 4 hours in Exchange Server 2007.

When considering changing these defaults, it's a good idea to consider any SLAs and user expectations. Is it reasonable to expect a user to wait for 24 hours before informing him/her about a delay? 12 hours? 1 hour?

Screenshot: Transport Server properties
Figure 1: In Exchange 2007, the default delay notification timeout is 4 hours

You can change the delay notification timeout using the Exchange console (EMC) from Server Configuration | Hub Transport | SERVERNAME -> Properties | Limits tab.

To change delay notification timeout using the Exchange shell:

Set-TransportServer "SERVERNAME" -DelayNotificationTimeout 01:00:00

This sets the notification timeout to 1 hour. The value is specified in dd.hh:mm:ss (the standard format used by the shell). Valid values— minimum: 00:00:01 (yes, 1 second!) to 30.00:00:00 (30 days). It's recommended to wait till transient failure retries have been completed before sending a delay notification (that is, higher than TransientFailureRetryInterval x TransientFailureRetryCount).

In Exchange Server 2003, the delay notification timeout can be changed from SMTP Virtual Server | Properties | Delivery tab. There are different delay notification timeouts for outbound and local mail.

If you decide users don't need to know about mail delivery delays (and there could be perfectly legitimate reasons for that - although as I write this I can't think of any... ), you can disable delay notifications:

Set-TransportServer "SERVERNAME" -ExternalDelayDsnEnabled $false -InternalDelayDsnEnabled
$false

Have you changed the default delay notification in your organization? What is a reasonable time for notifying users about delays?

Related:

Labels: , , ,

Monday, July 28, 2008

 

PowerShell: Listing multi-valued attributes

Posted by Bharat Suneja at 12:27 PM
In previous posts, we've taken a look at how to update multi-valued attributes and remove values from multi-valued attributes using PowerShell/Exchange Shell (EMS).

Multi-valued attributes have a special significance in AD, and interfaces/APIs used to access AD. Whereas single-valued attributes can be retrieved and updated quite easily, multi-valued attributes come with a twist. Values from a multi-valued attribute are returned as an array (of values). To evaluate values in a multi-valued attribute, you need to iterate through each one (using a foreach loop in most cases). Similarly, when updating a multi-valued attribute, we need to remember we're adding/updating one value of what could possibly be multiple items in an array.

With that out of the way, a real-word experience relates to how these values are listed in Exchange shell cmdlet output. For instance, the BypassedSenders property of ContentFilterConfig may have a few dozen safe senders that you do not want to subject to the Content Filter. If you list these bypassed senders using Get-ContentFilterConfig, the output will list a few bypassed senders. Note the trailing dots to indicate there are more values?

Using a format-list or fl (Get-ContentFilterConfig |select BypassedSenders | fl) doesn't help.

Screenshot: Multi-valued attributes and PowerShell
Figure 1: Output from Exchange shell cmdlets does not list all values in multi-valued attributes

BypassedSenders and Safelist Aggregation

The Content Filter Agent does not filter messages from addresses on its BypassedSenders property, regardless of the recipient. This should not be confused with a recipient's Safe Senders list (used by the Safelist Aggregation feature) to bypass mail for a recipient from the senders he/she adds to Safe Senders list in Microsoft Outlook. CFA's BypassedSenders is global in scope.

To get a list of all values in a multi-valued attribute such as BypassedSenders:

$senders = (Get-ContentFilterConfig).BypassedSenders; $senders

Alternatively, you can list them without adding them to a hash table ($senders in above example):

(Get-ContentFilterConfig).BypassedSenders


Screenshot: Multi-valued attributes and PowerShell 2
Figure 2: Listing all values in BypassedSenders multi-valued attribute

Similarly, multiple IP addresses or address ranges in a Receive Connector's RemoteIPRanges property:

(Get-ReceiveConnector "MyConnector").RemoteIPRanges

or formatted as a table with the required info:

(Get-ReceiveConnector "MyConnector").RemoteIPRanges | ft Lowerbound,Upperbound,RangeFormat -AutoSize

Screenshot: Multi-valued attributes and PowerShell 3
Figure 3: Listing all values in RemoteIPRanges multi-valued attribute of a Receive Connector

Related posts:

Labels: , , ,

Thursday, July 24, 2008

In Exchange Server 2003/2000, expanding a Mailbox Database provides information about mailboxes in a database, last logon/logoff times and account(s) that logged on to mailboxes (see 'Displaying Client IP Address in Exchange System Manager' for details).

Screenshot: Store Logons
Figure 1: In Exchange 2003, the Logons node displays Store logon-related information. Click here to see a bigger screenshot.

In Exchange Server 2007, these details are not displayed in the EMC. These can be retrieved easily using the Exchange shell.

The Get-LogonStatistics cmdlet provides the following logon-related information.

AdapterSpeed :
ClientIPAddress :
ClientMode :
ClientName :
ClientVersion :
CodePage :
CurrentOpenAttachments :
CurrentOpenFolders :
CurrentOpenMessages :
FolderOperationCount :
FullMailboxDirectoryName :
FullUserDirectoryName :
HostAddress :
LastAccessTime :
Latency :
LocaleID :
LogonTime :
MACAddress :
MessagingOperationCount :
OtherOperationCount :
ProgressOperationCount :
RPCCallsSucceeded :
StreamOperationCount :
TableOperationCount :
TotalOperationCount :
TransferOperationCount :
UserName :
Windows2000Account :
ServerName :
StorageGroupName :
DatabaseName :
Identity :

The command can be constrained to a mailbox database (get-logonstatistics -Database "MyDatabase" | fl), a mailbox server (get-logonstatistics -Server "MyServer"), or a particular mailbox.

Mailbox information

In ESM, the Mailboxes node of a Mailbox Store displays mailbox-related information such as mailbox size, number of items, and last logon/logoff.

Screenshot: Mailboxes node in Exchange 2003 ESM
Figure 2: In Exchange 2003, the Mailboxes node displays mailbox-related information. Click here to see a bigger screenshot.

This information can be retrieved using the Get-MailboxStatistics cmdlet. It provides the following information related to a mailbox:

AssociatedItemCount :
DeletedItemCount :
DisconnectDate :
DisplayName :
ItemCount :
LastLoggedOnUserAccount :
LastLogoffTime :
LastLogonTime :
LegacyDN :
MailboxGuid :
ObjectClass :
StorageLimitStatus :
TotalDeletedItemSize :
TotalItemSize :
Database :
ServerName :
StorageGroupName :
DatabaseName :
Identity :

It can also be constrained to a -Database, -Server, or mailbox.

Now that we're dealing with the shell, besides these cmdlets' built-in filtering capabilities (Database, Server, or mailbox), you can use Powershell's where-object cmdlet to further filter the results based on the properties returned by each cmdlet. For example, to find out logon sessions from a particular IP address:

Get-LogonStatistics -Server "MyServer" | where {$_.ClientIPAddress -like "192.168.2.101"}

Labels: , , , ,

Tuesday, July 15, 2008

It's easy to get a list of all members of a Distribution Group. The Exchange shell (EMS) ships with the Get-DistributionGroupMember cmdlet that makes it a short one-liner (compared to 100s of lines of code in VBS).

However, how do we get all Distribution Groups a user, group, or contact is a member of? There's no equivalent cmdlet that can list a recipient's distribution group memberships using the shell. From the AD side, a recipient's memberOf attribute is a back-linked attribute, which I briefly talked about in memberOf Attribute can now be used in OPATH filters!. A group's membership is stored in the group's member attribute.

In the following command/script (what's the boundary between a command and a script?? when do a bunch of commands become a script?), we look at all distribution groups in AD, look at each member and determine if it matches the one we're looking for.

$contact = get-contact "foo@somedomain.com"; Get-DistributionGroup | foreach {$dg = $_ ; write-host "Looking at: "
$dg; Get-DistributionGroupMember $dg | foreach {if ($_.identity -like $contact.identity) {"Member of : " + $dg} }}

Clearly, this isn't very efficient!

Using the ADSI provider

The shell can also look at the AD objects natively using the ADSI provider. It's not as friendly or easy to use (as a native AD provider for Powershell would probably be), but it's a huge improvement over VBScript. There's no need to grab AD objects into ADO recordsets— that part is taken care of by Powershell.

Here's one way to do this using the ADSI provider:

$dn = "LDAP://" + (Get-Contact foo@somedomain.com).distinguishedName; $foo=[ADSI]$dn; $foo.memberOf | foreach {$dg = $_; get-distributiongroup $dg}

Here's a script with some changes and validation: Get-DGMembership.zip

What it does: Uses the ADSI provider to get list of all groups a recipient is a member of, determines if the group is a Distribution or Security group, outputs names of Distribution Groups.
Usage:

.\Get-DGMembership.ps1 Mailbox1@mydomain.com

.\Get-DGMembership.ps1 Mailbox1@mydomain.com Contact2@somedomain.com

What we can really use is a native AD provider that lends the same automation capabilities to AD management tasks that the Exchange shell and Powershell lend to Exchange and Windows management tasks.

Labels: , , , , ,

Monday, July 07, 2008

I posted about this in Adventures with OPATH: some annoyances if you're used to LDAP, shortly after Exchange Server 2007 RTMed (Yes, it has really been that long... ). Here's a quick recipe to create a Dynamic Distribution Group to include all mailboxes on a database.

$DB = (Get-MailboxDatabase "SERVER\Storage Group\Mailbox Database").distinguishedName

New-DynamicDistributionGroup MyGroup -RecipientFilter {Database -eq $DB} -RecipientContainer "DC=MyDomain,DC=com" -OrganizationalUnit "OU=Distribution Groups,DC=MyDomain,DC=com" -RequireSenderAuthenticationEnabled $false

The first step gets the distinguishedName of the mailbox database in a variable called $DB.

Parameters:
- OrganizationalUnit: Specifies the container/OU where the group will be created
- RecipientContainer: Specifies container to pick up recipients from. If not specified, this gets set to the same value as the OrganizationalUnit parameter (the OU/Container where the group is created), and the filter may not return the expected recipients (or worse— may not return any recipients at all... )
- RequireSenderAuthenticationEnabled: As discussed in 'New Distribution Groups do not receive internet email by default', new groups do not receive internet email (that is, email from unauthenticated/anonymous senders)) by default. If you want the group to receive internet email, set this to $false.

Labels: , ,

 

Controlling OOFs per domain and per mailbox

Posted by Bharat Suneja at 9:49 AM
OOFs can be controlled per domain using Remote Domain settings. By default, setup creates the default Remote Domain for address space *. (As with Connector namespaces, * translates to all domains for which Exchange isn't authoritative/has an Accepted Domain for, and doesn't have an explicit Remote Domain for).


Figure 1: Remote Domains allow control of OOF messages to the internet or specific domains

The choices:
None: OOFs are disabled for the remote domain.
External: Allows only external OOFs to be sent to the remote domain. OOFs created using legacy Outlook clients and those sent by Exchange 2003/2000 servers will be not be allowed. If blocking OOFs to external domains in Exchange 2003/2000, this allows you to restrict legacy Outlook clients from sending OOFs, but allow Outlook 2007/Exchange 2007 users to send external OOFs.
ExternalLegacy: Allows external and legacy OOFs to be sent to the remote domain.
InternalLegacy: Allows internal and legacy OOFs to be sent to the remote domain.

Allowing Internal OOFs to Remote Domains

The InternalLegacy setting sends internal OOF messages to a Remote Domain. If verbiage or content of internal OOFs isn't something you want to share with the outside world, do not use this for Remote Domains.



The InternalLegacy option can be useful in distributed organizations with multiple address spaces and multiple email systems, or specific cases where you may want to share such information with a trusted organization.

Controlling OOFs per-mailbox

Besides the settings in Remote Domains, you can also control external OOFs per-mailbox. This is done using the Set-Mailbox cmdlet. The ExternalOofOptions parameter defaults to External. You can change it to InternalOnly to restrict a mailbox user from sending OOFs outside the organization:

Set-Mailbox foo@mydomain.com -ExternalOofOptions InternalOnly



Labels: , , ,

Tuesday, June 24, 2008

I remember writing plenty of scripts to report on different things such as user accounts created every week/month, user accounts modified, accounts disabled, etc. for SOX compliance. Some of those scripts used to be rather long, and in hindsight— involved a lot more lines of code than an administrator should have to write. Although I had a lot of fun (and still do... albeit with PowerShell), I would totally understand if you said you never wanted to hear about things like Wscript, VBScript, WSH, COM objects, ADSI, and WMI ever again.


Let's take a look at how the shell (EMS) makes it so easy.

In this examnple, we need to get a list of all accounts created in the last 7 days. When a user account is created, its whenCreated attribute gets stamped with the time of creation. Here's how it can be used:

Get-User -resultsize unlimited | where {$_.WhenCreated -gt (get-date).adddays(-7) | ft Name,whenCreated -Autosize

Similarly, when an AD object is changed, it's whenChanged attribute gets stamped with the time the change was made. This makes it easy to determine which objects were changed in a given period, a useful tool for auditing/reporting as well as troubleshooting. In the following example, we determine if any Receive Connectors were changed in the last 7 days.

Get-ReceiveConnector | where {$_.whenChanged -gt (get-date).adddays(-7)}

Another frequently required and requested report— how do I get a list of mailboxes that haven't been accessed in the last X days. Let's use 100 days as the value here:

Get-MailboxStatistics -resultsize unlimited | where {$_.LastLogonTime -lt (get-date).AddDays(-100)} | ft displayName,lastlogontime,lastloggedonuseraccount,servername

Or mailboxes that have never been logged on to:

Get-MailboxStatistics -resultsize unlimited | where {$_.LastLogonTime -eq $null | ft displayName,lastlogontime,lastloggedonuseraccount,servername

Note, you can filter mailboxes by Database or ServerName to restrict the results to a more manageable size.

Next, let's list mailboxes disabled in the last 14 days:

Get-MailboxStatistics | Where {$_.DisconnectDate -gt (get-date).AddDays(-14)} | ft displayName,ServerName,DatabaseName,TotalItemSize -Autosize

Labels: , , ,

Tuesday, June 17, 2008

 

Starting Task Manager in RDP or VM sessions

Posted by Bharat Suneja at 5:49 PM
You have a RDP (Terminal Services) session or a Virtual Machine session open, where the CTRL-ALT-DEL key combination fires up the Windows Logn/Security dialog on the host computer rather than the RDP or VM session you have open.

Getting to the Task Manager involves some mouse-clicks in such situations— Start -> Windows Security -> Task Manager (works in both RDP and VM sessions) or clicking on the appropriate shortcut in the VM client software. Hyper-V has a short-cut on its menu bar that makes it a single mouse click, but still not quick enough. It's actually annoying if you are happily pounding away at the keyboard for most part... and now need to lift your hand to grab a mouse and... you know where we're going with this!

Shorcuts exist - if you're at the cmdline, you can simply type taskmgr.exe (or Start -> Run -> type taskmgr.exe). Alternatively, you can create a desktop shortcut and point it to taskmgr.exe. If you simply want to remain at the cmdline and not bother with the GUI at all, use TaskList. You can filter the output in a number of ways - use tasklist /? to see all the options.

If you're on an Exchange 2007 box or have Windows PowerShell installed, it gets event better. Get-Process and Stop-Process commands are your friends here. You can filter by process name or PID, and also pipe the output from Get-Process to Stop-Process. For example:

Get-Process -Name svchost
Get-Process -Name MSExchange* | ft Id,Name,Handles,PM -AutoSize
Get-Process | ft Name,Company,ProductVersion,FileVersion -Autosize
Stop-Process -ID 6064
Get-Process mmc* | where {$_.Handles -gt 1000} | stop-process

Labels: , ,

Monday, June 16, 2008

 

Quick antispam report or status check?

Posted by Bharat Suneja at 8:06 AM
Having received an annoyingly higher proportion of spam in my Inbox this morning, I wanted to quickly check what the antispam agents are doing. Here's a quick cmdlet (besides the ones to check whether the antispam agents are enabled, checking the Content Filter SCL thresholds, etc.).

Get-AgentLog -StartDate "6/16/2008" | group action | ft name,count -Autosize

What you get back:

Name Count
---- -----
RejectCommand 520
AcceptMessage 39
RejectMessage 163
QuarantineMessage 11
DeleteMessage 21

The filters are still working. Perhaps it's one of those days when you wake up to high volume of spam.

Note to self: Create a quick monitoring script that provides more information from agent logs, antispam configs, and perfmon counters.

Related posts:
- Keeping tabs on Antispam filters: A few handy scripts in Exchange Server 2007
- Exchange Server 2007: How are RBLs performing?
- Exchange Server 2007: Managing And Filtering Anti-Spam Agent Logs

Labels: , , , ,

Tuesday, May 20, 2008

Another frequently asked question about SMTP mail - how can I remove internal host names and IP addresses from outbound internet mail? More often than not, this results from the belief that somehow if the outside world finds out an organization's internal IP addresses and host names, it makes the organization vulnerable. Auditors love to point this out for some reason. Perhaps it's a part of a checklist written by a security expert at some law firm somewhere, and given the viral nature of checklists it's all over the place!

Let's take a look at what we're talking about here. As a message makes its way from one server to another, it may be handled by more than one SMTP hosts. Each host adds a RECEIVED header at the beginning of message headers, leaving a trace of where the message has been and when (a timestamp).

Here are headers from a message received from Dell. (Unnecessary headers removed).

Received: from smtp.easydns.com (205.210.42.52) by exchange.somedomain.com
(192.168.2.171) with Microsoft SMTP Server id 8.1.240.5; Mon, 19 May 2008
03:12:46 -0700
Received: from mh.dell.m0.net (mh.dell.m0.net [209.11.164.66]) by
smtp.easydns.com (Postfix) with ESMTP id 647C222914 for ;
Mon, 19 May 2008 06:14:46 -0400 (EDT)
Received: from [192.168.138.130] ([192.168.138.130:57330]
helo=fc13a1.dc1.prod) by oms1.dc1.prod (ecelerity 2.1.1.24 r(19486)) with
ESMTP id 3B/AF-18306-11351384 for ; Mon, 19 May 2008
03:14:41 -0700

Message-ID: <14154167762.1211192081379@delivery.net>
Date: Mon, 19 May 2008 03:14:41 -0700
From: Dell Small Business
Reply-To:
To:
Subject: $429 desktop, plus new laptops. Hurry and shop now.
Errors-To: dell@smallbusiness.dell.com
Return-Path: dell@smallbusiness.dell.com

These headers can be used to determine the path taken by a message— useful information for troubleshooting and preventing message loops.

What the standards say
Let's take a look at what the standards say. RFC 2821 says (capitalization of words as it appears in the RFC, emphasis added):
4.4 Trace Information

When an SMTP server receives a message for delivery or further processing, it MUST insert trace ("time stamp" or "Received") information at the beginning of the message content, as discussed in section 4.1.1.4.

This line MUST be structured as follows:

- The FROM field, which MUST be supplied in an SMTP environment, SHOULD contain both (1) the name of the source host as presented in the EHLO command and (2) an address literal containing the IP address of the source, determined from the TCP connection.
and prohibits removing received headers (repeatedly). One example:
An Internet mail program MUST NOT change a Received: line that was previously added to the message header. SMTP servers MUST prepend Received lines to messages; they MUST NOT change the order of existing lines or insert Received lines in any other location.
More secure?
Should you remove these headers, and "hide" internal hosts and IP addresses? Is it really a security risk?

There are many opinions about security through obscurity, but if your security relies on hiding internal hostnames and IP addresses, you probably have other things to worry about.

Steve Riley, Senior Security Strategist at Microsoft, says:
In general, you can’t achieve any additional security by trying to hide things that weren’t designed to be hidden. IP addresses, wireless SSIDs, hostnames—these are all identifiers, and by definition, an identifier is intended to be known. Efforts to hide them generally fail, because the thing that the identifier points to still exists! Determined attackers will find the thing regardless of what you name it.
Microsoft does not remove internal message routing headers. Nor do Dell (as the message headers in the example above reveal), HP, and many other large organizations.

In many ways, the issues faced are similar to changing fqdn on SMTP Virtual Server/Receive Connector. Even if you make these changes, at least one internal hostname is likely to be revealed by the Message-ID (read "Masquerading SMTP Virtual Servers: Changing the fqdn and masquerade domain").

Nevertheless, many organizations may have a legitimate need to cleanse outbound mail of internal host names and IP addresses, and you probably don't want to invite adverse remarks in an IT or compliance audit (should you find such a requirement on the auditor's checklist).

How to remove Received headers in Exchange Server 2007
Exchange Server 2007 offers an easy way to accomplish this. If your transport server sends outbound email directly using DNS lookup, or delivers to a smarthost without authentication, simply remove the Ms-Exch-Send-Headers-Routing permission assigned to Anonymous Logon— a well-known security principal that refers to anonymous users, as shown below:

Get-SendConnector "Connector Name" | Remove-ADPermission -AccessRight ExtendedRight -ExtendedRights "ms-Exch-Send-Headers-Routing" -user "NT AUTHORITY\Anonymous Logon"

What's your take?
Does your organization remove internal Received headers? What are the reasons cited? Does removing internal received headers make your organization more secure? Feel free to leave a comment and share your opinion about this.

Labels: , , , ,

Monday, March 17, 2008

Standby Continuous Replication (SCR) is a new High Availability feature in Exchange Server 2007 SP1. It uses Continuous Replication (also used by LCR and CCR) to replicate Storage Groups from a clustered or non-clustered mailbox server, known as a SCR source, to a clustered or non-clustered mailbox server, known as a SCR target.

SCR is managed using the Exchange shell - no management features exist in the EMC to configure or manage it.

Unlike LCR and CCR, which are designed to have a single copy of a Storage Group (consisting of an Exchange Store EDB + transaction logs & system files), SCR is designed to have many-to-one and one-to-many "replication relationships". (A SCR relationship or partnership - not formally defined terms, but simply used to explain the concept here - is SCR replication of a particular Storage Group from a SCR source server to a particular SCR target server).

A Storage Group from one SCR source can be replicated to multiple SCR target servers, and Storage Groups from one or more SCR source mailbox servers can be replicated to a single SCR target mailbox server.

By default, the Replication Service delays replaying 50 transaction logs to the SCR replica Database. Additionally, you can configure the following parameters to control how SCR replicas behave:
ReplayLagTime: specifies how long the Replication Service waits before replaying replicated transaction logs to the replica Database (EDB) on the target. Default:1 day
TruncationLagTime sets a lag time for truncating log files on that replica. Provided the other requirements are met for log file truncation on the SCR replica, log files are not truncated till ReplayLagTime + TruncationLagTime has elapsed. Default:0.

Why do I need the delay?

Replay lag gives you the protection of having a copy of your database from back in time. This back-in-time copy can be used to recover from logical corruption, pilot errors etc.

Additionally, if there is no delay, in the case of a lossy failover of the SCR source to a LCR or CCR replica, the (new source) Database will be behind its SCR target(s), requiring reseeding. Not something one would want to do for large Databases over WAN links (or even locally within the same datacenter). Delaying the last 50 transaction logs from being replayed to the SCR target avoids the need to reseed.

However, a large number of transaction logs not replayed to the Database means increased storage requirements for the SCR target, and also an increase in the time it takes to activate it in case of failure of the SCR source. Before it can be brought online, all the logs will need to be replayed.

To avoid this, you can set the ReplayLagTime to 0 (from the default of 1 day). Note, the replay will still lag behind by 50 transaction logs - a hard-coded limit enforced by SCR that cannot be changed. The TruncationLagTime can be set higher, so logs are replayed but not truncated. You can then take VSS snapshots of the target for the point-in-time copies.

Once setup using the Enable-StorageGroupCopy command, the ReplayLagTime and TruncationLagTime cannot be changed without disabling and re-enabling that SCR relationship for the Storage Group.

How can I see ReplayLagTime and TruncationLagTime? The following command shows the SCR targets a Storage Group is being replicated to:

Get-StorageGroup "SG Name" | fl

However, neither the above command, nor Get-StorageGroupCopyStatus show the lag times.

The parameters are returned as an array when you use the former (Get-StorageGroup) - only the name of the SCR target is displayed in the StandbyMachine property.

To see the lag times:

$sg = Get-StorageGroup "MyServer\MyStorageGroupName"
$sg.StandbyMachines

Here's what it looks like:


Figure 1: Displaying the Replay and Truncation lag time

Can I change ReplayLagTime and TruncationLagTime without reseeding the Database? You need to disable replication and re-enable it to add or modify the lag times. :

Disable-StorageGroupCopy "Storage Group Name" -StandbyMachine "SCR Target Server"

When disabling SCR, you get prompted to delete all files in the replica folder on the SCR target. Skip that. Reseeding is not required if you do not delete the files:

WARNING: Storage group "DFMAILMAN.e12labs.com\dfmailman-sg1" has standby continuous replication (SCR) disabled. Manually delete all SCR target files from "C:\Exchange Server\Mailbox\First Storage Group" and "C:\Exchange Server\Mailbox\First Storage Group\Mailbox Database.edb" on server "mirror".

Now, let's enable SCR with the replay and truncation lag times:

Enable-StorageGroupCopy "Storage Group Name" -StandbyMachine "SCR Target Server" -ReplayLagTime 1.00:00:00 -TruncationLagTime 2.00:00:00

Once replication is enabled again, make sure to test replication status using:

Get-StorageGroupCopyStatus "SG Name" -StandbyMachine "SCR Target Server"

Labels: , , ,

Tuesday, March 11, 2008

 

Routing outbound mail using a particular IP address

Posted by Bharat Suneja at 11:35 AM
A question that frequently and inevitably pops up when discussing Exchange transport is that of being able to route outbound mail using a particular IP address. The Exchange Server 2003/2000 transport architecture was confusing for many newcomers— the difference between an SMTP Virtual Server and an SMTP Connector being the main cause of this confusion. This is further exacerbated by the fact that SMTP Connectors use SMTP Virtual Servers as bridgeheads.

Screenshot: SMTP Virtual Server properties - General tab
Figure 1: In Exchange Server 2003/2000, the IP address binding in SMTP Virtual Server properties is only for inbound connections

I've often quoted Scott Landry's post on the team blog— SMTP Virtual Server Myths Exposed. Myth #4 in Scott's post:
Myth 4: Virtual Server IP Address Will Be Used For Outgoing Connections

The last source of misunderstanding is the socket which will be used to open an SMTP connection. This may seem confusing and somewhat contradictory of my first point, but SMTP simply tells the Windows network stack to provide SMTP with a socket. It does not provide a source IP address to use, and as such, you will notice that the source IP address assigned by Windows will be based on the Windows routing table, not taking into consideration the IP of the SMTP VSI that is delivering the message. A common observation of this is that on a cluster server we are using the physical machine IP as our source IP, not any of the virtual IP addresses.
Exchange Server 2007, with its shiny new transport stack (freshly divorced from IIS' SMTP service), makes this quite clear. Receive Connectors, somewhat comparable to the SMTP Virtual Server in previous versions, are for receiving inbound mail. Send Connectors are for sending outbound mail.

When creating or modifying a Send Connector using the shell, you can specify the SourceIPAddress parameter to configure it to use a particular IP address for outbound mail. The IP address can be any IP address bound to a NIC on the Edge Transport server that is configured as a source server on the Send Connector. To modify an existing Send Connector, using the following command:

Set-SendConnector "ToInternet" -SourceIPAddress 1.2.3.4

However, as noted in the documentation, this only works on Edge Transport servers. Hub Transport servers ignore the SourceIPAddress parameter.

Labels: , , ,

Monday, March 03, 2008

Exchange Server 2007 allows easier delegation of administration responsibilities, based on the following predefined administration roles:
1) Exchange Organization Administrator
2) Exchange Server Administrator
3) Exchange Recipient Administrator
4) Exchange Public Folder Administrator and
5) Exchange View Only Administrator.


Figure 1: Exchange Server 2007 allows delegation of administrative responsibilities

The delegation wizard in the EMC allows you to delegate the Recipient Administrator role for the entire Organization, but doesn't allow more granular delegation at the Domain or OU level.

More about the Exchange Recipient Administrator role

Security principals that have the Exchange Recipient Administrator role delegated get membership of the Exchange View Only Administrators role. Additionally, they are assigned:
- Read access to all the Domain Users containers in AD (in domains where Setup /DomainPrep has been run)
- Write access to all the Exchange-specific attributes in those domains

When delegating the Exchange Recipient Administrator role using the Exchange console or the Add-ExchangeAdministrator command in the Exchange shell, all you're doing is adding the security principal (user/group) to Exchange Recipient Administrators, a (Universal) Security Group in the Microsoft Exchange Security container in AD.

For more details about Exchange Server 2007 permissions, refer to "Configuring Permissions in Exchange Server 2007".

Here's how you can delegate recipient administration for an OU.
Exchange Organization: E12Labs
Domain: E12Labs.com (DC=E12Labs,DC=com)
OU: San Francisco (OU=San Francisco,DC=E12Labs,DC=com)
User: foo (Best Practice: Assign permissions to Security Groups)

1 Allow generic read permission for objects in the OU:

Add-ADPermission -Identity "ou=San Francisco,dc=E12Labs,dc=com" -User "E12Labs\foo" -AccessRights GenericRead

2 Allow ReadProperty and WriteProperty permissions on Exchange-related attributes for objects in the OU

Add-ADPermission –Identity "ou=San Francisco,dc=E12Labs,dc=com" –User "E12Labs\foo" -AccessRights ReadProperty, WriteProperty -Properties Exchange-Information, Exchange-Personal-Information, legacyExchangeDN, displayName, adminDisplayName, displayNamePrintable, publicDelegates, garbageCollPeriod, textEncodedORAddress, showInAddressBook, proxyAddresses, mail

Property Sets in Active Directory

Exchange-Information and Exchange-Personal-Information are property sets - a number of related properties grouped together. Assigning permissions on a property set results in a single ACE in DACLS, making them much smaller and faster to process.

Exchange Server 2003 adds Exchange attributes to the Public Information and Private Information property sets that exist in Active Directory.

Exchange Server 2007 does not rely on these existing AD property sets, but creates 2 of its own. If deploying in an existing Exchange 2003 Forest, Exchange Server 2007 removes the Exchange properties added to the AD property sets and adds them to the new Exchange 2007 property sets. The Exchange-Information property set has 105 properties. Exchange-Personal-Information has 7. More information about the Exchange Server 2007 property sets and which properties are included in them can be found in "Property Sets in Exchange 2007".

3 Allow creation and management of Dynamic Distribution Groups in the OU
Exchange Server 2007 RTM:

Add-ADPermission -Identity "ou=San Francisco,dc=E12Labs,dc=com" -User "E12Labs\foo" -AccessRights GenericAll –InheritanceType Descendents -InheritedObjectType msExchDynamicDistributionList

Add-ADPermission -Identity "ou=San Francisco,dc=E12Labs,dc=com" -User "E12Labs\foo" -AccessRights CreateChild, DeleteChild -ChildObjectTypes msExchDynamicDistributionList

Exchange Server 2007 SP1:

Add-ADPermission -Identity "ou=San Francisco,dc=E12Labs,dc=com" -User "E12Labs\foo" -AccessRights CreateChild, DeleteChild -ChildObjectTypes msExchDynamicDistributionList

4 Allow permission to access RUS:

Add-ADPermission -Identity "CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=E12Labs,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=E12Labs,DC=com" -User "E12labs\foo" -InheritedObjectType ms-Exch-Exchange-Server -ExtendedRights ms-Exch-Recipient-Update-Access -InheritanceType Descendents

5 Allow permission to update Address Lists and Email Address Policies:

Add-ADPermission –Identity "CN=Address Lists Container,CN=E12Labs,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=E12Labs,DC=com" –User "E12Labs\foo" -AccessRights WriteProperty -Properties msExchLastAppliedRecipientFilter, msExchRecipientFilterFlags

Add-ADPermission –Identity "CN=Recipient Policies,CN=E12Labs,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=E12Labs,DC=com" –User "E12Labs\foo" -AccessRights WriteProperty -Properties msExchLastAppliedRecipientFilter, msExchRecipientFilterFlags

6In addition to these Active Directory permissions, recipient administrators also need Exchange View Only Administrator permission on the Exchange Organization. Use the following command to assign it:

Add-ExchangeAdministrator "E12Labs\foo" -Role ViewOnlyAdmin

A script for SP1: If you're on Exchange Server 2007 SP1, a script written by Ross Smith IV makes delegating recipient administration permissions on an OU a simple task accomplished quickly (No, it's not for Exchange Server 2007 RTM). The script - ConfigureSplitPerms.ps1, resides in the \Scripts folder in the Exchange Server install path. Usage:

.\ConfigureSplitPerms.ps1 -user "MyDomain\foo" -identity "OU=San Francisco,DC=ExchangeLabs,DC=net"

Labels: , , , ,

Monday, February 18, 2008

 

How to forward mail to an external email address

Posted by Bharat Suneja at 9:52 PM
In Exchange Server 2003, mail for a recipient can be forwarded to an alternate recipient by modifying the recipient's Delivery Options in ADUC | recipient -> properties | Exchange General tab.

If you need to forward mail to an external email address, you cannot simply type the address in Delivery Options. A (mail-enabled) Contact needs to be created in AD first, and Delivery Options modified to point to the Contact.

Exchange Server 2007: In Exchange Server 2007, these tasks remain the same. However, instead of using ADUC to accomplish them, you use the EMC or the shell (aka "EMS"). The new term for a Contact is MailContact.

1 To create a MailContact using the Exchange Management Console:

1. Expand Recipeint Configuration | Mail Contact
2. In the Action pane, click New Mail Contact
3. To create a new Contact object, leave the default (New Contact) selected | click Next
4. Type First name, Last name
5. Click Edit to add the external email address
6. Click New to complete creation of new MailContact

To create a new MailContact using the Exchange Management Shell:

New-MailContact -Name "Foo User" -ExternalEmailAddress "foo@externaldomain.com

Next, we set the recipient's Delivery Options to deliver to the alternate recipient.

2 To forward mail for a recipient to the MailContact using the Exchange Management Console:

1. Expand Recipeint Configuration | Mailbox | select mailbox | properties | Mail Flow Settings tab | Delivery Options
2. Under Forwarding address, select the Forward to checkbox
3. Click Browse to select the MailContact
Screenshot: Delivery Options -< Forwarding Address
Figure 1: Modifying Delivery Options to forward email to an alternate recipient

4. Optional: If a copy of the message needs to be delivered to both the external recipient and the original recipient's mailbox, select the Deliver message to both forwarding address and mailbox
5. Click OK to close Delivery Options properties
6. Click OK to close recipient's properties

Using the Exchange Management Shell:

Set-Mailbox "Joe Adams" -ForwardingAddress "foo@externaldomain.com"

To deliver a copy to the mailbox (in addition to the external email address - equivalent of step 4 above):

Set-Mailbox "Joe Adams" -ForwardingAddress "foo@externaldomain.com" -DeliverToMailboxAndForward $true

To get a list of mailboxes with forwarding enabled:

Get-Mailbox | where {$_.ForwardingAddress -ne $null} | ft name,forwardingaddress

Automatic forwarding and Remote Domains

Remote Domains are a bunch of settings, such as message formats, character sets, and OOFs, for messages sent to particular remote domains. The default Remote Domain setting applies to address space * - that is, all remote domains for which an explicit Remote Domain setting does not exist.

Screenshot: Remote Domain properties
Figure 2: The Allow automatic forward setting for remote domains impacts client-side automatic forwarding, and is disabled by default.

However, this setting only applies to client-side forwarding. For instance, if a user creates a rule in Microsoft Outlook to automatically forward mail to an external email address, the default setting does not allow it. To enable automatic client-side forwarding of mail to external addresses, select the Allow automatic forward checkbox in a remote domain's properties | Format of original message sent as attachment to journal report tab (Yes, the tab is mislabeled. It is the "Message Formats" tab... :).

Server-side forwarding setup by an administrator is not impacted by this setting.

Labels: , , ,

Tuesday, February 05, 2008

In "HOW TO: Grant Full Mailbox Access permission", we saw how to assign and view mailbox permissions, including Full Mailbox Access. Here's how you can get a list of mailboxes with explicitly-assigned (i.e. not inherited) Full Mailbox Access permissions.

Instead of running this against all mailboxes in the Organization, it makes sense to filter it against a sub-set of mailboxes.

Filtering mailboxes returned by Get-Mailbox

Mailboxes returned by the Get-Mailbox command can be filtered using -Server, -Database, -RecipientTypeDetails, and -OrganizationalUnit parameters. Note, the -Filter parameter can also be used and allows granular filtering of mailboxes that are returned, based on a number of filterable properties.

In this example, we use the -Server parameter to filter mailboxes on a particular server, and pipe it to the Get-MailboxPermission command:

Get-Mailbox -Server "e12postcard" | Get-MailboxPermission

This produces a long list of permissions - inherited and assigned explicitly to the mailbox(es).

Let's filter the above to reveal only the explicitly assigned permissions:

Get-Mailbox -Server "e12postcard" | Get-MailboxPermission | where { $_.IsInherited -eq $false }

The output shows all explicitly-assigned permissions, including the permissions assigned to the mailbox owner (NT AUTHORITY\SELF). Not quite what we want! Let's filter that out:

Get-Mailbox -Server "e12postcard" | Get-MailboxPermission | where { ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }

Now we have a list of all mailboxes with explicitly assigned permissions.

We can filter this further to list only the ones that have Full Mailbox Access permission assigned:

Get-Mailbox -Server "e12postcard" | Get-MailboxPermission | where { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }

Similarly, you can filter users that have other mailbox permissions assigned, such as SendAs, DeleteItem, ReadPermission, ChangePermission, ChangeOwner, or ExternalAccount.

Related Posts:
- HOW TO: Grant Full Mailbox Access permission
- HOW TO: Assign SendAs right using Exchange shell

Labels: , , ,

Monday, January 28, 2008

Exchange Server 2007 issues itself a self-signed certificate for use with services like SMTP, IMAP, POP, IIS and UM. The certificate is issued for a period of one year.

The self-signed certificate meets an important need - securing communication for Exchange services by default. Nevertheless, one should treat these self-signed certificates as temporary. It's not recommended to use these for any client communication on an ongoing basis. For most deployments, you will end up procuring a certificate from a trusted 3rd-party CA (or perhaps an internal CA in organizations with PKI deployed).

However, should you decide to leave the self-signed certificate(s) on some servers and continue to use them, these need to be renewed - just as you would renew certificates from 3rd-party or in-house CAs.

1 To renew the certificate for server e12postcard.e12labs.com, a server with CAS and HT roles installed:

Get-ExchangeCertificate -domain "e12postcard.e12labs.com" | fl

Note the services the certificate is enabled for (by default: POP, IMAP, IIS, SMTP on CAS + HT servers). Copy the thumbprint of the certificate.

Get a new certificate with a new expiration date:

Get-ExchangeCertificate -thumbprint "C5DD5B60949267AD624618D8492C4C5281FDD10F" | New-ExchangeCertificate

If the existing certificate is being used for SMTP, you will get the following prompt:

Confirm
Overwrite existing default SMTP certificate,
'C5DD5B60949267AD624618D8492C4C5281FDD10F' (expires 8/22/2008 7:20:34 AM), with certificate '3DA55740509DBA19D1A43A9C7161ED2D0B3B9E3E' (expires 1/28/2009 7:37:31 AM)?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):

Type y to continue. A new certificate is generated.


Thumbprint   Services   Subject
----------   --------   -------
3DA55740509DBA19D1A43A9C7161ED2D0B3B9E3E   .....   CN=E12Postcard

The new certificate is generated and enabled. Examine the new certificate:

Get-ExchangeCertificate -thumbprint "3DA55740509DBA19D1A43A9C7161ED2D0B3B9E3E" | fl

1 The old certificate is enabled for IIS, POP, IMAP and SMTP. The new certificate generated using the above command is enabled only for POP, IMAP and SMTP - IIS is missing.

To enable the certificate for IIS:

Enable-ExchangeCertificate -thumbprint "3DA55740509DBA19D1A43A9C7161ED2D0B3B9E3E" -services IIS

This enables the certificate for IIS (in addition to any other services it may already be enabled for - it adds to existing values of the services property).

1 Test services are working with the new certificate. If it works as expected, the old certificate can be removed:

Remove-ExchangeCertificate -thumbprint "C5DD5B60949267AD624618D8492C4C5281FDD10F"

Related posts:
- Outlook Anywhere and Exchange's Self-Signed Certificate
- Which name should I use as Common Name for my UC certificate?
- DigiCert: A Certificate Authority with excellent customer service

Labels: , , , , ,

Monday, December 24, 2007

Exchangepedia reader Guamaniac has an interesting tip in the comments on "Exchange 2007 Content Filter: The Whitelist Is Here!":
Get-ContentFilterConfig should give you a list of all the content filter settings on that particular Transport server.

And I know this is the simplest of features in PowerShell, but I just love the fact that you can pipe output to the clipboard:

get-contentfilterconfig | clip

and then peruse in your favorite text editor!
I'm used to simply highlighting the output using the mouse (which adds it to the clipboard). You need to enable QuickEdit on the command prompt window to be able to use this cut-and-paste functionality..

Labels: ,

Monday, December 17, 2007

One of the more useful improvements in Exchange Server 2007 is the abundance of logging for different features and components (read previous post "Exchange Server 2007: How many logs hath thee?"). In particular, the antispam agent logs fill an important gap in monitoring, reporting and troubleshooting message flow as it relates to antispam agents (read previous post "Exchange Server 2007: Managing And Filtering Anti-Spam Agent Logs"). As a messaging/Exchange administrator, you want to be able to pin point what the antispam agents have been up to, and determine if particular messsages, or sending hosts, domains or email addresses have been blocked by any of the antispam agents. The antispam agent logs and the get-agentlog command allow you to do this quickly and efficiently.

In addition to the the get-agentlog command, Exchange Server 2007 also ships with a number of canned scripts that help you keep tabs on what the agents are doing. These scripts are found in the \Exchange Server\Scripts directory, where \Exchange Server is the path of the Exchange Server 2007 installation. Note, no documentation or support is available for these scripts - they are meant to be examples you can use to write your own scripts. Let's take a peek in the directory and see what we find.

Commandline parameters used by antispam scripts

Most of the following scripts take the same (optional) parameters.
-top n: Where n is the number of results to display. If not specified, the script defaults to (top) 10.
-StartDate: Start date/time
-EndDate: End date/time
-location: path of agent log files. If no path is specified, the agent works against the default agent log file location.

1. Get-AntispamFilteringReport.ps1: Takes one of the following values as a mandatory parameter: 1) connections 2) commands 3) messagesrejected 4) messagesdeleted 5) messagesquarantined, and displays statistics for each agent.
2. Get-AntispamSCLHistogram.ps1: Provides a breakdown of number of messages stamped with each SCL value.
3. Get-AntispamTopBlockedSenderDomains.ps1: Lists top ten sender domains from which mail was blocked.
4. Get-AntispamTopBlockedSenderIPs.ps1: Lists the top ten IP addresses blocked by antispam agents, and number of messages blocked from each.
5. Get-AntispamTopBlockedSenders.ps1: Lists the top ten blocked senders (SMTP email addresses) and number of messages blocked from each. The script can report on P1 (i.e. address in message envelope in the MAIL header) or P2 addr