• 1. London, UK
  • 2. New York, NY
  • 3. Sydney, Australia
  • 4. Melbourne, Australia
  • 5. Paris, France
  • 6. Mumbai, India
  • 7. Moscow, Russia
  • 8. Bangalore, India
  • 9. San Francisco, CA
  • 10. Amsterdam, The Netherlands
Bharat Suneja

Friday, March 20, 2009

 

Released: PowerShell Snap-in For IIS 7

Posted by Bharat Suneja at 8:30 AM
The big news from MIX09 is probably the release of Internet Explorer 8, but for shell aficionados, Exchange folks and scripting geeks, the release of IIS Snap-in for Windows PowerShell is not a lesser event. The snap-in has 71 cmdlets to manage IIS, from web application pools to web site configurations, bindings, and SSL.

Download the IIS Snap-in for Windows PowerShell: X86 | x64.

For more information about the snap-in, head to IIS.net. IIS developer Sergei Antonov, who owns scripting and command-line tools, blogs here.

Curious to find out which cmdlets are included? Head over to the IIS 7 Cmdlets mini-reference.

Labels: , , ,

Thursday, February 19, 2009

 

Are Distribution Groups really being used?

Posted by Bharat Suneja at 8:00 AM
Over the years, you end up creating a large number of Distribution Groups based on user demands. The regular departmental Distribution Groups such as Sales, Marketing, Engineering, and HR. The geographical ones such as AllUS, All-California, All-BayArea, and so on. The ones by employment status such as All-FTE for full-time employees, All-Contractors, and so on. And ones to facilitate the working habits of executives and senior managers, who want to address their team with a distro (geekspeak for Distribution Group) like JoeSchmoe-DirectReports. Then there are the more interesting ones, such as All-MountainClimbers, All-GrungeFans.

Why are so many of these Distribution Groups prefixed with an All-? Can Distribution Groups ever be All-Whatever? Is it possible to include all grunge fans in the All-GrungeFans group? Or only the ones who confess? Can you guarantee everyone in the Sales dept will be included in the All-Sales group by default— even if you used Dynamic Distribution Groups? There will be times when someone does not populate the department attribute for the newly hired Manager of Inside Sales for Timbuktu, and surrounding areas. After two weeks in his exciting new inside sales position, the poor bloke finds out he hasn't received the number of sales leads freely flying around on the distro, and unfortunately won't be able to meet his targets for selling surfboards in Timbuktu that quarter.

Over the lifetime of Exchange deployments, there will be groups that get used more frequently, such as Send-Your-Jokes-Here-If-You-Have-Nothing-Better-To-Do-At-Work (the alias conveniently shortened to ExecTalk... ), or the ones that never get used, such as All-ExEmployees (hard as it is to believe, at least one of these two have been spotted in real-world deployments!).

One fine day, your friendly manager/auditor/HR person shows up at your desk wanting to know which distribution groups are in use.

That's where message tracking logs come to the rescue— assuming these are enabled. If you've been mucking around with these logs in Exchange 2007, you probably know a fair bit of PowerShell, and chances are you're absolutely loving it! If not, head over to previous post Exchange Server 2007: Message Tracking from the command line, and get to know the wonderful cmdlet Get-MessageTrackingLog.

Tracking messages sent to Distribution Groups
How do we get a list of messages sent to Distribution Groups? By getting a list of all Distribution Group expansion events, noted in message tracking logs with the EventID EXPAND. The RelatedRecipientAddress field in the EXPAND entry contains the PrimarySmtpAddress of the Distribution Group expanded. Use the following command to grab a list. You can restrain Get-MessageTrackingLog cmdlet in a number of ways. Since these have been covered in the previous post, I won't go into details here.

Get-MessageTrackingLog -Start 2/1/2009 -EventID Expand | ft Timestamp,RelatedRecipientAddress -Autosize

You get back a table that looks something like this:

Timestamp RelatedRecipientAddress
--------- -----------------------
2/18/2009 4:36:27 PM DG-Marketing@MyDomain.com
2/18/2009 4:41:18 PM DG-Sales@MyDomain.com

Next, how do we determine how many messages each Distribution Group received? This is easily done by piping the results to the Group-Object cmdlet:

Get-MessageTrackingLog -Start 2/1/2009 -EventId Expand | group-object RelatedRecipientAddress | ft Name,Count -Autosize

This returns a count for each group of messages:

Name Count
---- -----
DG-Marketing@MyDomain.com 123
DeptSales@MyDomain.com 145

To list messages sent to a particular Distribution Group:

Get-MessageTrackingLog -EventID Expand | ? {$_.RelatedRecipientAddress -like "DG-Marketing@MyDomain.com"} | ft Timestamp,Sender,MessageSubject -Autosize

Of course, you could use the message tracking GUI in EMC— but would it rate anywhere close on your geek satisfaction index?

Labels: , , ,

Tuesday, February 03, 2009

You're testing Exchange 2007's Messaging Records Management (MRM) features to implement your organization's messaging retention policies.

You create a new Managed Folder for Calendar items, and then create a Managed Content Setting for it to expire Calendar items in 1 year. Next, you create a Managed Folder Mailbox Policy and add the Managed Folder to the Policy. You apply the policy to a test mailbox.

Testing the Managed Folder Policy
You open the test mailbox, create a single-instance appointment that starts and ends on some date more than a year ago.

To test the new Managed Folder Policy, you manually run the Managed Folder Assistant against your test mailbox:

Start-ManagedFolderAssistant -Mailbox "Joe Adams"

You expect the meeting, which (starts and) ends at some date more than a year ago, to be expired and the RetentionAction specified in the Managed Content Setting to be applied. It doesn't.

Calculating Retention Age for Calendar items

You can tell the MFA when to start counting an item's retention age from, by specifying it in the Content Settings for a Managed Folder. It can be based on:
1) When the item was delivered to a mailbox or
2) When the item was moved to a folder

Screenshot: Configuring retention period in Managed Content Settings
Figure 1: Configuring retention period in Managed Content Settings

Calendar items such as meetings and appointments, and Tasks, are treated differently since these items have an end date. You could create a meeting for a future event, or create a recurring meeting that takes place at a certain interval (daily/weekly/monthly/yearly) during a certain period, or indefinitely. Therefore, the end date of these items needs to be considered when expiring them. Recurring meetings will expire based on the end date of the last occurrence. Meetings with no end date do not expire.


Figure 2: Recurring meetings can be scheduled to occur daily, weekly, monthly, or yearly for a long period, or indefinitely. When expiring such items, the MFA considers the end date.

If these items are deleted, and thus end up in the Deleted Items folder, the end date is no longer a factor. The Managed Folder Assistant expires Calendar items in the Deleted Items folder based on the message-received date. If the received-date cannot be determined, the message-creation date is used.

More details about retention age for different types of items in "How Retention Periods Are Calculated for Items in Managed Folders".

You locate an older PST and copy a Calendar item which occurs in roughly the same timeframe as the one you just created. When you run the MFA, the copied item with an end date from more than a year ago is expired!

When processing a mailbox, the MFA queries for Calendar items where the creation date is older than the expiration date. If you create a test item for a past date, as we did in this case, it does not get processed by the MFA until the creation date is older than the AgeLimitForRetention.


Figure 3: Calendar items created for a past date will have a creation time that is later than the meeting/appointment end time

Of course, you're not likely to run into this issue except in test scenarios. Real-world meetings do not get created in the past. The creation date is guaranteed to be equal to or older than the end date of the meeting..

Labels: , , , ,

Tuesday, December 09, 2008

If you're trying to get recipients from the whole AD Forest using the Exchange shell, there are two things to be aware of:

1. Session scope: By default, the scope of your shell session is set to the Domain of the computer you're running the session on.
2. Result size: By default, shell cmdlets return 1000 results. You can modify this using the Resultsize parameter. The number of search results to return can be specified, or you can use the value unlimited to return all results.

To view the current settings for your admin session, simply type $AdminSessionADSettings.

What you get back:

ViewEntireForest : False
DefaultScope : MyDomain.com
PreferredGlobalCatalog :
ConfigurationDomainController : MyDC.MyDomain.com
PreferredDomainControllers : {}

You can change the DefaultScope parameter to specify another domain or an OU. (Recipient cmdlets also have the OrganizationalUnit parameter which lets you restrict the command to a particular OU).

To return recipients from the whole Forest for all recipient cmdlets used in the session, you can set the session scope by using the following command:

$AdminSessionADSettings.ViewEntireForest = $True

Note, session variables are limited to the session. Once you close the shell window, it's gone. If you start another session, you'll need to set the ViewEntireForest variable to $True again.

You may find not having to return recipients from the entire Forest for the most part. If you do not want to change your session scope to the Forest, but return all recipients in a single recipient command, you can bypass the session scope by adding the IgnoreDefaultScope switch with recipient cmdlets:

Get-Mailbox -IgnoreDefaultScope -ResultSize unlimited

Other parameters such as the preferred GC, DC and config DC for the session can also be set by modifying the session variable.

Labels: , ,

Tuesday, November 04, 2008

 

Start Managed Folder Assistant for a single mailbox

Posted by Bharat Suneja at 10:33 AM
When testing Managed Folder Mailbox Policy settings in Exchange 2007, you may need to frequently run the Managed Folder Assistant (MFA)) to process a mailbox on-demand, so you can check the mailbox content and MRM logs. However, every time you run Start-ManagedFolderAssistant, the MFA processes all mailboxes on all Mailbox Databases on the server.

Of course, you can avoid all the agony by instructing the Managed Folder Assistant to process only the specified mailbox:

Start-ManagedFolderAssistant -Mailbox "Foo"

Processing a single mailbox results in the MFA completing its job quickly and makes parsing the MRM log easier— the MFA only logs events related to the specified mailbox.

The -Mailbox parameter does not take multiple mailboxes as input. To process more than 1 mailbox, you will need to use the Get-Mailbox cmdlet (or Get-User piped to Get-Mailbox, depending on the property you want to filter on) and pipe a filtered list of mailboxes to Start-ManagedFolderAssistant. For example, the following command will result in the MFA processing all mailboxes from the department:

Get-User -Filter {department -eq "Sales" -and RecipientType -eq "UserMailbox"} | Get-Mailbox | Start-ManagedFolderAssistant

Or maybe you want to have the MFA process all mailboxes with a particular policy applied. Note, the Filter requires the distinguishedName of the policy:

$policy = (Get-ManagedFolderMailboxPolicy "MRMPolicy-VPs").distinguishedName; Get-Mailbox -Filter {ManagedFolderMailboxPolicy -eq $policy} | Start-ManagedFolderAssistant

Labels: , , , ,

Monday, September 29, 2008

 

Disable Antispam agents on a Receive Connector

Posted by Bharat Suneja at 5:20 PM
Exchange 2007's antispam agents are enabled for all Receive Connectors on a transport server. Is there a way to disable the agents on a particular Receive Connector?

Although not as simple as turning an agent off for each IP address or Receive Connector, Exchange 2007's new transport permissions model allows you to do this just as easily.

The ms-Exch-Bypass-Anti-Spam permission is what allows a sender to bypass antispam agents. By default, mail from authenticated senders is not filtered.

To allow unauthenticated/anonymous senders to bypass antispam filters on a particular Receive Connector, use the following command:

Get-ReceiveConnector "My Receive Connector" | Add-ADPermission -User "NT Authority\Anonymous Logon" -AccessRights ExtendedRight -ExtendedRights ms-exch-bypass-anti-spam

Labels: , , , , ,

Friday, September 26, 2008

Have you been using the Set-MailboxCalendarSettings cmdlet to configure scheduling settings for resource mailboxes? Wish there was a graphical interface to configure these settings?

[PS] C:\>get-mailboxcalendarsettings cf-oahu | fl

AutomateProcessing : AutoAccept
AllowConflicts : False
BookingWindowInDays : 180
MaximumDurationInMinutes : 1440
AllowRecurringMeetings : True
EnforceSchedulingHorizon : True
ScheduleOnlyDuringWorkHours : False
ConflictPercentageAllowed : 0
MaximumConflictInstances : 0
ForwardRequestsToDelegates : True
DeleteAttachments : True
DeleteComments : True
RemovePrivateProperty : True
DeleteSubject : True
DisableReminders : True
AddOrganizerToSubject : True
DeleteNonCalendarItems : True
TentativePendingApproval : True
EnableResponseDetails : True
OrganizerInfo : True
ResourceDelegates : {}
RequestOutOfPolicy :
AllRequestOutOfPolicy : False
BookInPolicy :
AllBookInPolicy : True
RequestInPolicy :
AllRequestInPolicy : False
AddAdditionalResponse : False
AdditionalResponse :
RemoveOldMeetingMessages : True
AddNewRequestsTentatively : True
ProcessExternalMeetingMessages : False
DefaultReminderTime : 15
RemoveForwardedMeetingNotifications : False
Identity : MDomain.com/Conference Rooms/CF-Oahu

Output of Get-MailboxCalendarSettings cmdlet

Christian Schindler, MCT, MCA (Messaging), from Austria points out the little known fact that you can use OWA to configure calendar settings for resource mailboxes. Note, the user accounts for resource mailboxes are disabled by default. You would need to enable the account in ADUC before you try to logon using OWA.

An alternative to enabling resource mailboxes

If you want to avoid enabling resource mailbox accounts, here's an alternative. You can assign yourself (or any other account) FullAccess permission on the resource mailbox(es) you want to configure. Use the following command:

Get-Mailbox -Filter {RecipientTypeDetails -eq "RoomMailbox"} | Add-MailboxPermission -User "YourAccount" -AccessRights FullAccess

With the permission assigned, you can log on to OWA using your account, and open the resource mailboxes using OWA 2007's ability to open additional mailboxes, as shown in the following screenshot.

Screenshot: OWA | Open Other Mailbox


If you look at Options in OWA when logged in as an ordinary mailbox user (that is, not logged on to a resource mailbox), you see Calendar Options.

If you log on to a resource mailbox using OWA, you also see Resource Settings as one of the options.


Figure 1: The Resource Settings option is available in OWA when logged on to a resource mailbox. Full size screenshot here.

Not only does this allow you to configure the settings for automated processing of meeting requests, there's also a rich text editor for creating a custom response message.


Figure 2: The Resource Settings option also has a rich text editor for creating a custom HTML response message.

Labels: , , , ,

Tuesday, September 16, 2008

 

Configuring Deleted Item Retention

Posted by Bharat Suneja at 6:39 AM
After a user empties the Deleted Items folder, although these items disappear from the view of the mailbox, they are not completely deleted. They are retained till the Deleted Item Retention period expires in what's fondly referred to as the Dumpster— not to be confused with the Transport Dumpster maintained by Hub Transport servers.

Deleted Item Retention (DIR) can be configured on the Mailbox Database. It is set to 14 days by default. The other related parameters that can be configured on the MDB include deleted mailbox retention period and the option to not purge deleted items until the MDB has been backed up.

Screenshot: Deleted Item Retention settings on Mailbox Database
Figure 1: Deleted Item Retention settings for a Mailbox Database


Configuring Deleted Item Retention per-mailbox
Individual mailboxes can be configured with a different Deleted Item Retention period, which bypasses the limit set on the Mailbox Database. To configure the individual DIR settings for a mailbox using the Exchange console:
1. In Recipient Configuration | Mailbox | select recipient --> Properties | Mailbox Settings tab | double-click Storage Quotas

2. In the Storage Quotas property page, uncheck Use mailbox database defaults
Screenshot: Storage Quotas property page

3. In the Keep deleted items for days field, enter a new value

4. Optional: Check Do not permanently delete items until you back up the database

Why is it a good idea to not purge the dumpster till the Store has been backed up?
If not checked, items in the Dumpster will expire after the Deleted Items Retention period, and be permanently lost! If the Dumpster is purged before a backup takes place, the item is lost forever, with no way to recover it. Retention Policies in many organizations require that all messages or mailbox items should be recoverable.

5. Click OK to close the Storage Quotas property page | click OK to close mailbox properties.

Modifying the Deleted Item Retention period for a mailbox using the Exchange shell
The DIR period can be set by populating the RetainDeletedItemsFor property using the Set-Mailbox cmdlet. Using the shell's ability to pipe objects (output from one cmdlet to be processed by another cmdlet), you can use Get-Mailbox with the -Filter property and get the desired set of mailboxes to apply the new DIR period in bulk. You can also use a number of other properties to filter mailboxes based on the OU, Mailbox Database, Storage Group, etc. For example:

Get-Mailbox -OrganizationUnit "San Francisco" | Set-Mailbox -RetainDeletedItemsFor 20.00:00:00

(See Applying Managed Folder Policy to more than one user for more examples. The list of filterable properties that can be used in the -Filter parameter: Exchange 2007 RTM | SP1).

However, simply setting the RetainDeletedItemsFor property does not apply the new retention period to mailboxes. Remember the checkbox in the console for Use mailbox database defaults? How do we uncheck that using the shell?

Let's get all *Deleted* properties of a mailbox:

Get-Mailbox "My Mailbox" | ft *Deleted* -AutoSize

What you get back is:
Screenshot: Get-Mailbox output with all *Deleted* properties

The value modified by the checkbox in the console shows up in the DeletedItemFlags column in the Get-Mailbox output. It can have three values:
1) DatabaseDefault when the checkbox is selected
2) RetainForCustomPeriod when it's not
3) RetainUntilBackupOrCustomPeriod— a third value, if you've also selected the option not to purge the Dumpster before the Store's backed up.

