LyncIn1Box: Installing Lync on a Domain Controller

You might noticed when you try to install Lync on a Domain Controller the bootstrapper stops on the prerequirements phase that ‘the product cannot be installed on a DC.
Why you might want to do this? For lab resource savings (one single server, less administration)
Why it’s not possible? By analysing the structure of the product modules, most of them are configured with ACL’s, local group accounts and services with the computer Network Service Account. When you promote the computer to a DC, you loose access to those accounts and local groups.

On this post you will find the manual instructions to perform an installation of Lync Standard Edition with IM, enterprise voice (collocated mediation server) and conferencing. This is the first version, it has not been fully tested and… it will not be a valid configuration supported by Microsoft.
With more time I will try to post a script file to execute this steps automatically. But if you follow this instructions you just have to copy/paste the commands (identified in brown) and execute on your server.
The scripting is designed to run with any computername, domain or lync names, so you don’t have follow exactly the names shown. All instructions are to be performed with an elevated previleges command prompt, with a domain administrator account.

1. The environment requirements

This configuration was sucessfully tested on a virtual environment:

  • 2 vCPU, 4GB RAM, 16+10GB vHDD (drive C and D);
  • Windows 2008 R2 Standard edition server;
  • Server with an Active directory, DNS and a Enterprise Root CA and Powershell.
  • The Lync server setup binaries (virtual cd, local or network drive);

After you setup your server and install de AD, DNS and a CA… start the command prompt (run as an administrator).
2. The first requiremente are the windows components:
POWERSHELL -Command “Import-Module ServerManager; Add-WindowsFeature NET-Framework,web-server,Web-Static-Content,Web-Default-Doc,Web-Http-Errors,Web-Http-Redirect,Web-Asp-Net,Web-Net-Ext,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Http-Logging,Web-Log-Libraries,Web-Http-Tracing,Web-Windows-Auth,Web-Client-Auth,Web-Filtering,Web-Stat-Compression,Web-Mgmt-Console,Web-Scripting-Tools -verbose”
3. Install windows media package
dism.exe /online /norestart /add-package /packagepath:%windir%\servicing\Packages\Microsoft-Windows-Media-Format-Package~31bf3856ad364e35~amd64~~6.1.7601.17514.mum /ignorecheck
4. Althought the system doesn’t report de need, you should reboot the server because the VC2008 component will fail to install due to a lock down condition caused by the previous components. After log in open again the command prompt

5. The script guided variables

The script will follow all the settings defined by this variables that you must provide. If you restart your server in the middle of this instructions you need to set these environment variables. You can define/change the following variables:

  • SETUPSRV – The path where the Lync setup binaries are located (the amd64 from the original ISO)
  • LYNCDIR – Root folder where Lync will be installed;
  • SQLEXP – folder installation of sql express executables binaries (databases will be installed on %LYNCDIR%\DB)
  • SETUPLOG – almost all script commands will write log at this location. This will help you troubleshooting any problem.

Here are the values I used:
SET SETUPSRC=D:\Temp\Lync 2010\amd64
SET LYNCPS=%CommonProgramFiles%\Microsoft Lync Server 2010\Modules\Lync\Lync.psd1

6. Lync AD prep and central management store

Creating the log folder and jumping to the setup source binaries folder:
VC++2008 and SQL 2005 backward compatibility (to old for Lync no?)
%RUN% vcredist_x64.exe /q
%RUN% Msiexec /i SQLServer2005_BC.msi /qb! /L*v “%SETUPLOG%\SQLServer2005_BC.log”
Now for the first Lync base common and administration tools
%RUN% Msiexec /i setup\OcsCore.msi ADDLOCAL=Feature_OcsCore REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /qb! /L*v “%SETUPLOG%\Feature_OcsCore.log”
CMD /C Msiexec /i setup\UcmaRunTime.msi ADDLOCAL=Feature_UCMARuntime REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” BOOT=1 /qb! /L*v “%SETUPLOG%\Feature_UCMARuntime.log”
CMD /C Msiexec /i setup\AdminTools.msi ADDLOCAL=Feature_AdminTools REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /qb! /L*v “%SETUPLOG%\Feature_AdminTools.log”
Active Directory preparation
powershell.exe -command “Import-Module ‘%LYNCPS%’;Install-CsAdServerSchema -verbose -Report ‘%SETUPLOG%\Install-CsADServerSchema.html’;Get-CsAdServerSchema”
powershell.exe -command “Import-Module ‘%LYNCPS%’;Enable-CsAdForest -verbose -Report ‘%SETUPLOG%\Install-CsADForest.html’;Get-CsAdForest”
powershell.exe -command “Import-Module ‘%LYNCPS%’;Enable-CsAdDomain -verbose -Report ‘%SETUPLOG%\Install-CsADDomain.html’;Get-CsAdDomain”
SQL Express setup – this is the first trick: custom setup SQL to run services with the LocalSystem account
(tip: you can use a more recent version of SQL express like SP3)

