Import sites and subnets to Skype4B from AD sites and services

Wether it is to use for Call Admission Control or just to get pretty results on the location report on the monitoring server, I usually like to populate network regions, sites and subnets in the Skype for Business topology in every deployment I do.

Untitled picture
Pretty, pretty data 🙂

In many, if not most, environments I deploy in, the admins have taken their time to set up AD sites and services with the correct site names, so there’s no point in doing that job twice. I’ve made this script which takes the contents of the Sites container and imports it into the Skype for Business topology.

I’ve come across a couple of ways to convert AD sites to Skype for Business network topology, either adding all sites to one region, or converting the sites to regions themselves and adding offices manually. I also want to expand the script so that you can choose which region and site a given subnet belongs to for each subnet in sites and services.

Usage:

Run the .ps1 and then

Import-ADSitesAndSubnets -Regionid Someregion

or

 Import-ADSitesAndSubnets -UseSiteAsRegion 

And the script:

 

EnableSessionTicket from Powershell

To get support for Lync and Skype for Business on Windows Server 2012 R2, you need to add a registry key that changes TLS session caching on 2012 R2 Server. This is described here https://support.microsoft.com/en-us/kb/2901554

To create this key, use the following powershell oneliner:

Manage Acano server with Powershell: PSAcano version 0.2 released

v0.1 post is here

I’ve finally gotten time to complete coding of the 0.2 release of the PSAcano powershell module.

The module now contains all GET, POST, PUT and DELETE commands from the Acano API documentation, and everything that is possible to do with the API should now be possible to script in powershell.

Error handling is still not in the module, this is planned for the 0.3 release, I’ll be adding that the next couple of weeks.

You can download the latest release here, or you can clone the project with Git from here.

There are two branches that get updated frequently, master and dev. The master branch will be considered stable, and will have features added between releases. The dev branch is considered unstable and this is where active developement happens.

Here’s an example on how to add a call (call leg) to a coSpace using the module:

Then you can just run

Add-Participant -CoSpace df2d3e44-91ff-48f4-aeca-ffd951641ebe -SipUri anne.wallace@contoso.com

to add a participant.

PS Oneliners: Set Skype4B services to manual or automatic startup

If you need to reboot a Skype for Business server, you might not always want the services to start automatically afterwords for various reasons. For instance if you are doing a shutdown of an entire pool, you’d want to run

Start-CsPool -PoolFqdn skypepool.contoso.com

to do a cold start of the pool, instead of the services starting automatically.

Use these oneliners to set the services to manual startup and back again to automatic afterwords.

Script: Set-CsKhiCollectorSet.ps1

Lync Key Health Indicators are an essential tool in health monitoring your Lync deployment, and is the first step in deploying the Lync Call Quality Methodology

After adding the KHI counters to applicable Lync servers, it can be quite the chore to log in to all of them to start the performance counters. It is possible to reach all computers from a Performance Monitor snapin, but with a lot of servers that too can take some time.

This script finds all servers that normally run KHI counters, and starts or stops the counters on them. It can also get the current running status of the counters. It is also possible to supply a csv with servers to run on to the script.

Download latest version here

Script: Create live tiles that changes power scheme

After i got my Surface Pro, I’ve more often than before found myself needing to change between power schemes. On my laptop, I’ll usually set it to “Max performance” and just leave it there, but on the Surface it’s necessary to conserve power a bit more.

I’ve thought about making a live tile to do this, so I wrote a PowerShell script that will create one live tile for each configured powerscheme on the machine and pins it to the start screen. The code is based on a codesample for creating shutdown tiles, and this ScriptingGuy post. The script needs to be run as Administrator. Enjoy!

Download Create-PowerSchemeTiles.zip or copy the sourcecode:


#requires -Version 3.0

#####################################################################################
# Create-PowerSchemeTiles.ps1
#
# Creates live tiles for all configured power schemes on the machine and pins them to
# the start screen.
#
#
# Usage:
# .Create-PowerSchemeTiles.ps1
#
# Written by Tom-Inge Larsen (<a href="http://www.codesalot.com">http://www.codesalot.com</a>)
#
#####################################################################################

Function CreatePowerSchemeTile
{
    Param
    (
        [parameter(Mandatory=$true)][String[]]$SchemeGUID,
        [parameter(Mandatory=$true)][String[]]$SchemeName
    )
Write-Verbose "Creating Windows shutdown tile to Start menu."

#create a new shortcut
$ShortcutPath = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\" + $SchemeName + ".lnk"
$Shortcut = $WshShell.CreateShortcut($ShortcutPath)
$Shortcut.TargetPath = "$env:SystemRoot\System32\powercfg.exe"
$arguments = "-s " + $SchemeGUID
$Shortcut.Arguments = $arguments
$Shortcut.Save()

#change the default icon of shortcut
$Lnk = $Desktop.ParseName($ShortcutPath)
$LnkPath = $Lnk.GetLink
$LnkPath.SetIconLocation("$env:SystemRoot\System32\ddores.dll",20)
$LnkPath.Save()

#pin application to windows Start menu
$Verbs = $Lnk.Verbs()
Foreach($Verb in $Verbs) {
    If($Verb.Name.Replace("&","") -match "Pin to Start") {
        $Verb.DoIt()
    }
}

If(Test-Path -Path $ShortcutPath) {
    Write-Host "Create" $SchemeName "tile successfully." -ForegroundColor Green
    } Else {
    Write-Host "Failed to create" $SchemeName "tile." -ForegroundColor Red
   }
}

$Shell = New-Object -ComObject Shell.Application
$Desktop = $Shell.NameSpace(0X0)
$WshShell = New-Object -comObject WScript.Shell
$plans = Get-WmiObject -Class win32_powerplan -Namespace root\cimv2\power
$regex = [regex]"{(.*?)}$"
foreach ($plan in $plans) {
    $planGuid = $regex.Match($plan.instanceID.Tostring()).groups[1].value
    $planName = $plan.ElementName.Tostring()
    Write-Debug $planGuid
    Write-Debug $planName
    CreatePowerSchemeTile -SchemeGUID $planGuid -SchemeName $planName
}

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.
Download latest version here – Contains both versions and an example .csv

Or copy the sourcecode:


#####################################################################################
 # 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" -OUpath "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 contains this:

John Spencer,,john.spencer@litwareinc.com
Spencer John,Spencer Displayname John,spencer.john@litwareinc.com