PowerShell – show and adjust resource booking configuration according to 4 scenarios

There is an amazing article (https://itpro.outsidesys.com/2017/11/06/exchange-configuring-the-resource-booking-attendant-with-powershell/) published by John Dougherty on how to adjust resource booking configuration having 4 different scenarios.

Those 4 scenarios are:

  • Anyone can book the resource. No delegate approval required.
  • Anyone can book the resource. Delegate approval required for all requests.
  • Only a list of people can book the resource without delegate approval. All others require delegate approval.
  • Only a list of people can book the resource. All others are denied. There are no delegates.

Not everything can be done through an Admin portal, that’s why having such a PowerShell script is crucial.

I decided to do several things to improve that process:

  • Added code to check an existing configuration for every single Room and Resource. If the configuration is any different than these 4 above, then the script notifies you about it.
  • Combined scripts into a single one.
  • Added more user input to not adjust the code every time.
$scenario1 = "Anyone can book the resource. No delegate approval required."
$scenario2 = "Anyone can book the resource. Delegate approval required for all requests."
$scenario3 = "Only a list of people can book the resource without delegate approval. All others require delegate approval."
$scenario4 = "Only a list of people can book the resource. All others are denied. There are no delegates."

$resources = Get-Mailbox -ResultSize unlimited | Where-Object {
	($_.RecipientTypeDetails -eq "EquipmentMailbox") -or
	($_.RecipientTypeDetails -eq "RoomMailbox")
} | Get-CalendarProcessing

$collection = @()

$i = 0

ForEach ($resource in $resources) {
	$outObject = "" | Select "Number","Identity","Scenario"
	
	$i = $i + 1
	
	$outObject."Number" = $i
	$outObject."Identity" = $resource.Identity
	
	If (
		$resource.AllBookInPolicy -eq $True -and
		$resource.AllRequestInPolicy -eq $False -and
		$resource.AllRequestOutOfPolicy -eq $False -and
		
		$resource.ResourceDelegates.count -eq 0 -and
		$resource.BookInPolicy.count -eq 0 -and
		$resource.RequestInPolicy.count -eq 0 -and
		$resource.RequestOutOfPolicy.count -eq 0
	) {
		$outObject."Scenario" = $scenario1
	}
	
	ElseIf (
		$resource.AllBookInPolicy -eq $False -and
		$resource.AllRequestInPolicy -eq $True -and
		$resource.AllRequestOutOfPolicy -eq $False -and
		
		$resource.ResourceDelegates.count -gt 0 -and
		$resource.BookInPolicy.count -eq 0 -and
		$resource.RequestInPolicy.count -eq 0 -and
		$resource.RequestOutOfPolicy.count -eq 0
	) {
		$outObject."Scenario" = $scenario2
	}
	
	ElseIf (
		$resource.AllBookInPolicy -eq $False -and
		$resource.AllRequestInPolicy -eq $True -and
		$resource.AllRequestOutOfPolicy -eq $False -and
		
		$resource.ResourceDelegates.count -gt 0 -and
		$resource.BookInPolicy.count -gt 0 -and
		$resource.RequestInPolicy.count -eq 0 -and
		$resource.RequestOutOfPolicy.count -eq 0
	) {
		$outObject."Scenario" = $scenario3
	}
	
	ElseIf (
		$resource.AllBookInPolicy -eq $False -and
		$resource.AllRequestInPolicy -eq $False -and
		$resource.AllRequestOutOfPolicy -eq $False -and
		
		$resource.ResourceDelegates.count -eq 0 -and
		$resource.BookInPolicy.count -gt 0 -and
		$resource.RequestInPolicy.count -eq 0 -and
		$resource.RequestOutOfPolicy.count -eq 0
	) {
		$outObject."Scenario" = $scenario4
	}
	
	Else {
		$outObject."Scenario" = "!!! Possible misconfiguration !!!"
	}
	
	$collection += $outObject
}

$collection | Out-Host

Do {
	Try {
		$num = $true
		[int]$selectedinput = Read-host "Select a Resource you would like to adjust by typing its number"
	}
	Catch {$num = $false}
}
Until (($selectedinput -gt 0 -and $selectedinput -le $collection.count) -and $num)

$selectedresource = $collection[[int]$selectedinput - 1]

Write-host `n
Write-host "You selected" $selectedresource.Identity

If ($selectedresource.Scenario -ne $scenario1) {
	Write-host `n"Because of the current scenario applied to this resource, here is some additional info:"	

	Get-CalendarProcessing -Identity $selectedresource.Identity |
	Select @{
		Label="Current delegates";
		Expression={$_.ResourceDelegates}
	},
	@{
		Label="Current allowed users";
		Expression={$_.BookInPolicy}
	} | fl
}