Create the databases for the central management store
powershell.exe -command “Import-Module ‘%LYNCPS%’;$sysinfo = Get-WmiObject -Class Win32_ComputerSystem;$fqdn = ‘{0}.{1}’ -f $sysinfo.Name, $sysinfo.Domain;Install-CsDatabase -CentralManagementDatabase -SqlServerFqdn $fqdn -SqlInstanceName RTC -UseDefaultSqlPaths -Clean -Verbose -Report ‘%SETUPLOG%\Install-CentralManagementDatabase.html'”
COPY “%TEMP%\Create-CentralMgmtStore-ONESERVER*.log” “%SETUPLOG%”

7. Topology building

Now for the manual part (still don’t get it why there are not commands for that…).
Create the file share before because topology builder cannot do that and will generate an error:
ICACLS %LYNCSHARE% /inheritance:r
ICACLS %LYNCSHARE% /remove “BUILTIN\Administrators:(F)”
ICACLS %LYNCSHARE% /grant “BUILTIN\Administrators:(OI)(CI)(F)”
Run topology builder and create a new topology. I will not post pictures, so each bullet correspond to a windows wizard. you can choose the names, but your better follow the options in green:

  • Primary SIP Domain: <your sip domain>
  • < you can add additional sip domains>
  • First Site Name: <define your site name>
  • <No site details>
  • Open new Front End wizard
  • Front End pool fqdn
    FQDN: <your server fqdn>
    Select option: Standard Edition Server
  • Select features:
    Check Conferencing, which includes audio, video and application Sharing
    Check Enterprise voice
  • Select collocated server roles
    Check Collocate Mediation Server
  • Associate server roles…<No roles selected>
  • Define SQL store <no selections are possible>
  • Define a new file share
    File server FQDN: <your server fqdn>
    File Share: lyncshare
  • Specify the web services URL
    Keep the suggested External base URL
  • Specify PSTN gateways <none select>

You can now choose ‘publish topology’. On ‘Select Central Management Server’, click ‘Advanced’ and select ‘Use SQL Server Instance Defaults’. You should have a Lync Standard Topology similar to the one on the picture.

8. Trick #1 – “local groups” and security

With a standard edition server, from this point configurations are based on local groups create at the server level. This will result in setup fails and errors. To control and minimize we will create domain local groups identical to a normal setup with the required membership:
Powershell.exe -command “Import-Module activedirectory;New-ADGroupRTC Component Local Group‘ -GroupScope DomainLocal -Description ‘Lync Server Web Components And MCU service accounts are granted appropriate local permissions through this group’ -Verbose;Add-ADGroupMember ‘RTC Component Local Group’ ‘RTCComponentUniversalServices’,’RTCUniversalServerAdmins’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Local Administrators’ -GroupScope DomainLocal -Description ‘RTC domain Server Administrators get local Central Management database access through this group’ -Verbose;Add-ADGroupMember ‘RTC Local Administrators’ ‘Domain Admins’,’RTCUniversalServerAdmins’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Local Config Replicator’ -GroupScope DomainLocal -Description ‘Lync Server replication services are granted appropriate local permissions through this group’ -Verbose;Add-ADGroupMember ‘RTC Local Config Replicator’ ‘RTCUniversalConfigReplicator’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Local Read-only Administrators’ -GroupScope DomainLocal -Description ‘RTC domain Read-only Administrators get local Central Management database access through this group’ -Verbose;Add-ADGroupMember ‘RTC Local Read-only Administrators’ ‘RTCUniversalReadOnlyAdmins’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Local User Administrators’ -GroupScope DomainLocal -Description ‘RTC domain User Administrators get local DCOM permissions through this group’ -Verbose;Add-ADGroupMember ‘RTC Local User Administrators’ ‘RTCUniversalUserAdmins’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Server Applications’ -GroupScope DomainLocal -Description ‘Lync Server Server applications are granted appropriate local permissions through this group’ -Verbose”
Powershell.exe -command “Import-Module activedirectory;New-ADGroup ‘RTC Server Local Group’ -GroupScope DomainLocal -Description ‘Lync Server service accounts are granted appropriate local permissions through this group’ -Verbose;Add-ADGroupMember ‘RTC Server Local Group’ ‘RTCHSUniversalServices'”

9. Trick #2 – Central application databases

