Track Lync Schema update with Powershell
When I perform schema changes in very large forests it is nice to be able to track the status of the change as it replicates throughout the forest. I wanted to create a script that would quickly tell me what the current schema was on over 100 DCs.
If you don’t want to see how it was done you can just Download Track-LyncSchema.ps1
Starting with some scripts that I have built before foreach-parallel
to do parallel
processing, get-forestDomainControlles
to get a list of all DCs in the forest
and get-LdapData
to do direct ldap lookups quickly. get-LdapData
is necessary
because it will take too long to import the AD module into each thread of the parallel processor.
Import-module ActiveDirectory
function get-ForestDomainControllers () {...}
function get-ldapData ($ldapfilter,$searchRoot,$Server,[switch]$GC,$pageSize=1000,$Properties="*",$sizeLimit=0,[switch]$verbose,$o365FilterAddress){...}
function ForEach-Parallel () {...}
First we need to get all the DCs into an array, this can take a long time for large domains. We will only get the list if $DCs is empty - this way we can run this script multiple times but only do this step once.
if ($DCs -eq $null) {$DCs = get-ForestDomainControllers}
Next we locate the schema partition - likewise we only want to do this once. The PartitionsContainer
value on the AD forest object has a value like DC=Partitions,CN=Configuration,DC=Domain,DC=com
.
We will use -replace
to replace the partitions value with cn=schema
to get the schema partition.
if ($SchemaPartiton -eq $null) {$SchemaPartition = (get-adforest).partitionscontainer -replace 'CN=Partitions','CN=Schema'}
To get the Lync Schema version we need the rangeUpper value of the ms-RTC-SIP-SchemaVersion object in the schema partition. To do that, we will use get-ldapdata
with the searchroot
specified as the Lync schema object. In this code $_
represents the server being worked on in the pipeline when we do foreach.
$Value = get-ldapdata -searchRoot "CN=ms-RTC-SIP-SchemaVersion,$SchemaPartion" -properties rangeupper -server $_ | select -expand rangeupper
ForEach-Parallel
makes use of worker threads for parallelism, so we need to import the functions into the thread and also any values we want to pass. To get the $SchemaPartition
value into the thread, we pass it using the -Arguments
parameter and then the first
line of the executed code includes $SchemaPartition=$args[0]
Depending on the value, we want to return text that tells us what the version is, for this we use a switch statement
switch ($value) {
'1006' {$value = "LCS 2005 [$value]"}
'1007' {$value = "OCS 2007 R1 [$value]"}
'1008' {$value = "OCS 2007 R2 [$value]"}
'1100' {$value = "Lync Server 2010 [$value]"}
'1150' {$value = "Skype for Business 2015 [$value]"}
default: {$value = "Unknown schema value or no value [$value]"}
}
Then we export the value to an object so that it looks like a nice table and we can manipulate it if we want.
new-object psobject -Property @{server=$_;LyncSchemaVersion=$value}
The function that does the work looks like this. The foreach-parallel
command ends with -ImportFunctions
to import the get-ldapdata
into scope of each thread.
function track-LyncSchema {
$DCs.hostname | %p{
$SchemaPartition= $args[0]
$Value = get-ldapdata -searchRoot "CN=ms-RTC-SIP-SchemaVersion,$SchemaPartition" -properties rangeupper -server $_ | select -expand rangeupper
switch ($value) {
'1006' {$value = "LCS 2005 [$value]"}
'1007' {$value = "OCS 2007 R1 [$value]"}
'1008' {$value = "OCS 2007 R2 [$value]"}
'1100' {$value = "Lync Server 2010 [$value]"}
'1150' {$value = "Skype for Business 2015 [$value]"}
default {$value = "Unknown [$value]"}
}
new-object psobject -Property @{server=$_;LyncSchemaVersion=$value}
} -ImportFunctions get-ldapData -arguments $schemaPartition
}
We call the script from the commandline to get a list of all the servers and the schema version.
. .\track-LyncSchema.ps1
server LyncSchemaVersion
------ -----------------
TestDC100.wrish.com Skype for Business 2015 [1...
TestDC101.wrish.com Skype for Business 2015 [1...
TestDC213.wrish.com Skype for Business 2015 [1...
TestDC12.wrish.com Skype for Business 2015 [1...
...
Because we built the script to output objets, we can easily see how many are left to replicate.
. .\track-lyncschema.ps1 | group LyncSchemaVersion
Count Name Group
----- ---- -----
202 Skype for Business 2010... {@{server=Test..
20 Lync Server 2010 [1100] {@{server=Test..