Exchange 2007 PowerShell commands

Getting and Viewing data from Powershell

When viewing information from the Exchange Management Shell, sometimes all the information is bunched up like this:

Identity             User                 AccessRights        IsInherited Deny
——–             —-                 ————        ———– —-
nativeconnections… NT AUTHORITY\SELF    {FullAccess, Rea… False       False
nativeconnections… NATIVECONNECTIO\E… {ReadPermission}    True        False
nativeconnections… NATIVECONNECTIO\E… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\D… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\E… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\E… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\A… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\s… {FullAccess}        True        True
nativeconnections… NATIVECONNECTIO\E… {FullAccess}        True        False
nativeconnections… NATIVECONNECTIO\E… {FullAccess}        True        False
nativeconnections… NATIVECONNECTIO\E… {ReadPermission}    True        False
nativeconnections… NATIVECONNECTIO\E… {ReadPermission}    True        False
nativeconnections… NATIVECONNECTIO\E… {ReadPermission}    True        False
nativeconnections… NATIVECONNECTIO\E… {FullAccess, Del… True        False
nativeconnections… NATIVECONNECTIO\A… {FullAccess, Del… True        False
nativeconnections… NATIVECONNECTIO\s… {FullAccess, Del… True        False
nativeconnections… NATIVECONNECTIO\E… {FullAccess, Del… True        False
nativeconnections… NATIVECONNECTIO\D… {FullAccess, Del… True        False

What you will notice is that some of the column information is somewhat obscured by the default formatting used by the Exchange Management Shell. To fix this, you can pipe the results of the Get-MailboxPermission cmdlet into the format-table cmdlet (abbreviated to ft in the cmdlet example below) and also use the –AutoSize and –Wrap parameters as shown in this example cmdlet:

Get-MailboxPermission -Identity Firstname.Lastname@domainname.com | ft –AutoSize -Wrap

You can also use Format List (fl) options

Get-MailboxPermission -Identity Firstname.Lastname@domainname.com | fl Identity,User,AccessRights

Import email from a PST file to Exchange 2007

Before importing email to a PST file, you have to get all your permissions sorted out so you have access to everyone’s mailbox.

Get-Mailbox | Add-MailboxPermission -user domain\yourusername –AccessRight FullAccess -Inheritancetype all

To apply permission to one mailbox, this is the command:

Add-MailboxPermission -Identity Firstname.Lastname@domainname.com -User domain\yourusername -AccessRights FullAccess -InheritanceType all

Import PST files to Exchange 2007

Import-Mailbox -Identity contoso\john -PSTFolderPath C:\PSTFiles\john.pst -ContentKeywords "merger" -AttachmentFilenames "*orgchart*" -StartDate "03/01/2006 12:01:00" -RecipientKeywords tony@fabrikam.com

Import-mailbox -Identity ricardr -PSTFolderPath D:\PSTs -StartDate 1/1/06 -EndDate 12/1/06 -SubjectKeywords:’review’ -ContentKeywords:’project’,’alpha’

Import-Mailbox -Identity john -PSTFolderPath C:\PSTFiles\john.pst -ExcludeFolders "\Junk E-Mail","\Contacts"

Import-Mailbox -Identity john@contoso.com -PSTFolderPath C:\PSTFiles\john.pst -SenderKeywords christine@fabrikam.com

Get-Mailbox -OrganizationalUnit Students | Import-Mailbox -PSTFolderPath C:\PSTFiles\

The .pst files in C:\PSTFiles must each be named <alias>.pst. More info can be found here

Granting Send As and Receive As permission for one user to all Exchange mailboxes

get-mailbox | add-adpermission –user svc.QuestExchange@firewalls.com.au –accessrights ExtendedRight –extendedrights Send-As, Receive-As, ms-Exch-Store-Admin

Granting Full Control and Receive As permission for one user to an Exchange database

Get-MailboxDatabase | Add-ADPermission -User svc.QuestExchange@dc.local -AccessRights GenericAll -ExtendedRights Receive-As

Actual Import of a single PST file for a single user

Import-Mailbox -Identity user@emailaddress.com -PSTFolderPath "\\server\sharename\file.PST" -BadItemLimit 648 -Confirm:$false

Using Excel, you can quickly put together all your scripts using the =CONCATENATE(A2,B2,C2) formula. With this you break up your whole script into different columns for example A2, B2, C2 and then in the last column you have this formula =CONCATENATE(A2,B2,C2) and drag this down the page, it will populate the column with the proper script. Good to know for anything similar to this when only the some parts of the script is different, in the B column you have a list of all the different users, the other columns it’s the same stuff.

To run the .PS1 scripts, from within PowerShell, type the following command .\"Infigen mailbox permissions 01.ps1". As a tip, from within PowerShell file or folder you are looking for, type the first part of it and then hit TAB, it will toggle through the options. Will save you from typing the whole thing.

Export Exchange 2007 email to PST files

Get-Mailbox -server VSTLPREXCMB01 | Export-Mailbox -PSTFolderPath "\\10.10.30.51\d$\Mail Migration\Current Infigen Backup" -Confirm:$false

To Export/archive email and move from a mailbox older than a specified date:

Export-Mailbox -Identity user.name@domain.com -PSTFolderPath "Z:\file.pst" -EndDate "01/03/2008 12:01:00" -DeleteContent -BadItemLimit 648 -Confirm:$false

Mailbox sizes

Sizes can be listed in size order per database below:

Get-MailboxStatistics -database SG1-DB1 | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},ItemCount

Get-MailboxStatistics -database SG1-DB2 | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},ItemCount

Get-MailboxStatistics -database SG1-DB3 | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},ItemCount

Get-MailboxStatistics -database SG3-DB1 | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},ItemCount

Or you can list the mailbox sizes for each Exchange 2007 mailbox server

Get-MailboxStatistics -server MailboxServerName | Sort-Object TotalItemSize -Descending | ft DisplayName,@{label="TotalItemSize(MB)";expression={$_.TotalItemSize.Value.ToMB()}},ItemCount

Exporting data to .CSV files

You can use the ‘export-csv’ cmdlet to output MailboxStatistics data to a .csv file

Get-MailboxStatistics -server MailboxServerName | Sort-Object TotalItemSize -Descending | export-csv -path c:\MB.csv

This includes the following information:

  • LastLoggedOnUserAccount
  • LastLogoffTime
  • LastLogonTime
  • LegacyDN
  • MailboxGuid
  • ObjectClass
  • StorageLimitStatus
  • TotalDeletedItemSize
  • TotalItemSize
  • Database
  • ServerName
  • StorageGroupName
  • DatabaseName
  • Identity
  • OriginatingServer
  • ItemCount

Removing disconnected mailboxes from Exchange 2007

Exchange Server 2007 doesn’t allow us to purge the disconnected mailbox. In order to remove one or multiple disconnected mailboxes we can be performing these steps:

Listing all disconnected mailboxes

Get-MailboxStatistics | where-object { $_.DisconnectDate -ne $null } | Select DisplayName,MailboxGuid

Removing a single entry

Remove-Mailbox -Database <Database-Name> -StoreMailboxIdentity <MailboxGuid> -confirm:$false

Removing all users at the same time

$users = Get-MailboxStatistics | where-object { $_.DisconnectDate -ne $null } | Select DisplayName,MailboxGuid

Now that we have all disconnected mailboxes in a var, we can run the following cmdlet to remove all of them:

$users | ForEach { Remove-Mailbox -Database "Mailbox Database" -StoreMailboxIdentity $_.MailboxGuid -confirm:$false }

Auditing

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

Or mailboxes that have never been logged on to:

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

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

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)}