The following command normally would create all the required databases:
Install-CsDatabase -ConfiguredDatabases -SqlServerFqdn <localserverfqdn>-UseDefaultSqlPaths
but will fail on this case, because will try to assign local groups and permissions (server\group name) and they are not to be found.
So lets execute the database procedures with the ‘fixed’ local groups ;):
PUSHD “%CommonProgramFiles%\Microsoft Lync Server 2010\DbSetup”
cscript.exe //Nologo “DbSetup.wsf” /clean /sqlserver:%computername%.%userdnsdomain%\rtc /serveracct:%userdomain%\RTCHSUniversalServices;”%userdomain%\RTC Server Local Group” /adminacct:%userdomain%\RTCUniversalServerAdmins;”%userdomain%\RTC Local Administrators” /roacct:%userdomain%\RTCUniversalReadOnlyAdmins /role:se /verbose > “%SETUPLOG%\DbSetup-BackEndStore.log”
cscript.exe //Nologo “RtcAbDBSetup.wsf” /clean /sqlserver:%computername%.%userdnsdomain%\rtc /serveracct:%userdomain%\RTCComponentUniversalServices;”%userdomain%\RTC Component Local Group” /verbose > “%SETUPLOG%\DbSetup-ABStore.log”
cscript.exe //Nologo “RgsConfigDbSetup.wsf” /clean /sqlserver:%computername%.%userdnsdomain%\rtc /serveracct:%userdomain%\RTCComponentUniversalServices;”%userdomain%\RTC Component Local Group” /adminacct:%userdomain%\RTCUniversalServerAdmins /roacct:%userdomain%\RTCUniversalReadOnlyAdmins /verbose > “%SETUPLOG%\DbSetup-ApplicationStore.log”
cscript.exe //Nologo “RgsDynDbSetup.wsf” /clean /sqlserver:%computername%.%userdnsdomain%\rtc /serveracct:%userdomain%\RTCComponentUniversalServices;”%userdomain%\RTC Component Local Group” /adminacct:%userdomain%\RTCUniversalServerAdmins /roacct:%userdomain%\RTCUniversalReadOnlyAdmins /verbose >> “%SETUPLOG%\DbSetup-ApplicationStore.log”
cscript.exe //Nologo “CpsDynDbSetup.wsf” /clean /sqlserver:%computername%.%userdnsdomain%\rtc /serveracct:%userdomain%\RTCComponentUniversalServices;”%userdomain%\RTC Component Local Group” /adminacct:%userdomain%\RTCUniversalServerAdmins /roacct:%userdomain%\RTCUniversalReadOnlyAdmins /verbose >> “%SETUPLOG%\DbSetup-ApplicationStore.log”
cscript.exe //Nologo “xdssetup.wsf” /setsecurity /sqlserver:%computername%.%userdnsdomain%\rtc /publisheracct:%userdomain%\RTCUniversalServerAdmins;”%userdomain%\RTC Local Administrators” /replicatoracct:%userdomain%\RTCUniversalConfigReplicator;”%userdomain%\RTC Local Config Replicator” /consumeracct:%userdomain%\RTCUniversalReadOnlyAdmins;”%userdomain%\RTC Local Read-only Administrators” /role:master /verbose > “%SETUPLOG%\DbSetup-SetSecurity.log”

10. Trick #3 – Local database and replication service

The ‘rtclocal’ database SQL setup is similar to the central management store ‘rtc’
The setup of the replication service that will sync the central ‘XDS’ database with the local one:
will report a sucessfull install, but will not install anything… so we have to manually recreate all his actions.
10.1. creating the local xds database
PUSHD “%CommonProgramFiles%\Microsoft Lync Server 2010\DbSetup”
cscript.exe //U //Nologo xdssetup.wsf /clean /publisheracct:”%userdomain%\RTC Local Administrators” /replicatoracct:”%userdomain%\RTC Local Config Replicator” /consumeracct:”%userdomain%\RTC Server Local Group”;”%userdomain%\RTC Component Local Group”;”%userdomain%\RTC Local Read-only Administrators” /role:replica /verbose > “%SETUPLOG%\DbSetup-LocalReplica.log”
10.2. Creating the replica shared folder
MKDIR “%LYNCDIR%\xds-replica”

NET SHARE xds-replica=”%LYNCDIR%\xds-replica” /GRANT:”RTC Local Config Replicator,FULL”
ICACLS “%LYNCDIR%\xds-replica” /grant “RTC Local Config Replicator:(OI)(CI)(F)”
ICACLS “%LYNCDIR%\xds-replica” /remove “BUILTIN\Users”
 10.3. Manually extract and install the binary files and registry settings
