Lync – Unable to sign in via Edge (Checkpoint Firewalls)

I recently ran into a problem with Checkpoint Firewalls on a Lync 2010 deployment.  The customer already had a single 2010 Front End and wished to enable external sign in over the internet as it did not work over their VPN solution (Direct Access).  I installed the Edge server and Reverse Proxy but then encountered a strange issue where I was unable to sign in over the Edge server.  Some of the troubleshooting steps I took (Thinking it was my fault):

  • Verified Reverse Proxy worked correctly
  • Verified all Edge services were started
  • Verified all URLs and IP addresses in Topology Builder were correct
  • Installed latest CU Updates on Edge and FE (including DB updates)
  • Verified all root and intermediate certs were on Edge and FE in the correct stores
  • Verified all certificates were correct
  • Verified all ports were open using MS Port Query Tool and Edge Port Tester (Available here: http://www.mylynclab.com/2014/02/lync-edge-testing-suite-part-1-lync.html)
  • Verified that all internal and public DNS entries were correct
  • Verified CMS replication was working between FE and Edge.
  • Verified time and time zone on Edge server
  • Verified NIC config on Edge server and Static Routes.

Using OCSLogger and Snooper I was able to verify that the Lync client was hitting the Edge server but no SIP messages were hitting the Lync Front End.  The following error could be seen on the Edge Server.

TL_ERROR(TF_DIAG) [1]2BD8.2798::02/11/2015-16:37:36.771.001d4d31 (SIPStack,SIPAdminLog::TraceDiagRecord:SIPAdminLog.cpp(143))$$begin_record
LogType: diagnostic
Severity: error
Text: Message expired in the outbound queue before it could be sent
SIP-Start-Line: SUBSCRIBE sip:user.domain SIP/2.0
SIP-Call-ID: 450156f49d2549ce91da9c1bd1699750
SIP-CSeq: 1 SUBSCRIBE
Peer: edge.domain:5061
$$end_record

I should also mention the customers network config was outsourced so I had no access to the Firewalls or to view the rules.  I then came across this post: http://lync2013blog.blogspot.co.uk/2014/04/lync2013-and-checkpoint-firewall.html

I asked the customers network support to look at that post and ensure that the firewalls were not doing any Layer 7 inspection of SIP traffic.  Network support verified the rules had been implemented but Lync sign in still would not work.  I then logged a case with MS Support and we went through the motions of troubleshooting.  Their support guy came to the same conclusion that SIP messages were not getting from Edge to Front End and vice versa (Even though I could see the ports were open).  The network support guy also verified he could not see any dropped packets between Edge and Front End.

To cut a long story short it turned out that network support had only changed the TCP/5061 rule on the perimeter firewall and not the firewall between Edge and Front End (used for Federation).  As soon as they changed the rule on the inside Firewall Lync sign-in over Edge worked immediately.

So in summary if you are using Checkpoint Firewalls, the default rule of SIP 5061 will do layer 7 inspection of SIP and will not work with Lync.  You need to ensure that you create a standard port of TCP 5061 on your perimeter firewall (For federation) and internal firewall (between internal Edge and Front End).

Lync – UK +44 (0) Company_Phone_Number_Normalization_Rules.txt

A common problem in the UK is that companies Active Directory telephone numbers will be populated in the format:

+44 (0) 123 456 7891 or +44(0)1234567891

If you were to dial these numbers in the UK you would omit the +44 and just dial the 0.  If you are abroad you would dial +44 and omit the 0 (E164 format).

As part of the default Lync normalization rules it will remove all spaces and brackets ().  When using Lync click to call from a users contact card this normalizes the number to +4401234567891 which is invalid.  Therefore you need to either correct all numbers in AD to E164 format or add a normalization rule to the Company_Phone_Number_Normalization_Rules.txt file on your Lync File Share.  This is already well documented here:

http://technet.microsoft.com/en-us/library/bb936613(v=office.12).aspx

Lync 2010 Address Book Normalization

I did find some other posts about stripping the brackets and zero but I found these rules didn’t account for if there was a space before or after the brackets and anywhere else in the number.  This is the normalization rule I use:

Company_Phone_Number_Normalization_Rules.txt

# Normalize UK numbers that have a +44 (0) prefix with or without spaces

# +44 (0) 123 456 7891 would become +441234567891

# +44(0)1234567891 would become +441234567891

^\+44[\s]*\(0\)[\s]*([\d \ ]*)$

+44$1

Lync 2013 – Script Policy Summary – LyncPolicySummary.ps1

This simple script will summarise how many users are assigned each policy in Lync as well as how many users are against each registrar pool.

Lync-PolicySummary

 

# Author: Created by Weakest Lync, www.WeakestLync.com
# Purpose: Script to show the number of users assigned each policy
# Version: 1.0
# Changes: DATE - Change
# 09/11/2014 - Release 1.0

$users = Get-CsUser

Write-Host "Registrar Pool Sumamry" -ForegroundColor Yellow
$users | Group-Object RegistrarPool | Select-Object Count, Name
Write-Host "Voice Policy Summary" -ForegroundColor Yellow
$users | Group-Object VoicePolicy | Select-Object Count, Name
Write-Host "Dial Plan Summary" -ForegroundColor Yellow
$users | Group-Object DialPlan | Select-Object Count, Name
Write-Host "Conferencing Policy Summary" -ForegroundColor Yellow
$users | Group-Object ConferencingPolicy | Select-Object Count, Name
Write-Host "External Access Summary" -ForegroundColor Yellow
$users | Group-Object ExternalAccessPolicy | Select-Object Count, Name
Write-Host "Location Policy Summary" -ForegroundColor Yellow
$users | Group-Object LocationPolicy | Select-Object Count, Name
Write-Host "Client Policy Summary" -ForegroundColor Yellow
$users | Group-Object ClientPolicy | Select-Object Count, Name
Write-Host "Archiving Policy Sumamry" -ForegroundColor Yellow
$users | Group-Object ArchivingPolicy | Select-Object Count, Name
Write-Host "Pin Policy Sumamry" -ForegroundColor Yellow
$users | Group-Object PinPolicy | Select-Object Count, Name
Write-Host "Mobility Policy Sumamry" -ForegroundColor Yellow
$users | Group-Object MobilityPolicy | Select-Object Count, Name
Write-Host "Persistent Chat Policy Sumamry" -ForegroundColor Yellow
$users | Group-Object PersistentChatPolicy | Select-Object Count, Name
Write-Host "Hosted Voicemail Policy Sumamry" -ForegroundColor Yellow
$users | Group-Object HostedVoicemailPolicy | Select-Object Count, Name</pre>
<pre>

 

Lync 2013 – Import-CsUserData Error

The scenario is a migration from Lync 2010 to Lync 2013 in a new Active Directory forest and want to migrate users buddy lists.

You run DBIMPEXP.EXE on the Lync 2010 environment to export the user data to XML.  On the 2013 system you convert the XML to Lync 2013 format then run Import-CsUserData.

Convert-CsUserData -inputfile C:\temp\2010UserData.xml -outputfile C:\temp\2013UserData_Converted.zip -targetversion Current

Import-CsUserData -PoolFqdn "fpool01.domain.local" -FileName "C:\temp\2013UserData_Converted.zip"

When running Import-CsUserData you get the error:

PS C:\Users\username> Import-CsUserData -PoolFqdn “fpool01.domain.local” -FileName “C:\temp\2013UserData_Converted.zip”
Import-CsUserData : ‘@’ is an unexpected token. The expected token is ‘;’. Line 1364, position 39.
At line:1 char:1
+ Import-CsUserData -PoolFqdn “fpool01.domain.local” -FileName “C:\temp\2 …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (C:\Users\userna…mpExpImport.Zip:String) [Import-CsUserData], XmlException
+ FullyQualifiedErrorId : ExportFailure.IO,Microsoft.Rtc.Management.BlobStore.ImportOcsUserStoreDataCmdlet

If you look at line 1364 you will notice that the users SIP address has an “&” (amersand).  To fix I removed the users entry from the XML (All lines from <app:DocItem Name= to line </app:DocItem>) and zipped the files again.  The import then ran successfully.

Review: Kuando Busylight UC for Microsoft Lync

http://busylight.com/

I recently received a Busylight to test from Kuando.

Inside the box you receive a Busylight USB device, a sticky pad to attach the device to your desk or screen and some brief instructions. The Busylight itself is constructed from black plastic base with an aluminium main body.

 

Installation is very simple, download and install the software from the Busylight website: http://www.busylight.com/support/lync

Busylight runs in the system tray and starts at system startup. You can right click on the Busylight icon in the system tray to access menu features. You can change the speaker volume and make changes to the colours Busylight flashes. It’s worth noting that you can also fully customise the colours using registry settings.

The version of Busylight software I’m using also allows you to configure some nice features such as second call treatment and hotkeys.

The Busylight itself does what it says, it changes colour based on your Lync presence status. It’s useful if everyone in your Office understands what it means (Busylight do provide posters you can print to raise awareness). E.g. if you are set to “Busy” a person knows not to walk over to you.

From my own experience, the best feature is when you are receiving inbound Lync IM’s or calls. I haven’t took a photograph but Busylight will flash blue when you receive an IM or a call. Busylight also has an inbuilt speaker and acts as your ringer when receiving calls, even while your machine is locked. This is great for headset users (like myself) who usually rely on inbuilt laptop speakers and Lync toasts.

Available (Green) 

Away (Yellow) 

Busy (Red) Do Not Disturb (Pink)

 

If you are not happy with the default colours out the box, the Busylight software allows you to change some of them from the system tray. E.g. DND can be set to pulse red rather than solid pink. You can also customise the colours via the registry although I would imagine you would want to set these via GPO.

 

Overall I can certainly see the advantages of Busylight. It works really well and there are regular updates to the software adding new features. I also believe there is an API to customise Busylight further. For Busylight to work for its intended purposes people need to be educated on presence etiquette. It’s certainly very useful if you are a headset user as the inbuilt speaker rings more like a VOIP phone. I would like the ability to set custom ringtones as I’m not a huge fan of the inbuilt tones. I could also see these being useful mounted outside meeting rooms or managers offices. USB extension cable may be required!

Lync – Increase Internal Certificate Validity Period

When you deploy Lync and assign internal certificates to your Lync servers (E.g. Front End, Internal Edge, SBA and Gateways) by default you will only have a 2 year certificate from the “Web Server” template. I like to create a new Certificate Template for Lync with a 5 year lifespan as it can be quite annoying having to renew certificates, especially on the Edge servers and Gateways where you have to export the cert request. I have tried creating a 10 year Certificate Template but the Lync Deployment Wizard complains that the cert is valid for over 5 years. It’s also a good idea to set your Certificate Authority validity period to a long period, I usually opt for 20/25 years. This article will cover how to create a 5 year Certificate Template for Lync.  By assigning Certificates to your Lync servers with a longer validity period you won’t have to renew them as often.

First of all, open Certification Authority console. Right click “Certificate Templates” and click “Manage”.

Now we will duplicate the default Web Server certificate. In the Certificate Templates Console right click “Web Server” and click “Duplicate Template”.

Click the “General” tab. Enter a display name (e.g. LyncServer) and change the validity period to 5 years. Click “Apply”.  You should also check that the Private Key is exportable in the Request Handling tab.

Back in the Certification Authority console, right click “Certificate Templates”, click “New” > “Certificate Template to Issue”.

In the “Enable Certificate Templates” window, select “LyncServer” and click “OK”

Next we need to allow the Certificate Authority to issue certificates that are valid for more than 2 years. From an elevated command prompt (run as administrator) run the following:

certutil -setreg ca\ValidityPeriodUnits 5

Restart the Certificate Authority service:

When requesting internal Certificates in Lync Deployment Wizard you should now specify “LyncServer”:

Now you don’t need to worry about Lync internal certs for 5 years.

I recommend that you monitor your certificates expiry dates, SCOM works great for the certs on Lync servers. If you use TLS on your gateways you should make sure you monitor those certificates too with a third party application/script.

Lync 2013 – Standard Edition Pool Pair Failover Script

Lync 2013 introduced a new feature called Pool Pairing. Given the scenario below with 2 sites using Lync Standard Edition with paired pools, in the event that Front End 01 was to fail, or Site 1 failed completely all users will automatically register to Front End 02. However they will receive an error in their Lync client “Limited Functionality due to Outage”, lose their buddy lists, presence information, conferencing features and any Response Groups that were homed on FE01. They will still be able to make inbound and outbound PSTN calls (assuming you have resilient Voice Routing) and they will still be able to search contacts to make P2P audio and video calls. To restore full functionality you need to manually failover the pool following the procedure here: http://technet.microsoft.com/en-us/library/jj204678.aspx

Remembering or finding the various commands to run in a disaster scenario wastes valuable restore time so I have created a script to do all the hard work for you. The script can also fail back a pool once it is back in service. This script relies on my Lync Backup script to restore Response Groups here (I save these on the standby server if Active/Passive): http://weakestlync.com/2013/07/07/lync-2013-automated-backup-script/

Simple Lync Standard Edition Pool Pair topology:

Limited functionality error in Lync 2013 client:

The script is menu driven, the splash screen will show the script configuration, it is important to review all of this information before running:

From the main menu you have various options.

Options:

  • a – failover pool01 to pool02
  • b – failover pool01’s response groups to pool02
  • c – fail back pool01’s users to pool01
  • d – fail back pool01’s response groups to pool01
  • i – view manual DNS changes required during failover
  • j – shows pool state – Use to check if a pool is currently in a failover state
  • k – shows CMS status – Check replication is working and which server is master
  • l – view failed over response group status for both pools – Use to check if any Response Groups have been failed over
  • m – view backup service status for both pools – Use to check that the backup service is working OK
  • z – enable advanced mode (show failover options for both pools and CMS) – Use if you want to failover Pool02 to Pool01 or manually move CMS

Option z:

Here is the script, you need to modify the Script Configuration at the top to reflect your environment.:

Use this script at your own risk. I have not programmed Lync Enterprise Edition but it could easily be modified to failover an Enterprise Pool.

# Author:   Created by Weakest Lync, www.WeakestLync.com
# Purpose:  Script to failover Lync 2013 Standard Edition Pool Pair and Response Groups in a DR scenario
# Version:  1.0
# Changes:  DATE - Change
#           22/01/2014 - Release 1.0

# Script Configuration
$CustomerName = "Weakest Lync"							# Customer Name
$PrimaryFE = "frontend01.WeakestLync.com"			# Primary Lync Front End Pool
$PrimaryEd = "edge01.WeakestLync.com"				# Primary Lync Edge Pool
$SecondaryFE = "frontend02.WeakestLync.com"			# Secondary Lync Front End Pool
$SecondaryEd = "edge02.WeakestLync.com"				# Secondary Lync Edge Pool
$BackupPath = "C:\LyncBackups\Backups\"			# Backup Path - Uses Lync Automated Backup script to restore Response Groups: http://weakestlync.com/2013/07/07/lync-2013-automated-backup-script/
$ActivePassive = "Yes"							# yes/no. Is the Secondary Pool used for failover only?  This will hide menu options to failover the Secondary Pool.
$RGSRestorePath = "c:\Temp\"					# Temp folder

Function WindowColour {
    $a = (Get-Host).UI.RawUI
    $a.BackgroundColor = "DarkBlue"
}

Function FailoverDR ($Pool, $BackupPool, $Edge){
    cls
    MainHeader
    # Prompt user to confirm
    Write-Host "You are about to initiate a pool failover from " -NoNewline
    Write-Host $Pool -ForegroundColor Green -NoNewline
    Write-Host " to " -NoNewline
    Write-Host $BackupPool -ForegroundColor Green
    Write-Host ""
    $confirm = Read-Host "Please type YES to confirm"
    If ($confirm -ne "YES"){
    MainMenu
    }

    # Check that CMS is on Secondary server
    $LyncCMS = Get-CsManagementStoreReplicationStatus -CentralManagementStoreStatus
    If ($LyncCMS.ActiveMasterFqdn -ne $BackupPool){
        Write-Warning "CMS is not on Secondary server, running CMS failover command"
        Invoke-CsManagementServerFailover -BackupSqlServerFqdn $BackupPool -BackupSqlInstanceName RTC -Force
    }

    # Change Primary Edge next hop to Secondary Front End
    Set-CsEdgeServer -Identity $Edge -Registrar Registrar:$BackupPool

    # Failover pool
    Invoke-CsPoolFailOver -PoolFqdn $Pool -DisasterMode -Confirm:$false
    ReturnToMenu
}

Function FailbackDR ($Pool, $BackupPool, $Edge){
    cls
    MainHeader
    # Prompt user to confirm
    Write-Host "You are about to initiate a pool failback from " -NoNewline
    Write-Host $BackupPool -ForegroundColor Green -NoNewline
    Write-Host " to " -NoNewline
    Write-Host $Pool -ForegroundColor Green
    Write-Host ""
    $confirm = Read-Host "Please type YES to confirm"
    If ($confirm -ne "YES"){
    MainMenu
    }

    # Start CMS Replication
    Invoke-CsManagementStoreReplication -ReplicaFqdn $Pool

    # Change Primary Edge next hop to Primary Front End
    Set-CsEdgeServer -Identity $Edge -Registrar Registrar:$Pool

    # Failback pool
    Invoke-CsPoolFailBack –PoolFqdn $Pool -Confirm:$false
    ReturnToMenu
}

Function FailoverRGS ($Pool, $BackupPool){
    cls
    MainHeader
    # Prompt user to confirm
    Write-Host "You are about to initiate a Response Group failover from " -NoNewline
    Write-Host $Pool -ForegroundColor Green -NoNewline
    Write-Host " to " -NoNewline
    Write-Host $BackupPool -ForegroundColor Green
    Write-Host ""
    $confirm = Read-Host "Please type YES to confirm"
    If ($confirm -ne "YES"){
        MainMenu
    }

    # Get the latest RGS Backup file
    $LatestBackup = Get-ChildItem -Directory $BackupPath | Sort CreationTime -Descending | select -First 1
    $RGSBackupPath = $LatestBackup.FullName + "\Lync-RGS-Config_$Pool.zip"

    # Test RGS Backup file exists
    If(!(Test-Path $RGSBackupPath)){
        Write-Warning "No RGS Backup File"
        Write-Warning "Ensure that an RGS backup is located in the following location $RGSBackupPath"
        ReturnToMenu
    }

    # Import Response Group config to secondary pool
    Import-CsRgsConfiguration -Destination "service:ApplicationServer:$BackupPool" -FileName $RGSBackupPath -ReplaceExistingRgsSettings -Force
    ReturnToMenu
}

Function FailbackRGS ($Pool, $BackupPool){
    cls
    MainHeader
    # Prompt user to confirm
    Write-Host "You are about to initiate a Response Group failback from " -NoNewline
    Write-Host $BackupPool -ForegroundColor Green -NoNewline
    Write-Host " to " -NoNewline
    Write-Host $Pool -ForegroundColor Green
    Write-Host ""
    $confirm = Read-Host "Please type YES to confirm"
    If ($confirm -ne "YES"){
        MainMenu
    }

    # Check temp path exists
    If(!(Test-Path $RGSRestorePath)){
        New-Item -ItemType directory -Path $RGSRestorePath
    }

    # Temp export file name
    $RGSRestoreFile = $RGSRestorePath + "RGSExportPrimaryPoolRestore.zip"

    # If we already have a temp export file, delete it.
    If(Test-Path $RGSRestoreFile){
        Remove-Item $RGSRestoreFile
    }

    # Export Response Groups from Secondary pool that are owned by the Primary, then remove them.
    Export-CsRgsConfiguration –Source "service:ApplicationServer:$BackupPool" –Owner "service:ApplicationServer:$Pool" –Filename $RGSRestoreFile -RemoveExportedConfiguration -Force

    # Import Response Groups owned by the Primary pool back in to the Primary.
    Import-CsRgsConfiguration –Destination "service:ApplicationServer:$Pool" –OverwriteOwner –Filename $RGSRestoreFile -Force
    ReturnToMenu
}

Function MoveCMS($BackupPool){
    cls
    MainHeader
    # Prompt user to confirm
    Write-Host "You are about to move the Active CMS to " -NoNewline
    Write-Host $BackupPool -ForegroundColor Green
    Write-Host ""
    $confirm = Read-Host "Please type YES to confirm"
    If ($confirm -ne "YES"){
    MainMenu
    }
    $LyncCMS = Get-CsManagementStoreReplicationStatus -CentralManagementStoreStatus
    If ($LyncCMS.ActiveMasterFqdn -ne $BackupPool){
        Write-Warning "Server is not CMS Active Master, running CMS failover command"
        Invoke-CsManagementServerFailover -BackupSqlServerFqdn $BackupPool -BackupSqlInstanceName RTC -Force
        Write-Host "CMS Active Master moved to $BackupPool"
    }
    Else{
        Write-Host "CMS Active Master is already on $BackupPool"
    }
    ReturnToMenu
}

Function ManualChanges {
    cls
    MainHeader
    Write-Host "DNS Changes during Failover:"
    Write-Host "* Point lyncdiscover.sipdomain DNS record to Secondary Pool Web Services"
    Write-Host "* Point dialin.sipdomain DNS record to point to Secondary Pool Web Services"
    Write-Host "* Point meet.sipdomain DNS record to point to Secondary Pool Web Services"
    Write-Host ""
    Write-Host "DNS Changes during Failback:"
    Write-Host "* Point lyncdiscover.sipdomain DNS record to Primary Pool Web Services"
    Write-Host "* Point dialin.sipdomain DNS record to point to Primary Pool Web Services"
    Write-Host "* Point meet.sipdomain DNS record to point to Primary Pool Web Services"
    Write-Host ""
    ReturnToMenu
}

Function FailoverStatus{
    cls
    MainHeader
    Get-CsRegistrarConfiguration | Select-Object Identity, PoolState | Format-Table
    ReturnToMenu
}

Function CMSStatus{
    cls
    MainHeader
    Get-CsManagementStoreReplicationStatus
    Read-Host "Press any key to view more details"
    Get-CsManagementStoreReplicationStatus -CentralManagementStoreStatus
    ReturnToMenu
}

Function RGSStatus{
    cls
    MainHeader
    Read-Host "Press any key to view RGS Workflows in $SecondaryFE owned by $PrimaryFE"
    Get-CsRgsWorkflow -Identity "service:ApplicationServer:$SecondaryFE" -Owner "service:ApplicationServer:$PrimaryFE" | Select-Object OwnerPool, Name, LineUri | Format-Table
    Read-Host "Press any key to view RGS Workflows in $PrimaryFE owned by $SecondaryFE"
    Get-CsRgsWorkflow -Identity "service:ApplicationServer:$PrimaryFE" -Owner "service:ApplicationServer:$SecondaryFE" | Select-Object OwnerPool, Name, LineUri | Format-Table
    ReturnToMenu
}

Function BackupServiceStatus{
    cls
    MainHeader
    Read-Host "Press any key to view the Backup Service status for $PrimaryFE"
    Get-CsBackupServiceStatus -PoolFqdn $PrimaryFE | Format-List
    Read-Host "Press any key to view the Backup Service status for $SecondaryFE"
    Get-CsBackupServiceStatus -PoolFqdn $SecondaryFE | Format-List
    ReturnToMenu
}

Function AdvancedMode{
    # Forces script to show failover options for both pools
    $ActivePassive = "no"
    # Show advanced options on the menu
    $AdvancedMode = "Yes"
    MainMenu
}

Function ReturnToMenu{
    Read-Host "Press any key to return to main menu"
    MainMenu
}

Function MainHeader{
    cls
    Write-Host "      *** Lync 2013 Standard Edition Failover Script ***" -Foregroundcolor Magenta
    Write-Host ""
}

Function JustExit{
    cls
    exit
}

Function MainMenu ($blank){
    Get-Variable true | Out-Default; Clear-Host;  # Required due to PowerShell cls bug not clearing display
    MainHeader
    # Menu
    Write-Host "Primary Pool Disaster Recovery: " -NoNewline -ForegroundColor Yello
    Write-Host $PrimaryFE -ForegroundColor Green
    Write-Host "a. Disaster - Failover Pool + CMS"
    Write-Host "b. Disaster - Failover Response Groups"
    Write-Host "c. Recovery - Failback Pool"
    Write-Host "d. Recovery - Failback Response Groups"
    If ($ActivePassive -eq "no"){
        Write-Host "Secondary Pool Disaster Recovery: " -NoNewline -ForegroundColor Yellow
        Write-Host $SecondaryFE -ForegroundColor Green
        Write-Host "e. Disaster - Failover Pool + CMS"
        Write-Host "f. Disaster - Failover Response Groups"
        Write-Host "g. Recovery - Failback Pool"
        Write-Host "h. Recovery - Failback Response Groups"
        }
    Write-Host "Administration: "-ForegroundColor Yellow
    Write-Host "i. View manual changes required during failover/failback"
    Write-Host "j. View Registrar failover status"
    Write-Host "k. View Central Management Store status"
    Write-Host "l. View failed over Response Group status"
    Write-Host "m. View Backup Service status"
    If ($AdvancedMode -eq "Yes"){
        Write-Host "CMS Management: "-ForegroundColor Yellow
        Write-Host "n. Move CMS to Primary Pool"
        Write-Host "o. Move CMS to Secondary Pool"
    }
    else{
        Write-Host "z. Advanced Mode"
        }
    Write-Host "q. Exit Script (q, exit, quit)"
    Write-Host ""
    If ($blank -eq "1"){
        Write-Warning "Invalid selection"
        }
    $a = Read-Host "Select an option (e.g. q)"

    switch ($a){
        a {FailoverDR -Pool $PrimaryFE -BackupPool $SecondaryFE -Edge $PrimaryEd}
        b {FailoverRGS -Pool $PrimaryFE -BackupPool $SecondaryFE}
        c {FailbackDR -Pool $PrimaryFE -BackupPool $SecondaryFE -Edge $PrimaryEd}
        d {FailbackRGS -Pool $PrimaryFE -BackupPool $SecondaryFE}
        e {FailoverDR -Pool $SecondaryFE -BackupPool $PrimaryFE -Edge $SecondaryEd}
        f {FailoverRGS -Pool $SecondaryFE -BackupPool $PrimaryFE}
        g {FailbackDR -Pool $SecondaryFE -BackupPool $PrimaryFE -Edge $SecondaryEd}
        h {FailbackRGS -Pool $SecondaryFE -BackupPool $PrimaryFE}
        i {ManualChanges}
        J {FailoverStatus}
        k {CMSStatus}
        l {RGSStatus}
        m {BackupServiceStatus}
        n {MoveCMS -BackupPool $PrimaryFE}
        o {MoveCMS -BackupPool $SecondaryFE}
        q {JustExit}
        z {AdvancedMode}
        exit {JustExit}
        quit {JustExit}
        default {MainMenu -blank "1"}
    }
}

Function SplashScreen{
    MainHeader
    Write-Host "* This script can be used to failover a Lync Standard Edition Pool Pair."
    Write-Host "* Make sure you are running this script as Administrator (Lync Management Shell > Run As Administrator)."
    Write-Host "* Your account must be a member of the RTCUniversalServerAdmins and CsAdministrator groups."
    Write-Host ""
    Write-Host "* Customer Platform is " -NoNewline
    Write-Host $CustomerName -ForegroundColor Green
    Write-Host "* Primary Front End is " -NoNewline
    Write-Host $PrimaryFE -ForegroundColor Green
    Write-Host "* Primary Edge is " -NoNewline
    Write-Host $PrimaryEd -ForegroundColor Green
    Write-Host "* Secondary Front End is " -NoNewline
    Write-Host $SecondaryFE -ForegroundColor Green
    Write-Host "* Secondary Edge is " -NoNewLine
    Write-Host $SecondaryEd -ForegroundColor Green
    Write-Host "* Backup path (For RGS failover) is " -NoNewLine
    Write-Host $BackupPath -ForegroundColor Green
    Write-Host "* Is Pool Pair Active/Passive? (Secondary Pool is standby only) " -NoNewLine
    Write-Host $ActivePassive -ForegroundColor Green
    Write-Host ""
    Write-Host "Please review the details above, amend the script config if required."
    Write-Host ""
    Read-Host "Press any key to load menu"
    MainMenu
}
WindowColour
SplashScreen 

Lync Tip: Quickly restart all Lync services using PowerShell

You need to restart all Lync services, open services.msc and see 10+ Lync Server services.  Rather than go through each one hitting the stop or restart button with your mouse you can use PowerShell!

Stop all Lync Services:

Stop-CsWindowsService

Start all Lync Services:

Start-CsWindowsService

Much easier, right?

Lync Tip: Bandwidth Requirements Simple Calculator

So you need to calculate how much bandwidth Lync will use, you launch google and type “Lync bandwidth requirements”.  You click the top link for Microsoft Downloads “Lync 2010 and 2013 Bandwidth Calculator” here http://windowspbx.blogspot.co.uk/2012/01/simple-smb-lync-bandwidth-calculator.html.  You download the zip, open the excel file then realise you don’t have a degree in quantum physics or it’s Friday and you just want some quick figures to work with.

Behold Matt Landis’ “Very Simple SMB Lync Bandwidth Calculator” here: http://windowspbx.blogspot.co.uk/2012/01/simple-smb-lync-bandwidth-calculator.html

Obviously it’s not as detailed or accurate as the Microsoft calculator but good to find a ball park figure for one branch office.

Lync Tip: Port Query Tool

Struggling with Telnet/Microsoft Port Query Tool to test the correct firewall ports are open between Lync servers?

I almost started making my own tool/script but this guy has done the hard work for me!

http://flinchbot.wordpress.com/2013/05/10/portqueryui-config-xml-file-for-lync/

Really useful.

NorthernUC

Using Microsoft Skype for Business and Teams

ahandyblog

UC, SfB, Lync, Teams, Cloud, Exchange, Office365, EMS, Azure