Lync Interactive Response Group Creation and Modification Via PowerShell

Introduction and Overview

Microsoft Lync provides the ability for callers to interact via questions and answers within a response group before being delivered to the appropriate queue.   This type of response group is typically referred to as an Interactive Voice Response Call Flow.  These questions, answers, and call flow settings are kept within a workflow.  The Lync Control Panel provides access to create and modify these workflows via a web page, which allows for easy modifications, however this method only supports up to two levels of questions with each question having up to four possible answers.  Via the Lync Management Shell, we have the ability to define any number of IVR questions and any number of answers.  The purpose of this article is a walkthrough of the procedures to create a workflow and to show you how to go beyond the limit of questions and answers available to you via the Control Panel GUI.  This article goes quite deep and can be a lot to consume, but due to the nature of how the examples build upon themselves, I didn’t feel that it should be broken up.  If you’d prefer, there’s also a tl;dr version that is a short and sweet look at the just commands to modify an existing response group.

Creating a Workflow

To begin, ensure that you are logged on as a member of the RTCUniversalServerAdmins group, or as a member of a group that has access to work with Lync Response Groups.

Before you create your workflow, make sure your agent groups and queues are properly defined.  If you don’t typically work with PowerShell, you might want to create your interactive workflow via the Control Panel first, and simply modify it with PowerShell after the fact if you need a larger question/answer set than provided.

Let’s start by defining a basic question and answer set.  We’ll keep this simple, but once you have the basics, you can build on it easily.  It may be easiest to sketch out your IVR flow on a sheet of paper, write out the questions, answers, and actions as seen below.

sketch

Let’s convert it into PowerShell.  We’ll work backwards to build our tree. Let’s start with a new prompt for the Sales Action.

$SalesPrompt = New-CsRgsPrompt -TextToSpeechPrompt “You have chosen sales, thank you.”

In our example, we want to transfer that to the Company_Sales queue.  So we’ll need to create an action and specify the queue.  The easiest way to do this is to pull the queue into a variable and specify it when creating our new action.

$CompanySalesQueue = Get-CsRgsQueue -Identity service:ApplicationServer:lyncpool.domain.com -Name Company_Sales

$SalesAction = New-CsRgsCallAction -Prompt $SalesPrompt -Action TransferToQueue  -QueueID $CompanySalesQueue.Identity

Let’s repeat for Accounting.

$AccountingPrompt = New-CsRgsPrompt -TextToSpeechPrompt “You have chosen accounting, thank you.”

$CompanyAccountingQueue = Get-CsRgsQueue -Identity service:ApplicationServer:lyncpool.domain.com -Name Company_Accounting

$AccountingAction = New-CsRgsCallAction -Prompt $AccountingPrompt -Action TransferToQueue  -QueueID $CompanyAccountingQueue.Identity

Now that we’ve got our actions built, we can move up one more level and build the Answers to our questions.

$SalesAnswer = New-CsRgsAnswer -Action $SalesAction -DtmfResponse 1 -VoiceResponseList Sales -Name “Sales Answer”

$AccountingAnswer = New-CsRgsAnswer -Action $AccountingAction -DtmfResponse 2 -VoiceResponseList Accounting, Accounts -Name “Accounting Answer”

We have our actions for our answers, let’s build our question.

$QuestionPrompt = New-CsRgsPrompt -TextToSpeechPrompt “Please press 1 for Sales or say Sales, or press 2 for Accounting or say Accounting or Accounts”

$QuestionObject = New-CsRgsQuestion -Prompt $QuestionPrompt  -AnswerList ($SalesAnswer, $AccountingAnswer)

$QuestionAction = New-CsRgsCallAction -Action TransferToQuestion  -Question $QuestionObject

We now have what we need to create our  workflow with the New-CsRgsWorkflow command.  There are many parameters that can be specified and these can be found in TechNet article referencing it in the references section of this article.  For our example, we’re going to start with the basics and build on it afterwards.