%RUN% Msiexec /a setup\OcsCore.msi TARGETDIR=”%TEMP%\OcsCore” /passive /l “%SETUPLOG%\Feature_LocalStore.log”
XCOPY “%TEMP%\OcsCore\Program Files\Microsoft Lync Server 2010\Server\Replica Replicator Agent” “%LYNCDIR%\Server\Replica Replicator Agent\”
REG ADD “HKLM\Software\Microsoft\Real-Time Communications\{2A0B4BB2-4921-4b40-BA9E-81747CB84635}” /v “Version” /d “4.0.7577.0” /f
REG ADD “HKLM\Software\Microsoft\Real-Time Communications\{2A0B4BB2-4921-4b40-BA9E-81747CB84635}” /v “InstallDir” /d “%LYNCDIR%\\” /f
REG ADD “HKLM\Software\Microsoft\Real-Time Communications\{F812C31A-2347-41de-9B1B-E8E412051254}” /v “Version” /d “4.0.7577.0” /f
REG ADD “HKLM\Software\Microsoft\Real-Time Communications\{F812C31A-2347-41de-9B1B-E8E412051254}” /v “InstallDir” /d “%LYNCDIR%\\” /f
10.4. Create the replica service
SC CREATE REPLICA binpath= “%LYNCDIR%\Server\Replica Replicator Agent\ReplicaReplicatorAgent.exe -s /replicaRootDir:%LYNCDIR%\ /sqlInstance:(local)\rtclocal /sqlDatabase:xds” type= own start= auto DisplayName= “Lync Server Replica Replicator Agent” obj= LocalSystem

SC description REPLICA  “Lync Server Replica Replicator Agent”
SC sidtype REPLICA unrestricted
SC failure REPLICA reset= 86400 actions= restart/180000/restart/180000/noaction/0
POWERSHELL -Command “$objUser = New-Object System.Security.Principal.NTAccount(‘RTC Local Config Replicator’);$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]);$strSID.Value”>”%TEMP%\SID1.txt” && SET /P SID1= <“%TEMP%\SID1.txt”
10.5. Initial XDS database copy and replica configuration
powershell.exe -command “Import-Module Lync;$config = Export-CSConfiguration -AsBytes -Verbose;Import-CSConfiguration -ByteInput $config -LocalStore -Verbose;Enable-CSReplica -Verbose -Confirm:$false -Report ‘%SETUPLOG%\Enable-CSReplica.html'”
Note: Enable-CSReplica will generate an error while trying to add a ‘replica’ account to group… No problem. We just need it to configure the firewall and service validation

11. The quiet part

