Alan's sysadmin Blog

Working smarter not harder

Archive for the ‘Lync 2013’ Category

PS Script: Auto Generating New Extensions in Lync

Posted by Alan McBurney on August 29, 2014

This a script I’ve been meaning to put together for a while in order to find free extensions within a given extension range in Lync.

Within Lync I assign all enterprise voice users with a phone number and extension.
Some users have a DDI assigned whilst others use the base office number with an extension.

Each office has its own extensions range

100 – 109 HQ response Groups
110 – 299 HQ Users
300 – 399 Branch Office 1
400 – 499 Branch Office 2

Over time and depending on who activates new staff members the extensions tend to get out of sequence, so finding the next available extension within a range can be tedious.

The Get-FreeExtensions.ps1 script makes finding available extensions a lot easier.

The script has 4 parameters:
BaseNumber
ExtensionsRequired
ExtRangeStart
ExtRangeEnd

BaseNumber is the base number to search against without the +, ExtensionsRequired is the number of extensions that are needed within a given range, where ExtRangeStart and ExtRangeEnd define the range.

The script is run as the example below in order to generate 5 free extensions within the range 110 to 299

Get-FreeExtensions.ps1 -BaseNumber 442890454433 -ExtensionsRequired 5 -ExtRangeStart 110 -ExtRangeEnd 299

The script will always find the free extensions in ascending numerical order

<#
  .SYNOPSIS
  Finds free extensions within a given range
 
  .Author
  Alan.McBurney
 
  THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
  RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
 
  Version 1.0, August 28th, 2014
  Version 1.1, December 16th, 2014
 
    .Description
  This script will find the next available extension(s) within a given extension range.
  The script searches for extensions across:
    Users
    RgsWorkflows
    AnalogDevices
    CommonAreaPhones
    Unified Messaging
    MeetingRooms
  The script will also throw a warning if the number of required extensions are not
  available within the given range.
  
  .PARAMETER -BaseNumber
  This the base number to search for a free extension within
  
  .Parameter -ExtensionsRequired
  This is the number of free extensions that are required
  
  .Parameter -ExtRangeStart
  This is the start of the range to query
  
  .Parameter -ExtRangeEnd
  This is the end of the Range to query
  
  .Example
  Get-FreeExtensions.ps1 -BaseNumber 442890454433 -ExtensionsRequired 5 -ExtRangeStart 100 -ExtRangeEnd 199
