Wednesday, July 11, 2012

Useful Lync Powershell Scripts

I find myself having to create and use the same Lync Powershell scripts over and over again, so I thought I'd compile a list of some of the ones I've created for others.  It will get updated as time goes on.

Enjoy, and suggest others in the Comments.

Finding all the people who have a telephone number set in Lync
Get-CsUser -Filter {LineURI -ne $NULL} | FT Name, LineURI

Change SIP domain for all users

$UserList = Get-CsUser 
foreach ($User in $UserList)
   $oldAddress = $User.SipAddress
   $newAddress = $oldAddress -replace "", ""
   Set-CsUser -Identity $User.Identity -SipAddress $newAddress

Setting the AD office phone number to the TelURI for all users
#Only need to add the AD Powershell instance once
Add-WindowsFeature RSAT-AD-Powershell
Import-Module ActiveDirectory

$users = Get-CSUser

Foreach ($user in $users)
   $Tel = $user.LineURI
   $Tel = $Tel.Replace("tel:", "")
   If ($Tel -ne "")
      Set-ADUser -Identity $user.SAMAccountName -OfficePhone $Tel

Enable All Users in a Group for Lync Enterprise Voice
#Uses existing office number in AD for Enterprise Voice
Import-Module ActiveDirectory

$Users = Get-ADGroupMember lync_group

ForEach ($User in $Users)
    Enable-CsUser $User.SamAccountName -RegistrarPool LYNCPOOLNAME -SipAddressType EmailAddress
    $OfficePhone = (Get-CSADUser $User.SamAccountName).Phone
    $OfficePhone = $OfficePhone -replace "\D", ""
    Set-CSUser $User.SamAccountName -EnterpriseVoiceEnabled:$TRUE -LineURI "tel:+$OfficePhone"

Move All OCS Users Homed on a Specific Pool to Lync
Also sets conferencing policy and external access policy to automatic, rather than the legacy migrated OCS policies.  Replace items in bold with your environmental specifics.

get-csuser -OnOfficeCommunicationServer | Where {$_.HomeServer -eq "CN=LC Services,CN=Microsoft,CN=OCSPOOLNAME,CN=Pools,CN=RTC Service,CN=Services,CN=Configuration,DC=contoso,DC=com"} | Move-CsLegacyUser -Target LYNCPOOLFQDN -ExcludeConferencingPolicy -ExcludeExternalAccessPolicy -Confirm:$FALSE

Count How Many Users are on OCS and Lync
(Get-CsUser -OnOfficeCommunicationServer).Count
(Get-CsUser -OnLyncServer).Count

Get a List of All Lync-Enabled Users Along with Selected AD Properties
#Asked by a commenter. Harder than it initially looked....

$ErrorActionPreference = 'SilentlyContinue'
Import-Module ActiveDirectory
$Output = @()

Foreach ($LyncUser in Get-CSUser -ResultSize Unlimited)
$ADUser = Get-ADUser -Identity $LyncUser.SAMAccountName -Properties Department, Title, Mail
$Output += New-Object PSObject -Property @{DisplayName=$LyncUser.DisplayName; Department=$ADUser.Department; Title=$ADUser.Title; SAMAccountName=$ADUser.sAMAccountName; Mail=$ADUser.Mail; SIPAddress=$LyncUser.SIPAddress; LineURI=$LyncUser.LineURI; EVEnabled=$LyncUser.EnterpriseVoiceEnabled}

$Output | Export-CSV -Path .\Output.csv
$Output | FT DisplayName, Title, Department, SAMAccountName, Mail, SIPAddress, EVEnabled

Create Lync Network Sites and Subnets using Info from AD Sites & Services

Add Enterprise Voice Users to an AD Group
Foreach ($User in get-csuser -filter {EnterpriseVoiceEnabled -eq $TRUE})
{Add-ADGroupMember -Identity -Members $User.SamAccountName}

Enable All Users in an AD Group for Lync EV/Exchange UM
#Takes the office number from AD, assuming its formatted correctly, extracts the last 4 digits to use
#as the extension (for dialin conferencing), and uses it for the LineURI and extension for UM.

