Thursday, 18 October 2012

Setting up Meet URLs in Lync Server 2010 Multitenant

In this article I'm going to explain how I solved the problem of setting up the tenant meet URLs correctly in Lync Server 2010 Multitenant Pack for Parner Hosting. Microsoft released a special version of Lync Server 2010 intended just for hosting organizations that want to provide Lync services to multiple distinct organizations.

The deployment guide for this scenario can be very confusing in some sections and it takes multiple reading as well as good Lync 2010 background to get it right. But I still believe that some procedures in the document are not correct. The section that gave me the most trouble was about setting up simple URLs for hosted organizations.

In on-premise installation of Lync 2010 there is usually one SIP domain and one set of simple URLs. However, in multitenant installation there are multiple SIP domains, one SIP domain for each tenant.

The deployment guide in one section states that one should use Topology Builder to setup the meet URLs for a tenant. In a dynamic environment like multitenant hosting where you would use custom built provisioning service to set up tenants, you cannot rely on Topology Builder. Furthermore, if you try to run the scripts offered for setting up meet URLs (section 8.11.3), you would get the following error:

There must be an Active URL for Meet for each SIP Domain.

What this actually means is that you cannot set up one Meet URL for one SIP domain and assign it to one tenant organization and do the same for each tenant. That would make sense but it does not work. What you must do is create Meet URLs for all SIP domains and assign them all to a single tenant. And you must do that for each tenant.

This is the script I first wrote following the deployment guide:

#get your tenant GUID
$TenORgID = xxxx-xxxx-xxxx-xxxx-xxxx

#assing a SIP domain to a variable
$SIPDomain1 = ""

#generate a base URL for your Meet URL
$URL1 =  "" + $SIPDomain1

#generate a Simple URL entry
$urlEntry1 = New-CsSimpleUrlEntry -Url $URL1

#generate a Simple URL for the meet component and assing all the variables
$simpleUrl1 = New-CsSimpleUrl -Component "meet" -Domain $SIPDomain1 -SimpleUrl $urlEntry1 -ActiveUrl $URL1

#assign the Simple URL to your tenant
Set-CsSimpleUrlConfiguration –Tenant $TenORgID -SimpleUrl @{Add=$simpleUrl1}  -ErrorAction Stop

If you wrote the same script it means you too followed the deployment guide. The script would work if you have only one SIP domain on the system, but if you have multiple SIP domains you would get the error above.

So, the solution is to modify the script to create Simple URLs for each SIP domain and assign all these Simple URLs to a single tenant. And you must do that for all your tenants. The good thing is that, as you add new tenants and create SIP domain for each tenant, you must create Simple URLs for all SIP domains that exist on your system at that time but you don't have to fix each and every tenant. So, for a single tenant system, you would only create one Simple URL. When you add your second tenant, you would create two Simple URLs and assign them to your second tenant, three Simple URLs for your third tenant and so forth. As you add your tenants, your Simple URLs list would grow for your new tenants but you won't have to go back and correct the previously added tenants.

So, for your second tenant, let's name him Fabrikam, you would have a script like this:

$TenORgID = xxxx-xxxx-xxxx-xxxx-xxxx

$SIPDomain1 = ""
$SIPDomain2 = ""

$URL1 =  "" + $SIPDomain1
$URL2 =  "" + $SIPDomain2

$urlEntry1 = New-CsSimpleUrlEntry -Url $URL1
$urlEntry2 = New-CsSimpleUrlEntry -Url $URL2

$simpleUrl1 = New-CsSimpleUrl -Component "meet" -Domain $SIPDomain1 -SimpleUrl $urlEntry1 -ActiveUrl $URL1
$simpleUrl2 = New-CsSimpleUrl -Component "meet" -Domain $SIPDomain2 -SimpleUrl $urlEntry2 -ActiveUrl $URL2

Set-CsSimpleUrlConfiguration –Tenant $TenORgID -SimpleUrl @{Add=$simpleUrl1,$simpleUrl2}  -ErrorAction Stop

But of course, in a dynamic environment you must have more automated way of creating Meet URLs for new tenants. So I wrote the following script:

$OUName = "IT Solution Braindumps"
$PathRoot = "OU=OCS Tenants,DC=cloud,DC=local"
$TargetOU = "OU="+$OUName+","+$pathRoot
$TenantOU = Get-ADOrganizationalUnit -Identity $TargetOU -Properties msRTCSIP-TenantId -Server ""
$TenORgID = New-Object -TypeName System.guid -ArgumentList $TenantOU.ObjectGUID

$Count = 0

$SIPDomain = @()
$URL = @()
$URLEntry = @()
$SimpleUrl = @()

$siparray = Get-CsSipDomain

foreach($sip in $siparray)
 $SIPDomain += $sip.Identity
 $URL += "" + $SIPDomain[$Count]
 $URLEntry += New-CSSimpleUrlEntry -Url $URL[$Count]
 $SimpleUrl += New-CsSimpleUrl -Component "meet" -Domain $SIPDomain[$Count] -SimpleUrl $URLEntry[$Count] -ActiveUrl $URL[$Count]

Set-CsSimpleUrlConfiguration -Tenant $TenORgID -SimpleUrl @{Add=$SimpleUrl} -ErrorAction Stop

After the script executes you will get the following warning:

WARNING: Activation (Enable-CsComputer) may need to be re-run on impacted Front End servers.

Execute Enable-CsComputer and you are done.

The previous script fully automates generation of Simple URLs based on all existing SIP domains on a system and assignes them all to a tenant. When adding new tenant to your Lync 2010 hosting environment you can just automatically run this script.

Once you setup your tenant Meet URLs correctly, the tenant users would be able to succesfully schedule Online Meetings from Outlook and the meeting URL for other users to connect would be correctly populated.


There is one more thing to do. Tenant users must be configured with the correct Base URL for their tenant organization. Base URL is configured on the msRTCSIP-BaseSimpleUrl property for each tenant user in Active Directory. Here is how to do that:

$SIPDomain = ""
$CompanyName = "IT Solution Braindumps"
$BaseURL = ""+$SIPDomain
$PathRoot = "OU=OCS Tenants,DC=cloud,DC=local"
$TargetOU = "OU="+$CompanyName+","+$PathRoot
$OUObject = Get-ADOrganizationalunit -Identity $TargetOU

Get-ADUser -LDAPFilter "(objectClass=user)" -SearchBase $TargetOU -Properties msRTCSIP-BaseSimpleUrl -Server "" |Set-ADUser -Replace @{'msRTCSIP-BaseSimpleUrl'=$BaseURL}

Without setting this property your users would get this error when they click on the meet URL:

Error: Meeting URL is not valid.

Lync Server 2010 Logging Tool will also return this error:

Failed to find a domain mapping for this BaseURL

So you need to make sure that msRTCSIP-BaseSimpleUrl is set at the moment you provision tenant users.

There it is, I hope I made it clear enough for you to be able to set Meet URLs for tenant organizations in Lync. If you have troubles getting this to work please let me know. Also, if you have a better way to solve this problem, please share it here. I'm not going to exclude a possibility that I got everyhing wrong, but this is a configuration that works in my environment.

Wednesday, 17 October 2012

Trouble installing Exchange 2010 SP2 Rollup 4 v2

If you have trouble with the installation of KB2756485, that is, Rollup 4-v2 for Exchange Server 2010 SP2, you must run the installer from the elevated command prompt like this:


Once the installation starts, be patient because it can take a while.

If you just double click on the .msp file from Windows Explorer, the installation will start but it will very soon rollback and you will see this error in the application log:

Log Name:      Application
Source:        MsiInstaller
Date:          16.10.2012. 10:30:01
Event ID:      1024
Task Category: None
Level:         Error
Keywords:      Classic
User:          DOMAIN\username
Product: Microsoft Exchange Server - Update 'Update Rollup 4-v2 for Exchange Server 2010 Service Pack 2 (KB2756485) 14.2.318.4' could not be installed. Error code 1603. Windows Installer can create logs to help troubleshoot issues with installing software packages. Use the following link for instructions on turning on logging support:

You may also ran into some blog posts that say to try setting the execution policy in Powershell from RemoteSigned to Unrestricted, but that did not help in my case.

There, I hope it helps someone.