At this point, I wouldn't blame you if you instinctively proceed to use the Set-Mailbox cmdlet to flip the DeletedItemFlags property from DatabaseDefault to RetainForCustomPeriod. However, this doesn't work.

What Get-Mailbox actually displays as the DeletedItemFlags is a calculated property— properties which are calculated and displayed for ease of administration, but aren't actual properties that can be modified using the corresponding Set-Whatever cmdlet.

The property we need to modify is called UseDatabaseRetentionDefaults. It's a boolean property— valid values can be $true or $false.

When setting a custom/non-default Deleted Item Retention period on mailboxes, we should set the UseDatabaseRetentionDefaults property to $false:

Set-Mailbox "My Mailbox" -RetainDeletedItemsFor 20.00:00:00 -UseDatabaseRetentionDefaults $false

The Get-Mailbox output after this is done:


If you also set RetainDeletedItemsUntilBackup to $true:


Getting Dumpster Statistics
To get the total number and size of deleted items in the dumpster for a mailbox, use the Get-MailboxStatistics cmdlet:

Get-MailboxStatistics User@MyDomain.com | Select *Deleted*

The output:

DeletedItemCount TotalDeletedItemSize
---------------- --------------------
752                16020237B

Doesn't the output from the above command include the Deleted Items folder?
No. To get the statistics for the Deleted Items folder, use:

Get-MailboxFolderStatistics User@MyDomain.com | where {$_.FolderPath -like "/Deleted Items"}

The output:

Date : 9/16/2008 7:15:49 PM
Name : Deleted Items
Identity : User@MyDomain.com\Deleted Items
FolderPath : /Deleted Items
FolderId : LgAAAAAaFeUR2TeSRpY38Ihx7YFNAQCK6B+B4tC8RbU9t9FmHnW4AAAAABIcAAAB
FolderType : DeletedItems
ItemsInFolder : 361
FolderSize : 6214440B
ItemsInFolderAndSubfolders : 361
FolderAndSubfolderSize : 6214440B
OldestItemReceivedDate :
NewestItemReceivedDate :
ManagedFolder : DI30days

Labels: , , ,

Wednesday, September 10, 2008

 

SCRIPT: Get Storage Group Backup Status

Posted by Bharat Suneja at 2:47 PM
Exchange 2007 Mailbox Databases expose backup-related properties using the Get-MailboxDatabase cmdlet:

Get-MailboxDatabase "My Database" -status | select *backup* | fl

What you get back:
BackupInProgress :
SnapshotLastFullBackup :
SnapshotLastIncrementalBackup :
SnapshotLastDifferentialBackup :
SnapshotLastCopyBackup :
LastFullBackup :
LastIncrementalBackup :
LastDifferentialBackup :
LastCopyBackup :

Here's a quick shell script that dumps each Storage Group and its backup-related information. I haven't had the time to build in any validation or test to run remotely, but you can use it on an Exchange 2007 server to get the following details:

1. Storage Group Name
2. Transaction log file path
3. Date Storage Group was created
4. Name and timestamp of the oldest transaction log file
5. Number of transaction log files in the path
6. Mailbox Databases in each Storage Group
7. For each MDB, time when full, incremental, and differential backups (Streaming or VSS) were performed
(including a warning if the first log file is still available, which basically means a Full backup has never been completed).

In the following screenshot, the First Storage Group has never been backed up, so the E**00000001.log file still exists (and its timestamp is same as the Storage Group's creation time). The second Storage Group has just been backed up, and therefore has fewer transaction logs.

Screenshot: Output of Get-SGBackupStatus.ps1 script
Figure 1: Output of Get-SGBackupStatus.ps1 script

File: Get-SGBackupStatus.zip
Date: 9/11/2008

What needs to be added:
- Time (number of days/hours) from last backup
- Warning when last backup is older than X number of days

Using the -Status switch: Reader Wolfgang Sauer points out

If you saw this post yesterday and wondered why the *backup* fields in Get-MailboxDatabase output were showing up as blank (or $null in PowerShell-speak), even after a backup has been taken, it's because we left out the -Status switch that's required with Get-MailboxDatabase cmdlet to make these details show up. Thanks to reader Wolfgang Sauer from Germany for pointing out the omission.

The script and the screenshot have been updated accordingly. If you downloaded the script before today, please download the updated version.

Disclaimer:
All scripts/downloads on this site provided as-is, with no warranties, and confer no rights. Please test any scripts/downloads in a lab environment before using it in production.

Labels: , , ,

Wednesday, September 03, 2008

 

HOW TO: Prevent annoying spam from your own domain

Posted by Bharat Suneja at 8:46 AM
One of the more annoying types of spam is the one that seems to be coming from your own domain; or worse— from your own email address! Of course, users from your own domain don't generally spam each other— unless you're using one of the free web-based email services. And most of us don't spam ourselves.

Obviously, this is coming from a spammer who has spoofed your email address, or that of someone else from your domain. Unfortunately, SMTP— the protocol that allows mail clients and servers to exchange email, allows headers to be spoofed easily.

In Exchange Server 2007, Accepted Domains tell Exchange which domains to accept email for. If a domain - e12labs.com in this example, exists as an Accepted Domain, there is no reason external senders should use that domain in the MAIL or FROM headers.

You may have remote POP3/IMAP4 users who use SMTP to send mail. However, such sessions should be authenticated, and preferably use a separate Receive Connector.

Thanks to the extensive Transport Permissions model in Exchange 2007, we can easily prevent such spam. Receive Connectors have the ms-exch-smtp-accept-authoritative-domain-sender permission which dictates whether an Accepted Domain can be used in the MAIL or FROM headers. External/internet hosts submit mail to your server without authentication, as anonymous senders. To prevent anonymous senders from sending mail using your domain(s), we need to remove the ms-exch-smtp-accept-authoritative-domain-sender permission assigned to them.

Use the following command to remove the ms-exch-smtp-accept-authoritative-domain-sender permission from NT Authority\Anonymous Logon on internet-facing Receive Connector(s):

Get-ReceiveConnector "My Internet ReceiveConnector" | Get-ADPermission -user "NT AUTHORITY\Anonymous Logon" | where {$_.ExtendedRights -like "ms-exch-smtp-accept-authoritative-domain-sender"} | Remove-ADPermission

Once this permission is removed, when anonymous senders try to submit mail using your Accepted Domain(s), here's how the SMTP conversation goes:

220 E12Postcard.e12labs.com Microsoft ESMTP MAIL Service ready at Wed, 3 Sep 2008 06:22:43 -0700
helo
250 E12Postcard.e12labs.com Hello [172.31.0.170]
mail from:jadams@e12labs.com
550 5.7.1 Client does not have permissions to send as this sender

Exchange stopped spoofing of P1/envelope headers. Let's continue the session and try to spoof the P2 headers (the ones in the DATA part of the message) — maybe that'll work!

mail from:someone@someotherdomain.com
250 2.1.0 Sender OK
rcpt to:jadams@e12labs.com
250 2.1.5 Recipient OK
data
354 Start mail input; end with .
from:jadams@e12labs.com
subject: Header spoofing

This is how we spoof headers, spoof headers.

.
550 5.7.1 Client does not have permissions to send as this sender
quit
221 2.0.0 Service closing transmission channel

As you can see, removing the ms-exch-smtp-accept-authoritative-domain-sender permission stops spoofing of your domains in both envelope (P1) and message (P2) headers.

When not to remove the permission?
Is there a scenario where one should not remove the ms-exch-smtp-accept-authoritative-domain-sender permission from NT Authority\Anonymous Logon? Yes, on Receive Connectors used by internal or trusted SMTP hosts (such as copiers/scanners and application servers) that submit mail without authentication.

But you do have these internal/trusted hosts submitting to a separate Receive Connector, don't you?

Related posts:

Labels: , , , ,

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 example, 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 addresses (from headers in message body like FROM). Specify the option as a commandline argument (optional parameters -top n, -StartDate, and EndDate used in this example):

.\Get-AntispamTopBlockedSenders.ps1 P1 -top 20 -StartDate "12/1/2007" -EndDate "12/10/2007"

Replace the P1 in the above command with P2 to report on P2 senders.
6. Get-AntispamTopRBLProviders.ps1: Lists the top ten RBLs (aka "IP Block List Providers") and messages blocked by each (read previous post: "Exchange Server 2007: How are RBLs performing?").
7. Get-AntispamTopRecipients.ps1: Lists the top ten recipient addresses that receive spam. The addresses may or may not exist in your Organization - the reporting is based on actions taken by antispam agents on incoming messages. Recipient Filtering with Recipient Validation (dropping messages for recipients that do not exist in AD/GAL) is a great way to drop a large number of messages.

The following scripts are not used for reporting:
8. Reset-AntispamUpdates.ps1: Uninstalls any antispam updates and reinstalls the original "out-of-box" antispam data.
9. Install-AntispamAgents.ps1: By default, antispam agents are not installed on the Hub Transport server role (read previous post: "HOW TO: Install anti-spam agents on Hub Transport server"). This script installs them if you need to.
10. Uninstall-AntispamAgents.ps1: Uninstalls antispam agents.

Labels: , , , ,

Tuesday, December 04, 2007

The instructions in Exchange Server 2007: Bulk creation of mailboxes using Exchange Management Shell allow you to quickly create mailboxes in bulk using the New-Mailbox command.

Continuing from where we left off in that post, another scenario is being able to add Active Directory attributes to the new user object created by New-Mailbox. Note, the New-Mailbox command can populate only a limited set of AD attributes for an object - those related to Exchange. These are listed in the documentation for New-Mailbox.

To add AD attributes, the logical choice would be to use the New-User command to create the user, and mailbox-enable it by using Enable-Mailbox. This would work great, except for the fact that the New-User command doesn't exist! The key thing to remember is - Exchange provides only the commands necessary to create Exchange recipients. So you have commands like New-Mailbox, New-MailUser, New-MailContact, New-PublicFolder/New-MailPublicFolder, and New-DistributionGroup. However, there are no AD-equivalents like New-User, New-Contact (to create a Contact that's not mail-enabled), New-SecurityGroup or New-Group.

PowerShell and Active Directory

Active Directory isn't really PowerShell-enabled, as other components of Windows - like the file system, registry, etc., and Exchange Server 2007 are. There are no AD-related commands (Cmdlet? Shell folks, was it really necessary to introduce another word to the jargon - one that uses the entire word "command"? Perhaps something shorter would've been nicer if you wanted to have a unique word... :-) You can use the Directory Services provider, but that essentially leaves you in VBScript mode, with some PowerShell goodness! A little easier, but not natively shell, as you are used to with Exchange commands.

Quest adds these much-needed commands through its free add-on Management Shell for AD. Download it here. Quest has named them so they're differentiated from future commands that will be available natively in PowerShell. For the time being, the quirkiness of typing commands with a Q - as in New-QADUser instead of New-ADUser or New-User - is something we will have to live with, until AD is PowerShell-enabled.

Kudos to the folks at Quest for making these available for free.

Also take a look at PowerShell Community Extensions - it has an Active Directory provider that lets you navigate AD like a file system.

If you already have a user created, you can use the Set-User command to populate its AD-related attributes.

To accomplish what we want to do here (thanks to Evan Dodds for the input), we use the New-Mailbox command, and pipe the output to Set-User to populate AD attributes. In the following example, we add the Phone attribute, besides using the Alias, Name and UserPrincipalName attributes used to create the mailbox.

Add the Phone column in our CSV/spreadsheet, so it looks like the following:

Alias,Name,UPN,Phone
User_One,User One,userone@yourUPNsuffix.com,650.555.1121
User_Two,User Two,usertwo@yourUPNsuffix.com,650.656,2221
User_Three,User Three,userthree@yourUPNsuffix.com,650.797.3321

Now we modify the script/commands from the previous post:

$password=Read-Host "Enter Password" -AsSecureString

Import-CSV "c:\CreateRecipients.csv" foreach {new-mailbox -alias $_.alias -name $_.name -UserPrincipalName $_.UPN -database "Mailbox Database" -org "Users" -Password $password | set-user -phone $_.phone}

The above command(s) create the user account as part of New-Mailbox. When we pipe that to Set-User, we still have a reference to that object, and can use Set-User to populate the AD attribute Phone. (Changes made to the command from previous post highlighted.)

Related Posts:
- Exchange Server 2007: Bulk creation of mailboxes using Exchange Management Shell
- Exchange Server 2007: Bulk mailbox-enabling users using Exchange Shell

Labels: , , , , ,

Friday, November 30, 2007

Another frequently asked question about PowerShell/Exchange shell, and one that I myself had during the initial foray with the shell - what's the difference between using double quotes and single quotes in a shell command or script?

The biggest difference, and the only one I'm aware of, is the fact that using double quotes - e.g. "$mailboxes", expands the variable. (Note, if the variable has not been used/defined or doesn't have any value, you get no output.)

When using single quotes - e.g. '$mailboxes', it is treated as a string.

To see the difference in action:

$mailboxes = Get-Mailbox

Now that we have captured the value(s) of mailbox(es) in a variable (actually an array... it can have a single or multiple values. In this case, a single mailbox, if you only have one, or multiple mailboxes).

Next, let's get some output from this. First, let's try with single quotes:

Write-Host 'This is a list of all my mailboxes: $mailboxes'

What you get is simply:

This is a list of all my mailboxes: $mailboxes

Now let's try with double quotes:

Write-Host "This is a list of all my mailboxes: $mailboxes"

The output will list all your mailboxes, as seen below:

This is a list of all my mailboxes: Jane Doe John Doe....

I haven't found any side-effects of using double-quotes, except when you really want a particular variable/string to be treated as a string.

Labels: ,

Tuesday, November 06, 2007

 

Released: Windows PowerShell 2.0 CTP

Posted by Bharat Suneja at 10:00 AM
For all those eagerly awaiting developments on the shell front, Microsoft has released a Community Technology Preview (CTP) of Windows PowerShell 2.0.

PowerShell 2.0 boasts some interesting (many frequently requested) features, including:
- remoting (ability to execute commands on remote computers)
- "a very early alpha version" of the Graphical PowerShell utility
- background PowerShell jobs that run without interaction with the console (including ability to trigger/run these on remote computers)
- ability to write your own commandlets in PowerShell rather than having to use compiled VB.NET or C# code
- 24 new commandlets, improved WMI and ADSI support, and quite a few other features listed in "What's New in CTP of PowerShell 2.0" on the PowerShell team blog.

The Graphical PowerShell requires .Net Framework v3.0.

Download the Windows PowerShell 2.0 CTP from here, and don't rush to install it on your production Exchange Server 2007 servers just yet - it's still a beta product.

Labels: ,

Thursday, November 01, 2007

 

HOW TO: Hide Distribution Group membership

Posted by Bharat Suneja at 8:27 AM
Exchange Server 2003's ADUC extensions made hiding a Distribution Group's membership a trivial task, accomplished by right-clicking a group, selecting Exchange Tasks and selecting Hide Membership.

Screenshot: Exchange Tasks in Active Directory Users & Computers
Figure 1: The Exchange Tasks wizard in ADUC provides an option to hide Distribution Group membership in Exchange Server 2003

As the task suggests, it hides the group's membership in Outlook Address Book/GAL. It also prevents users from clicking the + link that appears before a Distribution Group when composing a new message, and expanding the group so messages are sent individually to all members rather than the DG.


Figure 2: Distribution Groups that have their membership hidden cannot be expanded in Microsoft Outlook

The Hide Membership task available from Exchange Tasks denies Read Property permission for the Members attribute, to the Everyone group. This also prevents Administrators trying to manage the group from seeing the group's members.


Figure 3: Hiding a Distribution Group makes changes to the Distribution Group's ACL

Hiding Distribution Group membership in Exchange Server 2007

Hiding Distribution Group membership is not supported in Exchange Server 2007. There is no option to hide Distribution Group membership in the console, nor a single parameter you can flip using the shell.

Nevertheless, you can prevent users from expanding the group in Microsoft Outlook, and hide the group's Member attribute so it's not visible in the properties pages in Outlook or OWA. The caveat - it's not a way to hide membership completely, as noted later in the post.

1 Adding Deny ACE for the Members property

Use the following command to deny the ReadProperty permission for the Distribution Group's Members property to a particular user or Security Group (Remember the security best practice - add users to Security Group -> assign permissions to Security Group?):

Add-ADPermission "Distribution Group Name" -user "User or Security Group Name" -Deny -AccessRights ReadProperty -Properties Member

Note, to simulate what Exchange Server 2003's Hide Membership task does, you can use the Everyone group in the -users parameter. This hides membership from the EMC as well, but the shell can still show membership using the Get-DistributionGroupMember command.

Once the permission is added, clicking on the + link in Microsoft Outlook produces the following not-so-descriptive error message, and the user is prevented from expanding the Distribution Group.


Figure 4: With the Deny ACE in place, Outlook users get an error when trying to expand the Distribution Group. Click here to see a larger image

Additionally, membership of the group is not revealed in the group's properties in the Address Book/GAL.

Adding Deny ACE using the GUI

If you've already used the shell to add the deny ACE, you can skip the following procedure and head to the next section.

For the console/GUI fans amongst us or those who simply haven't developed an intimate relationship with the shell (hopefully the following will make you a convert... :), ADSIEdit is your friend. Fire it up:

1. Navigate to the Distribution Group's properties
2. Select the Security tab
3. Click Add
4. Select the user or group you want to deny permission to (you can use the Everyone group to simulate what Exchange Server 2003 does)
5. Click OK
6. click Advanced (wait... ) to open Advanced Security Settings
7. Select the Permissions tab
8. Select the user or group if not already selected
9. Click Edit to open the Permissions Entry properties for the selected user/group
10. Select Properties tab
11. Click on the "Deny" checkbox for the Read Members property so it is checked.
12. Click OK to close the Permissions pages.
13. Click OK to close the Advanced Security Settings pages
14. Click OK to close the Properties dialog box



2 Prevent Delivery Reports from Distribution Group

Users can send a message to the Distribution Group with a Delivery Report requested, which can reveal the group membership.

To prevent a Delivery Report from being sent to the originator (consider this carefully, you may want senders to receive delivery reports if messages are not delivered to members of certain Distribution Groups. You can also enable delivery reports to the group Manager only.), use the following command:

Set-DistributionGroup "Distribution Group Name" -ReportToOriginatorEnabled $false

Once this is done, Exchange simply sends a Distributtion Group expanded/delivered to DG message in the Delivery Report, if one is requested, without revealing the group's members.


Figure 5: Preventing Delivery Reports to originator returns a "delivered to DG" message when Delivery Reports are requested

3 Hiding group membership in OWA

Membership of the Distribution Group can be viewed in OWA (OWA 2007). As reader Bart points out, this is easily fixed by flipping the hideDLMembership attribute to TRUE. At first look, the attribute doesn't seem to be exposed by the Exchange shell. You can use your LDAP/AD tool of choice, including ADSIEdit, to modify it.

Screenshot: ADSIEdit - hideDLMembership attribute
Figure 6: Flipping the Distribution Group's hideDLMembership attribute to True in ADSIEdit

With the attribute set to true, group membership is no longer revealed.

Yes, this means this workarounds mentioned above can be used to:

- Hide Distribution Group membership from Outlook users
- Prevent Outlook users from expanding the Distribution Group when composing new messages
- Hide Distribution Group membership from OWA users
- Prevent Delivery Reports from revealing group membership

The caveat: These workarounds succeed in hiding membership by examining the Distribution Group (or sending a message to it). This may meet your requirements for hiding group membership. However, you can examine the Member Of property page of a recipient and see which groups he/she is a member of. Agreed, this is not a convenient way of discovering group membership— particularly if you have a large number of recipients. Nevertheless, from a security standpoint, this does mean there's no hiding of group membership.

Labels: , , , ,

Wednesday, October 03, 2007

Exchange Server 2007's Managed Folders come in two flavors: 1) Managed Default Folders 2) Managed Custom Folders. Default folders are the ones created by default in user mailboxes, like Inbox, Sent Items, Deleted Items, etc. Custom Folders are the result of a much-requested feature by Exchange folks over the years: Can I create a folder called "Project Blah" in all mailboxes?

The Managed Default Folders tab (under Organization Configuration | Mailbox) displays a single entry for a default folder of a particular type, e.g. Deleted Items.



You create Managed Content Settings for a default folder like Deleted Items to permanently delete items in the folder after 30 days.



Next, you want to create another setting for your executives with a higher retention period of 300 days for the Deleted Items folder. If you try to create another Managed Content Settings for the same Default Managed Folder, you get the following error.

Managed Folders and Managed Content Settings

If Exchange only allows you to associate one Managed Content Settings with one Managed Folder, I've often wondered, why not allow specifying content retention settings in the Properties of that folder? Why have a Managed Folder AND a Managed Content Settings for that folder as separate objects?

This is to allow different Managed Content Settings for different types of items in a Managed Folder. For example, for the Deleted Items folder, you can create a Managed Content Setting to permanently delete messages after 30 days, but retain other types of items like faxes or Contacts for a little longer, let's say 60 days.

Note: You cannot change the Message Type selected in Managed Content Settings after it is created. To select a different Message Type, delete the Managed Content Settings object and recreate it with the correct/intended Message Type selected.

To create a new Managed Content Settings for a default folder, Deleted Items in this case, we need to create another default folder.

1. In the Exchange console, select Organization Configuration | Mailbox | Managed Default Folders.
2. From the Action pane on the right, click on the New Managed Default Folder link.
3. In the New Managed Default Folder page, enter a name for the new default folder instance. Note, unlike Managed Custom Folders, the default folders like Deleted Items, Inbox, Sent Items, Drafts, etc. already exist in a mailbox. What we're doing here is simply creating an instance/representation of a default folder, to be able to associate Managed Content Settings with it.



4. From the Default Folder Type drop-down, select the correct default folder type - for this example we select Deleted Items.
5. [Optional] Type a comment in the text box titled Display the following comment when the folder is viewed in Outlook.
6. Click New | click Finish on the Completion page.

Now you have another instance of the Deleted Items folder. You can create Managed Content Settings for it, and add it to a Managed Folder Mailbox Policy.



For more information on applying Managed Folder Mailbox Policy, read previous post "Applying Managed Folder Policy to more than one user".

 Related posts:
- Applying Managed Folder Policy to more than one user
- Exchange Server 2007: Why aren't Managed Content Settngs applied?
- Restricting Messaging Records Management to a particular message type

Labels: , , ,

Friday, September 14, 2007

Getting a list of actual Exchange ActiveSync (EAS) users was not an easy task with Exchange Server 2003, and certainly not one that could be accomplished in a hurry.

Yes, it indeed is a one-liner shell command with Exchange Server 2007:

Get-CASMailbox | where {$_.HasActiveSyncDevicePartnership} | select Name

10/7/2008:
Here's an updated version, which uses the -Filter parameter to filter recipients on the server-side:

Get-CASMailbox -Filter {HasActiveSyncDevicePartnership -eq $true} | Select Name

Labels: , , ,

Monday, September 10, 2007

 

Exchange Server 2007: Setting Message Size Limits

Posted by Bharat Suneja at 8:08 AM
In a previous post, we looked at how the maximum recipients per message settings are treated differently by Exchange Server 2007 and Exchange Server 2003/2000 when sending to Distribution Groups (read previous post "Distribution Groups and maximum recipients per message").

Another commonly asked question is about message size limits and the inability to send messages that are apparently within the maximum sizes configured. Let's take a look at the message size settings in different places.

Organizational limits: These apply to all Exchange servers in the Organization. You can set these using the Set-TransportConfig command from the Exchange shell:

Set-TransportConfig -MaxReceiveSize 40MB -MaxSendSize 40MB


In SP1, you can also set it using the Exchange console by going to Organization Configuration | Hub Transport | Global Settings tab | Transport Settings | properties.

Exchange Server 2007 | Transport Settings

Receive Connector limit: Unlike Exchange SMTP Virtual Servers in Exchange Server 2003/2000, Exchange 2007's Receive Connectors are only used to receive messages. The maximum message size limit can be different on different Receive Connectors on a Hub Transport or Edge Transport server. To modify the maximum message size on a Receive Connector using the Exchange console, select Server Configuration | Hub Transport | select a HT server | Receive Connectors -> select a connector | Properties | General tab.



To set ReceiveConnector limit using the shell:

Set-ReceiveConnector "CONNECTOR NAME" -MaxMessageSize 40Mb

Send Connector limit: Send Connectors are used for sending outbound messages to the internet or particular address spaces (domains). Edge Transport servers also have a Send Connector to send inbound messages to Hub Transport servers in an AD Site. To modify the maximum message size on Send Connectors, select Organization Configuration | Hub Transport | Send Connectors -> select connector | Properties | General tab.



To set SendConnector limit using the shell:

Set-SendConnector "CONNECTOR NAME" -MaxMessageSize 40Mb

Mailbox limit: Individual recipients like mailboxes can have their own limits to bypass the Organizational limits. To set these using the Exchange console: Recipients | Mailbox -> select mailbox | properties | Mail Flow Settings tab | Message Size Restrictions.


Do individual size limits bypass the Organization size limit?

Setting higher message size limits on an Exchange recipient bypasses the maximum message sizes in the Exchange Organization configuration, albeit only for internal messages, not for messages sent to or received from unauthenticated sources.

Troubleshooting Sender and Recipient Size Limits: Consider the sender's MaxSendSize and the internal recipient's MaxReceiveSize when troubleshooting message size issues.

If the sender's size limits allow sending a large message, but the recipient's limits do not allow receiving a message of that size, you get a NDR with the following text (note the enhanced status code informing you exactly why the message was rejected):
#550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##

If the recipient is allowed to receive a large message, but the sender isn't allowed to send a message of that size, you get the following NDR:
#550 5.2.3 RESOLVER.RST.SendSizeLimit; message too large for this sender ##

To set these using the Exchange shell:

Set-Mailbox "Joe Adams" -MaxSendSize 20Mb -MaxReceiveSize 20Mb

Distribution Groups and Contacts (MailContacts) only have maximum receive size in the Exchange console, but both MaxReceiveSize and MaxSendSize properties can be set for them using the Exchange shell.

Global Settings: Besides the above, another set of message size limits can impact Exchange Server 2007 recipients, but it's often overlooked when troubleshooting. This is the one in Exchange Server 2003 Global Settings | Message Delivery -> Properties.




- If you have these configured to a specific value before you upgrade the Organization to Exchange Server 2007, these are left untouched.
- If you have these set to "No Limit" before the Exchange Server 2007 upgrade, these are reset to the Exchange Server 2007 defaults.
- In case Exchange Server 2007's Organization settings (the ones you can set using Set-TransportConfig) conflict with these legacy Global Settings, the lower of the two sizes are used.

The problem is, these are neither visible in the EMC, nor using any of the Exchange shell commands.

If you still have an Exchange Server 2003 server in the Organization, you can use ESM to modify these limits. Alternatively, you can use ADSIEdit to browse to the Configuration container | Services | Microsoft Exchange | YourOrgName | Global Settings | Message Delivery -> Properties, and modify the following attributes as required:
1. delivContentLength -> corresponds to MaxReceiveSize parameter in Set-TransportConfig command.
2. SubmissionContentLength -> corresponds to MaxSendSize parameter in Set-TransportConfig command.
Note: The maximum value for both of the above is 2097151 KB, slightly under 2 Gb.
3. msExchRecipLimit -> corresponds to MaxRecipientEnvelopeLimit parameter in Set-TransportConfig command.

Set these to be the same as the equivalent Organization settings in Exchange Server 2007.


Exchange Server 2007 SP1 makes managing Global Settings easier.

If Global Settings have numeric values (i.e. aren't set to "No Limit"), using Set-TransportConfig to change maxReceiveSize, maxSendSize or maxRecipientEnvelopeLimit also changes the corresponding Global Settings.

Active Directory SiteLink limit: In Exchange Server 2007 SP1, you can also set maximum message size limit on AD Site Links. Exchange Server 2007 uses the AD Site topology to determine the least cost paths. If the message size to be delivered to a remote AD Site exceeds the limit on the AD Site Link, message delivery will fail. By default, the MaxMessageSize on AD Site Links is set to unlimited. This can be changed using the following command:

Set-ADSiteLink "SITE LINK NAME" -MaxMessageSize 20Mb

Routing Group Connector Limit: Routing Group Connectors are used in co-existence scenarios to transfer messages between Exchange Server 2003/2000 Routing Groups and the Exchange Server 2007 Routing Group (yes, there is one under the hood.. ). Messages exchanged between these Routing Groups should be below the message size limits of their respective RGCs. The default is set to unlimited. To set the MaxMessageSize on a Routing Group Connector:

Set-RoutingGroupConnector "CONNECTOR NAME" -MaxMessageSize 20Mb

Content conversion and message size limits

One source of confusion in previous versions of Exchange Server, as far as the message size limits are concerned, is that created by the content conversion process. Content conversion happens when Exchange converts an internet/MIME message into MAPI/Exchange format, and vice versa. Content conversion generally increases the message size - roughly by 30%. If you set a maximum message size of 10Mb., and wonder why a 9 Mb. attachment didn't make it through, consider the content conversion overhead, as also message headers (which are computed along with the DATA portion of the message to calculate the message size), and any actions taken by Transport Rules.

How does Exchange Server 2007 handle such messages? When a message enters the Exchange Server 2007 Org, it gets stamped with an X-MS-Exchange-Organization-OriginalSize header, which indicates the original size of the message before conversion. When considering message size limits, if the message has since ballooned to a larger size due to content conversion, added headers, etc. - the lower of the original message size and the current (converted) message size is considered, eliminating some of the confusion seen with message sizes in previous versions.

Using the Exchange shell to track failed message delivery

You can use the Exchange shell to track messages that could not be delivered because of message size issues. The RecipientStatus field in Message Tracking logs is used to store the SMTP response and enhanced status codes. The Message Tracking EventID we're looking for is FAIL. (Read previous post on message tracking: "Exchange Server 2007: Message Tracking from the command line")

To track messages that failed because of recipient's MaxReceiveSize:

Get-MessageTrackingLog -EventID FAIL | where {$_.RecipientStatus -like "*RecipSizeLimit*"}

To track messages that failed because of the sender's MaxSendSize:

Get-MessageTrackingLog -EventID FAIL | where {$_.RecipientStatus -like "*SendSizeLimit*"}

Labels: , , ,

Friday, August 10, 2007

The Exchange console does not have pre-canned filter options for Country or City to be able to create a Dynamic Distribution Group (DDG, aka "Query-Based Distribution Group") for all recipients or mailboxes in a particular country or city. You can use options to filter on Department, Company, State or Province, or the custom/extension attributes 1-15.

Screenshot: Exchange Management Console filtering options for new Dynamic Distribution Groups
Fig. 1: You can filter on Department, Company, State or Province or extension attributes 1-15 using pre-canned filters

If your Active Directory OUs are structured based on location (country/state/city), you can simply scope the DDG to that OU using the Exchange console, as shown in the following screenshot.

Screenshot: Exchange Management Console - setting scope of Dynamic Distribution Group
Fig. 2: You can set the scope of the DDG to a particular OU or container. Click here to see the complete dialog box.

However, if that's not the case (e.g. OU structure is based on business units or departments, etc.), you will need to use the Exchange shell to create a DDG with a custom filter.

To create a DDG for all user mailboxes from a particular country:

New-DynamicDistributionGroup -Name "US-Users" -OrganizationalUnit "OUorContainerNameToCreateGroupIn" -RecipientContainer "yourdomain.com" -RecipientFilter {RecipientType -eq "UserMailbox" -and CountryOrRegion -eq "United States"}

You can change the RecipientType to include other types of recipients.

To view recipients/mailboxes returned by the RecipientFilter: "HOW TO: View membership of a Dynamic Distribution Group".

Similarly, to create a DDG for all user mailboxes from a particular city:

New-DynamicDistributionGroup -Name "SF-Users" -OrganizationalUnit "OUorContainerNameToCreateGroupIn" -RecipientContainer "yourdomain.com" -RecipientFilter {RecipientType -eq "UserMailbox" -and City -eq "San Francisco"}

Labels: , ,

In "New Distribution Groups do not receive internet email by default", I wrote about Devin's observation that all new Distribution Groups created in Exchange Server 2007 do not receive internet/unauthenticated email by default.

Here's some more often overlooked Dynamic Distribution Group (DDG, aka "Query-Based Distribution Group" in Exchange/Windows Server 2003) quirkiness. When creating a new Dynamic Distribution Group using the Exchange shell, you need to specify the required OrganizationalUnit parameter. This tells Exchange which OU or Container the new group should be created in. The RecipientContainer parameter is optional. It sets the scope of the AD query for the Dynamic Distribution Group - only recipients from that OU or Container are returned (and thus get mail sent to that group).

If you do not specify the RecipientContainer parameter, the shell sets it to the same value as the OrganizationalUnit parameter. As a result, the query may not return any recipients at all, or may not return all the recipients you think it should.

The documentation for New-DynamicDistributionGroup does point this out:
If you do not specify a value for RecipientContainer, the default search filter is the location of the dynamic distribution group in Active Directory. This location is specified by using the OrganizationalUnit parameter.
Scenario: If you create all groups in an OU or container called Distribution Groups, which has no users (or recipients other than the groups), the query will not return any users at all because its scope is now set to the Distribution Groups OU or container!

To get the RecipientContainer and OrganizationalUnit parameters of a Dynamic Distribution Group:

Get-DynamicDistributionGroup "MyGroupName" | select Name,RecipientContainer,OrganizationalUnit


Previewing recipients returned by a DynamicDistributionGroup filter
There's no easy way to view "membership" (or rather, the recipients returned by the Dynamic Distribution Group's filter) for Dynamic Distribution Groups created using a custom filter. You cannot easily verify whether the group's picking up the right recipients. You can test by sending messages to the new group and requesting a Delivery Report. However, if no recipients are returned by the filter, the messages disappear into a black hole, never to be heard from again, with no NDRs.

"HOW TO: View membership of a Dynamic Distribution Group" shows how to preview recipients returned by the RecipientFilter.

Bottomline, and best-practice: It's a good idea to set the RecipientContainer property when creating new Dynamic Distribution Groups.

Update: You can use the Get-MessageTrackingLog cmdlet to parse Message Tracking logs and quickly determine the recipients returned upon expansion. The EXPAND event is logged when the Categorizer expands distribution groups.

