Posts tagged ‘powershell’

Adding external contacts to the #Lync addressbook

There are some scenarios where it would be nice to be able to add external contacts to the Lync addresse so that they are searchable for everyone in the organization. Or at least external in the sence that the contact has a sip domain that isn’t supported in the Lync topology.

One such scenario could be an integration with an internal Cisco Telepresence solution.

The way to solve this is to add a contact object to AD that has the msRTCSIP-PrimaryUserAddress attribute populated, and the contact should be added to the address book on the next synchronization pass. I’ve made a script to create this kind of object:

Note that displayName is not required, but if you don’t add it the contact will only display the sipadress in the Lync client. I guess it’s also possible to append other AD attributes to the user such as telephoneNumber.

I got a question about telephoneNumber as well, so I’ve added it as an optional parameter in the script.


#####################################################################################
# New-SipContact.ps1
#
# Creates a contact object in AD that will be included in Lync/OCS address books.
#
#
# Passing parameters:
# .\New-SipContact.ps1 -cn "John Spencer" -path "OU=SIPContacts,DC=contoso,DC=com" -sipaddress "john.spencer@litwareinc.com" -displayname "John Displayname Spencer"
#
# Written by Tom-Inge Larsen (http://www.codesalot.com)
#
#####################################################################################
param($cn,$OUpath,$sipAddress,$displayName="",$telephoneNumber="")

$fullpath= "LDAP://" + $OUpath
$SIPContactOU = [ADSI]$fullpath

$SIPContact = $SIPContactOU.create("contact", "cn=" + $cn)
$SIPContact.Put("Description","SIP Contact Object")
$SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $sipAddress)
if ($displayName -ne "") {
 $SIPContact.Put("displayName", $displayName)
}
$SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $sipAddress)
if ($telephoneNumber -ne "") {
 $SIPContact.Put("telephoneNumber", $telephoneNumber)
}
$SIPContact.setInfo()

I’ve also created one to bulk create contacts from a .csv file


#####################################################################################
# New-SipContactBulk.ps1
#
# Creates a contact object in AD that will be included in Lync/OCS address books.
#
#
# Passing parameters:
# .\New-SipContactBulk.ps1 -OUpath "OU=SIPContacts,DC=contoso,DC=com" -csv "c:\newcontacts.csv"
#
#
# Written by Tom-Inge Larsen (http://www.codesalot.com)
#
#####################################################################################
param($OUpath,$csv)

$fullpath= "LDAP://" + $OUpath
$SIPContactOU = [ADSI]$fullpath

$contacts = Import-Csv -path $csv -header "cn","displayName","sipaddress"

foreach ($contact in $contacts) {

$SIPContact = $SIPContactOU.create("contact", "cn=" + $contact.cn)
 $SIPContact.Put("Description","SIP Contact Object")
 $SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $contact.sipaddress)
 if ($contact.displayname -ne "") {
 $SIPContact.Put("displayName", $contact.displayName)
 }
 $SIPContact.setInfo()
}

The example csv file is here: newcontacts.csv

List static routing config

After adding a static route to Lync (for example when adding a CTP integration) you can use the following command to show the route:
Get-CsStaticRoutingConfiguration Service:Registrar:lspool01.contoso.com
Identity : Service:Registrar:lspool01.contoso.com
Route    : {MatchUri=video.contoso.com;MatchOnlyPhoneUri=False;Enabled=True;ReplaceHostInRequestUri=False}

This will list the static route, but it won’t show all the route details (specifically the route target which is semi often used in troubleshooting) as they are contained inside a Route object in the StaticRoutingConfiguration object. To list the details of the route, do:


$stroute = Get-CsStaticRoutingConfiguration Service:Registrar:lspool01.contoso.com
$stroute.Route

This will give you the content of the route.

Transport               : TransportChoice=Certificate=Microsoft.Rtc.Management.WritableConfig.Settings.SipProxy.UseDefaultCert;Fqdn=vcsc.contoso.com;Port=5061
MatchUri                : video.contoso.com
MatchOnlyPhoneUri       : False
Enabled                 : True
ReplaceHostInRequestUri : False

Script – New-CiscoTelepresenceIntegration.ps1

Script to enable routes from Lync to VCS Control:
######################################################################################################################################################################################
# New-CiscoTelepresenceIntegration.ps1
#
# Adds config in Lync 2010 for integration with Cisco Telepresence (Tandberg)
#
# Can optionally write logs to file or screen using -verbose and/or -logFile inputs
#
# eg.
# Clean Lync installation
# .\New-CiscoTelepresenceIntegration.ps1 -vcscfqdn vcsc011.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Coexisting with OCS 2007 R2
# .\New-CiscoTelepresenceIntegration.ps1 -coexistence $true -r2pool r2pool01.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Migration from OCS 2007 R2 to Lync
# .\New-CiscoTelepresenceIntegration.ps1 -hascoexisted $true -vcscfqdn vcsc011.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Important:
# This will delete any existing static routes created ! Do not run the script with hascoexisted = $true if you have added manual routes other than OCS/Lync/CTP integration
#
# Written by Tom-Inge Larsen (<a href="http://www.codesalot.com">www.codesalot.com</a>), Peder Saether and Trond Egil Gjelsvik-Bakke
# Based on config made by Marjus Sirvinsks (marjuss.wordpress.cm)
#
#######################################################################################################################################################################################
param($logFile,$coexistence=$false,$hascoexisted,$CTPSipDomain,$lsfepool,$r2pool,$vcscfqdn)

if ($logFile -ne $null) {
 $a = "Steps made to enable integration with Cisco Telepresence: `n"
 Out-File -FilePath $logfile -InputObject $a
}