Import-Module ActiveDirectory

#Import Exchange Powershell
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://EXCHANGESERVERFQDN/PowerShell/ -Authentication Kerberos
Import-PSSession $Session

$Users = Get-ADGroupMember TARGETADGROUP

ForEach ($User in $Users)
    Enable-CsUser $User.SamAccountName -RegistrarPool LYNCSERVERFQDN -SipAddressType EmailAddress
    $EmailAddress = Get-CSADUser $User.SamAccountName).WindowsEmailAddress
    $OfficePhone = (Get-CSADUser $User.SamAccountName).Phone
    $OfficeExt = $OfficePhone.Substring($OfficePhone.Length - 4)
    $OfficePhone = $OfficePhone -replace "\D", ""
    $OfficePhone = $OfficePhone + ";ext=" + $OfficeExt
    Set-CSUser $User.SamAccountName -LineURI "tel:+$OfficePhone"
    Set-CSUser $User.SamAccountName -EnterpriseVoiceEnabled:$TRUE
    Enable-UMMailbox $User.SamAccountName -UMMailboxPolicy "UMPOLICYNAME" -SIPResourceIdentifier $EmailAddress -Extension $OfficeExt

List All Remote PowerShell Sessions On A Machine
Get-WSManInstance -ComputerName COMPUTERNAME -ResourceURI Shell -Enumerate | FT Owner, ClientIP, State


  1. Thanks for the above examples Ken, I am wondering if you have ever tried using the -LdapFilter parameter. In specific, I wanted to get a list of all of the users display names, sam account names sip address and if they were enabled for enterprise voice or not. I ran ve Get-CsUser | Format-Table -Property DisplayName, SamAccountName, SipAddress, EnterpriseVoiceEnabled -

    In addition I wanted to get all of their AD related information such as department, title address and such information too. And from what I can see it can be done using the -LdapFilter Parameter but I can't find any working examples of it. Any pointers will be helpful.


    1. Jawad,
      The LDAPFilter is only used to filter results based on a specified criteria, like Show only users who reside in Las Vegas. It doesn't do anything for actually displaying information. To get both Lync information and AD information, you need to combine the results from 2 commands. See my newly added sample called "Get a List of All Lync-Enabled Users Along with Selected AD Properties"


  2. Uhmmm...hope I am not double posting here, was supposed to reply to my own comment With an edit to a typo but it seems that it actually replaced my original one.

    I was trying to point out that you could rather apply the "Filter" parameter of the Get-CsUser cmdlet, like

    Get-CsUser -Filter (LineURI -ne "") | ft Name,Lineuri

    This looks a little cleaner, and also leaves the filtering job to the Front End server if you are running the command from elsewhere - keeping unwanted results off the network.

    Great blog btw!


  3. The example for moving users on a specific pool to Lync has some redundant info. There is no need to specify -OnOfficeCommunicationServer if you're also specifying the pool's DN. And theoretically, you shouldn't need the entire DN. You could use a -contains "poolname".

  4. Great stuff, thanks! in 'Get a List of All Lync-Enabled Users Along with Selected AD Properties', it would be useful to exclude disabled AD users.

  5. Ken,

    I absolutely love your blog and find all your information super useful!

    Do you have a way/suggestion on how to display the next available extension for Lync? I like the script you have above to show all people with a telephone number, but short of copying that to an Excel file, filtering/sorting by LineURI, is there a better way to show that, for example, tel/ext# 1234 is available in a range of 1000-1999?


    1. You should look at fellow Lync dudes Stale and Lasse tool that does exactly that. Check it out at


  6. Super cool!!! I asked two different Lync contractors and they didn't have any suggestions (except to keep a running Excel file as we add/remove users - ick!). Should have known you'd know where to get it. Thanks a lot! Stale and Lasse have quite a few good tools on their site - I'll be testing these out tomorrow!

  7. Hi, Can you please help to share script to remove line uri for bulk users

    Thank you