Distribution Lists

Customized filters that use the RecipientFilter parameter

When you create a dynamic distribution group by using the RecipientFilter parameter, you are using customized filters. You can’t use customized filters and precanned filters at the same time. You must create a customized filter by using OPATH filter syntax. OPATH is the filtering syntax used by Windows PowerShell.

When you create your own OPATH customized filter, be aware of the following:

  • Use braces { } around the whole OPATH syntax string.
  • Include the hyphen before all operators.
  • The following are the most frequently used operators.

    -and

    -lt (less than)

    -or

    -gt (greater than)

    -not

    -like (string comparison)

    -eq (equals; not case-sensitive)

    -notlike (string comparison)

    -ne (does not equal; not case-sensitive)

The following will create a DL for all Australian User mailboxes & Mail contacts:

New-DynamicDistributionGroup -Name ‘DL-Infigen AUS’ -OrganizationalUnit ‘Gwpservices.local/GWPServices/Groups/DL’ -RecipientContainer ‘gwpservices.local’ -RecipientFilter "(RecipientType -eq ‘UserMailbox’ -or RecipientType -eq ‘MailContact’) -and (CountryOrRegion -eq ‘Australia’)"

More information can be found here:

Create Dynamic Distribution Groups in Exchange Labs
Create Dynamic Distribution Groups Using Customized Filters

Use customized filters to create dynamic distribution groups when the attributes that you want to use aren’t available with precanned filters, or when you want to use wildcard matches. For example, if you create a dynamic distribution group that filters on the Department attribute value "R*" and the Title attribute "Engineer", messages sent to this group are delivered only to user accounts that have those attributes.

