In part 1 we looked at connecting to Exchange from a Azure Automation with the intent to move our Exchange Tasks to Azure Automation. Today I will look a little more on doing some tasks with Exchange. I will demonstrate how to set and update calendar permissions and how to keep an Hierarchical Address Book up to date, turning the groups from manual it into a dynamic groups.
Exchange calendar permissions
Let’s dive right into it and start with the most common one. Set Calendar permissions.
I created a mail-enabled Security group named Reception in Exchange and added one of my Demo users to the group. I’ll show later how the test users is able to add entries into my calendar. But first let’s have a look at the runbook and how we can check that we get the desired results.
The script I used for the task is here loops trough all users mailboxes and checks if the Reception group have the correct access. If it doesn’t we add the access rights to the calendar. It’s an easy way to always keep new users with the correct calendar premissions, according to your organizations policy. The script checks for the Calendar and for the Kalendar as the default mailboxes for me might be Norwegian. You might have a different language and need to modify the script accordingly. If you are moving scripts from on-premise and you use Write-Host, remember to change them to Write-Output to get data into the output stream. The runbook will convert Write-Host to Write-Verbose, but these are not logged by default.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
.\EX-ConnectExchange.ps1 ## Variables for the script below ## $accessgroup = "reception@stellarlab.net" ## This needs to be a user or security group in Exchange ## End variables for script ## THIS is the script that configues the correct calendarpermissions on the accounts. $mail = Get-Mailbox -RecipientTypeDetails UserMailbox $mail | ForEach-Object { # First check if users have access to the mailbox If (Get-MailboxFolderPermission -Identity "$($_.Name):\Calendar" -User $accessgroup -ErrorAction SilentlyContinue){ Write-Output "$($_.DisplayName): Calendar permissions is already set"} elseif (Get-MailboxFolderPermission -Identity "$($_.Name):\Kalender" -User $accessgroup -ErrorAction SilentlyContinue) { Write-Output "$($_.DisplayName): Calendar permissions is already set" } ## Adds permissions if the user does not have access ## else { Add-MailboxFolderPermission -AccessRights Author -User $accessgroup -Identity "$($_.Name):\Calendar" -ErrorAction SilentlyContinue Add-MailboxFolderPermission -AccessRights Author -User $accessgroup -Identity "$($_.Name):\Kalender" -ErrorAction SilentlyContinue Write-Output "$($_.DisplayName): Calendar permissions is configured" } } |
The runbook looks this way, and once it has run you can see the recent jobs, output, errors etc. I’ve attached some images of the initial error I got, when I wrote the script. and the output from when it worked. There are some fucntions in the script that is not viable to use, in this case it’s the parameter -ForegroundColor.
To get most output from your script I would suggest to enable logging. If you use Versbose commands to output information the default setting so to not output this in the jobs. This needs to be done on each runbook.The second output, when all permissions has been set, and below it is one with a combined set of results.
Hierarchy Address Book
Next we are turning a HAB from a manual/static distribution group into a dynamic group using Automation and Exchange Online. There are some limits of fields that you can get from the Exchange. In this task we are using basic feature available to us in Exchange. The runbook script looks like this and does the following. We look up mailboxes using RecipientTypeDetails and UsageLocation. We also add all groups inside the group, since we use the Update-DistributionGroupMember we effectivly replace all users (and groups) within the hierarchy. So in order for the nested groups to be displayed correctly we need to add them into the array before we update the members.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
## Connect to Exchange Online .\EX-ConnectExchange.ps1 ## Add members to group "Resources" that is used in the HAB $members = @() $resources = Get-Mailbox -RecipientTypeDetails RoomMailbox, EquipmentMailbox ##Starts the looping process $resources | ForEach-Object { $members += $_.Alias } Update-DistributionGroupMember -Identity Resources -Member $members -Confirm:$false Write-Output "Added these resources to the resource group " $members ## Add members to group "Norway" that is used in the HAB $membersno = @() $resourcesno = Get-Mailbox -Filter {UsageLocation -eq "Norway"} ##Starts the looping process $resourcesno | ForEach-Object { $membersno += $_.Alias } Update-DistributionGroupMember -Identity Norway -Member $membersno -Confirm:$false Add-DistributionGroupMember -Identity Norway -Member resources Write-Output "Added these resources to the resource group " $membersno ## Add members to group "Norway" that is used in the HAB $membersuk = @() $resourcesuk = Get-Mailbox -Filter {UsageLocation -eq "United Kingdom"} ##Starts the looping process $resourcesuk | ForEach-Object { $membersuk += $_.Alias } Update-DistributionGroupMember -Identity uk -Member $membersuk -Confirm:$false Add-DistributionGroupMember -Identity uk -Member contacts Write-Output "Added these resources to the resource group " $membersuk |
Remeber to add data to Write-Output so you can get logging in your scripts. You can see the output result below for the Resource group, but not for the other groups. This is because the Write-Output was not added for the other groups. And finally you will se the HAB in Outlook updated with the “dynamic” users and groups.
In bigger organizations we might want to filter on Company, Department or Location. This is were a combination of Azure AD and Exchange is a good match to get users from Azure AD to get even more granular or dynamic based on objet properties. We will look at this in a later article.
Schedule the tasks
The last thing we need to do is to create a schedule and link our tasks to this schedule. We don’t want to enter automation to run the scripts manually. Open Schedule in the Shared Resources section and create your new schedule. I’ve created an hourly schedule that runs on the hour.
Go back to the Runbook and press Link to schedule, and select the schedule you want to link it to. Once it is set you can see it in the runbook’s left menu under Schedules in the Resources section and verify that it is configured.
do you have any steps in runbook to read csv file and export email address to csv file for exchange?
No, not currently.
You should run the script on-premise or you can store files in an Azure Storage account. I haven’t tried this yet.
I currently run something similar but with a Microsoft Form. We have many attorneys, so interns always need access to their calendars or contacts. The Form fills out the needed parameters that runs a Power Automate flow. An approval comes to me through Teams; once accepted, the Azure Automation connector starts to activate a runbook and emails them when it is completed.
That’s quite neat! =) Power Automate is a good way to go to do a lot of these tasks, especially if this is a request driven flow.