#>
param
(
  [parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Base Number without +')][long]$BaseNumber,
  [parameter(Position=2,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Number of Extensions Required')][int]$ExtensionsRequired,
  [parameter(Position=3,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Extension Range Start')][int]$ExtRangeStart,
  [parameter(Position=4,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Extension Range End')][int]$ExtRangeEnd
)
  
#Check to Ensure Lync Module is loaded or can be loaded
Function Get-MyModule
{
  Param([String]$Name)
  if (-not(Get-Module -name $Name))
  {
    if(Get-Module -ListAvailable | Where-Object {$_.Name -eq $Name})
    {
      Import-Module -Name $Name
    }
    else
    {
      Write-Host $Name PowerShell Module Not Available -ForegroundColor Red
    }
  }
}
  
Get-MyModule -Name Lync
  
Function Get-LyncExtensions
{
  $Extensions = @()
  $Extensions += (Get-CsUser).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsUser).PrivateNumber | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsRgsWorkflow).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsAnalogDevice).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsCommonAreaPhone).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsExUMContact).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsMeetingRoom).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  if (($Extensions).Count -gt "0")
    {
      $Extensions -replace "tel:\+$BaseNumber;ext=" | Sort
    }
}

If ((Get-LyncExtensions).Count -eq "0")
{
  Write-Host "Invalid Base Number detected, please ensure the base number is valid" -ForegroundColor Red
}
Else
{   
$UnUsedCount = 0
$ExtRange = ($ExtRangeStart..$ExtRangeEnd)
$FreeExt = @()
$UsedExt = Get-LyncExtensions
$CompareUsed = Compare-Object $UsedExt $ExtRange
   
foreach ($ext in $CompareUsed)
{
  if($ext.sideIndicator -eq "=>") {$FreeExt+=$ext.inputobject;$UnUsedCount++}
}
  
if ($ExtRangeStart -gt $ExtRangeEnd)
{
  Write-Host "Extension End Range must be equal or greater to Extension Start Range" -ForegroundColor Yellow
  } elseif ($ExtensionsRequired -gt $ExtRange.Count) {
    Write-Host "Extensions Required is greater than Specifed Extensions Range. Please ammend the Extension Range End parameter" -ForegroundColor Yellow
  } elseif ($ExtensionsRequired -gt $UnUsedCount) {
    Write-Host "Not enough free extensions within the specified range $ExtRangeStart-$ExtRangeEnd Maximum is $UnUsedCount" -ForegroundColor Yellow
  } else {
    $FreeExt | Select -First $ExtensionsRequired
  }
}

Posted in Lync, Lync 2013, PowerShell | Tagged: , , , , | Leave a Comment »

Script: Fixing Orphaned AdminSDHolder Accounts

Posted by Alan McBurney on August 27, 2014

This is intended as a follow up to Detecting members of Protected Groups within AD

It seems that no matter how many Exchange or Lync projects I do I always come across the issue of orphaned AdminSDHolders.

To overcome the tedium of detecting and fixing orphaned users I decided to put together a script to automate the task.

This script gets all users that are members of protected groups within AD and compares membership with users that have the AD Attribute AdminCount=1 set. If the user has the AdminCount=1 enabled but is not a member of a protected group within AD then the user is considered orphaned, the AdminCount is reset to 0 and inheritable permissions are enabled.

<#
.SYNOPSIS
Detects Orphaned SD Admin users, resets admin count attribute and enables inheritable permissions

.Author
Alan.McBurney

THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.

Version 1.0, July 10th, 2014

.DESCRIPTION
This script gets all users that are members of protected groups within AD and compares
membership with users that have the AD Attribute AdminCount=1 set.
If the user has the AdminCount=1 enabled but is not a member of a protected group then the user
is considered an orphaned admin user and the AdminCount is reset to 0 and inheritable permissions
are reset

.REFERENCES
"http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx">http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx</a>
"http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx">http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx</a>

.EXAMPLE
Reset-OrphanSDUsers

.Notes
To Do list: Enable logging
#>

#Check to Ensure Active Directory PowerShell Module is available within the system
Function Get-MyModule
{
Param([string]$name)
if(-not(Get-Module -name $name))
  {
    if(Get-Module -ListAvailable |Where-Object { $_.name -eq $name })
    {
      Import-Module -Name $name
      $True | Out-Null
    }
    else
    {
      Write-Host ActiveDirectory PowerShell Module Not Available -ForegroundColor Red
    }
  } # end if not module
  else
  {
    $True | Out-Null
  }   #module already loaded
} #end function get-MyModule

Get-MyModule -name "ActiveDirectory"

Function Set-Inheritance
{
Param($ObjectPath)
$Acl = Get-ACL -path "AD:\$ObjectPath"
  If ($Acl.AreAccessRulesProtected -eq $True)
  {
    $Acl.SetAccessRuleProtection($False, $True)
    Set-ACL -AclObject $ACL -path "AD:\$ObjectPath"
  }
}

#Get List of Proected Groups
$AdminGrp = Get-ADGroup -LDAPFilter "(adminCount=1)"

#Get List of Admin Users (Past and Present)
$AdminUsers = Get-ADUser -LDAPFilter "(adminCount=1)"

$Admins = ForEach ($Grp in $AdminGrp) {Get-ADGroupMember $Grp | Where-Object {$_.ObjectClass -eq "User"}}

#Create Empty Hash
$PGUSers = @{}
$OrphanUsers = @{}

#Compare $AdminUsers to $Admins and place in appropriate hash table
ForEach ($User in $AdminUsers)
{
If ($Admins -Match $User.Name)
  {
    $PGUsers.Add($User.Name, "Present")
  }
  Else
  {
    $OrphanUsers.Add($User.SamAccountName, "NotPresent")
  }
}

If ($OrphanUsers.Keys.Count.Equals(0))
{
  $True | Out-Null
}
Else
{
  #Clear AdminCount Attribute
  ForEach ($Orphan in $OrphanUsers.Keys)
  {
    $Orphan
    $ADUser = Get-ADUser $Orphan
    Set-ADUser $Orphan -Clear {AdminCount}
    Set-Inheritance $ADUser
  }
}

Posted in Active Directory, Exchange 2010, Exchange 2013, Lync, Lync 2013, PowerShell | Tagged: , | 1 Comment »

Creating File Shares with PowerShell

Posted by Alan McBurney on July 23, 2013

I’m gradually moving more and more to PowerShell only for server administration.

Today I needed to create a new file share for a Lync 2013 Std Edition installation on Server 2012 and once again I looked to achieve this though the Shell.

As it turns out that this is a very simple task so with no further ado here is the syntax

New-SmbShare –Name LyncShare -Path C:\LyncShare –Description “Lync 2013 File Share” –FullAccess Administrators

Posted in Active Directory, Lync, Lync 2013, PowerShell | Tagged: , | Leave a Comment »