Author Posts

May 15, 2015 at 9:45 am

I have a question about dot sourcing in PowerShell workflows. I am currently using a workflow to enable users in Lync Server 2013. I've created three functions that get the line uri, voice policy, and dial plan based on the users office attribute in Active Directory. Right now, my script looks like this:

workflow Setup-Lync {

    Param (
        [Parameter(Mandatory=$true)]
        [string]$UserPrincipalName
    )

    $Credential = Get-AutomationPSCredential -Name "DomainAdmin"
    $LyncConnectionUri = Get-AutomationVariable -Name "LyncConnectionUri"
    $ExchangeConnectionUri = Get-AutomationVariable -Name "ExchangeConnectionUri"

    inlineScript {

        # Create session to Lync and Exchange
        $LyncSession = New-PSSession -ConnectionUri $Using:LyncConnectionUri -Credential $Using:Credential
        $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $Using:ExchangeConnectionUri -Credential $Using:Credential
        
        # Load only the necessary cmdlets
        $LyncCmdlets = Import-PSSession $LyncSession -CommandName Enable-CsUser, Get-CsUser, Set-CsUser, Get-CsVoicePolicy, Grant-CsVoicePolicy, Get-CsDialPlan, Grant-CsDialPlan
        $ExchangeCmdlets = Import-PSSession $ExchangeSession -CommandName Get-User, Set-User, Enable-UMMailbox
         
        # Load custom functions
        . '\\pathto.ps1'

        # Get users Guid and Office attributes
        $User = Get-User -Identity $Using:UserPrincipalName | Select-Object DisplayName, Guid, Office

        # Enable user in Lync
        Enable-CsUser -Identity $Using:UserPrincipalName -RegistrarPool "registrarpool" -SipAddressType UserPrincipalName
        
        $CsUser = Get-CsUser -Identity $Using:UserPrincipalName

        # Enable enterprice voice
        Set-CsUser -Identity $CsUser.Identity -EnterpriseVoiceEnabled $True

        # Set line uri
        $LineURI = Get-LineURI -Office $User.Office
        Set-CsUser -Identity $CsUser.Identity -LineURI $LineURI

        # Set voice policy
        $VoicePolicy = Get-VoicePolicy -Office $User.Office
        Grant-CsVoicePolicy $CsUser.Identity -PolicyName $VoicePolicy.Identity

        # Set dial plan
        $DialPlan = Get-DialPlan -Office $User.Office
        if($DialPlan -ne $Null) {
            Grant-CsDialPlan $CsUser.Identity -PolicyName $DialPlan.Identity
        }

        $Phone = $LineURI.TrimStart("tel:")
        $Extension = $LineURI.Substring($LineURI.Length - 4,4)

        # Set phone in Active Directory
        Set-User -Identity $Using:UserPrincipalName -Phone $Phone

        # Enable unified messaging
        Enable-UMMailbox -Identity $Using:UserPrincipalName -UMMailboxPolicy "ummailboxpolicy" -SIPResourceIdentifier $Using:UserPrincipalName -Extensions $Extension

        # Remove session(s)
        Remove-PSSession $LyncSession, $ExchangeSession
    
    }

}

This seems to work great but I am not 100% sure this is the best method. Any suggestions?

May 15, 2015 at 9:49 am

The pathto.ps1 file looks like this:

Function Get-VoicePolicy ($Office)
{
    Switch ($Office)
    {
        "ATL" { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:ATL Users" } }
        "CHN" { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:CHA Users" } }
        "CLT" { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:CLT Users" } }
        "MDC" { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:MOB Users" } }
        "NSH" { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:BNA Users" } }
        default { Get-CsVoicePolicy | Where { $_.Identity -eq "Tag:BHM Users" } }
    }
}

Function Get-DialPlan ($Office)
{
    Switch ($Office)
    {
        "CHN" { Get-CsDialPlan | Where { $_.Identity -eq "Tag:Chattanooga Dial Plan" } }
        "CLT" { Get-CsDialPlan | Where { $_.Identity -eq "Tag:Charlotte Dial Plan" } }
        "MDC" { Get-CsDialPlan | Where { $_.Identity -eq "Tag:Mobile Dial Plan" } }
        "NSH" { Get-CsDialPlan | Where { $_.Identity -eq "Tag:Nashville Dial Plan" } }
        default { $Null }
    }
}

May 15, 2015 at 10:10 am

It is not the best method. A better approach would be to build your included script as a script module, and then use Import-Module to load it.

May 15, 2015 at 10:11 am

Figured that would be the case. Are there any good resources on how to do this, specifically within SMA?

May 15, 2015 at 10:13 am

Building a script module? Rename it as .psm1 instead of .ps1 and put it in a supported Modules folder. "Learn PowerShell Toolmaking in a Month of Lunches" has an entire chapter.