Step 1: Extending schema

To prepare Skype for Business online and your own Active Directory to use The Voice of O365, you need to expand your Active Directory schema with the following important attributes:

Active Directory attribute

Attribute name

Correct value for Online user

Correct value for The Voice of O365

Meaning

msRTCSIP-DeploymentLocator

HostingProvider

sipfed.online.lync.com

SRV:

Indicates where the location of the user is (SRV is checking using SRV records).

msRTCSIP-PrimaryUserAddress

SIPAddress

sip: userName @ contoso.com

sip: userName @ contoso.com

Indicates the SIP address of the user

msRTCSIP -UserEnabled

Enabled

True

True

Indicates whether the user is enabled

If you do not perform delegate control in step 5, you must set these values correctly. See below for sample script.

Actions

1. UPDATE AD

  1. Download here or load from a Skype for Business installation DVD / file

    1. ExternalSchema.ldf

    2. ServerSchema.ldf

    3. BackCompatSchema.ldf

    4. VersionSchema.ldf

  2. Open command prompt as administrator and go to the schematic map on the hard drive

  3. Start the commands below (replace dc.contoso.local with the address of a domain controller and "DC=contoso,Dc=local" with the distinguishedName of your AD). 

    ldifde -i -v -k -s dc.contoso.local -f ExternalSchema.ldf -c DC=X "DC=contoso,DC=local" -j c:\Schema ldifde -i -v -k -s dc.contoso.local -f ServerSchema.ldf -c DC=X "DC=contoso,DC=local" -j c:\Schema ldifde -i -v -k -s dc.contoso.local -f BackCompatSchema.ldf -c DC=X "DC=contoso,DC=local" -j c:\Schema ldifde -i -v -s dc.contoso.local -f VersionSchema.ldf -c DC=X "DC=contoso,DC=local" -j c:\Schema -j = Log file location -i = Import operation performed -v = Verbose (show changes on screen) -k = Keep going even if some entries can't be processed -s = Server location -f = File location -c = Change from-string in data to to-string. This lets you customize a generic LDIF file for your installation. For example, from-string might be the placeholder DC=X, and to-string might be your domain DN. Replaces in this case the DC=X without your domain locati

Script to update attributes

Save script below as .ps1 and run on domain controller. Or run from Powershell ISE. Please read the script carefully. SoftApp-distribution is not responsible for running the script.

Param( [ValidateSet("ou","group")] [Parameter(Mandatory=$true)] [string]$user_container, [Parameter(Mandatory=$true)] [string]$user_location, [Parameter(Mandatory=$false)] [ValidateSet("OneLevel","Subtree")] [string]$user_location_scope, [Parameter(Mandatory=$true)] [ValidateSet("onpremise","cloud","clear")] [string] $location ) ##### About script # Created by: Maarten Meijer # Copyright: SoftApp-distribution (2018) # Version: 1.1-b04072018 # 04-07-2018: Added scoping on OU # 04-07-2018: Added option to clear attributes and reset to defaults # 04-07-2018: Changed searching to a Searchbase to limit the results and fix error with incorrect OU name # # Requirements: # - Run on AD domain controller # # Usage: # 1. Just run the script! Parameters will be asked upon running. # Options/Parameters: ## -user_container ==> object that contains the user subset ("group" or "ou") ## -user_location ==> if a "group" is selected enter the sAMACCOUNTNAME here of the group. On selecting a OU enter the DN of the OU (use opening and closing ") ## -location ==> location of the hosted users ("onpremise" or "cloud") ## -user_location_scope ==> depth of OU searching ("OneLevel" or "Subtree") # # Important # This script sets the UPN as the SIGN IN ADDRESS of the user. If those are not the same, modify the script! # # # DO NOT CHANGE ANYTHING BELOW HERE $Logfile = "C:\change_ad.log" Function LogWrite { Param ([string]$logstring) Add-content $Logfile -value $logstring } LogWrite("UPDATE AD: " + (Get-Date).tostring()) LogWrite("user_container: " + $user_container) LogWrite("user_location: " + $user_location) LogWrite("location: " + $location) Import-Module ActiveDirectory Write-Host "[AD UPDATE] Start" -foregroundcolor Green #Get users from OU switch($user_container) { "group" { $found_group = Get-ADGroup -Identity $user_location if ($found_group -ne $null) { $users = Get-ADGroupMember -Identity $user_location | Get-ADuser } else { LogWrite("Unable to find group") Write-Host "Unable to find group" -foregroundcolor red break } } "ou" { #use searchbase instead of pipeline filter, otherwise can catch too many users if string is not correctly formatted. $users = Get-ADUser -Filter {Enabled -eq $true} -SearchBase $user_location -SearchScope $user_location_scope } } foreach ($user in $users) { #update attributes Write-Host "[$($user.UserPrincipalName)] Updating attributes" -foregroundcolor green LogWrite("[$($user.UserPrincipalName)] Updating attributes") if($location -eq "onpremise") { LogWrite("[$($user.UserPrincipalName)] onpremise") Set-ADUser -Identity $user.SamAccountName -replace @{'msRTCSIP-DeploymentLocator'="SRV:";'msRTCSIP-PrimaryUserAddress'="sip:$($user.UserPrincipalName)";'msRTCSIP-UserEnabled'="TRUE";} } elseif ($location -eq "cloud") { LogWrite("[$($user.UserPrincipalName)] cloud") Set-ADUser -Identity $user.SamAccountName -replace @{'msRTCSIP-DeploymentLocator'="sipfed.online.lync.com";'msRTCSIP-PrimaryUserAddress'="sip:$($user.UserPrincipalName)";'msRTCSIP-UserEnabled'="TRUE";} } elseif ($location -eq "clear") { LogWrite("[$($user.UserPrincipalName)] clear") Set-ADUser -Identity $user.SamAccountName -clear @('msRTCSIP-DeploymentLocator';'msRTCSIP-PrimaryUserAddress';'msRTCSIP-UserEnabled';) } } LogWrite("[AD UPDATE] Done") Write-Host "[AD UPDATE] Done" -foregroundcolor Green

Additional information