The main Lync services components setup are executed almost the same way as the bootstrapper does, with a difference: I only installed the english speech languages. You can copy/paste all the commands and wait. I put some comments to explain what they are, but will not interfere on the process.
ECHO …IIS URL Rewrite Module 2
%RUN% Msiexec /i rewrite_2.0_rtw_x64.msi REBOOT=ReallySuppress /qb! /L*v “%SETUPLOG%\rewrite_2.0_rtw_x64.log”
ECHO …Visual J# 2.0
%RUN% vj2se_x64.exe /Q:A /C:”install /QB!”
ECHO …Microsoft Server Speech Platform Runtime
%RUN% Msiexec /i setup\speech\SpeechPlatformRuntime.msi REBOOT=ReallySuppress /QB! /L*v “%SETUPLOG%\SpeechPlatformRuntime.log”
ECHO ……English Speech
%RUN% Msiexec /i setup\speech\en-US\MSSpeech_TTS_en-US_Helen.msi REBOOT=ReallySuppress /QB! /L*v “%SETUPLOG%\MSSpeech_TTS_en-US_Helen.log”
%RUN% Msiexec /i setup\speech\en-US\MSSpeech_SR_en-US_TELE.msi REBOOT=ReallySuppress /QB! /L*v “%SETUPLOG%\MSSpeech_SR_en-US_TELE.log”
ECHO …Unified Communications Managed API 3.0, Windows Workflow Activities Runtime
%RUN% Msiexec /i setup\ucmaworkflowruntime.msi REBOOT=ReallySuppress CLIENTUILEVEL=3 /QB! /L*v “%SETUPLOG%\ucmaworkflowruntime.log”
ECHO …Conferencing Server (Common Feature for OcsMCU) – needed to manually fix ACL
%RUN% Msiexec /i setup\OcsMcu.msi ADDLOCAL=OcsMCUCommon REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\OcsMCUCommon.log”
ICACLS “%LYNCDIR%\OCSMCU” /grant “RTC Component Local Group:(OI)(CI)(RX)”
ECHO …Conferencing Server (Application Sharing Server)
%RUN% Msiexec /i setup\OcsMcu.msi ADDLOCAL=ASMCU REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\ASMCU.log”
ECHO …Conferencing Server (Audio/Video Conferencing Server)
%RUN% Msiexec/i setup\OcsMcu.msi ADDLOCAL=AVMCU REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\AVMCU.log”
ECHO …Application Host
%RUN% Msiexec /i Setup\AppServer.msi ADDLOCAL=Feature_AppServer REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB!  /L*v “%SETUPLOG%\Feature_AppServer.log”
ECHO …Audio Test Service
%RUN% Msiexec /i Setup\Ats.msi ADDLOCAL=Feature_Ats REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_Ats.log”
ECHO …Call Park Services
%RUN% Msiexec /i Setup\CPS.msi ADDLOCAL=Feature_CPS REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_CPS.log”
ECHO …Web Conferencing Server
%RUN% Msiexec /i Setup\DataMcu.msi  ADDLOCAL=Feature_DataMCU REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\DataMCU.log”
ECHO …Core Management Server (Core Management Server)
%RUN% Msiexec /i Setup\MgmtServer.msi ADDLOCAL=Feature_MGMTServer REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_MGMTServer.log”
ECHO …Core Management Server (Master Replication Agent)
%RUN% Msiexec /i Setup\MgmtServer.msi ADDLOCAL=Feature_Master REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_Master.log”
ECHO …Core Management Server (File Transfer Agent)
%RUN% Msiexec /i Setup\MgmtServer.msi ADDLOCAL=Feature_FTA REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_FTA.log”
ECHO …Mediation Server
%RUN% Msiexec /i Setup\MediationServer.msi ADDLOCAL=Feature_MediationServer REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_MediationServer .log”
ECHO …Response Group Service
%RUN% Msiexec /i Setup\Rgs.msi ADDLOCAL=Feature_RGS REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_RGS.log”
ECHO …Lync Server
%RUN% Msiexec /i Setup\Server.msi ADDLOCAL=Feature_Server REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Server.log”
ECHO …Web Components Server (Common Files)
%RUN% Msiexec /i Setup\WebComponents.msi ADDLOCAL=Feature_WebComponents_CommonFiles REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_WebComponents_CommonFiles.log”
ECHO …Web Components Server (Reach Web)
%RUN% Msiexec /i Setup\WebComponents.msi ADDLOCAL=Feature_WebComponent_ReachWeb REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_WebComponent_ReachWeb.log”
ECHO …Reach Fonts
%RUN% Msiexec /i Setup\ReachFonts.msi ADDLOCAL=Feature_WebComponent_ReachFonts REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\Feature_WebComponent_ReachFonts.log”
ECHO …Web Components Server
%RUN% Msiexec /i Setup\WebComponents.msi ADDLOCAL=Feature_WebComponents_CommonFiles,Feature_WebComponent_AddressBook,Feature_WebComponent_AuthFramework,Feature_WebComponent_AdminUI,Feature_WebComponent_CertProv,Feature_WebComponent_DataMCUWeb,Feature_WebComponent_DevUpdate,Feature_WebComponent_DialinPage,Feature_WebComponent_GroupExpansion,Feature_WebComponent_JoinLauncher,Feature_WebComponent_LocationInfo,Feature_WebComponent_MeetingMCUWeb,Feature_WebComponent_OcsPowershell,Feature_WebComponent_Rgs,Feature_WebComponent_ReachWeb,Feature_WebComponent_WebTicket REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\WebComponents_All.log”
ECHO …Conferencing Server (IM Conferencing Server)
%RUN% Msiexec /i Setup\OcsMcu.msi ADDLOCAL=IMMCU REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\IMMCU.log”
ECHO …Conferencing Server (Web Conferencing Compatibility Server)
%RUN% Msiexec /i Setup\OcsMcu.msi ADDLOCAL=MeetingMCU REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\MeetingMCU.log”
ECHO …Registrar Store
%RUN% Msiexec /i Setup\Server.msi ADDLOCAL=RegistrarStore REBOOT=ReallySuppress INSTALLDIR=”%LYNCDIR%” /QB! /L*v “%SETUPLOG%\RegistrarStore.log”
ECHO … Exiting source setup dir folder
ECHO …Enable server roles (firewall config, register services,ACL’s. You can ignore the error related t add account to groups)
Powershell -Command “Import-Module  ‘%LYNCPS%’;Enable-CsComputer -Verbose -Report ‘%SETUPLOG%\Enable-CsComputer.html'”

12. Server Certificates

