Archive for August, 2011

h1

Windows VPN Client and local DNS resolution

August 25, 2011

Typically when configuring a remote access VPN, the goal is for DNS requests to be resolved by DNS servers on the remote/server side of the VPN connection.

This is either because the connection is from a less trusted network to a more trusted one – i.e. from home to office, and so split tunnels are not allowed. Even if split tunnels are allowed, the local client network is typically less complex and can use broadcast name resolution while the remote network is complex so using it requires DNS.

Since this is the predominant configuration, this is how most VPN clients are configured and many, including the Windows VPN client, do not offer an option to change this configuration.

In some cases, however, it makes sense for DNS resolution to remain local to the client side of the VPN connection. This is useful when the connection is from a more trusted and complex network to a less trusted and complex network. For example, a connection from the office network to a lab network or to a home network, would benefit from keeping DNS resolution on the client side of the connection.

I ran into this problem trying to configure a connection to my lab that would allow me to keep the connection open while working on the office network.

Unfortunately, this isn’t easy to do this with the VPN client that is included in Windows Vista/7 (The VPN client with Windows XP had an issue that resulted in a side effect with this exact configuration). While Windows does allow configuring the binding order to different interfaces using the ‘Advanced Settings’ menu option in the ‘Network Connections’ control panel, changing the binding order for ‘[Remote Access Connections]’ doesn’t seem to have any impact.

The binding order is stored in the registry in the following location: HKLM\System\CurrentControlSet\Services\Tcpip\Linkage\Bind. The list includes all the device GUIDs for network adapters and active connections in the binding priority order.

When working with the registry key, the following facts emerge:

  • Changing the order of the GUIDs in the registry does impact the binding order, including for VPN connections
  • Any changes to the key take effect immediately
  • When a VPN connection is completed, the GUID for the connection is added to the top of the bind order if it does not already exist
  • When a VPN connection is closed, the GUID entry for the connection is removed
  • If there are multiple GUID entries for the connection, only one is removed when the connection is closed

This mechanism creates the possibility of the following workaround:

  1. Examine the Bind registry key
  2. Connect to your VPN connection
  3. Check the Bind key again and copy the GUID that was added to the top of the list
  4. Paste the GUID entry at the bottom of the list 20 times
  5. Export the key and clean up the exported file to only include the bind key

The result is a key that will support the desired behavior. Every time a VPN connection is established, since the GUID is present, it will not be added. Since the GUID is at the bottom, DNS resolution will be done locally to the client. When the connection is disconnected, one GUID entry will be removed. After 20 VPN connections, the exported registry file can be used to reimport the key.

Of course, you can paste the GUID more times to reduce how often you have to reimport the key.

Also important to remember to redo this procedure if there are any changes to network adapters.

h1

Automatic Personal Archive Provisioning

August 23, 2011

Exchange 2010 supports automatic provisioning for new mailboxes. Unfortunately this mechanism does not extend to personal archives. As mailboxes are moved to Exchange 2010, they must be enabled for archives manually with the operator managing the size of each database and dividing the load accordingly.

The script below was created to automate this function and is intended to run automatically using a scheduled task on each CAS server.

Typically archive databases are flagged so that they do not participate in automatic provisioning for new mailboxes. The script selects the smallest archive database from the databases that are excluded from provisioning using the –IsExcludedeFromProvisioning parameter. Users are then enabled for archives using the target database.

The script also assigns one of two custom archive policies – a 180 day policy and a 360 day policy based on a group that defines users that get 360 days of retention in their mailbox. The script uses a custom attribute to overcome the issue of identifying mailboxes that are not members of the 360 day retention group.

Let me explain the issue:

PowerShell scripts often handle the ‘reverse group membership check’ issue by using a script that first assigns the common value (in this case 180 day retention) to everyone and then assigns the special value (in this case 360 day retention) to the members of a group.

The main weakness to this approach, especially for something like a retention policy is that any error with the second part of the script (say if someone renamed the group) would result in everyone getting a more restrictive retention policy and more archived items which is potentially disruptive and difficult to reverse.