Labels: , ,

Thursday, August 02, 2007

If you use the Exchange Server 2003/2000 extensions to Active Directory Users & Computers (ADUC) console to create mailboxes residing on Exchange Server 2007 servers, these mailboxes get stamped as legacy mailboxes.

Exchange Server 2007 mailboxes should be created using the Exchange (2007) console or shell.

To remove the legacy tag from mailboxes created using ADUC, use the following command:

Set-Mailbox "John Doe" -ApplyMandatoryProperties

This is documented in KB 931747: A mailbox that is located on an Exchange Server 2007 server may be identified as a legacy mailbox in Exchange Server 2007.

To get a list of legacy mailboxes:

Get-Mailbox | where {$_.RecipientTypeDetails -eq "legacymailbox"}

Note, not all legacy mailboxes reside on Exchange Server 2007 servers, so it's not a good idea to use the ApplyMandatoryProperties command to all of these. Mailboxes residing on Exchange Server 2003/2000 servers are also legacy mailboxes, and you may see some mailboxes moved from Exchange Server 2003/2000 servers carry this tag as well.

Let's filter the above list of legacy mailboxes to only the ones located on Exchange 2007 servers:

Get-ExchangeServer | Where {$_.IsExchange2007OrLater} | Get-Mailbox | where {$_.RecipientTypeDetails -eq "legacymailbox"}

Apply mandatory properties:

Get-ExchangeServer | Where {$_.IsExchange2007OrLater} | Get-Mailbox | where {$_.RecipientTypeDetails -eq "legacymailbox"} | Set-Mailbox -ApplyMandatoryProperties

Labels: , , ,

Tuesday, July 31, 2007

New Exchange Server 2007 Distribution Groups created using the Exchange shell or console do not receive internet mail (i.e. mail from unauthenticated senders) by default. Thanks to Exchange MVP Devin Ganger for pointing this out.

Screenshot: Distribution Group - Delivery Restrictions
Figure 1: By default, new Distribution Groups created in Exchange Server 2007 are configured to receive mail only from authenticated senders.

To allow internet mail to a Distribution Group:

Set-DistributionGroup "Group Name" -RequireSenderAuthenticationEnabled $false

When creating a new Distribution Group using the console, the option for authentication is not exposed. However, when creating one using the shell using the New-DistributionGroup command, the above optional parameter -RequireSenderAuthenticationEnabled can be set to false.

Labels: , ,

Tuesday, July 24, 2007

 

HOW TO: Forward mail to a Public Folder

Posted by Bharat Suneja at 2:14 PM
When trying to forward inbound mail for a recipient to a Public Folder using the Exchange console (Recipient ->Properties | Mail Flow Settings | Delivery Options | Forward to: ), the Recipient Picker GUI does not display mail-enabled Public Folders.

This can be done from the shell using the following command:

Set-Mailbox "Foo" -ForwardingAddress "TestPF@mydomain.com"

The above command forwards mail to the Public Folder, without delivering a copy to the original recipient. To have a copy delivered to the recipient and forward it to a Public Folder, set the DeliverToMailboxAndForward property to true:

Set-Mailbox "Foo" -ForwardingAddress "TestPF@mydomain.com" -DeliverToMailboxAndForward $true

Once this is done, Delivery Options in the console does display mail being forwarded to the Public Folder.

Delivery Options - forwarding to a Public Folder

Note, you can post to a Public Folder from Microsoft Outlook, but it should be mail-enabled to get an email address and receive (internet/smtp) email. To mail-enable a Public Folder, use the following command:

Enable-MailPublicFolder "\TestPF"

To find out how to add/remove email addresses and change the default email address for a public folder, read previous post "HOW TO: Add Email Addresses To Public Folders".

Labels: , , ,

Tuesday, July 10, 2007

An often heard requirement is that of preventing one or a few users from sending/receiving internet mail.

Outbound internet mail: On Exchange Server 2003/2000, this was accomplished using Delivery Restrictions on SMTP Connector(s) for address space *.

Exchange Server 2007 doesn't have a similar way of implementing Delivery Restrictions, but it provides the convenience of inspecting messages in the transport pipeline and taking actions on those, using Transport Rules. To create a Transport Rule to prevent users from receiving internet mail:

Create a Distribution Group - let's call it "DG-NoInternetMail". Add the recipients you want to prevent from sending internet email as members of the group.

Create a Transport Rule [Flash demo]
1) Fire up Exchange console | Organization Configuration | Hub Transport | Transport Rules tab | click New Transport Rule
2) Enter a name for the rule - e.g. Rule-NoInternetMail
3) On the Conditions page, select "From a member of a distribution list"
4) In the rule description, click the link for distribution list (underlined)
5) Click Add | Select the distribution list "DG-NoInternetMail"
6) Under Conditions, select a second condition "Sent to users inside or outside the organization"
7) In the rule description, click Inside (underlined) | change scope to Outside
8) Click Next
9) On the Actions page, select "send bounce message to sender with enhanced status code"
10) If you want to modify the text of the bounced message (optional): In the description, click "Delivery not authorized, message refused" | enter new message text
11) Click Next | verify the rule conditions and action in the summary
12) Click New | click Finish

Inbound internet mail: In Exchange Server 2003/2000, you can prevent a recipient from receiving internet mail by requiring authentication to be able to send to the recipient. Internet senders are not authenticated. There are other ways to prevent inbound mail for certain users - like using Recipient Filtering, or generating an invalid email address from a non-existent domain, e.g. foo@nonexistentdomain.corp.

Exchange Server 2007 recipients can be set up to require sender authentication to receive email.

Using the Exchange console:
- Recipient Configuration -> select recipient -> recipient properties | Mail Flow Settings tab | Message Delivery Restrictions | Properties
- check "require that senders are authenticated"

Using the shell:

Set-Mailbox "Foo User" -RequireSenderAuthenticationEnabled $true

Additionally, either of the other 2 alternatives mentioned above for Exchange Server 2003/2000 can be used to prevent users from receiving internet email.

Setting delivery restriction based on group membership: Rather than setting up each recipient to receive inbound mail from authenticated senders only, you can get membership of the above distribution group and pipe it into the Set-Mailbox command:

Get-DistributionGroupMember "DG-NoInternetMail" | Set-Mailbox -RequireSenderAuthenticationEnabled $true


Use OWA/Outlook to test sending internet mail from a user who is a member of the distribution group.

Labels: , , ,

Friday, July 06, 2007

You disable a particular anti-spam agent - let's say the Content Filtering Agent - from the Exchange console.



Next, you use the Get-TransportAgent command to get the status of transport agents - and surprisingly the Content Filter Agent shows up as Enabled!



Why doesn't Get-TransportAgent agree with the Exchange console about the status of an agent?

Fellow MCT and Exchange geek David Elfassy blogged about it recently.

The Anti-Spam tab is located under the Organization Configuration | Hub Transport node in the console. Disabling an agent from the console prevents the agent on all transport servers in the Organization from taking any action. It's an Organization-wide or global setting.

The Get-TransportAgent command is transport server-specific. It shows the status of agents on a particular server. With the Org-wide configuration set to disabled, an agent enabled on a particular transport server behaves like a soldier instructed to fire but not kill. (May not be the best analogy - it doesn't exactly scare spam, and it doesn't do much else).

To draw a parallel to Exchange Server 2003, you can enable settings on a particular filter - e.g. Recipient Filtering, in Global Settings. However, you still have the flexibility of being able to enable/disable it on a per-SMTP virtual server basis. This is somewhat similar.

To get the global/Org-wide status of a particular filter, you need to use the corresponding command for that filter.
- For Content Filter Agent: Get-ContentFilterConfig
- For Recipient Filter Agent: Get-RecipientFilterConfig
- For Sender Filter Agent: Get-SenderFilterConfig
- For SenderID Agent: Get-SenderIDConfig
- For Protocol Analysis Agent: Get-SenderReputationConfig

If you've carefully looked at the above list, you're probably wondering why there's no mention of Connection Filtering Agent in it. The Connection Filtering Agent handles multiple tasks which are listed individually in the console.

To check the global setting for configuration of each, use the corresponding config command:
- For IP Block List: Get-IPBlockListConfig
- For IP Block List Providers: Get-IPBlockListProvidersConfig
- For IP Allow List: Get-IPAllowListConfig
- For IP Allow List Providers: Get-IPAllowListProvidersConfig

To "disable" an agent in Organization Configuration (equivalent of what you do in the console) using the shell, use the corresponding Set command, e.g.:

Set-ContentFilterConfig -Enabled $false

Next, let's take a look at how you can disable an agent on a transport server. Generally, if the Get-Blah command returns a property like Enabled: True, you can use Set-Blah -Enabled $false to disable it (You probably know where we're going with this by now... :). Not so for Get-TransportAgent. Its "Set" counter-part - Set-TransportAgent allows you to modify only one property -Priority. You can change the order in which these agents fire by changing their Priority.

You use the Disable-TransportAgent command to disable an agent on a transport server:

Disable-TransportAgent "Connection Filtering Agent"

No points for guessing the command used to enable a transport agent - Enable-TransportAgent

Labels: , , , ,

Friday, June 29, 2007

 

HOW TO: Add Email Addresses To Public Folders

Posted by Bharat Suneja at 9:17 AM
A previous post shows how to add an additional email address to a mailbox/recipient [read "HOW TO: Add additional email addresses to a recipient"]. How do we add email addresses to Public Folders?

It should be pretty simple - If Get-Mailbox shows the emailaddresses property for a mailbox, and Set-Mailbox allows you to use the -EmailAddresses switch to add email addresses, one can't be blamed for believing it'll work the same way for Public Folders.

Objects other than Public Folders need to be mailbox or mail-enabled to be Exchange recipients, Public Folders do not (Yes, they are mail-enabled by default). To modify mail-related attributes of Public Folders, you use the Set-MailPublicFolder command.

To add additional email address to a (mail-enabled) Public Folder:

$PF = Get-MailPublicFolder "Sales"
$PF.EmailAddresses += "Sales-EMEA@domain.com"
$PF | Set-MailPublicFolder

The first line gets mail-related properties of Public Folder "Sales" in a variable called $PF. Next, we add the additional email address, without wiping out the existing ones. Finally, we commit the change using Set-MailPublicFolder.

If you simply use Set-MailPublicFolder "Sales" -EmailAddresses "Sales-EMEA@domain.com", it will replace the existing values in the EmailAddresses property.

Another difference to note between how the Set-PublicFolder and Get-PublicFolder commands work, compared to Set-MailPublicFolder and Get-MailPublicFolder - the former takes a relative path of a Public Folder. For instance, to get the Sales PF if it's in the root of the Public Folder tree, we would need to add a \ before the name:

Get-PublicFolder \Sales

However, the Get/Set-MailPublicFolder commands work using the alias/display name of the PF. Why the difference? One way to look at it - when using Get/Set-PublicFolder, you're working with the actual Public Folder. When using Get/Set-MailPublicFolder, you're working with the Active Directory object created for that Public Folder (which holds mail-related attributes, making it possible for a Public Folder to be mail-enabled).

To change the primary email address of the Public Folder "Sales" from "Sales@domain.com" to the new address we just entered - "Sales-EMEA@domain.com":

Set-MailPublicFolder "Sales" -EmailAddressPolicyEnabled $false -PrimarySmtpAddress "Sales-EMEA@domain.com"

As you may have already figured out, we exempted the Public Folder from getting EmailAddressPolicies applied. In Exchange Server 2003/2000, you could change the default email address of a recipient, without unchecking the checkbox. Result: A few minutes after you completed the change, Recipient Policies would apply and change the primary email address back.

Exchange Server 2007 doesn't let you change the default email address without exempting the recipient from email address policies.

Labels: , ,

Thursday, June 28, 2007

 

HOW TO: Grant Full Mailbox Access permission

Posted by Bharat Suneja at 5:52 PM
Follow-up to previous post titled "HOW TO: Assign SendAs right using Exchange shell" - the ability to assign SendAs and ReceiveAs permissions is preserved in AD Users & Computers, but the ability to grant Full Mailbox Access permission isn't available. Full Mailbox Access is a mailbox permission (without getting into a debate about what's a permission and what's a right, the term is used interchangeably here). In Exchange Server 2003/2000, mailbox permissions can be controlled from the Exchange Advanced tab | Mailbox Rights, as seen in the following screenshot.


Figure 1: In Exchange Server 2003/2000, mailbox permissions can be managed from ADUC

Since Exchange Server 2007 does not use ADUC for recipient management, this can't be done using ADUC.

The shell is your friend when it comes to assigning Full Mailbox Access and other mailbox permissions. You can use the Add-MailboxPermission command from the shell to assign it.

In the following example, we assign Full Mailbox Access permission on Joe Adams' mailbox to another user (janea):

Add-MailboxPermission "Joe Adams" -AccessRights FullAccess -user "janea"

Besides FullAccess, the following mailbox permissions can be granted using Add-MailboxPermission: 1) SendAs 2) ExternalAccount 3) DeleteItem 4) ReadPermission 5) ChangePermission 6) ChangeOwner

Viewing permissions using Get-MailboxPermission

To view permissions on a mailbox, use the Get-MailboxPermission command:

Get-MailboxPermission "Joe Adams"

To view explicitly assigned permissions (i.e. permissions that are not inherited):

Get-MailboxPermission "Joe Adams" | where {$_.IsInherited -eq $false}

To view all security principals with Full Access permission on a mailbox:

Get-MailboxPermission "Joe Adams" | where {$_.AccessRights -like "*FullAccess*"}

Managing Full Mailbox Access using the EMC in Exchange Server 2007 SP1

Exchange Server 2007 SP1 adds management of Full Mailbox Access permission to the EMC.
1. From Recipient Configuration | Mailbox | select mailbox.
2. In the Action pane (or by right-clicking the mailbox), click Manage Full Mailbox Access...


Figure 2: Exchange Server 2007 SP1 allows management of Full Mailbox Access permission from the EMC

Labels: , , , ,

Thursday, June 21, 2007

Exchange Server 2007 lets you create room and equipment mailboxes. Having these designated as resource mailboxes - either room or equipment - has its advantages as these get setup for resource booking without having to go through the cumbersome process of logging into such mailboxes and configuring calendar settings for each so they can be booked as resources.

Whereas an "All Rooms" Address List is created by default, equipment mailboxes are not listed in it, and there's no separate Address List for equipment. (Thanks to the person who asked this question in this morning's Exchange Q&A chat on TechNet!)

Additional Address Lists can be created easily for such equipment mailboxes.

To create an "All Equipment" Address List, use the following command in Exchange shell:

New-AddressList -name "All Equipment" -RecipientFilter {RecipientType -eq "UserMailbox" -and RecipientTypeDetails -eq "EquipmentMailbox"}

To view the mailboxes that get picked up by the above filter, use the following commands:

$AllEquipment = Get-AddressList "All Equipment"
Get-Recipient -filter $AllEquipment.RecipientFilter

You can also create more granular Address Lists, for example one for all projectors.

For this example, we follow a naming convention for naming equipment mailboxes for projectors, so it has a particular string like PROJ. In this case, our mailboxes follow a naming convention that results in projector mailboxes names like EQP-PROJ-InFocus1. You are free to make your own naming convention choices, this is just an example. Now we can use the following command to create an "All Projectors" Address List:

New-AddressList "All Projectors" -RecipientFilter {RecipientType -eq "UserMailbox" -and "RecipientTypeDetails -eq "EquipmentMailbox" -and name -like "*PROJ*"}

Now we have separate Address Lists for equipment resources, and also one for all projectors. This allows users to easily locate these resources using Address Lists when scheduling meetings.

Labels: , , ,

Thursday, May 31, 2007

 

Exchange Management Shell Quick Reference

Posted by Bharat Suneja at 12:49 PM
Do you find yourself frequently searching for documentation related to Exchange shell commands? Can you find your way around but need a quick reference you can look up frequently without having to search for anything? Microsoft has an Exchange Management Shell Quick Reference doc on their web site - it's an HTML doc but the download itself is an EXE archive that you need to expand after downloading.

Take a look at it here - a permanent link is being added to the Links Of Interest section in the right sidebar on this page.

Labels: , ,

Wednesday, May 30, 2007

 

View membership of a Dynamic Distribution Group

Posted by Bharat Suneja at 3:41 PM
Dynamic Distribution Group is the Exchange Server 2007 term for Query-Based Distribution Groups supported by Active Directory (and therefore Exchange Server 2003/2000) in Windows Server 2003. Unlike normal security and distribution groups, which have their membership defined by manually adding users/recipients as members, the membership of a Dynamic Distribution Group is determined every time the group receives a message. The (SMTP) Transport's Categorizer component queries a Global Catalog for a list of recipients matching the LDAP filter defined in the group.

Windows Server 2003's ADUC console allows you to preview recipients returned by the filter, by going to the group's properties and clicking Preview. However, with recipient management moved to Exchange in Exchange 2007, this ability to preview is limited to groups created using Exchange's "pre-canned" filters. If you're using a custom recipient filter (Exchange 2007 uses OPATH filters), you can't preview the recipients returned using the console.



In a previous post titled "Adventures with OPATH: some annoyances if you're used to LDAP", I talked about previewing membership using the Saved Queries feature in ADUC (the Windows 2003 version).

Later I noticed the product documentation was updated to include a way to view which recipients get picked up by the recipient filter - this is easily accomplished from the shell, using the following commands:

$Group = Get-DynamicDistributionGroup -Identity "My Dynamic Group"

This stores the Dynamic Distribution Group in a variable called $Group. Now we can use the Get-Recipient command and filter the output using the recipient filter from the variable $Group

Get-Recipient -Filter $Group.RecipientFilter

Labels: , , ,

Monday, May 28, 2007

 

New-Mailbox Parameters

Posted by Bharat Suneja at 6:14 PM
When creating a new mailbox using the New Mailbox wizard in the Exchange console, you are required to enter a number of parameters. The Completion page/dialog box in the wizard shows the shell command used under the hood to create the mailbox. This functionality is quite useful in understanding the commands used by such wizards, and the syntax that can be used in the shell to accomplish the same task. (As a side note, this display of commands is limited to wizards. If you add/modify a configuration setting directly, the commands used are not displayed).

When creating a new mailbox for a user Jim Murphy, the shell command used is displayed in the screenshot below.



Parameters used by the command displayed in the above screenshot:
1) Name: Jim Murphy
2) Alias: jmurphy
3) OrganizationalUnit: e12labs.com/users (Domain/Container or OU)
4) sAMAccountName: jmurphy
5) FirstName: Jim
6) Initials: '' (blank)
7) LastName: Murphy
8) Password: System.Security.Secure.String (hidden)
9) ResetPasswordOnNextLogon: $false
10) Database: distinguishedName of the mailbox database

