Several Administrators and Microsoft voice expert have this need in specifications of different use case implementation , lately so am i , and i had created a script that i want to share with you :
This PowerShell script will have as an entry a CSV file with two columns ( SipAddress and Phone ) , and will cerate for each UPN a resource account , affect a number to this resource account and create an autoAttendant and link it .
# Attention : the Administrator who will run this script needs to have at least this Azure Ad roles in the tenant ( Skype + teams + licence Admin)
#Connect to the 2 modules we will need in this script
Connect-MsolService
connect-microsoftteams
$teamsusers=import-csv "name_of_UPNandDID_list.csv"
foreach($user in $teamsusers){$user.SipAddress, $user.Phone}
$count =1
#Start-Transcript -Path "Where you want to save your transcript"
foreach($user in $teamsusers){
if($user)
{
$aaName = $user.SipAddress
$resourceAccountDomain = 'yourtenantdomain'
Set-CsUser -Identity $aaName@$resourceAccountDomain -EnterpriseVoiceEnabled $true
$newAaRaParams = @{
UserPrincipalName = "RA_AA_$aaName@$resourceAccountDomain"
ApplicationId = 'ce933385-9390-45d1-9512-c8d228074e07'
DisplayName = "RA_AA_$aaName"
}
$newAaRa = New-CsOnlineApplicationInstance @newAaRaParams
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
Get-MsolAccountSku
Set-MsolUser -UserPrincipalName $newAaRaParams.UserPrincipalName -UsageLocation US
Set-MsolUserLicense -UserPrincipalName $newAaRaParams.UserPrincipalName -AddLicenses "domainname:PHONESYSTEM_VIRTUALUSER"
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
#Get-CsOnlineApplicationInstance -Identities @($newAaRa.ObjectId) , to check if it is created
# Options
$aaLanguage = 'fr-FR'
$aaTimezone = 'Romance Standard Time'
# Callable entity
$operatorObjectId = (Get-CsOnlineUser $aaName@$resourceAccountDomain).Identity
$callableEntityParams = @{
Identity = $operatorObjectId
Type = 'User'
}
$targetUserEntity = New-CsAutoAttendantCallableEntity @callableEntityParams
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
# Menu option
$menuOptionParams = @{
Action = 'TransferCallToTarget'
DtmfResponse = 'Automatic'
CallTarget = $targetUserEntity
}
$menuOptionZero = New-CsAutoAttendantMenuOption @menuOptionParams
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
# Finally, the menu
$menuParams = @{
Name = "$aaName Default Menu"
# Accepts list, so use array sub-expression operator
MenuOptions = @($menuOptionZero)
}
$menu = New-CsAutoAttendantMenu @menuParams
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
# And the call flow
$defaultCallFlowParams = @{
Name = "$aaName Default Call Flow"
Menu = $menu
}
$defaultCallFlow = New-CsAutoAttendantCallFlow @defaultCallFlowParams
#Create After Hours Schedules
$timerangeMoFr = New-CsOnlineTimeRange -Start 09:00 -end 17:00
$timerangeSaSu = New-CsOnlineTimeRange -Start 01:30 -end 01:45
$afterHoursSchedule = New-CsOnlineSchedule -Name "After Hours Schedule" -WeeklyRecurrentSchedule -MondayHours @($timerangeMoFr) -TuesdayHours @($timerangeMoFr) -WednesdayHours @($timerangeMoFr) -ThursdayHours @($timerangeMoFr) -FridayHours @($timerangeMoFr) -SaturdayHours @($timerangeSaSu) -SundayHours @($timerangeSaSu) -Complement
$afterHoursGreetingPrompt = New-CsAutoAttendantPrompt -TextToSpeechPrompt "Welcome to the name of your standard! Unfortunately, you have reached us outside of our business hours. We value your call please call us back Monday to Friday, between 9 A.M. to 12 P.M. and 1 P.M. to 5 P.M. Goodbye!"
$automaticMenuOption = New-CsAutoAttendantMenuOption -Action TransferCallToTarget -CallTarget $targetUserEntity -DtmfResponse Automatic
$afterHoursMenu=New-CsAutoAttendantMenu -Name "After Hours menu" -MenuOptions @($automaticMenuOption)
$afterHoursCallFlow = New-CsAutoAttendantCallFlow -Name "After Hours call flow" -Greetings @($afterHoursGreetingPrompt) -Menu $afterHoursMenu
$afterHoursCallHandlingAssociation = New-CsAutoAttendantCallHandlingAssociation -Type AfterHours -ScheduleId $afterHoursSchedule.Id -CallFlowId $afterHoursCallFlow.Id
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
# Now, you can create an auto attendant
$autoAttendantParams = @{
Name = "AA_$aaName"
LanguageId = $aaLanguage
TimeZoneId = $aaTimezone
DefaultCallFlow = $defaultCallFlow
CallHandlingAssociations = @($afterHoursCallHandlingAssociation)
CallFlows= @($afterHoursCallFlow)
ErrorAction = 'Stop'
}
$newAA = New-CsAutoAttendant @autoAttendantParams
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
Set-CsPhoneNumberAssignment -Identity $newAaRaParams.UserPrincipalName -PhoneNumber $user.Phone -PhoneNumberType DirectRouting
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
$RAObjectId = (Get-CsOnlineUser RA_AA_$aaName@$resourceAccountDomain).Identity
$aaAssociationParams = @{
# As the previous association, array expected
Identities = $RAObjectId
ConfigurationId = $newAA.Identity
ConfigurationType = 'AutoAttendant'
ErrorAction = 'Stop'
}
Start-Sleep -Seconds 30
Write-Output “This command will be executed after 30 seconds”
$associationRes = New-CsOnlineApplicationInstanceAssociation @aaAssociationParams
# Check if resource accounts exist
'user number is:'
$count
Get-CsOnlineUser -Identity $user.SipAddress | ft UserPrincipalName, SipAddress,OnlineVoiceRoutingPolicy,TenantDialPlan, LineURI, EnterpriseVoiceEnabled
Get-CsOnlineApplicationInstance -Identities @($newAaRa.ObjectId)
Get-CsAutoAttendant -Identity $newAA.Identity
$count +=1
if($count -eq numberofUPN)
{
break}
}
}

Comments