My solution is to assign everyone in the org the less restrictive setting using a custom attribute field in AD once. Then adjust that custom attribute value based on the group membership and use the custom attribute value to configure the retention policy. This means that if the group is renamed or another error occurs, new members of the group might get the wrong policy but existing members would not be impacted.

Note that this can be accomplished with less effort if you deploy the Quest PowerGUI tools since the get-QADUser command does support a parameter –NotMemberOf. I didn’t use this since I was trying to create a solution that didn’t require additional software (in other words, come on Microsoft and implement this function!)

 

In addition, the script uses custom attribute 13 to identify a mailbox that shouldn’t use a personal archive. This is intended for service accounts and special purpose mailboxes.

#
#
# NAME: Maintenance.ps1
#
# AUTHOR: Guy Yardeni
#
# COMMENT: Script to run various maintenance tasks for Exchange 2010
#
#        Enable archives for mailboxes
#        Configure archive policy based on AD group
#

# Script to enable archive for any users who don’t already have one
# using the smallest archive database
#         
# Any text in Custom Attribute 13 will cause the script to skip the mailbox
#
#

# Return archive database with smallest size
$TargetDB = Get-MailboxDatabase -status | where {($_.ExchangeVersion.ExchangeBuild.Major -eq 14) -and ($_.IsExcludedFromProvisioning -eq $true)} | sort-object "DatabaseSize" | select-object -first 1

# Enable archive to relevant mailboxes to the target database
$results = Get-Mailbox | where {($_.ExchangeVersion.ExchangeBuild.Major -eq 14) -and ($_.ArchiveDatabase -eq $null) -and ($_.CustomAttribute13 -eq "")} | enable-mailbox

-archive -archivedatabase $TargetDB.Name -retentionpolicy "360 Day Default" |measure-object
 
#Write output for testing
Write-Host $results.count "mailbox(es) were enabled for archiving on database" $TargetDB.Name

# Script to set correct archiving policy
Get-Mailbox | where {($_.CustomAttribute12 -eq "")} | set-mailbox -CustomAttribute12 "180"
Get-DistributionGroupMember "Exchange Archive Users – 360 day" | Get-Mailbox | set-mailbox -CustomAttribute12 "360"
Get-Mailbox | where {($_.ExchangeVersion.ExchangeBuild.Major -eq 14) -and ($_.CustomAttribute12 -eq "180")} | set-mailbox -retentionpolicy "180 Day Default"
Get-Mailbox | where {($_.ExchangeVersion.ExchangeBuild.Major -eq 14) -and ($_.CustomAttribute12 -eq "360")} | set-mailbox -retentionpolicy "360 Day Default"

As always, comments about the code and approach are welcome!

h1

Exchange 2010 – monitoring move requests

August 22, 2011

A quick post to make a common task a little easier.

When managing move mailbox requests, it is often useful to be able to view certain statistics to ensure that progress and migration pace are as expected and that each server is playing its expected roles.

Exchange 2010 SP 1 makes that possible using the get-moverequeststatistics powershell command-let but some manipulation and formatting makes a big difference in monitoring the results.

Try this command for a friendly view of useful information about each open move request (as well as some cool tricks you can use with the format-table command):

Get-MoveRequest | Get-MoveRequestStatistics  |Sort-Object CompletionTimeStamp| ft DisplayName, @{Expression={$_.BadItemsEncountered};Label=”Errors”}, @{Expression={$_.PercentComplete};Label=”Percent”}, @{Expression={$_.TotalMailboxSize.ToString().Split(“(“)[0]};Label=”Size”}, @{Expression={$_.totalinprogressduration};label=”Time”},@{Expression={(($_.BytesTransferred/$_.TotalInProgressDuration.TotalMinutes)*60).ToString().Split(“(“)[0]};Label=”Pace/hr”}, @{Expression={$_.MRSServerName.ToString().Split(“.”)[0]};Label=”CAS”}, @{Expression={$_.SourceDatabase.ToString().Split(“\”)[0]};Label=”SourceServer”},SourceDatabase,Status,CompletionTimestamp -auto

Redirecting the output to a file on a scheduled basis also makes troubleshooting after hours mailbox moves much easier.

Follow

Get every new post delivered to your Inbox.