The new-mailbox command creates a new user account in Active Directory, and a new mailbox in Exchange. Documentation for the new-mailbox command has an extensive list of all the parameters - required and optional.

However, a new mailbox can be created using far fewer parameters - as shown below:

$password = Read-Host "Enter Password" -AsSecureString

The new-mailbox command does not accept a password if it is actually typed inline in the command, e.g. new-mailbox -password MyPassw0rd1.... The command in the above example results in the shell providing a prompt to securely enter a password, without making it visible in the shell. It is held in the variable $password. The variable can then be used in the new-mailbox command.

New-Mailbox -Password $password -Name "Jim Murphy" -UserPrincipalName jmurphy@e12labs.com -OrganizationalUnit Users -Database "Mailbox Database"

Note, not all the parameters used and displayed by the New Mailbox wizard are required. Some parameters, like alias are populated automatically by the shell. You can use the get-mailbox command to list all parameters for a mailbox, and determine which parameters were populated automatically.

get-mailbox "Jim Murphy" | fl

Labels: , ,

Wednesday, May 16, 2007

Scenario: You have a Managed Folder Mailbox Policy called Policy-DeletedItems90Days. The policy has Managed Content Settings to permanently delete items in the Deleted Items folder after 90 days.

You can easily apply this Managed Folder Mailbox Policy to a single user using the Exchange console, as shown in Figure 1.

Screenshot: Applying Managed Folder Mailbox Policy using the Exchange Management Console
Figure 1: Applying a Managed Folder Mailbox Policy to a user using the Exchange Management Console

A Managed Folder Mailbox Policy can also be applied to a mailbox using the following shell command:

Set-Mailbox "Foo User" -ManagedFolderMailboxPolicy "Policy-DeletedItems90Days"

How do we apply this to more than one user? By using the Get-Mailbox command to fetch a bunch of mailboxes - either all mailboxes in the Organization, or all mailboxes in a particular Organizational Unit (OU), or all (mailbox-enabled) users who are members of a particular distribution group, or other user parameters. The mailboxes returned can then be piped to the Set-Mailbox command.

To apply a Managed Folder Mailbox Policy to all (mailbox-enabled) users, we need to get a list of all mailboxes, and pipe it to the Set-Mailbox command:

Get-Mailbox -ResultSize unlimited | Set-Mailbox -ManagedFolderMailboxPolicy "Policy-DeletedItems90Days"

To apply the policy to all mailboxes in a particular OU, e.g. an OU called Sales - we restrict our Get-Mailbox query the OU:

Get-Mailbox -OrganizationalUnit "Sales" -ResultSize unlimited | Set-Mailbox -ManagedFolderMailboxPolicy "Policy-DeletedItems90Days"

Apply a Managed Folder policy to members of a Distribution Group

When applying the policy to members of a Distribution Group, remember that Distribution Group members can include recipients other than mailbox-enabled users (e.g. mail-enabled users, Contacts, other Distribution Groups, Public Folders, etc.). To apply the policy to all (mailbox-enabled) users who are members of a Distribution Group called DL-Sales, we will need to get members of the Distribution Group using the Get-DistributionGroup command, filter the result to get only mailbox-enabled users, and pipe it to the Set-Mailbox command:

Get-DistributionGroupMember "DL-Sales" -ResultSize unlimited | where {$_.RecipientType -eq "UserMailbox"} | Set-Mailbox -ManagedFolderMailboxPolicy "Policy-DeletedItems90Days"

One logical question after the last example - can I do this with Security Groups instead? You cannot get the group membership of a Security Group as easily as you can get the members of a Distribution Group. Unfortunately, the Exchange shell does not have any equivalent of Get-DistributionGroupMember command that will work for Security Groups, although it's possible to enumerate security group memberships using the ADSI provider. (You can search the web for shell scripts to enumerate security group members - Bharat)

Avoid the confirmation prompts when applying a Managed Folder policy
When applying a Managed Folder Mailbox Policy, you run into 2 prompts. The first one is the default confirmation prompt produced by Set-Mailbox. This is cmdlet saying, "Hey, something changed! Are you sure you want to do this?", and prompts you for a confirmation as shown below:

Confirm
Are you sure you want to perform this action?
Setting mailbox "exchangepedia.com/People/foo user1".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):

You can avoid it by simply using -Confirm:$false in the command.

Next, you will run into the confirmation prompt produced when applying a Managed Folder Mailbox Policy. This is the cmdlet realizing, "Hey, this one's a serious change - you're applying a MF policy! Are you really, really sure? And btw, it'd be a good idea to block legacy Outlook clients!". The resulting prompt is shown below:

Confirm
When assigning a managed folder mailbox policy with managed custom folders to the mailbox "exchangepedia.com/People/foo user1", Outlook clients older than Outlook 2007 do not have all available client features and clients older than Outlook 2003 SP2 are not supported. You may use the "Set-CASMailbox" task to enable client version blocking. Are you sure you want to assign a managed folder mailbox policy to this mailbox?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help
(default is "Y"):

To override this one, you'll need to use the ManagedFolderMailboxPolicyAllowed switch. The command from the above example will thus look like this:

Get-Mailbox -ResultSize unlimited | Set-Mailbox -ManagedFolderMailboxPolicy "Policy-DeletedItems90Days" -ManagedFolderMailboxPolicyAllowed -Confirm:$false

A default Managed Folder policy for new users

A related frequently asked question— Can you have a default Managed Folder Mailbox Policy that's applied to new mailboxes automatically? There's no built-in way to specify a policy as the default policy for all users or new users at the time of account creation. However, you can use the Windows Scheduler to schedule a script or command to run on a schedule and apply the required policy to users.

For example:
Get-Mailbox -ResultSize Unlimited -Filter {ManagedFolderMailboxPolicy -eq $null} | Set-Mailbox -ManagedFolderMailboxPolicy MyPolicyName -ManagedFolderMailboxPolicyAllowed -Confirm:$true

Why not use LDAP filters?
That's fine, you say, but you really liked the Exchange 2003 way of applying a Recipient Policy, using LDAP filters. Using pretty much any attribute you chose to filter on. In Exchange 2007, there's no built-in way of using LDAP filters to apply a policy.

It's not such a great idea to apply message retention policies using an LDAP filter, or at least not in a manner similar to Exchange 2003.

For instance, if you're using a particular attribute to filter on, such as department, or group membership - simply changing the attribute or group membership could change when and how a mailbox user's messages are retained or purged. If you have multiple overlapping Recipient Policies, at times it's difficult to determine which policy is applicable to a user.

Exchange 2007 offers a simpler and deterministic behavior— by making the policy a user attribute. A policy explicitly associated with a user allows you to instantly determine which policy applies, with no ambiguity. It's also auditable, and reportable.

The automation is provided by PowerShell. Of course, you can simulate Exchange 2003's Recipient Policy behavior by using an OPATH filter with the Get-Mailbox cmdlet.

However, if you still need to use an LDAP filter, Nick Smith shows you how in Applying Managed Folder Mailbox Policies via LDAP Filters.


Related posts:
- Managed Folders: How to apply different Managed Content Settings to Default Folders
- Exchange Server 2007: Why aren't Managed Content Settngs applied?
- Restricting Messaging Records Management to a particular message type

Labels: , , ,

Tuesday, May 08, 2007

To determine whether a mailbox server is clustered or standalone, and if clustered - whether it's using Cluster Continuous Replication (CCR) or Single Copy Cluster (SCC), use the following command:

Get-MailboxServer | select name,ClusteredStorageType

The possible values:
1. NonShared = CCR cluster
2. Shared = SCC cluster
3. Disabled = standalone / non-clustered mailbox server

Labels: , , , ,

Thursday, May 03, 2007

I wrote about SMTP logging in Exchange Server 2003/2000 in what is one of the most popular posts on Exchangepedia [read previous post - "Logging SMTP protocol activity"]. Exchange Server 2007 has its own SMTP stack, and what I like to think of as smarter or more intelligent Receive Connectors (these are protocol listeners, roughly equivalent or comparable to the SMTP Virtual Server we've known from Exchange Server 2003/2000 - Bharat).

Not enabled by default
I hoped to see (SMTP) protocol logging turned on by default on these connectors, this is one aspect that hasn't changed. Yes, SMTP logging is still not enabled by default! You have to remember to enable SMTP logging on transport servers.

To enable protocol logging on Receive Connectors, use the following command:

Set-ReceiveConnector "Connector Name" -ProtocolLoggingLevel verbose

In case you're wondering if there are any choices for the logging level - there aren't. It's either verbose or none.

To enable protocol logging from the Exchange console, go to Server Configuration | Hub Transport | select the Hub Transport server you want to configure | select the Receive Connector -> properties | General tab | change Protcol logging level to Verbose, as shown in the screenshot below.

Screenshot: Enabling SMTP protocol logging on a Receive Connector in Exchange 2007
Figure 1: Enabling SMTP logging on a Receive Connector

Unlike Exchange Server 2003/2000, you have to enable logging separately for Send Connectors (equivalent of SMTP Connectors), using the following command:

Set-SendConnector "Send Connector Name" -ProtocolLoggingLevel verbose

To do this using the Exchange console, go to Organization Configuration | Hub Transport | Send Connectors tab | select the Send Connector -> properties | General tab | change Protocol logging level to verbose.

Besides the visible Receive and Send connectors, an invisible Send Connector lurks under the hood - used to transport messages within the organization, between Hub Transport servers, Edge Transport servers, and Exchange Server 2003/2000 servers. It's the Intra-Organization Send Connector. You won't see it in the console, or in the shell if you use the get-SendConnector command. To configure protocol logging for this Intra-Organization Send Connector:

Set-TransportServer "TRANSPORT SERVER NAME" -IntraOrgConnectorProtocolLoggingLevel verbose


Where do protocol logs reside?
- Unlike Exchange Server 2003/2000, which maintain separate protocol logs for each instance of a SMTP Virtual Server, all Receive Connectors share "SmtpReceive" logs. Similarly, Send Connectors share "SmtpSend" logs.
- Receive Connector logs are located in
\Exchange Server\TransportRoles\Logs\ProtocolLog\SmtpReceive
- Send Connector logs are located in
\Exchange Server\TransportRoles\Logs\ProtocolLog\SmtpSend

How do you change the path of SMTP logs?


To change the path of SmtpReceive logs:

Set-TransportServer "TRANSPORT SERVER NAME" -ReceiveProtocolLogPath "C:\New SmtpReceive Log File Directory"

To change the path of SmtpSend logs:

Set-TransportServer "TRANSPORT SERVER NAME" -SendProtocolLogPath "C:\New SmtpSend Log File Directory"

If you do decide to change the path, ensure the new directories/folders exist with appropriate permissions, as outlined in "How to Configure Protocol Logging" in the product documentation. In addition to the above, you can also control the maximum log file size, the maximum directory size, and the maximum age of log files. This ensures you don't have to worry about purging the logs manually over time, or scheduling a script to do this periodically.

SMTP logs are an important troubleshooting tool - enabling SMTP logging after the fact isn't any help when troubleshooting SMTP mail flow.


Labels: , , ,

Tuesday, May 01, 2007



One of the common complaints from users and many messaging folks is spam received from senders that appear to be from your own domain. SMTP mail is exchanged with anonymous internet hosts without any authentication. Headers are effortlessly spoofed. Rather than use an unregistered or invalid domain in the From: field, many spammers find it attractive to use an address from your domain - even an invalid one, or worse - a perfectly valid one. (It is advisable to not have resolution of anonymous senders enabled. Read previous post "A Late New Year's Resolution: Do Not Resolve Anonymous Senders")

Messages that appear to be sent from your domain probably have a better shot at making it through some spam filters, and certainly have a higher chance of being opened by recipients in your domain, once they do make it to the Inbox.

One way of tackling this menace is by using SenderID filter to drop messages that return a FAIL result (from a SPF record lookup). It's advisable to publish SPF records for your domain(s), if you haven't already done so. Explicitly designate SMTP hosts authorized to send for your domain(s). However, the impact of SenderID and whether you should consider dropping email based on it is an open debate, and the topic of another post.

In addition to the above, Exchange Server 2007 allows you to configure ReceiveConnectors to drop messages where the FROM address is from your own domain. It's a good idea to do so if you don't expect any legitimate messages sent without authentication (with your domain in the From: field). To configure a ReceiveConnector to reject such messages:

Remove-ADPermsission "ReceiveConnector-Name" –user “NT AUTHORITY\Anonymous Logon" –extendedrights “ms-Exch-SMTP-Accept-Authoritative-Domain-Sender”

Consider doing this only on the ReceiveConnector that receives inbound internet mail. There may be a need for certain - generally internal - senders like copiers/scanners, and other non-Exchange mail hosts to be able to send with an address from your domain in the FROM field, without authentication. As discussed in previous post titled "Exchange Server 2007: How To Allow Relaying", it is advisable to create an additional ReceiveConnector for such trusted/internal hosts.

Labels: , , , ,

Tuesday, April 24, 2007

When creating a new mailbox (or a mailbox-enabled user) in Exchange Server 2007, you have the option of creating a user mailbox or a resource mailbox - the latter for conference rooms, equipment like projectors, etc.

If you've already created a user mailbox instead, and want to convert it to a resource mailbox, use the following command:

Set-Mailbox "MailboxName" -Type Room

This sets up the mailbox as a room mailbox. The following changes take place (perhaps not an extensive list):
IsResource: True
UserAccountControl: Yes, Exchange Server 2007 resource mailboxes are disabled (displayed as "AccountDisabled" in the shell)
ExchangeUserAccountControl: AccountDisabled
LinkedMasterAccount: NT AUTHORITY\SELF
RecipientTypeDetails: RoomMailbox
AddressListMembership: In addition to the Default GAL and All Users address lists, the mailbox is made a member of All Rooms address list

AutomateProcessing in MailboxCalendarSettings is set to AutoUpdate. AutoUpdate sets up the mailbox to be processed by the Calendar Attendant. This processes meetings for users as they are received - even if the user is not logged on. Calendar items (meetings) are placed on the user's Calendar as tentative. As meeting updates are received, it marks the older instances as outdated.

The other choice here is AutoAccept, which sets it up for processing by the Resource Booking Attendant. It is similar to the Auto-Accept Agent for Exchange Server 2003 (a separate web download) - with a lot more configuration options, and without the XML configuration file required by AAA. To set up the mailbox for resource booking:

Set-MailboxCalendarSettings "MailboxName" -AutomateProcessing AutoAccept

There are plenty of configuration options one can use with Set-MailboxCalendarSettings command. Look at these in the documentation to figure out if you want to change any of the defaults.

To get a list of all resource mailboxes:

Get-Mailbox | where {$_.IsResource -eq "true"}

Labels: , , ,

Thursday, April 05, 2007

In Exchange Server 2007, Managed Folder Mailbox Policies are applied to mailboxes to control message retention. Conceptually, this is somewhat similar to Recipient Policy with Mailbox Manager settings in Exchange Server 2003, which is commonly used by administrators to accomplish tasks like emptying users' Deleted Items folders after a set period like 90 or 180 days.

(Messaging Records Management is an interesting topic, and a good candidate for a more elaborate article in the near future explaining how it works - Bharat)

Just as Exchange 2003's Mailbox Manager process runs on a schedule and applies the Mailbox Manager policies to mailboxes, Exchange 2007's Managed Folder Assistant (MFA) applies Managed Folder Policies. By default, it's set to "Never Run", as shown in the screen-shot below.
Screenshot: Managed Folder Assistant is set to 'Never Run' by default

If you've just gone through the entire process of creating Managed Folder Policies, and are wondering why the mailboxes are not getting processed and why messages older than X number of days aren't getting purged, it's most likely because you haven't modified the above default and actually set a schedule for the MFA to run.

To schedule the MFA, start the EMC, expand Server Configuration | Mailbox | select the mailbox server | Properties | Messaging Records Management tab | click the Customize button, and select a time period.


In addition to being able to schedule the agent to run— preferably after-hours, just like you did with Exchange Server 2003's Mailbox Manager - you can also trigger it manually from the shell, using the following command:

Start-ManagedFolderAssistant

This triggers the agent to run immediately. You can specify which server(s) to start the agent on, by using the -Server SERVERNAME parameter:

Start-ManagedFolderAssistant -Server EXCHANGE1, EXCHANGE2

You can also specify which mailboxes to process by adding the -Mailbox "Mailbox Identity parameter (the identity of a user can be specified as an SMTP address, domain\username, or mailbox GUID), as described in the online docs:

Start-ManagedFolderAssistant -Mailbox foo@yourdomain.com

Note: You cannot use both the -Server and -Mailbox parameters together.

Related posts:
- Managed Folders: How to apply different Managed Content Settings to Default Folders
- Applying Managed Folder Policy to more than one user
- Restricting Messaging Records Management to a particular message type

Labels: , , ,

Tuesday, March 20, 2007

 

Enabling POP3 in Exchange Server 2007

Posted by Bharat Suneja at 11:54 AM
As Terry Myerson posted on the Exchange team blog not too long ago (read previous post titled " Exchange Server 2007 SP1: A bag of goodies!"), the Exchange Management Console will get POP and IMAP management - amongst other features - in Exchange Server 2007 SP1.

Till then, the shell is the only option to configure these.

I'm not in love with POP, but surprisingly, many environments and organizations continue to use it, preferring it over IMAP4 - which is a better protocol according to many folks. For some reason, users seem to like it as well - perhaps because it's a simple, "no-frills" protocol that lets users fetch their mail using a number of different clients available for almost every flavor of operating system you can think of.

By default, the POP3 service (Microsoft Exchange POP3, or MSExchangePOP3) is set to start manually. To enable POP3, the service should be set to start automatically from the Services.msc console, or from Exchange shell using the following command:

Set-service msExchangePOP3 -startuptype automatic

Setting the service to start automatically takes care of starting it when the computer is restarted. For the current session, you still need to start the service from the Services console, or from the shell:

Start-service -service msExchangePOP3

The default authentication type on the POP3 "virtual server" is set to SecureLogin. The other options: 1) PlainTextLogin and 2) SecureLogin. The login type can be changed (to plaintextlogin in this example) using the following command:

Set-POPSettings -LoginType plaintextlogin

For more details on the authentication types, refer to "Configuring Authentication for POP3 and IMAP4" in Exchange Server 2007 documentation. (Thanks to Evan Dodds for the pointers... )

Next, binding POP3 to a particular IP address. By default, POP3 is bound to all IP addresses. To bind it to a particular IP address:

Set-POPSettings -UnencryptedOrTlsBindings "1.2.3.4:110"

Labels: , ,

Monday, March 19, 2007

Related to the previous posts "HOW TO: Add additional email addresses to a recipient" and "HOW TO Update multi-valued attributes in PowerShell" - removing one or more values from a multi-valued property is equally easy (though not a one-liner... ). The following example shows you how to remove a domain from the list of BypassedSenderDomains - a multi-valued property of ContentFilterConfig:

$foo = Get-ContentFilterConfig
$foo.BypassedSenderDomains -="somedomain.com"
$foo | Set-ContentFilterConfig

Similarly, removing a proxy email address:

$mailbox = Get-Mailbox User1
$mailbox.EmailAddresses -="somexistingaddress@yourdomain.com"
$mailbox | set-mailbox

Labels: , , ,

Friday, March 16, 2007

When adding new email addresses to a recipient using Exchange shell, remember that EmailAddresses property/proxyAddresses attribute is a multi-valued attribute. You can use the same syntax described in the previous post "HOW TO Update multi-valued attributes in PowerShell" to add one-off email addresses that are not created by EmailAddressPolicy.

$foo = get-mailbox User1
$foo.EmailAddresses +="sales@yourdomain.com","info@yourdomain.com"
$foo | set-mailbox

The above can also be easily accomplished using the console - Recipients | select a mailbox, Distribution Group or Contact | properties | E-mail Addresses tab | Add.

Labels: , , ,

Wednesday, March 07, 2007

 

HOW TO: Assign SendAs right using Exchange shell

Posted by Bharat Suneja at 5:45 PM
In Exchange Server 2007, recipients are managed from the Exchange console or shell. The Exchange console does not show security tab for a recipient.

You can still use AD Users & Computers console to modify permissions on a recipient, as the documentation suggests ["How to Grant Send As Permissions for a Mailbox"] - and in this case, assign the Send As permission. In ADUC | select recipient | Properties | Security tab.

You can use the Exchange shell to assign SendAs right (e.g. on a Distribution Group) to a user:

Add-AdPermission "Group Name" -user "User Name" -AccessRights
extendedright -ExtendedRights "send as"

Documentation for Add-ADPermission

icon - updates.gif
11/29/2007:
Exchange Server 2007 SP1 includes a Manage Send As Permissions wizard, similar to the Full Mailbox Access wizard found in the RTM version.

1. In EMC, right-click a recipient | select Manage Send As Permission



2. In the Managed Send As Permission wizard, click the Add button to add the recipient which needs to be assigned Send As permission on the selected recipient

Labels: , , , ,

Tuesday, February 20, 2007

I posted about OPATH filters recently [read previous posts 1) Adventures with OPATH: some annoyances if you're used to LDAP and 2) memberOf Attribute can now be used in OPATH filters!].

One of the issues was my inability to get a list of filterable properties that can be used in OPATH filters - unlike LDAP filters (I hate to call them legacy filters :), you cannot use *all* the attributes of recipients in an OPATH filter. Commands referenced in the documentation to get this did not work for me the last last time I checked.

Last week Evan Dodds informed me the list of filterable properties should be up on his blog soon, and here it is, as promised - Filterable Properties in Exchange 2007 RTM. He warns "The rest of this blog post will be long. And boring". Not if you've been waiting for this info Evan... it's an interesting reference!


Updated list of filterable properties in SP1

There are differences in the filterable properties used by the -Filter parameter used in recipient commands like Get-Mailbox, and the properties used in OPATH filters for the -RecipientFilter parameter (for Address Lists, EmailAddressPolicies, Dynamic Distribution Groups). Both lists have been updated for SP1.

Filterable properties for the -Filter parameter: RTM SP1

Filterable properties for the -RecipientFilter parameter: RTM SP1

As you'll find out from the post - and this is one of the issues I've had with OPATH - a lot of ldap attributes are referenced in OPATH using a name that's different from their LDAP Display Name (ldapDisplayName). Here's a list of some of the common ones:

1. the ldap attribute for last name is sn (or surname, as it's known in many cultures). OPATH refers to it as LastName.
2. physicalDeliveryOfficeName is referred to as Office
3. st (the LDAP quivalent of State) is known as StateOrProvince
4. mailNickname - a commonly used attribute in LDAP filters - is known as Alias
5. cn becomes CommonName
6. targetAddress (used for mail-enabled Contacts/Users) becomes RawExternalEmailAddress
7. msExchHideFromAddressLists becomes HiddenFromAddressListsEnabled
8. memberOf, as noted in previous post, is MemberOfGroup
9. msExchRequireAuthToSendTo becomes RequireAllSendersAreAuthenticated
10. mail (the email attribute seen on General tab of a recipient in ADUC) becomes WindowsEmailAddress

Yes, many of the OPATH property names do make a lot more sense, and while these will make things easier to figure out for newbies - as Evan notes in his post, it does add some complexity for folks used to LDAP syntax, filters, and attribute names.

I'm beginning to equate the OPATH property names to what "users" see in their Address Books in Outlook - simplified property names. At times you struggle with the cross-references between those simplified property names, and the actual attribute names that they map to when you fire up a tool like ADSIEdit or edit a Display Template.

If you've been using OPATH for any length of time, I am certain you must have felt some of that discomfort. Evan's post and the list of filterable properties may help alleviate some of that.

Labels: , , , ,

Monday, February 19, 2007

Multivalued attributes are simply attributes that can have more than one value. Examples include members attribute of groups, or proxyAddresses attribute of recipients.

In GUI interfaces, it is simple to add/modify multivalued attributes. VBScript has control codes that allow you to control the interaction with multi-valued attributes - 1 = clear all entries, 2 = update all entries, 3 = append, and 4 = delete.

Exchange shell uses Add commands to add new entries to some multivalued attributes - e.g. Add-IPBlockListEntry to add another IP address or range to the IP Block List.

However, if you want to add more values to stuff like BypassedSenderDomains in ContentFilterConfig, there's no equivalent of an Add command. If you try to add a value to the attribute using the following syntax, the existing values will be replaced by the newer ones:

Set-ContentFilterConfig -BypassedSenderDomains "somedomain.com"

You could copy the existing values (e.g. microsoft.com,zenprise.com), and paste these along with the new value:

Set-ContentFilterConfig -BypassedSenderDomains "microsoft.com","zenprise.com","somedomain.com"

However, this copying and pasting can be tricky for attributes that have a lot of values. Another alternative (..thanks to Vivek for the suggestion):

$foo=Get-ContentFilterConfig
$foo.BypassedSenderDomains +="somedomain.com"
$foo | Set-ContentFilterConfig

This is a great workaround... and it works!

However, it'd be much easier to have a switch that lets you append to such multi-valued attributes, in keeping with the shell's promise of allowing most operations using one-liners.. something like Set-ContentFilterConfig -BypassedSenderDomains +domainthree.com,domainfour.com to add values to the attribute, and some other combination to remove a particular value.

Update:
To remove a value from a multivalued attribute, for example from the BypassedSenderDomains property of the ContentFilterConfig used in the preceding example:

$foo=Get-ContentFilterConfig
$foo.BypassedSenderDomains -="somedomain.com"
$foo | Set-ContentFilterConfig

Labels: , , ,

Tuesday, February 13, 2007

I've blogged about OPATH filters before [read previous post "Adventures with OPATH: some annoyances if you're used to LDAP"], and one of the annoyances was the the fact that it wasn't possible to use the memberOf attribute to pick up (or exclude) members of certain groups from all the stuff that uses OPATH filters such as EmailAddressPolicies, Address Lists, and Dynamic Distribution Groups.

Evan Dodds has some good news today - it seems this did get included in RTM!

Things to know before you start using memberOf attribute in filters
Before you set out to use it in your OPATH filters, consider the following:

1 It's generally not advisable to use the memberOf attribute to filter stuff, because it's a back-linked attribute. (Nevertheless, in many situations, the use of this attribute to filter recipients is inevitable). Using back-linked attributes is not very efficient from an AD perspective, and thus best avoided if possible. So what are back-linked attributes? If you answered "an attribute that's not a forward-linked attribute" you wouldn't be too off the mark :)

Jokes aside, back-linked attributes like memberOf only get generated when they are accessed. In other words, they are not stored in the AD object you're accessing. For instance, the memberOf attribute of a user/contact/group is generated from the member attribute of groups. Does the low-performance part make more sense now?

2 Unlike LDAP filters, the actual attribute name - memberOf is not used in OPATH filters. The filterable property name for OPATH filters is MemberOfGroup.

3 Like LDAP filters, you need to specify the distinguishedName of the group you want to use. For example:

"MemberOfGroup -eq 'CN=Sales,OU=Distribution Groups,DC=e12labs, DC=com'"

Evan just blogged about this - read more about it on his blog, including his example that shows you how to get the distinguishedName of a group in a variable, and uses the variable in the recipient filter.

This is great news, and a big help for folks who need to use group memberships in a recipient filter.

Labels: , , , ,

Friday, February 09, 2007

 

Empower Your PowerShell with PowerGadgets

Posted by Bharat Suneja at 8:46 AM
Exchange MVP Andy Webb showed off this great tool called PowerGadgets recently that can help you build cool gadgets - with or without Windows Vista. The gadgets take piped output from PowerShell commandlets and scripts (as well as SQL databases and web services).

Why I think this is so cool:
- it allows you to visualize data output by PowerShell commands and scripts. The samples shown here are simply displays, but you can create pretty fancy stuff like gauges and charts
- comparatively, it makes PerfMon - which is a useful tool, but so NT 4.0-ish - look like.. well, NT 4.0-ish :)
- critical or important data can be displayed in real-time or close-to-real-time on your desktop or Windows Vista sidebar
Gadget - Content & Recipient Filter
Andy created a gadget that takes the output from the get-antispamtoprblproviders.ps1 script [read previous post about this script - "Exchange Server 2007: How are RBLs performing?"]. The gadget runs the script and shows you number of messages blocked by the RBL provider Spamhaus.org (if you're using it with Exchange Server 2007's IP Blocklist Providers feature).

Yet another one of Andy's gadgets shows the Top 20 mailboxes by size. Very cool!

Thanks to input from Andy, and Vivek Sharma, I was able to effortlessly create a gadget that shows messages scanned by Exchange Server 2007's Content Filter agent.

I created another one that shows you number of messages dropped by Recipient Filter using Recipient Validation (drop messages for recipients that do not exist in AD).

Both the above gadgets use real-time output from perfmon counters captured by shell commands and refresh every minute.

You can create gadgets natively from within PowerShell, or use the PowerGadgets Creator GUI that walks you through creating one. Download PowerGadgets from www.powergadgets.com.

Here are the gadgets:
1. Andy's Spamhaus gadget
2. Andy's Top 20 Mailboxes gadget
3. Content Filter gadget - shows total messages scanned by Content Filter agent
4. Recipient Filter gadget - shows messages dropped because of invalid recipients

Update:
Right-click on the above links and save as/download.


If you've created a gadget using PowerShell, spread the word by adding a comment to this post.

Labels: , , , ,

Wednesday, February 07, 2007

You've setup Exchange Server 2007, and configured the shiny new Content Filter agent (CFA), which is more than just a rewrite of the equally loved and hated Intelligent Message Filter (IMF) from Exchange Server 2003. The CFA has three thresholds - equivalent of Gateway thresholds and (gateway) actions in IMF. These are: 1) SCLDeleteThreshold 2) SCLRejectThreshold and 3) SCLQuarantineThreshold.

1. SCLDeleteThreshold: Messages with SCL equal to or higher than the SCLDeleteThreshold are deleted silently. To enable the SCLDeleteThreshold:

set-ContentFilterConfig -SCLDeleteThreshold 8 -SCLDeleteEnabled:$true

2. SCLRejectThreshold: Messages with SCL equal to or higher than the SCLRejectThreshold are rejected during the SMTP session, after the data is received. In this case, senders get a NDR. To enable the SCLRejectThreshold:

set-ContentFilterConfig -SCLRejectThreshold 7 -SCLRejectEnabled:$true

In the above case, Exchange doesn't accept the message. After the data is received, it responds with a 500 5.7.1 error and a rejection response (by default this response is: Message rejected due to content restrictions. This rejection message can be configured using the following command (response message used here is for illustration, not a real suggestion - Bharat) :

set-ContentFilterConfig -RejectionResponse "Stop spamming you *****!"

The actual NDR is generated and sent to the sender by the sending host. What the sending host will see after the message content is sent (and if you actually modified the rejection response based on my example :)
500 5.7.1 Stop spamming you *****!

Screenshot: Configuring SCL thresholds in Content Filtering properties
Figure 1: Exchange Server 2007's Content Filtering agent can be configured with the equivalent of all 3 Gateway actions available in Exchange Server 2003's Intelligent Message Filter (IMF): 1) Delete messages 2) Reject messages and 4) Quarantine messages

3. SCLQuarantineThreshold: Messages with SCL equal to or higher than the SCLQuarantineThreshold are delivered to the quarantine mailbox, provided you have one configured. To enable the SCLQuarantineThreshold and configure a quarantine mailbox:

set-ContentFilterConfig -SCLQuarantineThreshold 6 -SCLQuarantineEnabled:$true -QuarantineMailbox:MyQuarantineMailbox@mydomain.com

This is an improvement over IMF, which had only one gateway action (and one corresponding gateway threshold). The Content Filter agent allows the flexibility of enabling all three actions on the gateway - the rule is: SCLDeleteThreshold > SCLRejectThreshold > SCLQuarantineThreshold.

To get a list of all three SCL values and whether each action is enabled or not, use the following command:

get-ContentFilterConfig | Select SCL*

