One-liner to export all email addresses to CSV

This command exports all email addresses for all users in the organization:

Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName, SamAccountName, PrimarySmtpAddress, @{Name="EmailAddresses";Expression={$_.EmailAddresses | Where-Object {$_.PrefixString -ceq "smtp"} | ForEach-Object {$_.SmtpAddress}}} | Export-CSV c:\EmailAddresses.csv -NoTypeInformation -Encoding Unicode

If you want to narrow it down a bit you could add either a Where or narrow the scope sown to a specific OU as in the following example:

Get-Mailbox -ResultSize Unlimited -OrganizationalUnit "sundis.local/Test/Users" | Select-Object DisplayName, SamAccountName, PrimarySmtpAddress, @{Name="EmailAddresses";Expression={$_.EmailAddresses | Where-Object {$_.PrefixString -ceq "smtp"} | ForEach-Object {$_.SmtpAddress}}} | Export-CSV c:\EmailAddresses.csv -NoTypeInformation -Encoding Unicode

Let me know if you have any questions!

Users is unable to access OWA options (ECP) in Exchange 2010 and 2013

This is not an especially new issue but there is not much information about it so here goes anyway.

The issue

Some users, but not all, of a customer of mine reported that they could not save their signatures in OWA. After some investigation I found that the users that could save their signature had the an Role Assignment Policy set, “Default Role Assignment Policy”. This was the only policy in use and all users should have that policy.

When I did a quick check online, some had reported that the following event with event ID 4 and the error message "The user "username" isn’t assigned to any management roles."  where logged in the Application Log on the CAS servers. However, my customer had no such events in the Application Logs on their CAS servers.

The users that could not save their signature had an empty Role Assignment Policy attribute set. Exchange needs to have the RoleAssignmentPolicy property (msExchRBACPolicyLink  attribute) to be able to determine which settings the users has the rights to change in ECP. This is based on RBAC and if you want to read up on Role Assignment Policies have a look here.

Lets have a look at this in more detail. I have got two users, Test User1 with no policy set. And Test User2 with the “Default Role Assignment Policy” set. We will start with the first user…


A broken Mailbox

Test User1 (no policy set)
Run the following command to view the RoleAssignmentPolicy property.

Get-Mailbox <identity> | Name,RoleAssignmentPolicy



As you can see, the RoleAssignmentPolicy property is empty. In ADSI Edit the attribute you should look for is called msExchRBACPolicyLink as shown below.


As you probably have guessed already, the attribute is empty for Test User1. If I go to OWA and try to change some of the options I receive the following error message “Sorry! Access Denied. You don’t have permission to open this page. If you’re a new user or were recently assigned credentials, please wait 15 minutes and try again.”.

In both Exchange 2010 and 2013 the message looks like this.



A working mailbox

Test User2 (“Default Role Assignment Policy” set)

Again, run the following command to view the RoleAssignmentPolicy property:

Get-Mailbox <identity> | Name,RoleAssignmentPolicy



Much better as you can se, when we use ADSI Edit the msExchRBACPolicyLink contains the Distinguished Name of the “Default Role Assignment Policy”.


For Test User2 it works fine to change the settings in ECP.


Why did it happen?

I did some more investigating and found that the reason that this issue occurred for some users was that my customer create some mailboxes using AD Toolkit. When AD Toolkit creates the mailboxes the msExchRBACPolicyLink attribute is not set.

This can be achieved in AD Toolkit as well by adding an attribute when creating the mailboxes and specifying the msExchRBACPolicyLink attribute with a correct Role Assignment Policy.



Well the easiest way to solve the issues is to add a Role Assignment Policy for the affected mailboxes. To find all users with an empty msExchRBACPolicyLink attribute you can run the following command.

Get-Mailbox -ResultSize Unlimited | Where { $_.RoleAssignmentPolicy -like $null}



To add a Role Assignment Policy for all the listed users run the following command:

Get-Mailbox -ResultSize Unlimited | Where { $_.RoleAssignmentPolicy -like $null} | Set-Mailbox –RoleAssignmentPolicy “Default Role Assignment Policy”



And that should be it, all users should now be able to change their settings in ECP.

Thanks for reading and do not hesitate to let me me know if you run in to any issues!

Multiple updates released including SP3 for Exchange 2010

