Friday, September 13, 2013

Quick Ways To Assign Retention Policies in Exchange 2010

In life there are things that we would rather not retain... like this


I've had several instances where people wanted to apply Retention Policies to their mailboxes in Exchange 2010 to a massive amounts of mailboxes. I've come up with several different methods

  1. Apply the Retention Policy through your identity management software (not an original idea)
  2. Apply the Retention Policy to all mailboxes that do not have one via Scheduled Task
  3. Apply the Retention Policy to members of a specific AD Group
  4. Use Cmdlet Extension Agents for Exchange 2010

Option 1

Work with your Identity Management provider, they probably have the ability to modify the provisioning scripts

Option 2

Create a PowerShell script file and create a Scheduled Task
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010Set-ADServerSettings -ViewEntireForest $true #Apply Retention Policy - to Mailboxes that do not have one$policy = "DefaultPolicy"get-mailbox -filter {RetentionPolicy -eq $null} -resultsize unlimited | Set-Mailbox -RetentionPolicy $policy 

Option 3


Create a PowerShell script and change the $policy and $GroupName variables
#########################################################Apply Retention Policy to members of an AD GroupAdd-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010Set-ADServerSettings -ViewEntireForest $true $policy = "LegalPolicy"$GroupName="LegalUsers"$groupidentity = $(Get-Group $GroupName ).Identity.DistinguishedNameGet-Mailbox -Filter{(memberofgroup -eq $groupidentity)} -ResultSize Unlimited | Set-Mailbox -RetentionPolicy $policy 

Option 4

Learn how Cmdlet Extension Agents work and have at it.
http://technet.microsoft.com/en-us/library/dd335067(v=exchg.141).aspx

Friday, May 17, 2013

Pulling Enhanced Recipient Information from Exchange


Who is your daddy and what does he do?

I don’t like having to do inefficient repetitive tasks. There are situations where I want to pull specific information about a mailbox or a distribution group but I don’t want to have to look it up 5 different places in the GUI or type out the commands over and over again. This could be the user’s mailbox statistics, the ManagedBy list for distribution groups, a user’s ActiveSync device statistics, the mailbox features they have enabled, etc…

My solution 
A script that will grab a standard set of information regardless of the recipient type and the ability to supply additional parameters to grab additional information.

The basics of my script


  • Grabs the recipient object (Mailbox, Distribution Group, MailUser, Contact, etc…)
  • Mailbox
    • Name
    • Alias
    • Primary SMTP Address
    • Organizational Unit
    • City
    • Country or Region
    • Office
    • Company
    • Recipient Type Details (UserMailbox, RoomMailbox, LinkedMailbox, etc…)
    • Database
    • Hidden From Address Lists Enabled (Hidden from the GAL/OAB)
    • Mailbox Features
      • ActiveSync Enabled
      •  OWA Enabled
      • ECP Enabled
      • Emws Enabled
      •  POP Enabled
      •  Imap Enabled
      • MAPI Enabled
      • EWS Enabled
    • Any ActiveSync Device Statistics
    • Optional
      • Logon Statistics
      • Mailbox Statistics
      • Mailbox Quota Information
      • Mailbox Folder Statistics
      • Out of Office Configuration
      • Junk Email Configuration
  • Distribution Group (Dynamic or Regular)
    •  Primary SMTP Address
    • Recipient Type Details
    • Organizational Unit
    • When Created (UTC)
    • When Changed (UTC)
    • Managed By
    • Accept Messages Only From (“Allowed Senders”)
  • Mail User
    •  Name
    • Alias
    • Primary SMTP Address
    • Organizational Unit
    • City
    • Country or Region
    • Office
    • Company
    • Recipient Type Details (UserMailbox, RoomMailbox, LinkedMailbox, etc…)
    • Database
    • Hidden From Address Lists Enabled (Hidden from the GAL/OAB)
    •  External Email Address
  • Contact
    •  Name
    • Alias
    • Primary SMTP Address
    • Organizational Unit
    • City
    • Country or Region
    • Office
    • Company
    • Recipient Type Details (UserMailbox, RoomMailbox, LinkedMailbox, etc…)
    • Database
    • Hidden From Address Lists Enabled (Hidden from the GAL/OAB)
    • Windows Email Address