First detect local CA setting to use on the request command:
FOR /F “tokens=3*” %x in (‘REG QUERY HKLM\SYSTEM\CurrentControlSet\services\CertSvc\Configuration /v Active’) DO @SET CANAME=%x%y
FOR /F “tokens=3*” %x in (‘REG QUERY HKLM\SYSTEM\CurrentControlSet\services\CertSvc\Configuration\%CANAME% /v CASERVERNAME’) DO @SET CAFQDN=%x%y
Now lets request the certificates. I choose to separate the Default and Webinternal from the External
%RUN% POWERSHELL -Command “Import-Module ‘%LyncPS%’;$cert=Request-CSCertificate -New -Type Default,WebServicesInternal -CA ‘%CAFQDN%\%CANAME%’ -FriendlyName ‘LyncDefInternal’ -KeySize 2048 -PrivateKeyExportable $False -Verbose -Report ‘%SETUPLOG%\Request-CSCertificate-DefaultInternal.html’ ;Set-CSCertificate -Type Default,WebServicesInternal -Verbose -Confirm:$false -Thumbprint $cert.thumbprint -Report ‘%LYNCLOG%\Set-CSCertificate-DefaultInternal.html'”

%RUN% POWERSHELL -Command “Import-Module ‘%LyncPS%’;$cert=Request-CSCertificate -New -Type WebServicesExternal -CA ‘%CAFQDN%\%CANAME%’ -FriendlyName ‘LyncExternal’ -KeySize 2048 -PrivateKeyExportable $False -Verbose -Report ‘%SETUPLOG%\Request-CSCertificate-WebExternal.html’ ;Set-CSCertificate -Type WebServicesExternal -Verbose -Confirm:$false -Thumbprint $cert.thumbprint -Report ‘%LYNCLOG%\Set-CSCertificate-WebExternal.html'”

13. Almost there – the main trick

At this point you should have all the Lync services on the computer. You can confirm that they are configured with the NetworkService account, which is going to fail when starting the service. Will will change this and fix  some services enablement the the Enable-CSComputer didn’t complete (don’t know where it fails)

A similar ‘Identity tunning’ is required on the Lync Web applications.

ECHO … detecting IIS installation folder
FOR /F “tokens=3*” %x in (‘REG QUERY HKLM\SYSTEM\CurrentControlSet\services\W3SVC\Parameters /v InstallPath’) DO ECHO SET IIS=%x%y>%temp%\IIS.CMD
ECHO …Changing application identity
FOR %p IN (CSExtAuthAppPool CSExtConfAppPool CSExternalAppPool CSExtReachAppPool CSExtSearchAppPool CSIntAuthAppPool CSIntConfAppPool CSInternalAppPool CSIntReachAppPool CSIntSearchAppPool) DO (“%IIS%\appcmd” set config /section:applicationPools /[name=’%p’].processModel.identityType:LocalSystem)
It is necessary to fix the Web service startup. The default web site is started and prevents the Lync Internal site to start
POWERSHELL -Command “Import-Module WebAdministration; Stop-WebSite ‘Default Web Site’ -Verbose;Start-WebSite ‘Lync Server Internal Web Site’ -Verbose;Start-WebSite ‘Lync Server External Web Site’ -Verbose”
Note: After the first reboot go to the IIS MMC and check if the Default Web site has started again. If so, fix it using the MMC.

14. It show time – start the engines!

Now is just time to start and tune the system:
ECHO …Disable CDR and QoE monitoring
POWERSHELL -Command “Import-Module ‘%LYNCPS%’;Set-CsCdrConfiguration -Identity global -EnableCDR $false -Verbose;Set-CsQoEConfiguration -Identity Global -EnableQoE $false -Verbose”
ECHO …Starting Lync Services
POWERSHELL -Command “Import-Module ‘%LYNCPS%’;Start-CsWindowsService -Verbose -Report ‘%SETUPLOG%\Start-LyncServices.html'”
Go to the Lync Event Log and check for any important errors.

Only just some final recommendations to get all great:

  • Add administrator account to Lync administrators
    Powershell.exe -command “Import-Module activedirectory;Add-ADGroupMember ‘CSAdministrator’ Administrator -Verbose”
  • Install Silverlight. You will need touse Lync Control Panel
  • Configure DNS for internal autodiscover and the simple URLs. here’s my sample:
    DNSCMD %computername% /RecordAdd lync.local _sipinternaltls._tcp SRV 0 0 5061 %computername%.%userdnsdomain%
    DNSCMD %computername% /RecordAdd lync.local meet CNAME oneserver.lync.local.
    DNSCMD %computername% /RecordAdd lync.local dialin CNAME oneserver.lync.local.
  • Reboot the server to see if everything is stable

15. The final result

Now you should have a Lync lab with only one server. This is just a Proof-of-concept, but the initial tests I made show that most of the features are available… even a videoconferencing as shown

Feedback is very welcomed