Service Pack 3 for Exchange 2010

Microsoft has released a number of updates. The big news here is the release of Service Pack 3 for Exchange 2010 with the two following major features:

Coexistence with Exchange 2013
Support for Windows Server 2012

Great new for all of you wanting to implement Exchange 2013 in your existing environments. But coexistence also requires an update of Exchange 2013.  CU1 for Exchange 2013 is scheduled for release in Q1 so it should be released soon. That said, installing Exchange 2013 in a existing Exchange 2010 Service Pack 3 environment WILL work all tough it is not supported. But it enables you to start running tests in your lab and prepare for the release of CU1.

More information on SP3 for Exchange 2010 can be found here.
If you want to go straight to the download you can find it here.

More updates…

But wait, there is more… Microsoft has also released Update Rollup 6 for Exchange Server 2010 SP2 and Update Rollup 10 for Exchange 2007 SP3. Both are considered security releases so they will be available on Windows Update.

More information on these can be found here.
Update Rollup 6 for Exchange Server 2010 SP2 can be found here.
Update Rollup 10 for Exchange 2007 SP3 can be found here.

Bulk copy SAMAccountName to Alias using PowerShell

Just a short one to show how to copy the SAMAccountName to Alias using PowerShell. You can easily change the initial population of $Mailboxes and test the script on a single, or smaller number of users.

You also need to remove the Write-Host commands and -ErrorAction Inquire –Whatif in the Set-Mailbox command after your testing.

During testing:

$Mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox

foreach ($Mailbox in $Mailboxes)

	$SAMAccountName = $Mailbox.SAMAccountName
	$OldAlias = $Mailbox.Alias

	if ($SAMAccountName -ne $OldAlias)
		Write-Host $Mailbox.SAMAccountName
		Write-Host $Mailbox.Alias
		Set-Mailbox $Mailbox -Alias “$SAMAccountName” -Confirm:$false -ErrorAction Inquire -Whatif

After testing:

$Mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox

foreach ($Mailbox in $Mailboxes)

	$SAMAccountName = $Mailbox.SAMAccountName
	$OldAlias = $Mailbox.Alias

	if ($SAMAccountName -ne $OldAlias)
		Set-Mailbox $Mailbox -Alias “$SAMAccountName” -Confirm:$false

Verifying the changes:

Listing all mailboxes where SAMAccountName and Alias differs…

Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Where {$_.SAMAccountName -ne $_.Alias}

Let me know if you have any questions, thanks for reading!

List empty distribution groups

A short tip on how to list all empty distribution groups. In this example I export the results to a csv file.

$DistributionGroups = Get-DistributionGroup -Resultsize Unlimited
$DistributionGroups |? {!(Get-DistributionGroupMember $_)} | Select-Object Name | Export-Csv "C:\EmptyDistributionGroups.csv"

Configure Lync 2010 voice using a SIP gateway and an uncertified SIP trunk, step-by-step – Part 2

This post takes on right where post 1 in this series ended and we will jump right into it. We will cover PSTN Gateway configuration, Trunk configuration, Normalization rules and Voice Routes.

PSTN Gateway

Head over to you Lync Server 2010 and open up Lync Server Topology Builder, then choose Download Topology existing deployment and click Ok.


Choose a location and enter a name for you topology file and then click Save.


Expand Mediation pools and then click Edit Properties… in the Actions pane.


Select New to create a PSTN gateway.


Enter the FQDN or IP address for your gateway, ensure TCP is set as we configured TCP in the Intertex IX78 in the previous post and change the default port to 5060. When finished click Ok.


Make sure that the gateway is listed in the The following gateways are associated with this mediation server and  then click Ok.


Go ahead and publish your new topology. I will not cover the publishing in this post, instead we will continue with configuring our trunk.

Trunk Configuration

Open the Lync Server control Panel and navigate to Voice, Trunk Configuration and click New.


Make sure your settings match mine and then create a translation rule by clicking New.


I will create a Translation Rule that looks for the +00 prefix, and makes sure that the number is more then 3 digits long, then it replaces 0 digits (in other words it does not replace anything). We will use Normalization Rules to make sure that the dialed numbers have an ok syntax. When finished click Ok to save our Translation Rule.


Take a quick look at the configured settings and then click Ok to save your Trunk configuration.