if ($lsfepool -eq $null) {
 $lsfepool = Read-Host "Please enter Lync Front End pool FQDN."
}

if ($CTPSipDomain -eq $null) {
 $CTPSipDomain = Read-Host "Please enter the SIP domain in the Cisco Telepresence environment."
}

if ($coexistence -eq $false) {
 #Change encryption level if SRTP option is not available for VCS
 $mediaconfiguration = get-csmediaconfiguration
 $requireencryption = ($mediaconfiguration.EncryptionLevel -eq "RequireEncryption")
 if ($requireencryption) {
 write-warning "This will set the media encryption level to Support Encryption. Are you sure you want to do this? (y/n)"
 $confirmation = Read-Host

 } else {
 $confirmation = 'y'
 }
 switch ($confirmation) {
 'y' {
 set-CsMediaConfiguration -EncryptionLevel supportencryption

 $registrarid = "service:registrar:"+$lsfepool
 $trustedappregistrar = "Registrar:"+$lsfepool

 if ($hascoexisted -eq $true) {
 Remove-CsStaticRoutingConfiguration -Identity $registrarid
 }

 if ($vcscfqdn -eq $null) {
 $vcscfqdn = Read-Host "Please enter the FQDN for the VCS Control"
 }

 #Establish trust
 $applicationpooladded = $true
 New-CsTrustedApplicationPool -Identity $vcscfqdn -Registrar $trustedappregistrar -site 1 -RequiresReplication $false -ThrottleAsServer $true -TreatAsAuthenticated $true -force

New-CsTrustedApplication -ApplicationID "CiscoTelepresenceDirectSIP" -TrustedApplicationPoolFqdn $vcscfqdn -Port 5061

 #Create static routes if needed

 if ($hascoexisted -eq $true) {
 New-CsRegistrarConfiguration -Identity $registrarid
 }

 New-CsStaticRoutingConfiguration -identity $registrarid

$route = New-CsStaticRoute -TLSRoute -destination $vcscfqdn -port 5061 -matchuri $CTPSipDomain -usedefaultcertificate $true

Set-CsStaticRoutingConfiguration -identity $registrarid -route @{Add=$route}

 Enable-CsTopology
 }
 'n' {
 Write-Warning "No change was made to the topology. Media Encryption Level must be set to Support Encryption"
 if ($logFile -ne $null) {
 $a = "No change has been made. `n"
 Out-File -FilePath $logfile -InputObject $a -Append
 }
 }
 }
}

else {

# If we coexist with R2, we might want to route all traffic via R2 FE, to possibly avoid
 # compromising security with deployments using TCP or if Lync is only intended as a
 # pilot.

 if ($r2pool -eq $null) {
 $r2pool = Read-Host "Please enter OCS 2007 R2 Front End pool FQDN."
 }

 $registrarid = "service:registrar:"+$lsfepool

 New-CsRegistrarConfiguration -Identity $registrarid
 New-CsStaticRoutingConfiguration -identity $registrarid

$route = New-CsStaticRoute -TLSRoute -destination $r2pool -port 5061 -matchuri $CTPSipDomain -usedefaultcertificate $true
 Set-CsStaticRoutingConfiguration -identity $registrarid -route @{Add=$route}

Enable-CsTopology
}

if ($logFile -ne $null) {

$a = "Route added: `n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsStaticRoutingConfiguration $registrarid | Select-Object -ExpandProperty Route | Where-Object {$_.MatchUri -eq $CTPSipDomain} | Out-File -FilePath $logfile -Append
 if ($applicationpooladded -eq $true){
 $a = "`nTrusted Application Pool added:`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsTrustedApplicationPool $vcscfqdn | Out-File $logfile -append
 }
 $a = "`nRegistrar added:`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsStaticRoutingConfiguration $registrarid | Out-File $logFile -append

 if ($confirmation -eq 'y') {
 $a = "`nMedia encryption level was already set to or was set to Support Encryption.`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 }

 Write-Host "Logfile: " $logFile "is written."
}

Disable AD disabled CS users powershell script

I’ve made a script to disable AD disabled users from Lync. The script pulls all AD disabled users and checks if they are disabled for Lync as well. If not, they will be. Optional output to screen and/or file.
#####################################################################################
# Disable-AdDisabledCsUsers.ps1
#
# Pulls all AD disabled users from AD and disables them for Lync as well
#
# Can optionally write logs to file or screen using -verbose and/or -logFile inputs
#
# eg.
#
# .\Disable-AdDisabledCsUsers.ps1 -verbose $true -logFile "c:\logfile.log"
#
#
#
# Written by Tom-Inge Larsen (codesalot.com)
#
####################################################################################
param($verbose,$logFile)
Import-Module active*

if ($logFile -ne "") {
    $logoutput = [System.IO.StreamWriter] $logFile
    $logoutput.WriteLine("AD disabled users that was Lync disabled:")
}

$disabledADusers = Search-ADAccount -AccountDisabled -UsersOnly | Select-Object userprincipalname

$disabledADusers | foreach-object {
    $identity = $_.userprincipalname
    $csuser = Get-CsUser -Identity $identity -ErrorAction SilentlyContinue | Select-Object Enabled

    if ($csuser.enabled -eq $true) {
        Disable-CsUser -Identity $identity
        if ($verbose -eq $true) {
            Write-Host "AD disabled user" $identity "is now disabled for Lync as well"
        }
        if ($logFile -ne "") {
            $logoutput.WriteLine($identity)
        }
    }
}

if ($logFile -ne "") {
    $logoutput.close()
    if ($verbose -eq $true) {
        Write-Host $logFile "written."
    }
}