Reinstall the Client Access Role in Windows Small Business Server 2008

Updated: August 5, 2010

Applies To: Windows Server 2008

Warning

You should only uninstall or reinstall the Client Access Role as a last resort. Before you uninstall or reinstall the Client Access Role, you should first troubleshoot the related software and services, and try to isolate the root cause of the issue. If you are unable to determine and correct the root cause, you may be able to fix the issue by restoring the server from a good backup.

Important

You should not perform the steps in this document over a remote connection that uses Remote Web Workplace or Terminal Services Gateway. The certificate that these components use is reset during the process, so you might not be able to reconnect to complete the steps. It is recommended that you complete these steps on-site or that you first install the Windows SBS 2008 root certificate.

To verify whether the Client Access Role is already installed

  1. Click Start, click Control Panel, click Classic View, and then double-click Programs and Features.

  2. Click Microsoft Exchange Server 2007, and then click Change.

  3. On the User Account Control page, click Continue.

  4. In the Exchange Maintenance Mode dialog box, click Next.

  5. In Server Role Selection, if the Client Access Role check box is grayed out or already selected, the role is installed and you do not need to reinstall it. If it is not selected, click Cancel, and then complete the steps in the following procedure.

To reinstall the Client Access Role in Windows Small Business Server 2008

  1. Create a registry value to use with Windows SBS 2008 Disc 2 (Component Technologies for Server Repair) and Microsoft Exchange Server 2007 by doing the following:

Note

You can skip this step if Microsoft Exchange Server 2007 with Service Pack 2 is installed on the server, and if you are using the Exchange Server 2007 SP2 installation folder as the source for the Exchange Server 2007 installation files.

1.  Open Registry Editor.  
      

Warning

Incorrectly editing the registry may severely damage your system. Before making changes to the registry, you should back up any valued data on the computer.

2.  On the **User Account Control** page, click **Continue**.  
      
3.  Navigate to HKEY\_LOCAL\_MACHINE\\SOFTWARE\\Classes\\Installer\\Products\\461C2B4266EDEF444B864AD6D9E5B613\\SourceList\\Media.  
      
4.  Create a new string value named MediaPackage: Right-click **Media**, click **New**, click **String Value**, in **Name** type **MediaPackage**, and then press ENTER.  
      
5.  Double-click **MediaPackage**, in **Edit String**, in **Value data**, type **\\CMPNENTS\\Exchange12\\**, and then click **OK**.  
      
6.  Close Registry Editor.  
      
  1. Install the Client Access Role by doing the following:

    1. Click Start, click Control Panel, click Classic View, and then double-click Programs and Features.

    2. Click Microsoft Exchange Server 2007, and then click Change.

    3. On the User Account Control page, click Continue.

    4. In the Exchange Maintenance Mode dialog box, click Next.

    5. In Server Role Selection, select Client Access Role, and then insert Windows SBS 2008 Disc 2 (Component Technologies for Server Repair) into the server.

Note

If the Client Access Role is grayed out or already selected, the role is installed and you do not need to reinstall it.

6.  In **Specify the path for the Exchange Server installation files**, click **Browse**.  
      
7.  Click **\<DVD Drive\>:\\CMPNENTS\\Exchange12**, where *\<DVD Drive\>* is the name of your media drive, click **OK**, and then click **Next**.  
      

Note

If Service Pack 2 for Microsoft Exchange Server 2007 is installed on Windows SBS 2008, you need to select the Exchange Server 2007 SP2 installation folder as the source for the Exchange Server 2007 installation files.

8.  In the **Readiness Checks** dialog box, click **Install**.  
      

Note

The installation might take several minutes.