Normalization Rules

Normalization rules define how phone numbers expressed in various formats are to be routed for the named location. It is a way of forming an E. 164 number from the number dialed by an Lync Server 2010 user. It is necessary for call routing because users may dial numbers in various formats.

I will list all my 5 Normalization Rules, you might not need all of them but this is what works for me in my lab in Sweden. Feel free to add a comment if you need help with forming these rules, it can be quite tricky. More information regarding Normalization Rules can be found here and here.

Navigate to Voice Routing and Dial Plans and open your Global Dial Plan.


In my example you can see the 5 Normalization Rules that I use for my lab environment. Create a new rule by clicking New.


This rule initiates on the starting digits 00, it does simply that and nothing more. The reason for this is that I want to normalize all numbers to include both country code and area code, for example 0046855566677. I would recommend you to try different Normalization Rules until you have a combination of rules that fits your needs and demands.


To make sure that your rule works you can test it before clicking Ok and saving it. If I enter a number that I believe should match the rule and then click Go it should display the normalized number in green.


My next Normalization Rule initiates if a number starts with a single 0 and is at least 1 digit long. In Sweden our area codes starts with a single 0. Then it adds the prefix 0046 to make it a standard Swedish number including the country code.


When I enter a number with Stockholm’s area code it should Normalize it to a number that that removes the initiating 0 and then adds the prefix for the Swedish country code.


My next Normalization Rule initiates on any number starting with one of the numbers 1 to 8. A local number in Sweden can start with any of those numbers. It must also be at least 5 numbers long since no telephone number in Sweden has less then 5 numbers. Then it adds the local area code of both Sweden and Stockholm.


And when I test this rule with a local number it should add a prefix of 00468.

Note: This Normalization Rule assumes that this server is placed in Stockholm and that all numbers missing an area code is meant for Stockholm.


This next rule initiates based on the staring digit +, as in +46855566677. It then removes the + and adds 00.


And when tested it does exactly that…


And last but not least, this rule initiates when the number starts with 33 and is exactly 3 digits long. This indicates that it is a local number and it should not be normalized in any way.


When tested it does seem to match, note that I have also checked Internal Extension.


When you have added all your Normalizations Rules you can make more tests if you want and then click Ok to save your Dial Plan.


I am by far no expert in normalization rules, if you have any thought on the rules I use please feel free to post a comment or contact me and I will be happy to optimize my lab.

Route Configuration

Our final step towards a working Lync Server 2010 voice implementation is to configure routing. A Voice Route looks for a specific pattern in numbers and then decides which gateway that it will route the call to. Navigate to Voice Routing and then Route. Click New to create a new route.


Give the Voice Route a Name and then add the pattern that you want this route to match. In my case I have normalized everything that is supposed to leave the Lync Server with 00 I add 00. In your case this might differ depending on your Normalization Rules.


The next step is to add an Associated gateway. Click on Add to open the gateway selection.


Search for and select the gateway you would like to add and then click Ok to save your selection.


Next we must add an Associated PSTN usages, click Select to open the PSTN usage record selection.


Select your PSTN record and then click Ok.


Now it is time to test our routing. Enter a suitable number that you think should match the pattern and click Go.


Also, to make sure that all is well, enter a number that should not match the pattern.


When finished save the Voice Route by clicking Ok.

Now make sure that you Commit all changes properly!!

After this you should be all set and ready for testing. This concludes part 2 of this series, I hope you have enjoyed reading it and that you find it useful. If you have any thoughts or questions regarding the configuration please do not hesitate to post a comment.

Part 1 in this series can be found here!

Part 2 in this series can be found here!

Quick Tip: View the database size and mailbox count for mailbox databases

In this quick tip post I will show you how to retrieve mailbox database size and mailbox count for one or all mailboxes. Lets start with mailbox database size.

Mailbox database size

This command is quite simple and utilizes the –Status parameter in the Get-MailboxDatabase cmdlet:

Get-MailboxDatabase –Identity <MailboxDatabaseName> -Status | Select ServerName,Name,DatabaseSize

To retrieve the size of all mailbox databases:

Get-MailboxDatabase -Status | Select ServerName,Name,DatabaseSize

And if you want to sort this on DatabaseSize:

Get-MailboxDatabase -Status | Select ServerName,Name,DatabaseSize | Sort-Object DatabaseSize –Descending