So where's the equivalent of IMF's Store threshold? (to move messages to users' Junk Mail folders)?

It's called SCLJunkThreshold, and it resides in a different location - in the Organization configuration. It can be set using the set-OrganizationConfig command:

set-OrganizationConfig -SCLJunkThreshold 5

Setting SCLJunkThreshold not intuitive?

Before you jump to conclusions about this being counter-intuitive, or confusing - which it may be, consider this - it is in response to the different server roles in Exchange Server 2007.

The gateway actions - delete, reject and quarantine - can be thought of as message transport actions, and thus applicable to transport server roles (the Edge server, or the Hub if you have antispam agents enabled on it). Moving messages to users' Junk Mail folders can be thought of as something that happens at the Store, performed by the Mailbox Server role.

Another aspect to consider when setting the SCLJunkThreshold - if you're in a topology with an Edge server, the SCLJunkThreshold on the Edge doesn't impact anything. This needs to be set on your Exchange Org - the Edge server is not a part of it.

The Defaults: By default, the SCLJunkThreshold is set to 4. If you have an existing Exchange Server 2003 SP2 server installed, and you haven't tweaked the Store threshold, IMF v2's default Store threshold of 8 is used - this is what you'll see in the Org's SCLJunkThreshold. Given that the SCLRejectThreshold is set to 7 by default, messages will not move to users' Junk Mail folder unless the SCLJunkThreshold is lower than the transport thresholds (i.e. the Delete, Reject and Quarantine thresholds).

How the Junk Mail threshold is calculated: Unlike the transport actions of deleting, rejecting, and quarantining messages - which check for SCL equal to or higher than their respective thresholds, for moving messages to Junk Mail folder the Store checks for SCLs higher than the SCLJunkThreshold. This is consistent with the behavior of IMF in Exchange Server 2003 (read previous post: IMF Confusion - Store threshold rating text in UI).

If you want to disable rejection of messages with SCL of 7 or above, use the following command:

set-ContentFilterConfig -SCLRejectEnabled:$false



Related Posts:
- Exchange Server 2007: Managing And Filtering Anti-Spam Agent Logs
- Moving items to Junk Mail folder doesn't do much

Labels: , , ,

Wednesday, January 31, 2007

To make the SenderID filter work with non-Exchange smtp hosts acting as your mail gateways for inbound mail, you need to tell Exchange about them. If Exchange does not know about these, SenderID will not be able to determine the correct sending host, and you may see SenderID checks fail on all inbound mail.

This may have been a source of confusion for users in the past - which hosts do you consider as "internal" - the ones on your internal network? or only those located in perimeter networks (aka "DMZ")? how about those located at your ISP?

Exchange needs to know about all smtp hosts that do not belong to senders - the ones that will handle your inbound mail, whether at your ISP or in your perimeter or internal networks, before messages are delivered to the Exchange Org. (Start by taking a look at MX records in external DNS zones - do these point to non-Exchange servers? If yes, do these hosts route mail to Exchange servers?).

In Exchange Server 2003 this is done by entering internal smtp server addresses in Global Settings | Message Delivery properties | General tab | Perimeter IP List and internal IP Range Configuration.

Screenshot: Adding internal SMTP servers to Exchange Server 2003's Perimeter IP List
Figure 1: Setting up internal or perimeter SMTP hosts in Exchange Server 2003's PerimeterIPList

On Exchange Server 2007, you can configure this from the shell:

set-transportconfig -InternalSMTPServers 1.2.3.4,1.2.3.5,1.2.3.6

Updates:
8/16/2007: SP1 Beta2 allows setting InternalSMTPServers parameter using the Exchange console, as shown below:

Screenshot: SP1 Beta2 - Setting InternalSMTPServers using the Exchange console
Figure 2: Setting up InternalSMTPServers using the Exchange console in Exchange Server 2007's new Global Settings tab | Transport Settings | properties | Message Delivery tab

Labels: , , ,

Tuesday, January 30, 2007

Messaging Hygiene features in Exchange Server 2003, including the Intelligent Message Filter (IMF), did not have a way to whitelist sending domains or SMTP addresses.

This is a follow up to a previous post, and one of the more popular ones on this blog— "IMF: Where's the whitelist?". ("IMF and whitelist" has for long been one of the most common search terms on this blog - Bharat).

Whitelists are common in most 3rd-party anti-spam tools. Adding domains or SMTP addresses of important senders like customers, vendors, or your CEO's home email address (almost always an AOL address... :) for instance, ensures messages from these domains or addresses do not get filtered by the anti-spam filter.

Bypassed Senders and Sender Domains: The Whitelist
The good news is— Exchange Server 2007's shiny new Content Filter Agent (or IMF v3 if you will) has whitelists! You can add SMTP addresses and domains to the Content Filter configuration, and have messages from these senders and domains bypass the Content Filter Agent. However, you need to resort to the Exchange shell (EMS) to manage it.

Use the following shell command to add sender SMTP addresses to the BypassedSenders list:

Set-ContentFilterConfig -BypassedSenders foo@somedomain.com,foo2@somedomain.com

Use the following command to whitelist the sending domain:

Set-ContentFilterConfig -BypassedSenderDomains somedomain.com,someotherdomain.com

Some whitelisting considerations
Before you start using whitelists, here are a few things you should consider:

  • SMTP headers can be spoofed easily. If spammers spoof any of the addresses or domains you whitelist, your recipients may end up getting more spam as all of it will bypass the Content Filter.
  • Use SenderID Filtering to detect and protect your mail system from header spoofing.
  • Maintaining whitelists, just as maintaining blacklists, is a manual process that imposes its own management costs.
  • Checking every inbound message against a list of whitelisted recipients imposes a performance penalty - miniscule as it may be. Use the whitelists sparingly.

Nevertheless, many IMF users have repeatedly demanded this functionality and it's great to finally have it in what some folks call IMF v3.0.

Bypassed Recipients: The Exception List
The Content Filter can also be configured with an exception list - to not apply the filter to inbound messages for particular recipients. This can be done from the console by going to Hub Transport | Anti-spam tab | Content Filtering -> properties | Exceptions. This list is limited to a 100 recipients - you can add generic recipients that you want to exempt from the Content Filter, such as sales@yourdomain.com, info@yourdomain.com, etc.

To add recipients to the exception list using the Exchange shell:

Set-ContentFilterConfig -BypassedRecipients sales@yourdomain.com,info@yourdomain.com

Related Posts:

Labels: , , , ,

Monday, January 29, 2007

If you’ve deployed or have been testing Exchange Server 2007, you must have certainly crossed paths with OPATH. OPATH is a querying language, somewhat similar to SQL. It is used to filter objects in PowerShell. OPATH filters replace the LDAP filters for EmailAddressPolicies (equivalent of Recipient Policies), Address Lists/GAL, and Dynamic Distribution Groups (aka “Query-Based Distribution Groups”) in Exchange Server 2007.

There are some good posts about OPATH on the team blog, including the introductory post OPATH recipient filtering for Exchange Server 2007 by Evan Dodds. (Evan has more on his blog).

If you achieved some degree of expertise, or familiarity, with LDAP filters in Exchange Server 2003/2000 and Active Directory, it’s going to be difficult to fall in love with OPATH. It is meant to make things easier for administrators, and it certainly will for many. However, it still feels like a version 1.0 product that has its limitations.

I will mention a scenario here that illustrates this limitation. It is very common for Exchange 2003/2000 users to use group membership as a basis to apply Recipient Policies, or filter Address Lists/GAL. Some admins also use group memberships to create consolidated Query-based Distribution Groups. OPATH filters cannot use the memberOf attribute, so group membership cannot be used in any filters!

In fact, OPATH filters do not expose all recipient attributes that can be used in LDAP filters, making the transition from LDAP filters in previous versions to OPATH not as straightforward as one would have liked.

There are other inconsistencies as well. For instance, though Exchange shell commands will understand which Store you’re referring to by using the syntax ServerName\Storage Group Name\Store Name(or simply Store Name if it’s a unique Store, or Storage Group Name\Store Name if it’s a unique Storage Group name), OPATH filters will not. They still require the distinguishedName of the Store.

In this scenario, a user’s trying to apply Journaling to a particular Store, but the requirement is to locate the journaling mailbox on the same Store, and exclude that mailbox from journaling. The good news – Exchange Server 2007 has enhanced journaling that will let you meet such requirements. You can journal based on group memberships. The solution seems to be an easy one: create a Dynamic Distribution Group that picks up all mailboxes on that Store, except the journaling mailbox.

Using LDAP filters, this would look like:

(&(objectClass=user)(mailNickname=*)(homeMDB=distinguishedName of Store)(!name=JournalMailbox))

– where JournalMailbox is the name of the journaling mailbox. The filter picks up all users that have their homeMDB – the distinguishedName of a mailbox Store – pointing to a particular mailbox Store, and exclude the user called JournalMailbox.

Using a PowerShell command with an OPATH filter to create this Dynamic Distribution Group:

New-DynamicDistributionGroup “Group Name” –organizationalUnit “ou=Distribution Groups, DC=E12Labs, DC=com” -RecipientContainer "dc=e12labs,dc=com" –RecipientFilter {(RecipientType –eq ‘UserMailbox’ –and database –eq “CN=Mailbox Database, CN=First Storage Group, CN=InformationStore, CN=E12Postcard, CN=Servers, CN=Exchange Administrative Group (FYDIBOHF23SPDLT), CN=Administrative Groups, CN=E12Labs, DC=com” –and –not name –like “JournalMailbox”)}

For a while, I kept feeding the identity of the mailbox database – “E12POSTCARD\First Storage Group\Mailbox Database” – but couldn’t get any combination thereof to work. This format is commonly used in Exchange shell commands, e.g. to list all mailboxes on that mailbox Store:

Get-MailboxDatabase “E12Postcard\First Storage Group\Mailbox Database” | get-mailbox

What I liked about using OPATH filters in the shell: it automatically modifies your filter to exclude System Mailbox and CAS_ mailbox.

Next, how do you preview which users are being picked up by this filter? Exchange Server 2003/2000, and AD Users & Computers (in Windows Server 2003) let you preview which recipients are picked up when you create a LDAP filter. There’s no equivalent of the preview feature in Exchange shell. Not a problem, let’s head over to the Exchange console to preview, you say.

In the console | Dynamic Distribution Group properties | Filter tab shows you the filter used, and the fact that it was a custom filter created using PowerShell. No Preview button here. On the Conditions tab – which is used to select from the ”precanned” filter conditions, the Preview button is grayed out – possibly because this is a custom filter.



What are the ways to test whether the group picks up the right users/mailboxes, and more importantly in this case – since we’re going to use this group to apply enhanced journaling, whether it excludes the JournalMailbox?

Perhaps using the Saved Queries feature in AD Users & Computers console would be a good idea! Dynamic Distribution Groups save the filter in two attributes – 1) msExchQueryFilter attribute holds the OPATH filter that you may have entered in the shell when creating the group, and 2) msExchDynamicDLFilter attribute holds the LDAP filter. The shell converts your OPATH filter to the familiar LDAP filter syntax that we’re used to and stores it in this attribute. Previewing the group is now as simple as copying the group’s msExchDynamicDLFilter attribute, and pasting it into Saved Queries in ADUC, you think.

However, this may not work in some conditions. Here’s the particular one that I came across. Exchange Server 2007 does create one Administrative Group called Administrative Group (FYDIBOHF23SPDLT). (In case you're wondering, the latter string in the brackets can be decoded to Exchange12Rocks - read "The Secret Decoder Ring - The Hidden Truth in the Exchange 2007 Admin and Routing Group Names" on the team blog for more details ). All Exchange Server 2007 servers reside in this single Administrative Group.

When converting the filter, the shell actually changed the brackets ( and ) to what look like their ASCII codes - \28 and \29, so it looks like Exchange Administrative Group \28FYDIBOHF23SPDLT\29. It took me a little while to figure this out, and make the necessary change in Saved Queries. Once this was done, I could preview the recipients picked up by the Dynamic Distribution Group.

That’s a good workaround, albeit a little painful one if you weren’t aware of some of these quirks. Making the Preview feature in Exchange console work with custom queries would have made things a lot easier, and that’s on my wishlist for SP1. Additionally, a shell equivalent (of Preview) will be quite welcome since custom queries can only be used from the shell.

Another value-add would be ability to use LDAP filters and have the shell convert these to OPATH filters, just as it does the OPATH to LDAP filter conversion. This would make things a lot easier for folks used to or familiar with LDAP filters.

Meanwhile, it would be great to have these quirks and workarounds documented. Something like a Guide to OPATH Filters if you're used to LDAP.

Update 5/30/2007: After the post was published, I found the ability to view Dynamic Distribution Group "membership" - or rather the recipients returned by its query, using the shell was included in the product documentation - "How to View Members of a Dynamic Distribution Group".

Labels: , , , ,

Tuesday, January 09, 2007

From a recent discussion, and something I've been wanting to post about for a while: SMTP tarpitting is enabled by default on ReceiveConnectors in Exchange Server 2007.

What is tarpitting? It's the process of introducing a delay in SMTP connections from hosts that are suspected of inappropriate SMTP behavior - for instance, by sending messages to non-existent addresses in your domain. (Tarpit is a noun, I use tarpitting as a verb to describe the process. The word probably can't be found in a dictionary, but perhaps appropriate usage to describe the process, just like telnetting, and emailing - Bharat)

If you've used Recipient Filtering on Exchange Server 2003 and selected the option to drop messages for recipients that do not exist in AD, it's a best practice to use SMTP tarpitting to get some level of protection from directory harvesting attacks. Directory harvesting is typically used by spammers to send email to addresses in your domain - which may or may not exist in your directory - to figure out which addresses are valid and which ones are not.

With the option in Recipient Filtering enabled, the SMTP virtual server will respond with a 550 error (550 5.1.1 User unknown) when it comes across an email address in the message's RCPT TO command - before the message body is transmitted. With tarpitting enabled, this response is delayed a few seconds, configurable using a registry setting (in Exchange Server 2003 on Windows Server 2003 SP1 - it is a Windows Server 2003 feature), as described in Microsoft KBA 842851. Most spammers will drop the connection if there's such a delay - it is more expensive for spammers to continue spamming/harvesting with such delays in place.

Does this sound too good to be true? What's the down side? Or are there any? On servers with high volume of SMTP traffic, you may notice more open connections, and open connections consume resources. The trick is to make sure this delay is not too high, resulting in more open connections for much longer, but high enough to make the sending hosts displaying suspicious behavior to drop connections.

Having said that, I've not come across many cases of performance degradation that could specifically be attributed to tarpitting delays, but you'll need to test this in your environment to figure out what works best.

Also note, authenticated connections are not subjected to tarpitting delays. Additionally, tarpitting only makes sense on ReceiveConnectors exposed to internet hosts.

Exchange Server 2007's ReceiveConnectors are configured with a tarpit interval of 5 seconds by default. A good way to observe this behavior is by telnetting to the SMTP port of an Exchange Server 2007 server and first sending a message to a valid recipient, and then trying to send a message to a recipient that does not exist.

To check the SMTP tarpit interval on your ReceiveConnectors, use the following shell command:

get-ReceiveConnector | select name,tarpitinterval

You can set it to a higher value - I have mine set to 10 seconds - using set-ReceiveConnector:

set-ReceiveConnector "Receive Connector Name" -tarpitinterval 00:00:10

The value is in hours:minutes:seconds.

At the time of writing, the documentation for set-ReceiveConnector command says this can be set in days as well (number of days and number of hours separated by a dot), but further it also states the maximum value for tarpitinterval is 10 minutes (00:10:00) - which is confirmed by the shell when you try to set it to a value higher than 10 minutes. (Nevertheless, technically speaking the documentation isn't wrong - you can in fact set it in days - e.g. 00.00:09:00 - as long as the value of days is zero! :) I'm told the doc will soon be changed/corrected).

To disable the tarpit behavior, set the value to 00:00:00.

Labels: , , , , ,

Wednesday, January 03, 2007

 

Exchange Server 2007: How To Allow Relaying

Posted by Bharat Suneja at 9:15 PM
In Exchange Server 2003, unauthenticated hosts can be allowed to relay by adding their IP address(es) in SMTP Virtual Server properties | Access tab | Relay. This is commonly done for application servers, and devices that need to send mail - like copiers that can scan documents and send by email.

Screenshot: Allowing relaying on Exchange Server 2003 SMTP Virtual Server
Figure 1: Controlling relay restrictions in Exchange Server 2003

