Read OCS User Properties with PowerShell

Reading OCS User Properties with PowerShell (including those darn policies!): Yes, here's another PowerShell example, I've got the bug now.  Although I'll always be known as a Perl guy, I can see how popular PowerShell is becoming.  Anyway, here's a PowerShell script that reads OCS related attributes from a user in Active Directory, including the msRTCSIP-UserPolicy attribute, which everyone seems to have trouble unraveling.  No surprise, that thing is a pain!

Just so you Perl fans don't get upset, you can find the Perl version of this script in the article - Reading a User's OCS Properties with a Perl Script.

The script takes the user name as a command line argument.  It can be the cn, samAccountName, or displayname of the user.  Use quotes around any user name that contains a space.  If the user name is omitted, the script will get the OCS properties of the currently logged on user.  To run the script, save the code in a file such as getOCSproperties.ps1 and run it from within PowerShell, as shown:

./getOCSproperties.ps1 username

The script uses the System.DirectoryServices.DirectorySearcher to find the user, then retrieves the user's OCS attributes.  As for the policies, which is an (or an array of) DNwithBinary objects, they have to be broken down into their BinaryValue (which tells us what type of policy it is), and the DNString (which holds the distinguished name of the policy object itself).  We then get the policy object and retrieve the policy content, which is a piece of XML.  We can then dig the name of the policy out of the XML and display the policy name and type in the output.  Finally the script breaks down the option flags by bit and displays their status.

By the way, we show how to handle the policies in Perl and VBScript in the articles: msRTCSIP-UserPolicy - Here's How to Read it and msRTCSIP-UserPolicy - Here's How to Write it.

Those articles show how to handle the DNWithBinary objects, but Perl and VBScript access those objects directly via COM.  PowerShell on the other hand, accesses these COM objects through a .Net interop assembly.  Unfortunately, interop lacks the information to handle this type of COM object, so we have to bypass interop by making a direct call to COM, using [System.__ComObject].InvokeMember.  We also use this technique to get the username property from the adsysteminfo object in the beginning of the script to get the currently logged on user.

#get the username from the commandline or use the current username
if($args.count -eq 0){
 $adinfo=New-Object -Com "adsysteminfo"
 $username=[System.__ComObject].InvokeMember("username",[System.Reflection.BindingFlags]::GetProperty,$null,$adinfo,$null)
}else{
 $username=$args[0]
}
#setup a System.DirectoryServices search
$filter = "(&(objectCategory=User)(¦(cn=" + $username + ")(samaccountname=" + $username + ")(displayName=" + $username + ")(distinguishedName=" + $username + ")))"
$domain = New-Object System.DirectoryServices.DirectoryEntry
$searcher = New-Object System.DirectoryServices.DirectorySearcher
$searcher.SearchRoot = $domain
$searcher.PageSize = 1000
$searcher.Filter = $filter
$results = $searcher.FindAll()
if($results.count -eq 0){ "User Not Found"; }else{
 #walk through the users we found
 ""
 foreach ($result in $results){
  $user=$result.GetDirectoryEntry();
  "        -------------------------------------------------------"
  ""
  "`tOCS Properties for:`t" + $user.cn + " (" + $user.displayName + ")"
  # is the user enabled?
  $enabled = "False"
  $enabled=$user.Get("msRTCSIP-UserEnabled")
  trap [System.Runtime.InteropServices.COMException]{
   continue;
  }
  "`t  User OCS Enabled:`t" + $enabled
  if($enabled -eq "True"){
   #user SIP and Pool or Server Name
   "`t  User SIP Address:`t" + $user.Get("msRTCSIP-PrimaryUserAddress");
   $pool = New-Object System.DirectoryServices.DirectoryEntry("LDAP://" + $user.Get("msRTCSIP-PrimaryHomeServer").Substring(28))
   "`t   OCS Pool/Server:`t" + $pool.dNSHostName
   #counfounded policies!
   $policies = $user.Get("msRTCSIP-UserPolicy")
   foreach($policy in $policies){
    $policyDN=[System.__ComObject].InvokeMember("DNString",[System.Reflection.BindingFlags]::GetProperty,$null,$policy,$null)
    $policyBIN=[System.__ComObject].InvokeMember("BinaryValue",[System.Reflection.BindingFlags]::GetProperty,$null,$policy,$null)
    $bits=""
    foreach ($byte in $policyBIN){  $bits=$bits + [string] $byte; }
    $policyType = ""
    if($bits -eq "1000"){ $policyType = "`t    Meeting Policy"; }
    if($bits -eq "2000"){ $policyType = "`t      Voice Policy"; }
    if($bits -eq "4000"){ $policyType = "`t   Presence Policy"; }
    $policyObj = New-Object System.DirectoryServices.DirectoryEntry("LDAP://" + $policyDN)
    $policyName=([xml] $policyObj.Get("msrtcsip-policycontent")).instance.property[0].InnerText
    $policyType +":`t" + $policyName;
   }
   #archiving
   $archive = $user.Get("msRTCSIP-ArchivingEnabled")
   if($archive -eq 0){ $archive = "False"; }else{ $archive = "True"; }
   "`t Archiving Enabled:`t" + $archive;
   #federation
   $federation = $user.Get("msRTCSIP-FederationEnabled")
   if($federation -eq 0){ $federation = "False"; }else{ $federation = "True"; }
   "`tFederation Enabled:`t" + $federation;
   #option flags
   $flags = $user.Get("msRTCSIP-OptionFlags")
   if(($flags -band 1) -eq 1){ $pim = "True"; }else{ $pim = "False"; }
   if(($flags -band 16) -eq 16){ $rcc = "True"; }else{ $rcc = "False"; }
   if(($flags -band 64) -eq 64){ $oam = "True"; }else{ $oam = "False"; }
   if(($flags -band 128) -eq 128){ $uce = "True"; }else{ $uce = "False"; }
   if(($flags -band 256) -eq 256){ $ep = "True"; }else{ $ep = "False"; }
   if(($flags -band 512) -eq 512){ $rcd = "True"; }else{ $rcd = "False"; }
   if(($flags -band 1024) -eq 1024){ $aa = "True"; }else{ $aa = "False"; }
   ""
   "         Public IM Enabled:`t" + $pim
   "       Remote Call Control:`t" + $rcc
   "        Anonymous Meetings:`t" + $oam
   "             Unified Comms:`t" + $uce
   "         Enhanced Presence:`t" + $ep
   "        Rmt Call Dual CTRL:`t" + $rcd
   "            Auto Attendant:`t" + $aa
  }
  ""
 }
 "        -------------------------------------------------------"
 ""
}

Stay tuned for more PowerShell examples, and we'll start posting Lync scripts as soon as our environment is setup!

0 comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...