And with sorting on the mailbox database name:

Get-MailboxDatabase -Status | Select ServerName,Name,DatabaseSize | Sort-Object Name –Descending

Mailbox count for mailbox databases

Now we will focus on counting mailbox databases. This command is also quite easy to use.

Get-Mailbox -ResultSize:Unlimited | Group-Object -Property:Database | Select-Object Name,Count | Sort-Object -Property:Count –Descending

Let’s break this up a bit… The first part is a ordinary Get-Mailbox cmdlet with -ResultSize:Unlimited to include all mailboxes:

Get-Mailbox -ResultSize:Unlimited

Then we group the objects from the result of the Get-Mailbox cmdlet on Database to be able to count based on each mailbox database:

Group-Object -Property:Database

Moving on with a selection of the properties we want to display including a count:

Select-Object Name,Count

And finally we sort the results based on the count property to get it in a nice list with the mailbox database with most mailboxes on top:

Sort-Object -Property:Count -Descending

One-liner to export mailbox size, quotas and more to a CSV file

I got a question form a friend if I could help and sort out a command that exported mailbox size and quotas to a CSV file  for him. This should work for both Exchange Server 2007 and 2010, here is how we did it:

First run a get mailbox command:

Get-Mailbox -ResultSize Unlimited

Then we add a pipe and a number of attributes we want to get:

Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName, IssueWarningQuota, ProhibitSendQuota

We continue with adding two that performs Get-MailboxStatistics to receive attributes from the mailbox that the Get-Mailbox Cmdlet does not give us:

@{label=”TotalItemSize(MB)”;expression={(Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()}} and @{label=”ItemCount”;expression={(Get-MailboxStatistics $_).ItemCount}}

Then we add another attribute that Get-Mailbox gives us:


And to finish it off we export the results to a CSV file after another pipe:

| Export-Csv “UserMailboxSizes.csv” –NoTypeInformation

And the complete command again with all parts combined together:

Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName, IssueWarningQuota, ProhibitSendQuota, @{label="TotalItemSize(MB)";expression={(Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()}}, @{label="ItemCount";expression={(Get-MailboxStatistics $_).ItemCount}}, Database | Export-Csv "C:\Scripts\UserMailboxSizes.csv" -NoTypeInformation

This command can of course be modified and you can add other attributes or functions. In the following example I use where to get only the mailboxes that does not use the database default quota.

Where {$_.UseDatabaseQuotaDefaults -eq $false

And the complete command:

Get-Mailbox -ResultSize Unlimited | Where {$_.UseDatabaseQuotaDefaults -eq $false} | Select-Object DisplayName, IssueWarningQuota, ProhibitSendQuota, @{label="TotalItemSize(MB)";expression={(Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()}}, @{label="ItemCount";expression={(Get-MailboxStatistics $_).ItemCount}}, Database | Export-Csv "C:\Scripts\UserMailboxSizes.csv" -NoTypeInformation

There you go, enjoy and do not hesitate to let me know if you have any questions!

A fix for the “Close all dialogs” issue with EMC in combination with IE9 has been released!

I usually do not write about news or hotfix releases on my blog, mostly because I find it a bit unnecessary since you all probably follow the Microsoft Exchange Team Blog. But for this one I will make an exception.

Microsoft just released a fix for the problem with interoperability between Exchange Management Console and Internet Explorer 9 that many has seen since the release of IE9. When IE9 is installed and you try to close the EMC you will receive the following error message:

You must close all dialog boxes before you can close Exchange Management Console.


Neither the hotfix or the KB article is available to the public yet, but it can be requested from Microsoft support. The hotfix that you need to request is for the KB 2624899, more information on how to contact Microsoft Support follows…


How do I call support? Will I need to pay for this?

In order to reach Microsoft support, you can find the correct support contact for your location here. Microsoft does not charge for hotfixes or support cases related to product bugs. Both IE and Exchange support teams should be able to get this patch for you. 


More information regarding this can be found here!

Script to configure Exchange Server 2010 for SSLOffloading

When using a hardware load balancer you sometimes come across the need of configuring Exchange Server to support SSLOffloading. In my case I use a Citrix Netscaler to publish Exchange Server in a scenario where I have enabled SSLOffloading in the Citrix Netscaler. So, in order for this to work configuration changes needs to be done in Exchange Server 2010.

The script below configures both Exchange 2010 RTM and SP1, it also configures basic authentication in IIS for ECP, EWS and OWA.

# This script will configure the Exchange 2010 RTM and SP1 Client Access Servers for SSLOffload
# It applies when using Hardware loadBalancer with SSLOffloading enabled
# Created by Martin Sundström 2011-09-26
Write-Host -f DarkGray "This script will configure the Exchange 2010 RTM and SP1 Client Access Servers for SSLOffload"

# Set SSLOffload registry key for OWA 
Write-Host -f DarkGray -f DarkGray "Setting SSLOffload registry key for OWA..."

New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\MSExchange OWA' -Name SSLOffloaded -Value 1 -PropertyType DWORD 

Write-Host -f DarkGray -f DarkGray "Done!"
Write-Host -f DarkGray -f DarkGray ""

# Assign Static Ports"
Write-Host -f DarkGray "Assigning static ports..."

# Assign Static Port for MSExchangeAB 
New-Item -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeAB -Name Parameters -Type Directory
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeAB\Parameters -Name RpcTcpPort -Value 60000 -PropertyType String 

# Assign Static Port for MSExchangeRPC 
New-Item -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeRPC -Name ParametersSystem -Type Directory
New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeRPC\ParametersSystem -Name "TCP/IP Port" -PropertyType DWORD -Value 59532

Write-Host -f DarkGray "Done!"
Write-Host -f DarkGray ""

# Disable RequireSSL on websites
Write-Host -f DarkGray "Disabling RequireSSL on websites..."

."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site" -commitPath:APPHOST -section:access -sslFlags:None -section:basicAuthentication -enabled:true
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/Autodiscover" -commitPath:APPHOST -section:access -sslFlags:None 
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/ecp" -commitPath:APPHOST -section:access -sslFlags:None -section:basicAuthentication -enabled:true
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/EWS" -commitPath:APPHOST -section:access -sslFlags:None -section:basicAuthentication -enabled:true
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/Microsoft-Server-ActiveSync" -commitPath:APPHOST -section:access -sslFlags:None 
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/owa" -commitPath:APPHOST -section:access -sslFlags:None -section:basicAuthentication -enabled:true
."$($env:windir)\system32\inetsrv\appcmd" set config "Default Web Site/rpc" -commitPath:APPHOST -section:access -sslFlags:None 

Write-Host -f DarkGray "Done!"
Write-Host -f DarkGray ""

# Configure Outlook Anywhere
Write-Host -f DarkGray "Configure Outlook Anywhere"

$enabled = Get-OutlookAnywhere -Identity "$($env:COMPUTERNAME)\RPC*" 
If ($enabled) 
	Set-OutlookAnywhere -Identity "$($env:COMPUTERNAME)\RPC*" -SSLOffloading $true
	Write-Host -f DarkGray "Configure Outlook Anywhere and remember to check the box to enable SSL Offloading"

Write-Host -f DarkGray "Done!"
Write-Host -f DarkGray ""

# This part of the script only applies to Exchange Server 2010 RTM, a version check will be made:
$VersionCheck = ((get-exchangeserver -identity ($env:COMPUTERNAME)).AdminDisplayVersion | Out-String ).StartsWith("Version 14.1")

If ($VersionCheck = $False)
	# Configure web.config files
	Write-Host -f DarkGray "Configuring web.config files for RTM..."

	$path = (Get-AutodiscoverVirtualDirectory -Server ($env:COMPUTERNAME)).Path
	(Get-Content $path\web.config) | Foreach-Object {$_ -replace "httpsTransport", "httpTransport"}  | Set-Content $path\web.config
	$path = (Get-WebServicesVirtualDirectory -Server ($env:COMPUTERNAME)).Path 
	(Get-Content $path\web.config) | Foreach-Object {$_ -replace "httpsTransport", "httpTransport"} | Set-Content $path\web.config  

	Write-Host -f DarkGray "Done!"
	Write-Host -f DarkGray ""

# Run IISReset
Write-Host -f DarkGray "Running `"iisreset`" to complete the process..."


Write-Host -f DarkGray ""

Feel free to use and edit as you need and don’t hesitate to drop a comment if you find any errors or have any questions!