In Exchange Server 2007, SMTP Virtual Servers have been replaced by Receive Connectors, and the SMTP stack is now native to Exchange (unlike Exchange Server 2003, you no longer need to install IIS' SMTP service/stack). Understandably, the way you allow relaying has changed as well.

Do you really need to allow relaying?
Before you setup unauthenticated relaying, it's important to understand the need for relaying. If your application server or devices like copiers need to send mail only to internal recipients - mail for which Exchange has an AcceptedDomain (or a Recipient Policy in Exchange Server 2003/2000) and therefore will receive inbound mail for - it is not considered relaying. The application server or device should be able to do this without any configuration on Exchange.

Recipient Policies and Exchange Server 2007

Exchange Server 2003 Recipient Policies tell Exchange which domains to receive inbound email for, and to generate email addresses. Exchange Server 2007 splits this functionality into AcceptedDomain - which, as the name suggests, tells Exchange which domain(s) to accept inbound email for - and EmailAddressPolicy which actually generates the email addresses. Unlike Exchange Server 2003/2000, there's no RUS to watch AD for new recipients or changes to existing ones. Recipients are provisioned in Exchange - using the console or the shell - and EmailAddressPolicy applied in real-time.

Just like previous versions, Exchange Server 2007 allows authenticated relaying by default. So if your application server or device can authenticate, that's the way to go.

The best way to allow unauthenticated relaying, or certainly the more secure and recommended one, is to create a new Receive Connector. I recommended this approach even on Exchange Server 2003/2000 - it's not a good idea to use your internet-exposed SMTP virtual server to allow unauthenticated relaying, even if restricted by IP addresses.

Scott Landry wrote about this recently on the Exchange team blog in "Allowing application servers to relay off Exchange Server 2007".

To create a new Receive Connector, you need another IP address on your Exchange server. (The other alternative is to create a new Receive Connector that listens on a different port instead of the default SMTP port (TCP port 25). Most app servers and devices don't like this, and many won't let you configure an alternate port for sending smtp mail. I would simply add another IP address to the server. As a sidenote, Exchange Server 2007's Receive Connectors also consider the RemoteIPRanges in addition to the IP address + port combination for binding. More about that in a future post.).

The easy way: With the new IP address added to the Exchange server - let's say it is 192.168.1.17, and your app server, device or copier that needs to relay is 192.168.1.100, fire up Exchange shell and use the following command:

New-ReceiveConnector -Name RelayConnector -usage Custom -Bindings '192.168.1.17:25' -fqdn server.domain.com -RemoteIPRanges 192.168.1.100 -server MYEXCHANGESERVER -permissiongroups ExchangeServers -AuthMechanism 'TLS, ExternalAuthoritative'

What this does - creates a new Receive Connector called RelayConnector for usage type: custom, binds it on port 25 on IP address 192.168.1.17, gives it the fqdn of server.domain.com, and allows the IP address 192.168.1.100 to connect to it. Additionally - and most importantly, it also assigns ExchangeServers permission group to it, and disables authentication - or rather, it assumes you completely trust the IP address 192.168.1.100 and have another means of authenticating it, such as IPSec.

This also bypasses all security for messages received from that IP address - doesn't apply any anti-spam filters, nor cares about message size limits, resolves P2 headers, and allows sending on behalf of users. Going back to Exchange Server 2003, this is somewhat similar to adding the sending host's address to Connection Filtering's Global Accept list.

A better, more secure way: If you want it to be more secure, you can create a Receive Connector with PermissionGroups set to AnonymousUsers:

New-ReceiveConnector -Name RelayConnector -usage Custom -Bindings '192.168.1.17:25' -fqdn server.domain.com -RemoteIPRanges 192.168.1.100 -server MYEXCHANGESERVER -permissiongroups AnonymousUsers

Notice, we've left out the AuthMechanism parameter in the above command.

Next, allow anonymous users to relay. This is done by allowing anonymous users the extended right ms-Exch-SMTP-Accept-Any-Recipient for this Connector:

Get-ReceiveConnector RelayConnector | Add-ADPermission -User "NT AUTHORITY\ANONYMOUS LOGON" -ExtendedRights "ms-Exch-SMTP-Accept-Any-Recipient"

For more information about transport permissions, refer to "Exchange Server 2007 Transport Permissions Model" in Exchange Server 2007 documentation. Granular permissions can be assigned to security principals on Receive (and Send) Connectors. For instance, if you want to have these messages bypass the anti-spam filters, you can also assign the ms-Exch-Bypass-Anti-Spam permission.

What's the difference? The difference between the 2 approaches can be seen when you send test messages, as shown in the following screenshot:

Screenshot: Messages from both Connectors shown in Microsoft Outlook
Figure 2:The difference between the 2 approaches can be seen in how messages are displayed in email clients

The first message at 9:22 AM is sent by the first Connector, where the message received without authentication actually shows up as sent by me - the P2 headers are resolved. (More about resolving anonymous senders in previous post: " A Late New Year's Resolution: Do Not Resolve Anonymous Senders"). Whereas the second message at 9:34 AM actually shows up with the sender's SMTP address.

The second message also went through the anti-spam filters - a quick check of the message headers reveals the antispam headers.

Screenshot: Message headers showing antispam headers
Figure 3: Messages received using the second method do not bypass anti-spam filters by default

Labels: , , ,

 

HOW TO: Add a License Key to Exchange Server 2007

Posted by Bharat Suneja at 11:52 AM
When you install Exchange Server 2007, including the evals posted on Microsoft's web site, it is unlicensed. Unlicensed servers function as 120-day trials, according to Exchange Server 2007 documentation.

When you start the Exchange console, you get a list of all unlicensed servers and the number of days left for the trial to expire.


Unlike previous versions of Exchange, the trial versions can be upgraded to fully functional versions by simply adding a product key. This can be done easily from the console by right-clicking the server in Server Configuration, and selecting Enter Product Key [screenshot].

From the Exchange shell, you can enter the product key using the set-ExchangeServer commandlet:

set-ExchangeServer SERVERNAME -ProductKey aaaaa-aaaaa-aaaaa-aaaaa-aaaaa


To get a list of all Exchange Server 2007 servers and their product keys and trial status, including number of days left:

get-ExchangeServer | select name,ProductID,*trial*

(Note: I typically format this as a list rather than a default table, particularly for a smaller number of objects - the table tends to chop off bits of a field when you have too many fields displayed:
get-ExchangeServer | select name,ProductID,*trial* | fl)

The output looks something like this:

Name: E12EDGE
ProductID:
IsExchange2007TrialEdition: True
IsExpiredExchange2007TrialEdition: False
RemainingTrialPeriod: 29.19.12.55.8950288

Yes, the timing displayed is very precise, down to the seconds and milliseconds :) - but you can probably tell it's 29 days.

Labels: , ,

Tuesday, December 26, 2006

 

Exchange Server 2007 Scriptacular Demo Pack posted

Posted by Bharat Suneja at 4:54 PM
Vivek has posted what he calls the Exchange Server 2007 Scriptacular Demo Pack on his blog. This is a bunch of scripts Vivek & Mihai wrote while Exchange shell was being developed. It contains the out-html, out-ie and out-email scripts from Vivek's blog that I've talked about earlier, and some that I haven't seen before.

Download it from Vivek's blog [ Announcing the Exchange 2007 PowerShell Scriptacular demo pack!].

Labels: ,

Wednesday, December 20, 2006

Exchange Server 2007 includes the much-required feature that allows you search for and export messages to another mailbox. You can search all mailboxes for messages with particular keywords and export those messages to a separate mailbox, which can then be accessed by compliance/legal folks who need access to such messages.

Another scenario where this feature comes in handy: being able to delete infected messages across all mailboxes.

The Export-Mailbox command exports messages with user-specified keywords in the message subject or body to a specified folder in a mailbox. Kumar Cunchala from the product team talks about how to do cross-mailbox searches on the team blog.

Before you ask, there's no support for exporting these messages to a PST file yet (Update: This was added in Exchange 2007 SP1). You could, of course, connect to the mailbox to which you export these messages and manually copy stuff to a PST using Outlook.

Labels: , , ,

Sunday, December 17, 2006

 

Conflicting Mailbox Store Policies

Posted by Bharat Suneja at 10:19 PM
I spent some time (ok, I'll admit - more than "some time"... ) writing a script to get user mailbox storage limits/quotas [an improvement on the script I posted earlier - read previous post "SCRIPT: Show mailbox limits"]. The new script checks users' individual mailbox limits (if these are set in user properties in ADUC). If no individual limits exist, it checks the limits on user's mailbox Store, and also checks if any System Policies apply mailbox storage limits to the Store. If any policies are found, it checks the limits on those as well, and reports on what the user's actual limits are. Something like the Resultant Set of Policies feature/snap-in for Group Policies, for user's mailbox storage quotas.

Out of curiosity (and in an attempt to see if the script breaks), I tried to apply multiple Mailbox Store policies that apply storage limits to the same Store. Almost certain that Exchange System Manager will do no validation if an existing Mailbox Policy is already applied, I was pleasantly surprised to find that it in fact does validate!

When trying to apply a second Mailbox Store policy (with storage limits) to a Mailbox Store that already has such a policy applied, ESM throws up the following error:


At this point, the easy choice is to click on the "Yes" button, but I was still hoping if I selected No the second conflicting policy may be applied :)

No such luck - ESM curtly informs you that the second policy could not be applied "... because you refused to remove the object from the control of conflicting policies."



I can't help but think about all the thought that goes into creating such software - though we all have our own pet peeves and can count the things we don't like about Exchange, for a change it's great to be able to appreciate the things you do like about it. Having worked on a couple of cool software features in Zenprise (stuff I'd love to talk and blog about soon!), I have a new-found appreciation for such thoughtfulness and attention to detail.

This certainly helps me avoid writing another few hundred lines of code to figure out if multiple System Policies for mailbox quotas are applied to a Store, which one has priority and how to make the script figure that out.

As a sidenote, writing a script using VBScript to accomplish something in an Exchange Server 2003/2000 environment seems like a real pain now - given what I accomplished in about 300 lines of code tonight is so easily accomplished using a one-liner in Exchange (2007) shell, and something I do several times a day! (At times just because it's so easy to do, without writing any code! :)

The Exchange shell equivalents:
Get-mailbox | select name,database,*quota*
and
Get-MailboxStatics

Labels: , ,

Thursday, December 14, 2006

I’d written about how to bulk create mailboxes (including user accounts) from a CSV file [read previous post: Exchange Server 2007: Bulk creation of mailboxes using Exchange Management Shell]. This is in response to the reader who posted a comment asking for a way to mailbox-enable existing user accounts.

Bulk mailbox-enabling users using the Exchange console

In Exchange Server 2007 SP1, the Exchange console (EMC) allows you to create mailboxes for existing users. When selecting an existing user in the New Mailbox wizard, you can select multiple users by using the regular SHIFT-Click (to select a continuous list of users) and CTRL-click (to pick the users you want).

First we need to find the users without mailboxes. The get-user command will list all users. The RecipientType property of the user is either User or UserMailbox. As the name clearly suggests, those with UserMailbox as RecipientType are already mailbox-enabled – leaving those with RecipientType User.

You can enable all users with RecipientType User:

get-user | where-object{$_.RecipientType –eq “User”}

Yes, that may not be a great idea! So let’s filter these users. If these users reside in a particular Organizational Unit, we can restrict our search to that OU. In this case, we’ll look for users in the OU called “People”:

get-user –organizationalUnit people | where-object{$_.RecipientType –eq “User”}

Now we get a list of all users (who are not mailbox-enabled) from that OU. We can further restrict this list to all users who are members of a particular department. Since Sales is our favorite department, let’s pick Sales:

get-user –organizationalUnit people | where-object{$_.RecipientType –eq “User” -and $_.department –eq “Sales”}

Now we’ve got a smaller list of folks – those residing in the People OU belonging to Sales dept. and aren’t mailbox-enabled yet. Let’s go ahead and mailbox-enable these users:

get-user –organizationalUnit people | where-object {$_.RecipientType –eq “User” -and $_.department –eq “Sales”} | Enable-Mailbox –Database “EXCHANGE1\Mailbox Database” | get-mailbox | select name,windowsemailaddress,database

The above command mailbox-enables these users and outputs a list of their names, default email address, and the mailbox Store on which their mailbox(es) reside.

Similarly, you can also use other user attributes of user accounts like city, state, country, etc. to selectively mailbox-enable users.

The WOW! factor and what really makes it a fun process is the fact that once you get a hang of the syntax and know what you're looking for, the entire process happens really quickly.

PowerShell / Exchange shell does to VBS scripts what scripting did to repetitive GUI tasks.

Labels: , ,

Tuesday, November 28, 2006

Exchange Server and many other MTAs including most web-based services send the sender's display name (e.g. "Joe User") in email messages, in addition to the smtp (email) address. If you want to prevent sending display names in outbound internet mail for any reason, you can turn this off.

Exchange Server 2003/2000 (Exchange System Manager):
- Global Settings | Internet Message Formats | Default -> properties | Advanced tab | uncheck "Preserve Sender's Display Name on messages" [screenshot]

In Exchange Server 2007, Internet Message Formats are replaced by Remote Domains. You can achieve similar result either by using the Exchange Management Console or the Exchange shell:

1) Using Exchange Management Console:
- Organization Configuration | Hub Transport | Remote Domains tab | Default -> Properties | Message Format tab | uncheck "Display senders name on messages" [screenshot]

2) Using the shell:

set-RemoteDomain * -DisplaySenderName:$false

Labels: , , ,

Tuesday, November 14, 2006

An update to the earlier post on HOW TO: Find an email address in Active Directory (Note: Content from this post has been merged with the previous post, simply click on this link to see the roll-up post on finding email addresses), which shows how to find a recipient with a particular email address using ADUC's Saved Queries feature.


4 Using CSVDE/LDIFDE to find an email address: Saved Queries isn't available in the Windows 2000 version of ADUC. You can also use CSVDE or LDIFDE to export this information to a file, using the following command:

csvde -f outputfilename.csv -d "dc=domain,dc=com" -r "(&(mailnickname=*)(proxyAddresses=smtp:foo@domain.com))" -l name

Replace "dc=domain,dc=com" with your AD domain name and suffix, and foo@domain.com with the exact email address you're looking for.

To find all recipients who have an email address from a particular SMTP domain, you can use a wildcard, e.g.:

csvde -f outputfilename.csv -d "dc=domain,dc=com" -r "(&(mailnickname=*)(proxyAddresses=smtp:*@domain.com))" -l name

In the above example, only the name field is exported. All CSVDE/LDIFDE queries also return the object's distinguishedName. To add more fields to the list, insert a coma after name and type new field names separated by a coma: e.g.

name,displayName,sAMAccountName,proxyAddresses,homeMDB


5 Finding email addresses using the Exchange shell (Exchange Server 2007): The Exchange Server 2007 shell makes it easier (once you familiarize yourself with shell basics). To get a list of all recipients with email addresses from a particular domain:

get-recipient | where {$_.emailaddresses -match "domain.com"} | select name,emailaddresses

To get a list of recipients with a particular email address:

get-recipient | where {$_.emailaddresses -match "foo@domain.com"} | select name,emailaddresses

Changes:
01/03/2007: Changed title, added Update to differentiate from previous post with same title

12/03/2007: Content from this post merged into the previous post HOW TO: Find an email address in Active Directory.

Labels: , , ,

Wednesday, November 01, 2006

Bulk creation of mailboxes (and the accompanying user accounts) in Exchange Server 2003/2000 involved some elaborate scripting effort. This task can now be done fairly effortlessly, thanks to the Exchange Management Shell (EMS). The shell can very easily import/use CSV files saved from a spreadsheet or text editor and create the mailbox-enabled users. Here's how.

Step 1 Create a spreadsheet (or you can use a standard text editor like Notepad to create a CSV file) with the following columns. You can add more fields if you wish:
Alias,Name,UPN

Add data for new accounts in following lines/rows. Here's what it'll look like:
Alias,Name,UPN
User_One,User One,userone@yourUPNsuffix.com
User_Two,User Two,usertwo@yourUPNsuffix.com
User_Three,User Three,userthree@yourUPNsuffix.com

Save the file as CSV - let's call it CreateRecipients.csv

Step 2 Now fire up Exchange Management Shell and issue the following command:

$Password=Read-Host "Enter Password" -AsSecureString

This will prompt you for a password. The same password will be used as the initial password for all your mailbox-enabled users.

Step 3 Next, issue the following command:

Import-CSV CreateRecipients.csv | foreach {new-mailbox -alias $_.alias -name $_.name -userPrincipalName $_.UPN -database "Mailbox Database" -org Users -Password $Password}

This will create the user accounts and mailboxes.

Here's how the shell interprets the above command:
Import-csv CreateRecipeints.csv gets data from the CSV file.

- The filename should be enclosed in quotes if you're providing the complete path with spaces, e.g. "c:\My Scripts\CreateRecipients.csv".
- If you're not running the command from the same directory (folder) where the CSV file is located, you will need to provide the complete path to the file.

- The | pipes the data from the CSV to the next command.
- foreach parses through each line in your CSV file, using the first row as a header. All the column headings/names get treated as field names.
- The new-mailbox command, as you may already know by now, creates a new mailbox-enabled user.
- For each variable, you either enter a value at the command line (for instance, we're using the value "Mailbox Database" for the Store), or you can pick up the value from your CSV file provided you have a column for it with a heading. For instance, for the -alias field, we use $_.alias - which tells the script to look for the column called alias in your CSV file and pick up the value from the current row or line.

If running the command on the same server where you want to create the mailboxes, you can simply use the Store name, e.g. "Mailbox Store". To create mailboxes on another server's Store(s), you can use either ServerName\Store, or ServerName\StorageGroup\Store, or even the GUID of the Store. How do you get those??? Use the Get-MailboxDatabase commandlet.

- The -org field stands for OU (or Container) you want to create the accounts in. If all the accounts you create from the CSV file will reside in the same container or OU, you can provide this at the command-line, as we did in the example above. Alternatively, you can include the OU/Container name in your spreadsheet/CSV file in a field - let's say OU - and modify your command to say: -org $_.OU
Note: Luckily you do not need to provide the distinguishedName of the OU or Container - simply the name of the OU or Container works.
- The -password field picks up the password from the variable called $password that we created earlier.

The new-mailbox command allows you to enter a lot of attributes for each mailbox-enabled user. These are documented here and also in the Exchange Server 2007 online help. For each attribute you want to populate, add it to your spreadsheet/CSV file.

Updates
July 9, 2007: To create new mailboxes with settings based on an existing mailbox, use the following commands:

$Template = Get-Mailbox "Template Mailbox"
Import-CSV CreateRecipients.csv | foreach {new-mailbox -alias $_.alias -name $_.name -userPrincipalName $_.UPN -database "Mailbox Database" -org Users -Password $Password -templateinstance $Template}

Labels: ,

Wednesday, October 04, 2006

 

HOW TO:Get PowerShell version info

Posted by Bharat Suneja at 4:55 PM
While the command ver could get you the version info on a command prompt, and winver does it in the GUI, if you're stumbling to find the command to get the version number of Windows PowerShell installed on your computer (like I did for a while), it is Get-Host.

Perhaps adding an alias for ver so it works out of the box would've been a good idea folks... ! :)

To add the alias: new-alias ver get-host

Labels:

Tuesday, October 03, 2006