New-CsRgsWorkflow -Parent “service:ApplicationServer:lyncpool.domain.com”  -Name “Our IVR” -Description “Sales and Accounting IVR” -PrimaryUri “sip:salesacctivr@domain.com” -LineUri “tel:+15556667777” -DisplayNumber “+1 (555) 666-7777” -Active $true -DefaultAction $QuestionAction

FAkecreate2

Running the above command will create the workflow for us, but it wasn’t too complex as there was really only one question and two answers.  The next sections will show you how to add, modify, and remove questions and answers to go as deep as you’d like.

Adding Answers and New Questions

Adding Answers

Now we have a functional Interactive Response Group, but it’s time to make some changes.  Let’s use our example to add a third option to the original question to allow a caller to transfer to support.  We’ll start by building out our new answer as before.

$SupportPrompt = New-CsRgsPrompt -TextToSpeechPrompt “You have chosen support, thank you.”

$CompanySupportQueue = Get-CsRgsQueue -Identity service:ApplicationServer:lyncpool.domain.com -Name Company_Support

$SupportAction = New-CsRgsCallAction -Prompt $SupportPrompt -Action TransferToQueue  -QueueID $CompanySupportQueue.Identity

$SupportAnswer = New-CsRgsAnswer -Action $SupportAction -DtmfResponse 3 -VoiceResponseList Support -Name “Support Answer”

We’ll need to add our new answer on by loading our existing workgroup into a variable we can modify.  Once we’re done, we’ll save our changes by writing it back into to workflow with Set-CsRgsWorkflow.

Let’s load our workflow into a variable.

$workflow =GetCsRgsWorkflow -Name “Our IVR”

If we want to see what answers are already assigned to the first question, we can now review it simply by typing the following command.  Keep in mind that the answers are stored as an array, and can be accessed as such later.

$workflow.DefaultAction.Question.AnswerList

original_two_answers

To add our new answer, we use the following command.

$workflow.DefaultAction.Question.AnswerList.Add($SupportAnswer)

addanswer4

We can confirm by reviewing the contents of $workflow.DefaultAction.Question.AnswerList, that the new answer has been added.  However, we’re not done yet.  We’ve only added the answer to our $workflow variable.  This hasn’t been written back to our workflow.  The final step to save the command is to use the Set-CsRgsWorkflow command as seen below.

SetCsRgsWorkflow $workflow

save2

Adding Questions

So far, we’ve only set up answers that transfer to queues, but what if we need to ask another question before you can be properly transferred?  Let’s take the sales response and divide them into the tea sales team and the biscuit sales team.  Let’s build out a new question as we did at the start.

$TeaSalesPrompt = New-CsRgsPrompt -TextToSpeechPrompt “You have chosen tea sales, thank you.”

$CompanyTeaSalesQueue = Get-CsRgsQueue -Identity service:ApplicationServer:lyncpool.domain.com -Name Company_Tea_Sales

$TeaSalesAction = New-CsRgsCallAction -Prompt $TeaSalesPrompt -Action TransferToQueue  -QueueID $CompanyTeaSalesQueue.Identity

$BiscuitSalesPrompt = New-CsRgsPrompt -TextToSpeechPrompt “You have chosen biscuit sales, thank you.”

$CompanyBiscuitSalesQueue = Get-CsRgsQueue -Identity service:ApplicationServer:lyncpool.domain.com -Name Company_Biscuit_Sales

$BiscuitSalesAction = New-CsRgsCallAction -Prompt $BiscuitSalesPrompt -Action TransferToQueue  -QueueID $CompanyBiscuitSalesQueue.Identity

$TeaSalesAnswer = New-CsRgsAnswer -Action $TeaSalesAction -DtmfResponse 1 -VoiceResponseList Tea -Name “Tea Sales Answer”

$BiscuitSalesAnswer = New-CsRgsAnswer -Action $BiscuitSalesAction -DtmfResponse 2 -VoiceResponseList Biscuits -Name “Biscuit Sales Answer”

$SalesQuestionPrompt = New-CsRgsPrompt -TextToSpeechPrompt “Please press 1 for Tea Sales or say Tea, or press 2 for Biscuit sales or say Biscuits”

