Return the Effective Policy Assignments for a User

You say you want to know which Microsoft Lync Server 2010 policies have been assigned to the user Ken Myer? Well, that’s easy enough; all you have to do is run the following command:

 
Get-CsUser "Ken Myer"

 
In return, Windows PowerShell should show you information similar to this:

 
VoicePolicy : RedmondVoicePolicy
ConferencingPolicy :
PresencePolicy :
DialPlan :
LocationPolicy :
ClientPolicy : RedmondClientPolicy
ClientVersionPolicy :
ArchivingPolicy :
PinPolicy : RedmondPinPolicy
ExternalAccessPolicy :
HostedVoiceMail :
HostedVoicemailPolicy :

 
As you can see, Ken has been assigned three different per-user policies: RedmondVoicePolicy; RedmondClientPolicy; and RedmondPinPolicy. Any other questions?

 
Oh, right: what about all those other policies? Take conferencing policy, for example. There’s nothing listed next to conferencing policy; does that mean Ken is under no restrictions whatsoever when it comes to conferencing?

 
In a word: no. With Lync Server 2010 you are always under the jurisdiction of a policy of some kind; if you haven’t been assigned a per-user conferencing policy that means that you’re either under the sway of a conferencing policy configured for your site or, if there is no such site policy, the global conferencing policy. No user account ever goes unmanaged.

 
So then why doesn’t anything show up next to ConferencingPolicy? Well, as it turns out, Get-CsUser only shows you per-user policies; that’s because that information is stored in Active Directory and is readily available. What the cmdlet doesn’t do is try to resolve the so-called “effective policy;” in other words, it doesn’t try to determine whether Ken’s conferencing behaviors are managed by a site policy or by a global policy. All we know is that those behaviors aren’t managed by a per-user policy.

 
Which simply means this: if you want to determine the effective policy assignments for a user, well, you’re going to have to do that yourself. In the case of a conferencing policy, that means determining the site where Ken Myer’s user account is homed and checking to see if there’s a conferencing policy assigned to that site. If there is, you must then report back the Identity of the site policy; if not, you need to report back the Identity of the global policy. And then you have to repeat this same process for voice policies, dial plans, client version policies, archiving policies, etc., etc.

 
You know, that does sound like an awful lot of work, doesn’t it? Which is why you might want to run this script instead:

 
$y = @()

$user = Get-CsUser $args[0]
$site = (Get-CsSite | Where-Object {$_.Pools -contains $user.RegistrarPool}).Identity

if ($user.ClientPolicy -eq $Null)
    {
        $x = Get-CsClientPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}         

                if ($y -contains "site:$site")
                    {"Client Policy : site:$site"}
                else
                   {"Client Policy : Global policy"}
    }
else
   {"Client Policy : " + $user.ClientPolicy}

 
$y = @()
if ($user.LocationPolicy -eq $Null)

    {
        $x = Get-CsLocationPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Location Policy : site:$site"}
                else
                 {"Location Policy : Global policy"}
    }
else
   {"Location Policy : " + $user.LocationPolicy}

 
$y = @()
if ($user.VoicePolicy -eq $Null)
    {
        $x = Get-CsVoicePolicy

        foreach ($i in $x)
    {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Voice Policy : site:$site"}
                else
                   {"Voice Policy : Global policy"}
    }
else
   {"Voice Policy : " + $user.VoicePolicy}

 
$y = @()
if ($user.ConferencingPolicy -eq $Null)
    {
        $x = Get-CsConferencingPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
          
                if ($y -contains "site:$site")
                    {"Conferencing Policy : site:$site"}
                else
                   {"Conferencing Policy : Global policy"}
    }
else
   {"Conferencing Policy : " + $user.ConferencingPolicy}

 
$y = @()
if ($user.PresencePolicy -eq $Null)
    {
        $x = Get-CsPresencePolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Presence Policy : site:$site"}
                else
                   {"Presence Policy : Global policy"}
    }
else
   {"Presence Policy : " + $user.PresencePolicy}

 
$y = @()
if ($user.ArchivingPolicy -eq $Null)
    {
        $x = Get-CsArchivingPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Archiving Policy : site:$site"}
                else
                   {"Archiving Policy : Global policy"}
    }
else
   {"Archiving Policy : " + $user.ArchivingPolicy}

 
$y = @()
if ($user.PinPolicy -eq $Null)
    {
        $x = Get-CsPinPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Pin Policy : site:$site"}
                else
                   {"Pin Policy : Global policy"}
    }
else
   {"Pin Policy : " + $user.PinPolicy}

 
$y = @()
if ($user.ExternalAccessPolicy -eq $Null)
    {
        $x = Get-CsExternalAccessPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"External Access Policy : site:$site"}
                else
                   {"External Access Policy : Global policy"}
    }
else

   {"External Access Policy : " + $user.ExternalAccessPolicy}

 
$y = @()
if ($user.HostedVoiceMailPolicy -eq $Null)
    {
        $x = Get-CsHostedVoiceMailPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
         

                if ($y -contains "site:$site")
                    {"Hosted Voice Mail Policy : site:$site"}
                else
                   {"Hosted Voice Mail Policy : Global policy"}

     }
else
   {"Hosted Voice Mail Policy : " + $user.HostedVoiceMailPolicy}

 
$y = @()
if ($user.ClientVersionPolicy -eq $Null)
    {
        $x = Get-CsClientVersionPolicy

        foreach ($i in $x)
            {$y += ($i.Identity)}
                if ($y -contains "Service:Registrar:" + $user.RegistrarPool)

                   {"Client Version Policy : Service:Registrar:" + $user.RegistrarPool}
                elseif ($y -contains "site:$site")
                    {"Client Version Policy : site:$site"}
                else
                   {"Client Version Policy : Global policy"}
    }
else
   {"Client Version Policy : " + $user.ClientVersionPolicy}

 
$y = @()
if ($user.DialPlan -eq $Null)
    {
        $x = Get-CsDialPlan

        foreach ($i in $x)
            {$y += ($i.Identity)}
                if ($y -contains "Service:Registrar:" + $user.RegistrarPool)
                   {"Dial Plan : Service:Registrar:" + $user.RegistrarPool}
             elseif ($y -contains "site:$site")
                    {"Dial Plan : site:$site"}
                else
                   {"Dial Plan : Global dial plan"}
    }
else
   {"Dial Plan : " + $user.DialPlan}

 
We aren’t going to bother trying to explain how this script works; suffice to see if methodically takes each policy type, checks to see if the user has been assigned a per-user policy and, if not, checks to see if that user is under the jurisdiction of a site policy or the global policy. (And, in the case of dial plans and client version policies, whether the user is managed by a service-scoped policy instead.) For now, all you need to know is that the script just needs the Identity of the user. For example, if you’ve saved this script as C:\Scripts\Get-EffectivePolicy.ps1 you simply need to run a command like this one:

 
C:\Scripts\Get-EffectivePolicy.ps1 "Ken Myer"

 
Do that, and PowerShell will reward you with output similar to this:

 
Client Policy : RedmondClientPolicy
Location Policy : site:Redmond
Voice Policy : RedmondVoicePolicy
Conferencing Policy : Global policy
Presence Policy : Global policy
Archiving Policy : site:co1
Pin Policy : RedmondPinPolicy
External Access Policy : site:Redmond
Hosted Voice Mail Policy : Global policy
Client Version Policy : Service:Registrar:red-cs-001.vdomain.com
Dial Plan : site:co1

 
Pretty cool, huh?