PowerShell Function Get-MenuInput

I was recently working on a script with a unique requirement.  There was a desire to automate a business process, but there were also a number of exceptions and special cases.  In the end we decided to try and filter/select the best options then present them to the user running the script and have them make the final decision.

As part of that script I created a handy little function that accepts an array virtually any length and collects the users input as to which one we should use.  For example you could pass a list of all Lync Registrar pools in North America and get input as to which one we should use for provisioning.

Feel free to use or adapt this as needed, just leave a comment below if you find it useful or see any improvements.

function Get-MenuInput {
    <#
        .SYNOPSIS
        Allow the user to choose an option from a menu.
        .DESCRIPTION
        This function prints a menu list to the screen based on a supplied array.
        It allows the user to choose and option based on
        the number index and returns the chosen value as a string.
        .EXAMPLE
        $Pool = Get-MenuInput -Array (Get-CsService -Registrar).PoolFqdn
        .EXAMPLE
        Get-MenuInput -Array $Array -Prefix "DialPlan:"
        .PARAMETER Array
        String Array of available menu options.
        .PARAMETER Prefix
        Text string to add to the front of each options.
        .OUTPUT
        Returns the single chosen array item
        .INPUT
        None.
    #>
    param (
        [Parameter (Mandatory = $true)]
        [array]$Array,
        [string]$Prefix
    )

    #Note how many objects are in the array.
    #Number of menu options
    $ArrayLength = $Array.Length

    #Print each option in the array with a numbered choice index
    #Do While Loop is used to validate the users input
    Do {
        #Reset the Numbered Choice Index
        $i = 1

        #Write a line to the host for each item
        foreach ($item in $Array) {
            Write-log -Level Info -Data "$i - $Prefix$item"

            #Increment the Choice Index
            $i++
        }

        #Save the users choice as a variable
        $MenuChoice =  Read-Host -Prompt 'Please Choose the number of the desired option' 

    } While ($MenuChoice -lt 1 -or $MenuChoice -gt $ArrayLength)

    #Decrease the variable by one to convert to an array index that starts with 0
    $MenuChoice = $MenuChoice - 1

    #Log the choice
    Write-Host "$($Array[$MenuChoice]) Chosen." -ForegroundColor Green

    #Return the chosen option as a string
    $Array[$MenuChoice]

}

As always this is provided AS IS with no warranty or guarantee.  Use at your own risk.

Lync Documentation Script

I don’t like documentation, but it is a necessary evil.  It is important to document a Lync configuration for easy access to key information as well as tracking changes over time.  However since I do not enjoy it, nor do I know anyone who does, I have started scripting documentation where possible.

Below is my current script for documenting a Lync 2010/2013 environment.  Although it will run with Lync 2010, PowerShell 3.0 or later is required which is not installed by default on Lync 2010 servers.  It is still a work in progress, use at your own risk etc. etc.

Download

 

 

XP clients unable to connect to Exchange 2013 Outlook Anywhere

I was working on a recent green field deployment of Exchange 2013 that ran into a client issue.  The default authentication configuration of the Client Access Server (CAS) did not allow XP clients with Outlook 2007 to connect from outside the organization.  Users on these machines would be prompted for credentials repeatedly even when the proper username/password was used, and a successful connection was never made.

We found there were three requirements in order for the XP clients to connect.

1. The Office 2007 clients had to have Service Pack 3 with the Outlook 2007 November 2012 update (12.0.6665.5000).  More information can be found here http://go.microsoft.com/fwlink/p/?linkid=3052&kbid=2687404

2.  The EXPR Outlook Provider had to have the CertPrincipalName configured.  In this case a wildcard existed in the common name of the certificate, so it was set to msstd:*.domain.com.  More information on the Set-OutlookProvider command can be found here http://technet.microsoft.com/en-us/library/bb123683(v=exchg.150).aspx

3. Finally the authentication allowed for Outlook Anywhere clients had to be changed.  The main issue seems to be a conflict between Exchange 2013 and XP clients on the understanding of Negotiate authentication.  A number of forum post suggest switching the Exchange virtual directories to Basic Authentication, but this is a little heavy handed.  In the end by just adding basic and NTLM authentication to the IIS section of Outlook Anywhere, XP clients were able to connect.  The best part is that Outlook Anywhere itself still required Negotiate authentication, and the XP cleints were connecting with it, so the security of the environment was not affected.

The command used is below.

Get-OUtlookAnywhere | set-Outlookanywhere -IISAuthenticationMethods Basic,NTLM,Negotiate

In order for the changes to take affect an IISReset must be run on each CAS server.

Updating AD Telephone Numbers based on LineURI

I had a situation come up the other day during a Lync Voice installation.  The users LineURI in Lync was correct, but the Telephone number field in AD had been poorly maintained in both inconsistent formats and incorrect numbers.  I ended up writing a couple lines of PowerShell that they could use to update the Telephone field based on the LineURI, that they could then either run at intervals or put into a scheduled task.

Continue reading

Adding new SIP domains to Lync

I had this question come up today, and figured I would share.  What is involved in adding a new SIP domain to an already existing Lync deployment.

Its recommended for a users SIP address to be the same as their Primary STMP address, so in most cases you can gather all the current email domains to plan and deploy the appropriate SIP domains initially.  Of course cases do come up where a new SIP domain has to be added, change in company name, acquisition, or other issues.

Continue reading