private/Scripts/Initialize-CsAutoAttendants.ps1
<#
.SYNOPSIS This is a quick and nasty Teams AutoAttendant setup script It will check if the auto attendat exists, if not it will check/create the associated user, licence them and create the AA. .DESCRIPTION Created by James Arber. www.UcMadScientist.com .EXAMPLE Initialize-CsAutoAttendants Todo Todo .INPUTS This function accepts both parameter and pipline input .REQUIRED FUNCTIONS Write-UcmLog: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/Write-UcmLog.ps1 Test-MSOLConnection: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/Test-MSOLConnection.ps1 New-MSOLConnection: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/New-MSOLConnection.ps1 New-Office365User: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/New-Office365User.ps1 Grant-Office365UserLicence: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/Grant-Office365UserLicence.ps1 Write-HTMLReport: https://github.com/Atreidae/PowerShell-Fuctions/blob/main/Write-HTMLReport.ps1 AzureAD (Install-Module AzureAD) Connect-MsolService .LINK http://www.UcMadScientist.com https://github.com/Atreidae/PowerShell-Fuctions .ACKNOWLEDGEMENTS .KNOWN ISSUES Leaving script open for long periods of time (days) can cause timeout issues with Office365. Close the PowerShell Window / ISE or kill any PSSessions to resolve. .NOTES Version: 0.1 Date: 26/11/2020 .VERSION HISTORY 1.0: Initial Public Release #> Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Position=1)] $AAUPN=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=1)] $CCUPN=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=2)] $Password=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=3)] $FirstName=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=4)] $LastName=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=5)] $Country=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=6)] $DisplayName=$null, [Parameter(ValueFromPipelineByPropertyName=$true, Position=7)] $CSVFile=$null ) #todo, Non public release. Dot Source all the external functions BEGIN { ############################# # Script Specific Variables # ############################# $ScriptVersion = 0.1 $StartTime = Get-Date $Script:LogFileLocation = $PSCommandPath -replace '.ps1','.log' #Where do we store the log files? (In the same folder by default) #region Functions ################## # Function Block # ################## $Function = "Begin-Block, Fucntion Import" Write-UcmLog -Message "$ScriptVersion script started at $StartTime" -Severity 1 -Component $Function Write-UcmLog -Message 'Importing functions' -Severity 1 -Component $Function Function Invoke-CsAutoAttendant { <# .SYNOPSIS Checks for and creates everything for an AutoAttendant .DESCRIPTION Checks for and creates everything for an AutoAttendant .EXAMPLE Invoke-CsAutoAttendant -AAUPN T-AA-emergency@contoso.onmicrosoft.com -CCUPN T-CC-emergency@contoso.onmicrosoft.com -FirstName Caleb -LastName Sills -Country US -DisplayName "Caleb Sills" .PARAMETER AAUPN Defines the UPN used to create the AutoAttendant Resource Account. .PARAMETER CCUPN Defines the UPN used to create the CallQueue Resource Account, by default the AutoAttendant will be pointed to this queue This must be different from the AA UPN .PARAMETER Language #todo .PARAMETER TimeZone #todo .PARAMETER TTSGreeting (Optional) #If specified will create a text to speech message .PARAMETER AADefaultRouteType (Optional) #If specified what are we sending teh call to #todo .PARAMETER AADefaultRouteDestination (Optional) #If specified what SIP address/Number are we going to #todo .INPUTS This function accepts both parameter and pipline input .REQUIRED FUNCTIONS Write-UcmLog: https://github.com/Atreidae/PowerShell-Functions/blob/main/New-Office365User.ps1 AzureAD (Install-Module AzureAD) Connect-MsolService .LINK http://www.UcMadScientist.com https://github.com/Atreidae/PowerShell-Functions .ACKNOWLEDGEMENTS .NOTES Version: 1.0 Date: 25/11/2020 .VERSION HISTORY 1.0: Initial Public Release #> Param ( [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory, Position=1)] $UPN, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory, Position=2)] $DisplayName, [Parameter(ValueFromPipelineByPropertyName=$true, Mandatory, Position=3)][ValidateSet('AutoAttendant', 'CallQueue')] $ResourceType ) #region FunctionSetup, Set Default Variables for HTML Reporting and Write Log $function = 'Invoke-CsAutoAttendant' [hashtable]$Return = @{} $return.Function = $function $return.Status = "Unknown" $return.Message = "Function did not return a status message" # Log why we were called Write-UcmLog -Message "$($MyInvocation.InvocationName) called with $($MyInvocation.Line)" -Severity 1 -Component $function Write-UcmLog -Message "Parameters" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Keys)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Parameters Values" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Values)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Optional Arguments" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$Args" -Severity 1 -Component $function -LogOnly Write-Host '' #Insert a blank line to make reading output easier on loops #endregion FunctionSetup #region FunctionWork #Check to see if we are connected to SFBO $Test = (Test-SFBOConnection) If ($Test.Status -ne "OK") { Write-UcmLog -Message "Something went wrong creating user $UPN" -Severity 3 -Component $function Write-UcmLog -Message "Test-MSOLConnection could not locate an MSOL connection" -Severity 2 -Component $function $Return.Status = "Error" $Return.Message = "No MSOL Connection" Return $Return } #> Write-UcmLog -Message "Checking for Existing Resource Account $UPN ..." -Severity 2 -Component $function #Check user exits $AppInstance = $null $AppInstance = (Get-CsOnlineApplicationInstance | Where-Object {$_.UserPrincipalName -eq $UPN}) if ($AppInstance.UserPrincipalName -eq $UPN) { Write-UcmLog -Message "Resource Account already exists, Skipping" -Severity 3 -Component $function $Return.Status = "Warning" $Return.Message = "Skipped: Account Already Exists" Return $Return } Else { #User Doesnt Exist, make them Write-UcmLog -Message "Not Found. Creating user $UPN" -Severity 2 -Component $function Try { [Void] (New-CsOnlineApplicationInstance -UserPrincipalName $UPN -DisplayName $DisplayName -ApplicationId $ApplicationID -ErrorAction Stop) Write-UcmLog -Message "Resource Account Created Sucessfully" -Severity 2 -Component $function $Return.Status = "OK" $Return.Message = "Resource Account Created" Return $Return } Catch { Write-UcmLog -Message "Something went wrong creating user $UPN" -Severity 3 -Component $function Write-UcmLog -Message $Error[0] -Severity 3 -Component $Function $Return.Status = "Error" $Return.Message = $Error[0] Return $Return } } #endregion FunctionWork #region FunctionReturn #Default Return Variable for my HTML Reporting Fucntion Write-UcmLog -Message "Reached end of $function without a Return Statement" -Severity 3 -Component $function $return.Status = "Unknown" $return.Message = "Function did not encounter return statement" Return $Return #endregion FunctionReturn } #endregion Functions } PROCESS { #region FunctionSetup, Set Default Variables for HTML Reporting and Write Log $function = 'Process-Block' # Log why we were called Write-UcmLog -Message "$($MyInvocation.InvocationName) called with $($MyInvocation.Line)" -Severity 1 -Component $function Write-UcmLog -Message "Parameters" -Severity 3 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Keys)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Parameters Values" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Values)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Optional Arguments" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$Args" -Severity 1 -Component $function -LogOnly Write-Host '' #Insert a blank line to make reading output easier on loops #endregion FunctionSetup #region FunctionWork #Assume if we cant see a UPN, then we didnt get passed anything on the pipeline if (!$UPN) { #Now check for a CSV file attribute Write-UcmLog -Message "No UPN Found, checking for CSV" -Severity 1 -Component $function If (!$CSVFile) { Write-UcmLog -Message 'No CSV Provided, Prompting user' -Severity 2 -Component $Function Write-Host '' Write-Host '' Write-Host 'No attendants to create! Please enter a CSV filename in the script folder' $CSVFile = (Read-Host -Prompt 'Filename') Write-UcmLog -component $Function -message "User provided $CSVFile" -Severity 1 } #Now we have a CSV file defined, check for it Write-UcmLog -Message 'Checking for CSV File' -Severity 2 -Component $Function $CSVFilePath = $PSCommandPath -replace 'Initialize-CsAutoAttendants.ps1', $CSVFile If(!(Test-Path -Path $CSVFilePath )) { Write-UcmLog -Message "Could not locate $CSVFile in the same folder as this script" -Severity 3 -Component $Function Write-UcmLog -Message "No Attendants to process, Exiting Script" -Severity 5 -Component $Function Exit } Write-UcmLog -Message 'Calling Main Loop' -Severity 1 -Component $Function #Okay, we have what we think is a good CSV file, pass it to Invoke-CSUser Write-UcmLog -Message "Executing process block with Attendant $DisplayName" -Severity 1 -Component $Function Import-CSV -Path $CSVFilePath | ForEach-object {$_ | Invoke-CsAutoAttendant} } #Check to see if we got something on the pipeline, if we did. process it if ($AAUPN) { Write-UcmLog -Message "Executing process block with Attendant $DisplayName" -Severity 2 -Component $Function $_ | Invoke-CsAutoAttendant } #endregion FunctionWork } END { #region FunctionSetup, Set Default Variables for HTML Reporting and Write Log $function = 'END-Block' # Log why we were called Write-UcmLog -Message "$($MyInvocation.InvocationName) called with $($MyInvocation.Line)" -Severity 1 -Component $function Write-UcmLog -Message "Parameters" -Severity 3 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Keys)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Parameters Values" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$($PsBoundParameters.Values)" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "Optional Arguments" -Severity 1 -Component $function -LogOnly Write-UcmLog -Message "$Args" -Severity 1 -Component $function -LogOnly #endregion FunctionSetup Write-UcmLog -Message "Executing process block with Attendant $DisplayName" -Severity 1 -Component $Function } #Check for and create the users <# ForEach ($Attendant in $aa) {$Attendant | New-TeamsResourceAccount -ResourceType AutoAttendant} ForEach ($Attendant in $aa) {$Attendant | Grant-Office365UserLicence -licencetype PHONESYSTEM_VIRTUALUSER} ForEach ($CallQueue in $cc) {$CallQueue | New-TeamsResourceAccount -ResourceType CallQueue} ForEach ($CallQueue in $CC) {$CallQueue | Grant-Office365UserLicence -licencetype PHONESYSTEM_VIRTUALUSER} #Licnec for stuff PHONESYSTEM_VIRTUALUSER #> |