Set OCS Meeting Policies using a Perl Script

Here's how to set a user's OCS meeting policy (msrtcsip-userpolicy) using a simple Perl script. It took me a while to figure this one out. I haven't seen any examples of this in any languages.

This script requires a little discussion. An OCS user has an Active Directory attribute called msRTCSIP-UserPolicy. This attribute is a list of DNWithBinary objects that contain the distinguished name (DN) of the OCS policy, and some bits that specify whether the policy should be applied as a meeting policy or a voice policy. The msRTCSIP-UserPolicy attribute may point to one policy, or it may point to more than one (if for example you have a meeting policy AND a voice policy). Hopefully these points will become clear when you see the script.

OK, so the first thing you have to do is identify the DN of the policy you want to apply to the user. So here's a quick script that lists all of the OCS policies in your forest, and prints out the name, type and DN of each.

use Win32::OLE;
use XML::Simple;
$dse=Win32::OLE->GetObject("LDAP://RootDSE");
$configDN=$dse->Get("ConfigurationNamingContext");
$ocsPolicyContainerDN="CN=Policies,CN=RTC Service,CN=Services,$configDN";
$ocsPolicyContainer=Win32::OLE->GetObject("LDAP://$ocsPolicyContainerDN");
foreach $ocsPolicy (in $ocsPolicyContainer){
 $policyType=$ocsPolicy->Get("msrtcsip-policyType");
 if($policyType eq "uc"){ $policyType = "Voice Policy"; }
 if($policyType eq "meeting"){ $policyType = "Meeting Policy"; }
 $policyDN=$ocsPolicy->{distinguishedName};
 $policyContent=$ocsPolicy->Get("msRTCSIP-PolicyContent");
 $hashref=XMLin($policyContent);
 $policyName=$hashref->{property}->{Name}->{content};
 print "Policy Name:       $policyName\n";
 print "Policy Type:       $policyType\n";
 print "DistinguishedName: $policyDN\n"; 
 print "\n";
}

OK, now you have the DN for each of your policies. Now for simplicity, let's say you aren't using voice integration, and you just want to apply a meeting policy to a user. Use the next script to apply a single policy to a user. Replace the DN in the beginning of the script with the correct DN of the meeting policy you want to apply.

use Win32::OLE;
$user="myUser";
$meetingPolicy="CN={AF5C03A2-13C7-4E73-82FF-7B7D8ABF4E17},CN=Policies,CN=RTC Service,CN=Services,CN=Configuration,DC=myDomain,DC=com";
$pol1="B:8:01000000:$meetingPolicy";
# search for the user to find the distinguishedName
$dse=Win32::OLE->GetObject("LDAP://RootDSE");
$root=$dse->Get("RootDomainNamingContext");
$adpath="GC://$root";
$base="<".$adpath.">";
$connection = Win32::OLE->new("ADODB.Connection");
$connection->{Provider} = "ADsDSOObject";
$connection->Open("ADSI Provider");
$command=Win32::OLE->new("ADODB.Command");
$command->{ActiveConnection}=$connection;
$command->{Properties}->{'Page Size'}=1000;
$rs = Win32::OLE->new("ADODB.RecordSet");
$command->{CommandText}="$base;(&(objectCategory=User)(¦(cn=$user)(samaccountname=$user)));distinguishedName;subtree";
$rs=$command->Execute;
until ($rs->EOF){
 $dn=$rs->Fields(0)->{Value};
 $userObj=Win32::OLE->GetObject("LDAP://$dn");
 $userObj->Put("msRTCSIP-UserPolicy",$pol1);
 $userObj->SetInfo();
 if(Win32::OLE->LastError() == "0"){
  print "Policy Set Successfully\n";
 }else{
  print "Something Went Horribly Wrong\n";
 }
 $rs->MoveNext;
}

By the way, B:8:01000000 is the prefix that means it's a meeting policy. If you were setting a voice policy, you would use B:8:02000000.

The next script sets both the meeting policy and the voice policy. Here we have to setup an array of policies to stuff into the attribute.

use Win32::OLE;
$user="myUser";
$meetingPolicy="CN={AF5C03A2-13C7-4E73-82FF-7B7D8ABF4E17},CN=Policies,CN=RTC Service,CN=Services,CN=Configuration,DC=myDomain,DC=com";
$voicePolicy="CN={07AADE4C-FFD2-44F6-8B06-9A25057E006E},CN=Policies,CN=RTC Service,CN=Services,CN=Configuration,DC=myDomain,DC=com";
$pol1="B:8:01000000:$meetingPolicy";
$pol2="B:8:02000000:$voicePolicy";
@pols=($pol1,$pol2);
# search for the user to find the distinguishedName
$dse=Win32::OLE->GetObject("LDAP://RootDSE");
$root=$dse->Get("RootDomainNamingContext");
$adpath="GC://$root";
$base="<".$adpath.">";
$connection = Win32::OLE->new("ADODB.Connection");
$connection->{Provider} = "ADsDSOObject";
$connection->Open("ADSI Provider");
$command=Win32::OLE->new("ADODB.Command");
$command->{ActiveConnection}=$connection;
$command->{Properties}->{'Page Size'}=1000;
$rs = Win32::OLE->new("ADODB.RecordSet");
$command->{CommandText}="$base;(&(objectCategory=User)(¦(cn=$user)(samaccountname=$user)));distinguishedName;subtree";
$rs=$command->Execute;
until ($rs->EOF){
 $dn=$rs->Fields(0)->{Value};
 $userObj=Win32::OLE->GetObject("LDAP://$dn");
 $userObj->PutEx(2,"msRTCSIP-UserPolicy",\@pols);
 $userObj->SetInfo();
 if(Win32::OLE->LastError() == "0"){
  print "Policy Set Successfully\n";
 }else{
  print "Something Went Horribly Wrong\n";
 }
 $rs->MoveNext;
}

Hope that helps everyone!


0 comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...