$SalesQuestionObject = New-CsRgsQuestion -Prompt $SalesQuestionPrompt  -AnswerList ($TeaSalesAnswer, $BiscuitSalesAnswer)

$SalesQuestionAction = New-CsRgsCallAction -Action TransferToQuestion  -Question $SalesQuestionObject

Now that we have our new question, we’ll need to assign it to an existing response.  Once we’re done, we’ll save our changes by writing it back into to workflow with Set-CsRgsWorkflow.

Let’s load our workflow into a variable.

$workflow =GetCsRgsWorkflow -Name “Our IVR”

If we want to see what answers are assigned to the first question, we can review it simply by typing the following command.  Keep in mind that the answers are stored as an array, and can be accessed as such later.

$workflow.DefaultAction.Question.AnswerList

answerlist1

We can see our sales response action is set to TransferToQueue.  We now want to change that to be a second set of questions.  To do so, we’ll need to change this action.  Remember that the answer list is an array, so to access the first answer, we’d use $workflow.DefaultAction.Question.AnswerList[0], to get to the second we’d use $workflow.DefaultAction.Question.AnswerList[1] and so on.  To change our action to reflect the new question we’d use the following commands.

$workflow.DefaultAction.Question.AnswerList[0].Action=$SalesQuestionAction

AddQuestion2

We can now confirm by reviewing the contents of $workflow.DefaultAction.Question.AnswerList, that the new question has been added.  You might be asking how to go one level deeper now and see the answers to the question you just added.  You can see them by typing the following command.

$workflow.DefaultAction.Question.AnswerList[0].Action.Question.AnswerList

addquestion3

As you can see, we can now add another question one level deeper with a similar command such as $workflow.DefaultAction.Question.AnswerList[0].Action.Question.AnswerList[0].Action=$YetAnotherQuestionAction and so on and so on.

However, we’re still not done yet.  We’ve only added the question to our $workflow variable.  This hasn’t been written back to our workflow.  The final step to save the command is to use the Set-CsRgsWorkflow command as seen below.

SetCsRgsWorkflow $workflow

Removing Answers and Questions

Removing Answers

Removing answers is a bit simpler than adding them, because there’s nothing to create.  Let’s take our accounting answer that we created at the beginning and pull it out.   This isn’t a particularly easy task in the GUI, but PowerShell makes it possible.  Let’s start once again by loading our workflow into a variable.

$workflow =GetCsRgsWorkflow -Name “Our IVR”

Let’s look at that accounting answer we want to remove.  We can see the answers by typing the following command:

$workflow.DefaultAction.Question.AnswerList

RemoveAnswer1

There it is, the second answer.  Remember that these are arrays, and arrays start counting with 0, so to get answer 2 we’ll subtract 1.  In our example, to access answer two, we’d use $workflow.DefaultAction.Question.AnswerList[1], the third answer would be $workflow.DefaultAction.Question.AnswerList[2], etc.  To remove the second answer, the exact command would be:

$workflow.DefaultAction.Question.AnswerList.Remove($workflow.DefaultAction.Question.AnswerList[1])

RemoveAnswer2

RemvoeAnswer3

Which is a bit to type, especially as you dive deeper into deeper levels of questions, but still, not too bad.  🙂

Remember to save it using the following command:

SetCsRgsWorkflow $workflow

Removing Questions

This section is somewhat of a trick, because you don’t just remove a question.  Remember that a question is an action and we can’t just remove an action without replacing it with something else, what would be the point of having an answer without an action?  To replace a question, just rewrite it as seen in the Adding Questions section and replace the action the same way.  To replace it with a queue, build out the action the same way we did in the Adding Answers section and set it as follows (and as always don’t forget to save with Set-CsRgsWorkflow).

$workflow.DefaultAction.Question.AnswerList[0].Action=$ReplacementAction

Modifications

I left modifications for last because it’s difficult to discuss without getting past the question and answer additions, subtractions, and replacements.  Perhaps we want to change a prompt.  Did you notice we added the support response in the Adding Answers section but never modified the prompt to let callers know the option existed?  We can review the prompt by looking at the question with $workflow.DefaultAction.Question, then modify it with:

$workflow.DefaultAction.Question.Prompt.TextToSpeechPrompt=”Please press 1 for Sales or say Sales, press 2 for Accountin or say Accouting, or press 3 for Support or simply say Support.”

ModifyPrompt1

MofifyPrompt2

And as always, don’t forget to save with Set-CsRgsWorkflow.  Did I mention you need to save?  You need to save.

save2

If you made it all the way here to the end, you have my gratitude.  Thank you for reading!

 

 

8 thoughts on “Lync Interactive Response Group Creation and Modification Via PowerShell

  1. Barbara

    I’m attempting to replace old Nortel CallPilot applications using Lync Interactive Response Groups. Many of our phone trees just had a couple of options to select brief recorded messages like directions to our offices, before allowing the caller the option to be transferred to a specific dept. This seems fairly easy to do in Lync 2013, but I can’t seem to find a way to allow the caller to repeat the recorded message they just listened to. What am I missing ? Is there a way to modify the interactive response group workflow to allow a caller to repeat the text to speech or recorded message they just heard rather than transfering them to a queue?

    1. C. Anthony Caragol Post author

      Sorry for the delay in the reply, I’ve been getting a lot of spam recently and it can be tough to sort through it all for the real comments. Repeating the comment is difficult in the IVR, because you can’t loop back up easily. In these scenarios, I typically use a combination of Exchange Automated Attendants mixed with the IVR or other Response Groups. The Automated Attendants will allow you to play a recorded message, transfer to extensions, loop back upon themselves and have timeouts. When it’s time to move into a queue, I’ll transfer from the AA to the IVR. However, as you’ve found, there is a deficiency in the IVR system that’s not easily remedied by the response groups themselves, any additional sophistication and you’re looking at a third party product :/

  2. Absials

    Hi Anthony,
    My question is about creating/updating Response Groups via Lync powershell.
    While playing with the Response Groups through Powershell I often get the error “…Cannot insert duplicate key row in object ‘dbo.Agents’ with unique index ‘IX_Agents_UserSid’….”.
    The scenario is I remove an Agent from a group and try to add this agent immediately again to the same OR any other group. It is known scenario that there is some latency associated with the deletion process of an agent as also mentioned at http://support.microsoft.com/kb/2393943. While the agent is marked for deletion, we cann’t play with this agent until the deletion process is over which can be delayed at Lync server end. So, I was wondering if there is any way to forcefully process/remove the agent using any command without a delay…? Thanks for your time

    1. C. Anthony Caragol Post author

      Ohhhh yeah, the delay. I’ve actually written a tool to manage and make response group duplicates but I never released it because the delay was too frustrating to handle within the tool. I don’t really have an answer for you, but if you find one PLEASE come back and let me know 🙂

  3. Jurgen

    Nice post…

    I am trying to set up an Interactive Response menu where there is also an action if NO choice is made.
    F.e. press 1 for sales, 2 for support. If you don’t make a choice, you will be directed to a waiting queue.
    Do you know if that is possible at all? If so, how it is done?

    Thanks!

    1. C. Anthony Caragol Post author

      I typically use Exchange Automated Attendants for that purpose. I’m not sure you can effectively accomplish the timeout with native Response Group IVR, but you can with Exchange UM.

  4. Jung Drinkwater

    I am trying to reset the Response Group Queue time-out checkbox to false using lync shell. It make sense how to add the action and its settings but it’s not clear how to disable the queue time-out checkbox using lync shell. Is there a way to do that?

    Thanks,
    jung

    1. Absials

      Hi Jung,
      You need to define call action again as you defined while enabling time-out action. Please try following shell commands for this process and let me know if you need more help on it:
      ——————————————————————————-
      $x = New-CsRgsCallAction -Action Terminate
      $z = Get-CsRgsQueue -Identity ‘your-queue-identity’
      $z.TimeoutAction = $x
      $z.TimeoutThreshold = $Null
      Set-CsRgsQueue -Instance $z
      ——————————————————————————-

Comments are closed.