New-DynamicDistributionGroup -Name <group name> -RecipientFilter {<custom filter attribute conditions>}

New-DynamicDistributionGroup -Name "Washington Management Team" -RecipientFilter {(RecipientType -eq ‘UserMailbox’) -and (Title -like ‘Director*’ -or Title -like ‘Manager*’) -and (StateOrProvince -eq ‘WA’)}

Create Dynamic Distribution Groups Using Precanned Filters

Use precanned filters to create dynamic distribution groups when the attributes that you want to use are available with the IncludedRecipients parameter. For example, if you create a dynamic distribution group that filters on the Department and State/Province attributes, messages sent to this group are delivered only to user accounts that have those attributes.

New-DynamicDistributionGroup -Name <group name> -IncludedRecipients <value> <precanned filter attributes>

New-DynamicDistributionGroup -Name "Washington Sales and Marketing" -IncludedRecipients MailboxUsers -ConditionalDepartment Sales,Marketing -ConditionalStateOrProvince Washington

Delegation of distribution list membership

To give users the access to modify memberships of distribution lists themselves in Outlook, you can do this one by one or all in one hit user by user.

One by one:

Add-ADPermission -id “DL-Name” -User “domain\username” -AccessRights WriteProperty -Properties “Member”

All distribution lists in one hit:

Get-DistributionGroup | Add-ADPermission -User “domain\username” -AccessRights WriteProperty -Properties “Member”

Change send & receive message size limits

There two places to change the limits, Global & Connector. In this example, we are setting the send & receive setting to 50MB.

Global Limits

Global limits are used when you have a mixed Exchange Server 2003 / 2007 environment. Global settings apply to all Exchange Servers 2003 and 2007 because these Message size limits are stored in Active Directory. These global settings are equivalent to the global settings section in the Exchange Server 2003 System Manager. When the settings on the Organizational level conflict with the Global limits the lowest setting takes precedence.

This is done on either Hub Transport or the Mailbox server.

To view:

Get-Transportconfig

To set:

Set-Transportconfig -maxsendsize 50mb
Set-Transportconfig -maxreceivesize 50mb

Connector Limits

One can also define message size limits on Exchange Server 2007 Connectors. Exchange Server 2007 uses send connectors; receive connectors and foreign connectors to enable interoperability with “Standard” or Legacy messaging systems. Message size limits for connectors are bound to the specific Exchange Edge Transport or Hub Transport Server.

To view:

Get-receiveconnector | ft (You are looking for the one generally on Port 25)
Get-sendconnector | ft

To set:

Set-receiveconnector -identity “receive connector name” -MaxMessageSize 50MB
Set-sendconnector -identity “send connector name” -MaxMessageSize 50MB

10 Comments

  1. Way cool! Some extremely valid points! I appreciate you writing this post plus
    the rest of the website is also really good.

  2. If you’ve done office parties or corporate work, make sure to mention that as well.
    But you can’t just stand there grinning like an idiot until they finish laughing.
    Whether these are taken live – while you are doing a real gig – or whether you have them done on a
    false stage, will depend on you.

  3. It’s really a nice and useful piece of info. I am glad that you shared this
    helpful info with us. Please keep us up to date like this.
    Thank you for sharing.

  4. Hi there to every body, it’s my first pay a quick visit of
    this website; this weblog contains amazing and actually
    fine information for readers.

  5. Asking questions are genuinely good thing if
    you are not understanding anything entirely, but this post presents nice understanding even.

  6. After looking over a few of the articles on your web page, I seriously like
    your technique of blogging. I book-marked it
    to my bookmark website list and will be checking back soon.
    Please visit my website too and tell me how you feel.

  7. Hello There. I found your blog using msn. This is an extremely well written article.

    I will be sure to bookmark it and return to read more of your
    useful info. Thanks for the post. I’ll certainly return.

  8. Hi there I am so happy I found your website, I really found you by error, while
    I was looking on Bing for something else, Anyhow I am here now and would just like to say cheers for a fantastic
    post and a all round enjoyable blog (I also love the theme/design), I don’t have time to browse it
    all at the minute but I have bookmarked it and also included your RSS feeds,
    so when I have time I will be back to read more, Please do keep up the
    awesome jo.

  9. When some one searches for his essential thing, thus he/she desires to
    be available that in detail, so that thing is maintained over here.

  10. Great weblog right here! Additionally your web site so much up very fast!
    What host are you the use of? Can I get your affiliate hyperlink to your host?
    I want my web site loaded up as quickly as yours lol

Leave a Reply to Franklin Cancel reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s