9.  When the installation finishes, click **Finish**.  
      
  1. Run Windows PowerShell commands by doing the following:

    1. Copy and paste the following cmdlets into a text file:

      #run script with "casrepair.ps1 -ErrorAction "Continue" to see error messages
      #$script:ErrorActionPreference = "SilentlyCOntinue"
      # Set environmental and global variables variables
      $LocalServerName = hostname
      $ActiveSyncMailboxName = "Windows SBS Mobile Mailbox Policy" + " " + $LocalServerName
      $OABVDir = $LocalServerName + "\OAB (SBS Web Applications)"
      $OAB = Get-OfflineAddressBook | Select-Object -Property Name
      $strDomainDNS = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
      $DomainAdmins = $strDomainDNS + "\Domain Admins"
      $OrgName = Get-OrganizationConfig | Select-Object -Property DistinguishedName
      $DefaultExchangeCertificate = "CN=" + $LocalServerName
      ######################################################################
      #  BackupSettings
      #  Create backups in case we need to revert any changes made by the script
      ######################################################################
      function BackupSettings{
      # first backup IIS
      cd $env:windir\system32\inetsrv
      .\appcmd add backup
      # export AD config
      $mytime = get-date
      $filenum = $mytime.ToFileTime()
      $filename = "$($env:temp)\httpbackup_$($filenum).ldf"
      $root = [ADSI]"LDAP://rootDSE"
      $objConfNamingContext = [ADSI]"LDAP://$($root.configurationNamingContext)"
      $strFilter = "(ObjectClass=msExchProtocolCfgHTTPContainer)"
      $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
      $objSearcher.SearchRoot = $objConfNamingContext 
      $objSearcher.PageSize = 1000
      $objSearcher.Filter = $strFilter
      $objSearcher.SearchScope = "Subtree"
      $colProplist = @("name","distinguishedName")
      # use out-null to supress the 0, 1, etc output
      foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)| out-null} 
      $colResults = $objSearcher.FindAll()
      foreach ($objResult in $colResults)
          {
      $objItem = $objResult.Properties
      ldifde -m -f $filename -d $objItem.distinguishedname
           }
      # backup applicationhost.config manually
      copy -force $env:windir\system32\inetsrv\config\applicationhost.config $env:temp\applicationhost.config_$filenum
      }
      ######################################################################
      #  RemoveDirectoriesUsingPowerShell
      #  First try to use Powershell to gracefully remove the existing
      #  vdirs from the Default Web Site and 
      ######################################################################
      function RemoveDirectoriesUsingPowerShell{
      #remove certificates
      Get-ExchangeCertificate | Where { $_.Subject -eq "$DefaultExchangeCertificate" } | ForEach { Remove-ExchangeCertificate -Thumbprint $_.Thumbprint }
      # clean up any owa virtual directories
      Get-OWAVirtualDirectory | Remove-OWAVirtualDirectory -Confirm:$False
      # delete OWS
      Get-WebServicesVirtualDirectory | Remove-WebServicesVirtualDirectory  -Confirm:$false
      # remove activesync, oab, UM, autodiscovery
      Get-ActiveSyncVirtualDirectory         | Remove-ActiveSyncVirtualDirectory  -Confirm:$false 
      Get-OabVirtualDirectory                | Remove-OabVirtualDirectory -Force:$true -Confirm:$false
      Get-UMVirtualDirectory                 | Remove-UMVirtualDirectory  -Confirm:$false
      Get-AutodiscoverVirtualDirectory       | Remove-AutodiscoverVirtualDirectory  -Confirm:$false
      }
      ######################################################################
      #  RemoveDirectoriesUsingAppcmd
      #  Use appcmd to try to remove any lingering objects that PowerShell 
      #  wasn't able to remove
      ######################################################################
      function RemoveDirectoriesUsingAppcmd{
      # clean up any lingering objects, we'll try via appcmd first, then manually edit
      cd $env:windir\system32\inetsrv
      .\appcmd delete app /app.name:"SBS Web Applications/owa" | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Exadmin"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Exchange"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Exchweb"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Public"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/EWS/bin"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/EWS"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Microsoft-Server-ActiveSync"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/UnifiedMessaging/bin"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/UnifiedMessaging"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Autodiscover/bin"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Autodiscover/help"  | out-null
      .\appcmd delete app /app.name:"SBS Web Applications/Autodiscover"  | out-null
      .\appcmd delete vdir /vdir.name:"SBS Web Applications/OAB"  | out-null
      }
      ######################################################################
      #  RemoveEntriesFromApplicationHost
      #  Finally, if PowerShell and appcmd weren't able to delete the vdirs
      #  we'll remove them from the applicationhost.config
      ######################################################################
      function RemoveEntriesFromApplicationHost{
      $sites = @("owa","ews","UnifiedMessaging","Autodiscover","Exadmin","Exchange","Public","Exchange ActiveSync","Microsoft-Server-Activesync","Exchweb","oab","OAB")
      # load xml file in to memory
      $applicationHost = New-Object XML
      $applicationHost.Load("c:\windows\system32\inetsrv\config\applicationhost.config")
      #default web site and sbs web applications site objects
      $dws = $applicationHost.Configuration."system.applicationHost".sites.site | Where-Object { $_.name -eq 'Default Web Site' }
      $swa = $applicationHost.Configuration."system.applicationHost".sites.site | Where-Object { $_.name -eq 'SBS Web Applications' }
      ##  delete keys values under <customMetadata>
      $keys = $applicationHost.Configuration."system.applicationHost".customMetadata
      # remove paths
      foreach($site in $sites)
      {
      foreach ($key in $keys.key)        { if ($key.path -match $site ){$keys.RemoveChild($key)} }
      # clean up SBS Web Applications first
      foreach ($app in $swa.application) { if ($app.path -match $site) {$swa.RemoveChild($app) } }
      # Get any remnants on the Default Web Site
      foreach ($app in $dws.application) { if ($app.path -match $site) {$dws.RemoveChild($app) } }
      #clean up locations (web sites)
      foreach ($loc in $applicationHost.configuration.location) { if ($loc.path -match $site) { $applicationHost.configuration.RemoveChild($loc) }}
      }
      $applicationHost.Save("c:\windows\system32\inetsrv\config\applicationhost.config")
      iisreset /noforce
      }
      ######################################################################
      #  RemoveEntriesFromAD
      #  Remove lingering AD objects from CN=HTTP,CN=Protocol
      #  CN=HTTP,CN=Protocols,CN=MARKSTANSBS,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrativ
      #   eGroups,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=markstancom,DC=loca
      ######################################################################
      function RemoveEntriesFromAD {
      # TODO - limit to only server itself
      $strFilter = "(&(ObjectClass=msExchVirtualDirectory)(!(name=*rpc*)))"
      $root = [ADSI]"LDAP://rootDSE"
      $objConfNamingContext = [ADSI]"LDAP://$($root.configurationNamingContext)"
      $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
      $objSearcher.SearchRoot = $objConfNamingContext 
      $objSearcher.PageSize = 1000
      $objSearcher.Filter = $strFilter
      $objSearcher.SearchScope = "Subtree"
      $colProplist = @("name","distinguishedName")
      # use out-null to supress the 0, 1, etc output
      foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)| out-null} 
      $colResults = $objSearcher.FindAll()
      foreach ($objResult in $colResults)
          {
      $objItem = $objResult.Properties
      $owadir=[ADSI]"LDAP://$($objItem.distinguishedname)"
      $owadir.psbase.deleteTree()
      write-host "Deleting $($objItem.name)"
           }
      }
      ######################################################################
      #  RecreateDirectories
      #  Creates OWA vdirs using the same settings as SBS default install
      ######################################################################
      function RecreateDirectories{
      #create new vdirs
      New-OWAVirtualDirectory -WebsiteName "SBS Web Applications" -OwaVersion "Exchange2007" -ExternalAuthenticationMethods Fba 
      Set-OWAVirtualDirectory -InternalUrl "https://sites/owa/" -ClientAuthCleanupLevel "Low" -LogonFormat "UserName" -DefaultDomain $strDomainDNS -Identity "Owa (SBS Web Applications)" 
      New-OWAVirtualDirectory -WebsiteName "SBS Web Applications" -OwaVersion "Exchange2003or2000" -VirtualDirectoryType "Exadmin" -ExternalAuthenticationMethods Fba 
      New-OWAVirtualDirectory -WebsiteName "SBS Web Applications" -OwaVersion "Exchange2003or2000" -VirtualDirectoryType "Mailboxes" -ExternalAuthenticationMethods Fba
      New-OWAVirtualDirectory -WebsiteName "SBS Web Applications" -OwaVersion "Exchange2003or2000" -VirtualDirectoryType "Exchweb" -ExternalAuthenticationMethods Fba
      New-OWAVirtualDirectory -WebsiteName "SBS Web Applications" -OwaVersion "Exchange2003or2000" -VirtualDirectoryType "PublicFolders" -ExternalAuthenticationMethods Fba
      New-WebServicesVirtualDirectory -WebsiteName "SBS Web Applications" -InternalUrl "https://Sites/EWS/Exchange.asmx" -basicauthentication 1 -windowsauthentication 1 
      New-ActiveSyncVirtualDirectory -WebsiteName "SBS Web Applications" -InternalUrl "https://Sites/Microsoft-Server-ActiveSync" -ExternalAuthenticationMethods Basic -InternalAuthenticationMethods Basic 
      New-OabVirtualDirectory -WebsiteName "SBS Web Applications" -InternalUrl "https://Sites/OAB"
      Set-OabVirtualDirectory -PollInterval "30" -Identity "oab (sbs web applications)"
      New-UMVirtualDirectory -WebsiteName "SBS Web Applications" -InternalUrl "https://Sites/UnifiedMessaging/Service.asmx" 
      New-AutodiscoverVirtualDirectory -WebsiteName "SBS Web Applications" -InternalUrl "https://Sites/Autodiscover/Autodiscover.xml" -BasicAuthentication 1 -WindowsAuthentication 1 
      #configure vdirs
      Set-ClientAccessServer -Identity $LocalServerName -AutoDiscoverServiceInternalUri "https://sites/Autodiscover/Autodiscover.xml" 
      Set-OfflineAddressBook $OAB.Name -VirtualDirectories $OABVDir -Versions Version2,Version3,Version4 -PublicFolderDistributionEnabled:$True
      iisreset /noforce
      # configure vdirs with SBS defaults
      cd $env:windir\system32\inetsrv
      .\appcmd.exe unlock config "-section:system.webserver/security/authentication/windowsauthentication"
      .\appcmd.exe set config "SBS Web Applications/ews" "-section:windowsAuthentication" "-useKernelMode:False" /commit:apphost
      .\appcmd.exe set config "SBS Web Applications/AutoDiscover" "-section:windowsAuthentication" "-useKernelMode:False" /commit:apphost
      .\appcmd.exe set config "SBS Web Applications/oab" "-section:windowsAuthentication" "-useKernelMode:False" /commit:apphost
      .\appcmd.exe set site "Default Web Site" /Bindings:"http/*:80:"
      .\appcmd.exe start site "Default Web Site"
      .\appcmd.exe start site "SBS Web Applications"
      }
      ######################################################################
      #  Begin main logic flow here
      ######################################################################
      ######################################################################
      BackupSettings
      RemoveDirectoriesUsingPowerShell
      RemoveDirectoriesUsingAppcmd
      RemoveEntriesFromApplicationHost
      RemoveEntriesFromAD
      RecreateDirectories
      ######################################################################
      ######################################################################
      
    2. Name the text file sbscasreinstall.ps1, and then save it in C:\windows\system32.

    3. Open Exchange Powershell: Click Start, click All Programs, click Microsoft Exchange Server 2007, right-click Exchange Management Shell, and then click Run as administrator.

    4. On the User Account Control page, click Continue.

    5. In the Exchange Management Shell, type .\sbsCASreinstall.ps1, and then press ENTER.

    6. Close the Exchange Management Shell.

  2. Update the settings in the Internet Information Services (IIS) Manager by doing the following:

    1. Click Start, click Administrative Tools, and then click Internet Information Services (IIS) Manager.

    2. On the User Account Control page, click Continue.

    3. Expand the name of your Windows SBS 2008 server, and then expand Sites.

    4. Click Default Web Site, and then click Start.

    5. Expand SBS Web Applications, and then click OAB.

    6. In OAB Home, double-click SSL Settings.

    7. Select Require SSL and Require 128-bit SSL, and then click Apply.

  3. Rerun the Internet Address Management Wizard to associate the new virtual directories with the correct external URL.

  4. If your server uses a trusted certificate, you must also run the Add Trusted Certificate Wizard.