$scenariocollection = @()

$scenariocollection += New-object PSObject -Property(@{Number = 1; Option = $scenario1})
$scenariocollection += New-object PSObject -Property(@{Number = 2; Option = $scenario2})
$scenariocollection += New-object PSObject -Property(@{Number = 3; Option = $scenario3})
$scenariocollection += New-object PSObject -Property(@{Number = 4; Option = $scenario4})

$scenariocollection | Out-Host

Do {
	Try {
		$num = $true
		[int]$selectedoptioninput = Read-host "Select an option you would like to apply to" $selectedresource.Identity
	}
	Catch {$num = $false}
}
Until (($selectedoptioninput -gt 0 -and $selectedoptioninput -le $scenariocollection.count) -and $num)

If ($selectedoptioninput -eq 1) {
	$Properties = @{

		AutomateProcessing = 'AutoAccept'

		AllBookInPolicy       = $true
		AllRequestInPolicy    = $false
		AllRequestOutOfPolicy = $false

		ResourceDelegates  = $null
		BookInPolicy       = $null
		RequestInPolicy    = $null
		RequestOutOfPolicy = $null

		AddAdditionalResponse = $false
		AdditionalResponse = $null
	}
	
	Set-CalendarProcessing -Identity $selectedresource.Identity @Properties
	
	Write-host `n"Done!"
}

ElseIf ($selectedoptioninput -eq 2) {
	$delegatesstring = Read-host "Create a comma separated list with each delegate's primary email address (using mail enabled distribution groups is allowed)"
	$delegates = $delegatesstring.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries).Trim()
	
	$Properties = @{

		AutomateProcessing = 'AutoAccept'

		AllBookInPolicy       = $false
		AllRequestInPolicy    = $true
		AllRequestOutOfPolicy = $false

		ResourceDelegates  = $delegates
		BookInPolicy       = $null
		RequestInPolicy    = $null
		RequestOutOfPolicy = $null

		AddAdditionalResponse = $false
		AdditionalResponse = $null
	}
	
	Set-CalendarProcessing -Identity $selectedresource.Identity @Properties
	
	Write-host `n"Done!"
}

ElseIf ($selectedoptioninput -eq 3) {
	$usersstring = Read-host "Create a comma separated list with each allowed user's primary email address (using mail enabled distribution groups is allowed)"
	$users = $usersstring.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries).Trim()
	
	$delegatesstring = Read-host "Create a comma separated list with each delegate's primary email address (using mail enabled distribution groups is allowed)"
	$delegates = $delegatesstring.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries).Trim()
			
	$Properties = @{

		AutomateProcessing = 'AutoAccept'

		AllBookInPolicy       = $false
		AllRequestInPolicy    = $true
		AllRequestOutOfPolicy = $false

		ResourceDelegates  = $delegates
		BookInPolicy       = $users
		RequestInPolicy    = $null
		RequestOutOfPolicy = $null

		AddAdditionalResponse = $false
		AdditionalResponse = $null
	}
	
	Set-CalendarProcessing -Identity $selectedresource.Identity @Properties
	
	Write-host `n"Done!"
}

ElseIf ($selectedoptioninput -eq 4) {
	$usersstring = Read-host "Create a comma separated list with each allowed user's primary email address (using mail enabled distribution groups is allowed)"
	$users = $usersstring.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries).Trim()
	
	$responsestring = Read-host "Message that other users will see when attempting to book a restricted resource"
		
	$Properties = @{

		AutomateProcessing = 'AutoAccept'

		AllBookInPolicy       = $false
		AllRequestInPolicy    = $false
		AllRequestOutOfPolicy = $false

		ResourceDelegates  = $null
		BookInPolicy       = $users
		RequestInPolicy    = $null
		RequestOutOfPolicy = $null
		
		AddAdditionalResponse = $true
		AdditionalResponse = $responsestring
	}
	
	Set-CalendarProcessing -Identity $selectedresource.Identity @Properties
	
	Write-host `n"Done!"
}

Remove-Variable * -ErrorAction SilentlyContinue

Leave a Reply