36 thoughts on “LyncIn1Box: Installing Lync on a Domain Controller

  1. cheapest dedicated server 29/02/2012 / 21:17

    Do you have any video of that? I’d love to find out some additional information.

  2. goodthings2life 21/04/2012 / 22:29

    When I run the PowerShell command to create the central management database, it generates the following error:

    Install-CsDatabase : Cannot bind parameter ‘SqlServerFqdn’. Cannot convert value “” to type “Microsoft.Rtc.Management.Deploy.Fqdn”. Error: “Invalid fully qualified domain name (FQDN).

    Any thoughts on how to get past that?

    • LuisR 22/04/2012 / 21:09

      open a powershell and run the commands:
      $sysinfo = Get-WmiObject -Class Win32_ComputerSystem
      $fqdn = “{0}.{1}” -f $sysinfo.Name,$sysinfo.Domain

      Does it shows your computer fqdn?
      What is your Windows Domain dns you choose?

  3. goodthings2life 22/04/2012 / 21:23

    Ah, figured it out… your posted command has a small error and should be (fixing a couple ” and ‘ issues):

    powershell.exe -command “Import-Module ‘%LYNCPS%’;$sysinfo = Get-WmiObject -Class Win32_ComputerSystem;$fqdn = ‘{0}.{1}’ -f $sysinfo.Name, $sysinfo.Domain;Install-CsDatabase -CentralManagementDatabase -SqlServerFqdn $fqdn -SqlInstanceName RTC -UseDefaultSqlPaths -Clean -Verbose -Report ‘%SETUPLOG%\Install-CentralManagementDatabase.html'”

    • LuisR 23/04/2012 / 18:10

      Where right. Thanks for the correction 😉
      Please feel free to give suggestions, and if the Cookbook works at your envirnment

  4. Monty 24/04/2012 / 08:18

    Im getting error on 10.1:
    Unrecognized argument: local
    So this command doesnt accept spaces between ‘RTC local Administrator’
    Is there a workaround?

    • LuisR 25/04/2012 / 08:22

      It one more missing quotes case. Fixed!
      Thanks for testing

  5. Mike 25/06/2012 / 00:45

    When I run the PowerShell command to create the central management database, it generates the following error:

    Error: An error occurred: “Microsoft.Rtc.Common.Data.SqlConnectionException” “A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)”

    Wouldn’t the same approach apply to SQL Server 2012?
    – Mike

    • LuisR 25/06/2012 / 12:32

      sql 2012 is not supported for Lync
      this is due to the client connectivity changes on sql

  6. Mike 01/07/2012 / 21:14

    *sigh* ok a slight set-back here. (Who would have dreamed that Lync2010 would not be patched for SQL2012 … talk about a weird thing).

    Fought my way back in, though. Now experimenting with the same setup on SQL2008 R2 (DataCenter).

    Got way past the former obstacle, but seem to get stuck again here at 10.1, when trying to create the local xds database.

    I get the error: “Error starting SQL Server on zzz\rtclocal” … blablabla … “Ensure that zzz\rtclocal is a valid SQL instance”.

    LuisR … what’s with my gear here?

    There’s not much of an indication of error prior to this. What’s happening here.

    – Mike

    • LuisR 06/07/2012 / 08:14

      The SQL2008R2 (datacenter) is a separate SQL server from the DC/Lync server?

      • Mike 09/07/2012 / 11:09

        The SQL2008R2 (DataCenter) is a standard-installation (completely green-flagged) on the DC. I try to put Lync on top of this … but wait a minute … you are saying that I should just skip the SQL2008R2 (DataCenter) installation? (That SQL simply installs as part of your guide?)

        Thanks for taking the time LuisR!
        – Mike

      • luis-ramos 09/07/2012 / 17:30

        The script instructions of this blog are using with a SQL2008 express edition installation (step 6). SQL2008R2 started support after the Lync RTM release, so I might need to run Lync updates pack, to check if you can go around this. (Lync setup checks for the SQL version)


  7. Mike 10/07/2012 / 21:48

    It could be a warmly welcomed sweet extension to the impressive setup you’ve managed here. Man, luis-ramos, your natural born continuosly curious inquiry into this matter is astonishingly admirable. Please – please! – keep the world posted on your cool endeavours.

    – Mike

  8. anakkin 13/07/2012 / 14:11

    I lost 2 days on that tutorial solving hundreds problems, but finally it works. Please, fix all ‘ and “, because both cmd and PowerShell display it as normal characters, but they’re not working as they should :/

    • LuisR 13/07/2012 / 18:57

      You had better luck than me. It tooked me 3 weeeks of testing and troubleshooting to create this script.

      The problem might be with the copy/paste to and from the way wordpress and different browsers handle those characters.

      personal reminder: better upload a txt file with the scripts

  9. Mike 15/07/2012 / 16:54

    @anakkin: The copy/paste issue is hinted by a few of the other testers in this thread already.

    Lifting this thing into the realms of more combinations of OS’ and especially SQL Server versions would be very welcomed extension.

    Keep it up, LuisR!

    Thanks, man.

  10. Mike 01/08/2012 / 00:16

    I finally gave it another go with SQL Express 2008.

    I made a clean install. No signs of errors anywhere. Everything ran in accordance with prescription – EXCEPT – I cannot LOG ON to Lync 2010 Control Panel, neither from browser (server.domain/cscp) nor Control Panel.

    Unauthorized: Authorization failed.
    The application cannot verify your credentials.

    Verify your logon credentials and contact your support team.

    The Event Viewer does not seem to hint any problems.

    The account is Administrator with CSAdministrator membership. I tried creating a new account with all CS* memberships to no avail.

    It seems so close – and yet so far away, hahaha!

    Do you have any ideas, LuisR?


    – Mike

  11. AB 16/08/2012 / 09:46

    excellent post but if you get the error “ERROR_SQL_DMO_UNAVAILABLE – “Microsoft.Rtc.Common.Data.SqlConnectionException” “Cannot open database “xds” requested by the login. The login failed. Login failed for user ‘GCOM\Administrator’.” , you have to manually run the Lync install (Setup\amd64\Setup.exe) and run “Prepare first standard edition server”. Once done , try to publish again .. should work

  12. Pooh and Yoon 22/08/2012 / 22:43

    Great! all done. but can’t login to the control panel. any.. clue???

    • LuisR 04/09/2012 / 18:09

      Check the IIS CSManagementAppPool identity. It should be running with the localsystem account.

  13. megasema 26/12/2012 / 22:19

    Trying to publish the topology and getting the following error:
    Error: Script failed (code “ERROR_NO_DB_DRIVE_ACCESS”) when installing “CentralMgmtStore” on “\rtc”. For details, see the following log file: “C:\Users\Administrator\AppData\Local\Temp\Create-CentralMgmtStore-home.lynclab.com_rtc-[2012_12_26][14_17_55].log”
    any chance to help me?

    • LuisR 27/12/2012 / 17:02

      I believe, it could be that you don’t have a second disk drive (D:) configured, full or the setup account lost access to this drive/folder.

  14. Chris 11/02/2013 / 20:28


    I’ve got Lync Server 2013 and want to install it on Windows Server 2012 Datacenter! Would you be so nice to give me and the world a instruction for installing Lync Server 2013 on a Domaincontroller 2012.

    • LuisR 11/02/2013 / 21:03

      Yeah it would be nice.
      Unfortunally, as you notice I have little time to publish new posts.
      And I have no feedback from others if my procedures really worked for them 😦

  15. Bruce Wong 22/04/2013 / 15:37

    Hi. LuisR,

    I am installing Lync 2013 Enterprise with SQL server 2008 R2 as backend. When publishing topology. I always found below error (i extracted the most important part). Do you have any idea on it? Thanks.

    InstallDatabaseInternalFailure: An internal error has occurred while trying to create or update the database.
    Error: Invalid account ‘AM\RTCUniversalConfigReplicator’ specified specified for login. The account is of type ‘NtAccountTypeUnknown’ where as the permitted account types are group or user.

    InstallDatabaseInternalFailure: An internal error has occurred while trying to create or update the database.
    Error: Invalid account ‘AM\RTCUniversalReadOnlyAdmins’ specified specified for login. The account is of type ‘NtAccountTypeUnknown’ where as the permitted account types are group or user.

    • LuisR 22/04/2013 / 20:33

      I didn’t tried Lync 2013 on a 2008R2/2012? DC … I’m working on it 😉
      But it looks like you are trying to add the RTCUniversal groups and they are still not created on the DC.

  16. Distributor Tas Rajut KAAY 05/11/2014 / 03:44

    Excellent post. I’m dealing with a few of these issues as well..

  17. Stephen White 16/03/2015 / 01:37

    Hi Luis –


    I’m trying to install Lync 2013 and I get stuck at step #9. The WSF files you reference that are supposed to be in the “%CommonProgramFiles%\Microsoft Lync Server 2010\DbSetup” folder are not there, and I can’t find any WSF file in any of the Lync folders.

    Any ideas here?


    Stephen White

    • LuisR 16/03/2015 / 21:08

      Hello Stephen
      I didn’t create any support for Lync 2013 😦
      Probably the database setup in Lync 2013 has different scripts or another approach.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

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

Google+ photo

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

Twitter picture

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

Facebook photo

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


Connecting to %s