Here’s the script (Get-RecipientInformation

Example Usage

Variables      
·         Name 
    • The recipient alias, SamAccountName, or GUID. This should be as unique as possible.
·         Statistics [switch]
    • This will pull Mailbox, Logon and Folder Statistics for mailboxes
·        OOF [switch]
    • This will pull the Out of Office configuration for mailboxes
  • JunkEmail [switch]
    • This will pull the Junk Email configuration for mailboxes

 Mailbox

Get-RecipientInformation Han.Solo
-----------------------------------------
Recipient Information
-----------------------------------------

Name                          : Han Solo
Alias                         : Han.Solo
PrimarySmtpAddress            : LeiaIsMine@righthandedexchange.com
OrganizationalUnit            : righthandedexchange.com/Users
City                          : Hoth
CountryOrRegion               : Rebel Base
Office                        : Hanger Bay
Company                       : Rebel Alliance
RecipientTypeDetails          : UserMailbox
Database                      : Database-1138
HiddenFromAddressListsEnabled : False



-----------------------------------------
Mailbox Features
-----------------------------------------

ActiveSyncEnabled : False
OWAEnabled        : True
ECPEnabled        : True
EmwsEnabled       : False
PopEnabled        : True
ImapEnabled       : True
MAPIEnabled       : True
EwsEnabled        :



-----------------------------------------
ActiveSync Device Statistics
-----------------------------------------

DeviceFriendlyName  : Black iPhone 5
DeviceOS            : iOS 6.0.2 10A551
DeviceModel         : iPhone5C1
Status              : DeviceOk
StatusNote          :
LastSyncAttemptTime : 12/21/2012 1:46:08 AM
LastSuccessSync     : 12/21/2012 1:46:08 AM

Distribution Group

Get-RecipientInformation -Name RebelAlliance
------------------------------------------------------------
Distribution Group: RebelAlliance
------------------------------------------------------------
PrimarySmtpAddress   : DownWithTheEmpire@righthandedexchange.com
RecipientTypeDetails : MailUniversalDistributionGroup
OrganizationalUnit   : righthandedexchange.com/DistributionGroups
WhenCreatedUTC       : 8/26/2005 2:26:58 PM
WhenChangedUTC       : 4/23/2013 2:38:16 PM

ManagedBy
---------
Bail Organa

Tuesday, April 9, 2013

Oops - I deleted the user's mailbox... Please help

How to Relink/Restore a mailbox with the "Least Amount of Administrative Effort"

http://www.youtube.com/watch?v=JlsSy8xpsYs

yeah yeah yeah yeah yeah
Yeah yeah yeah yeah yeah yeah
 I think I did it again
I made you upset, your mailbox is gone
Oh Exchange
It might seem like a rush
But it doesn't mean that I'm oblivious
'Cause to lose all your emails
That is just so frustrating
Oh Exchange, baby
 Oops!...I did it again
I played with your mail, got lost in the shame
Oh Exchange, baby
Oops!...You think I’m the IT shiz
That I'm sent from below
I'm not that incompetent 


From time to time I run across a situation where an Admin has been a little overzealous and has either deleted the AD account for the user or disconnected the mailbox. Sometimes they create a new mailbox and call it "Macaroni" but that's like sewing a plaid sleeve on a polyester suit. Sure, it's a sleeve, but take a look in the mirror.

The other situation is when a user is "moved" between domains in the same forest. By "moved", I mean "deleted and then a new account created" in the new domain. The major issue with that is, the LegacyExchangeDN will be gone if you simply recreate the mailbox and the user won't have any items from the previous mailbox. Yes, you can have the user export their mailbox to PST before this action is done, but there's no guarantee that they grabbed everything. I've seen it happen where they grab the Inbox, but forget the Calendar or Contacts.

My solution 

A script that will either Reconnect the previous mailbox to the AD account OR perform a restore  from the previous mailbox to the new one.

The basics of my script

  • Grabs the AD User object for restoration purposes
  • Searches each mailbox server in the environment for the disconnected mailbox of the user
  • If the AD User has a mailbox
    •  A New-MailboxRestoreRequest is performed to restore the items from the disconnected mailbox to the new mailbox.
    • The disconnected mailbox's LegacyExchangeDN is added to the new mailbox as a X500 address.
  • If the AD User does not have a mailbox, 
    • The latest disconnected mailbox is connected to the AD User

Here’s the script (Relink-Mailbox.ps1) - Download 

Example Usage

Variables      
  • Mailbox 
    • The mailbox alias, SamAccountName, or GUID. This should be as unique as possible.
  • DoNotRunDatabaseCleanup
    • Prevents the script from automatically running the Clean-MailboxDatabase cmdlet


Relink-Mailbox.ps1 -Mailbox "UserA"
Script Output


04/01/2013 14:05:52 - Grabbing user's AD Object: UserA
04/01/2013 14:06:19 - Grabbing list of disconnected mailboxes
04/01/2013 14:09:25 - Connecting Mailbox
04/01/2013 14:09:57 - Waiting for AD Replication - 4 Minutes

DisplayName     Alias          WhenChangedUTC            
-----------     -----          --------------            
A, User         UserA          04/01/2013 15:03:57   




Sunday, February 24, 2013

Fixing IMCEAEX NDRs - Missing X500 Addresses

My Lyrical Inspiration

http://www.youtube.com/watch?v=VuHVZ_-b868

Mr.
IMCEA and me tell each other NDR tales
Stare at the
rejected mai
"She's
rejected by you. Ah, no, no, she's rejected by me."
Frowning in the transport
Coming through in
Outlook
When everybody
bounces you, you will never be delivered

Imagine the following scenarios

  • A user complains about something weird going on with their mailbox
    • Admin disconnects that mailbox and creates a new mailbox for the user
    • User complains that they are not receiving emails from internal users
    • User can receive emails from external senders
    • Other users complain they can’t send email to the user
    • Emailing the user from OWA works
    • Emailing the user from Outlook works when selecting them from the Address Book
  • You migrate from Exchange 2003/2007 to Exchange 2010
    • The mailbox move fails
    • A new mailbox is created and the previous mailbox imported via PST
    • Same complaints as above
  •  Provisioning software “accidently” disables the user
    • The software “fixes” the issue by adding a new mailbox to the account
    • User complains they are missing their email
    • User complains that they are not receiving emails from internal users
    • Users report receiving NDRs like the example below

Delivery has failed to these recipients or groups:
Han Solo
The e-mail address you entered couldn't be found. Please check the recipient's e-mail address and try to resend the message. If the problem continues, please contact your helpdesk.

Diagnostic information for administrators:
Generating server: mail.domain.com
IMCEAEX-_O=DOMAIN_OU=EXCHANGE+20ADMINISTRATIVE+20GROUP+20+28FYDIBOHF23SPDLT+29_CN=RECIPIENTS_CN=Han+20Solo891@righthandedexchange.com
#550 5.1.1 RESOLVER.ADR.ExRecipNotFound; not found ##

The scenarios are pretty similar except the timeframe. All stem from Outlook caching the LegacyExchangeDN for the user and not being able to find that in the Exchange system. The fix is to add the LegacyExchangeDN as an X500 address as a Proxy Address to the user’s mailbox. The real issue is that we are usually reactive on this and wait until a user reports the problem and sends us a NDR. Even then, we still have to convert the mumbo-jumbo that the NDR says into a valid X500 address. I don’t like being reactive or waiting for users to open tickets with this issue. I figured out that I can find this information in the Message Tracking Logs in Exchange with the EventID of FAIL. This isn’t the only information that can be gleaned from the FAIL events, but that’s a story for another day.

The basics of my script

  •  Search message tracking logs for X days for all FAIL events that have a recipient that matches IMCEAEX (See the example above)
  •  Convert the IMCEAEX address to a valid X500 address (strip out the junk)
  • Filter out the duplicates leaving only unique instances
  • Determine the potential user name from the X500 address and search for an existing mailbox.  
  • Add the X500 address to the user’s mailbox.

Here’s the script - Download 

Example Usage

Variables      
  • AutoHeal
    • Attempt to fix the invalid accounts by adding the missing X500 address as a Proxy Address
  • Days
    • Number of days to search in the logs. Default is 1
  •  Servers
  • Filter the list of server(s) to use. Defaults to all Transport servers.



Find-X500Failures -days 1 -AutoHeal
Script Output

Searching for messages sent after: 02/22/2013
Found 90 Unique user(s)
---------------------------------------
Results
---------------------------------------

Name              Alias              Status                              
----              -----              ------                              
Johnny B Good     Johnny.B.Good      Updated                             
Eddie Du Little   Eddie.Du.Little    Updated

Monday, February 18, 2013

Quick Reconnect of a Disconnected Mailbox

This is what I use to quickly reconnect a disconnected mailbox. You'll need to know the alias/SamAccountName of the user to reconnect.

#Reconnect Disconnected Mailbox
$idb="username"
#Get list of disconnected mailboxes
$mbxserver=get-mailboxserver
$mbxList=$mbxserver|%{(Get-Mailboxstatistics -Server $_.name | ?{ $_.DisconnectDate -ne $null })}
#Get the User to reconnect
$user=Get-User $idb
#Search for the user in the Disconnected Mailbox List
$dMB=$mbxlist|where {$_.displayname -match $user.DisplayName}|select displayName, mailboxGUID, Database
#Connect mailbox to user
Connect-Mailbox -Alias $user.SamAccountName -User $user -Database $dMB.Database -identity $dMB.MailboxGUID

Tuesday, February 12, 2013

How to Properly Replace a User's Mailbox Due to Corruption


Occasionally users will manage to do something to their mailbox and the only alternative to fix it is to disconnect their current mailbox and create a new one. I’m an efficiently lazy admin that likes to automate the mundane stuff to make life easier for everyone.

This involves the following steps

·                     Grab information about the current mailbox
·                     Disconnect source mailbox and connect new mailbox
·                     Configure new mailbox with the email addresses from the old mailbox (X400, SMTP, X500, etc)
·                     Restore all mail items from the previous mailbox (New-MailboxRestoreRequest)
·                     Re-provision ActiveSync or BES devices (not scripted)

Here’s the script – Use it at your own risk
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010

$idb="UserA"

#Get User Information
$mbx=get-mailbox $idb
$user=Get-User $idb


#Disconnect the current mailbox
Disable-Mailbox -Identity $idb -Confirm:$false
sleep 60
#Create a new mailbox
Enable-Mailbox -Identity $user -Database $mbx.Database.Name -Alias $mbx.alias -PrimarySmtpAddress $mbx.primarySMTPAddress

#Allow AD time to catch up
sleep 120

#Add LegacyExchangeDN as X500 address to prevent NDRs
$mbx.EmailAddresses+=("X500:{0}" -f $mbx.LegacyExchangeDN)
#Add SMTP Addresses from old mailbox to new mailbox - After Search is completed
Set-Mailbox -Identity $idb -EmailAddresses $mbx.EmailAddresses

#Get Disconnected Mailbox and create restore
$mbxserver=get-mailboxserver
$mbxList=$mbxserver|%{(Get-Mailboxstatistics -Server $_.name | ?{ $_.DisconnectDate -ne $null })}
$restore=$mbxList|Where-Object {$_.DisplayName -match $mbx.DisplayName}
$request=New-MailboxRestoreRequest -SourceStoreMailbox $restore.MailboxGUID -SourceDatabase $restore.Database -TargetMailbox $idb -AllowLegacyDNMismatch

$requestStatus=get-mailboxRestoreRequest $request.RequestGuid

while ($requestStatus.Status -notmatch "Completed"){
#Check every 5 minutes
       $requestStatus=get-mailboxRestoreRequest $request.RequestGuid
       Write-Output ("Checked at {0} : {1}" -f (Get-Date), $request.Status)
       Sleep 300
}
Write-Output "Restore Request Completed"