Last active
April 24, 2024 17:26
-
-
Save joerodgers/a856787f46c9403055ebcc071e469e5e to your computer and use it in GitHub Desktop.
Automation Account Runbook POC for creating new conference room mailboxes based on submissions in a SPO list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop | |
Import-Module -Name "ExchangeOnlineManagement" | |
Import-Module -Name "PnP.PowerShell" | |
class MailboxRequest | |
{ | |
[int] | |
$RequestId | |
[string] | |
$FirstName | |
[string] | |
$LastName | |
[string] | |
[string] | |
$Identity | |
[string] | |
$UsageLocation | |
[string] | |
$MailboxDisplayName | |
[string] | |
$TimeZone | |
[string] | |
$RequestStatus | |
} | |
function Get-Country | |
{ | |
$json = '[{"Name":"Afghanistan","Code":"AF"},{"Name":"Albania","Code":"AL"},{"Name":"Algeria","Code":"DZ"},{"Name":"Andorra","Code":"AD"},{"Name":"Angola","Code":"AO"},{"Name":"Antigua and Barbuda","Code":"AG"},{"Name":"Argentina","Code":"AR"},{"Name":"Armenia","Code":"AM"},{"Name":"Australia","Code":"AU"},{"Name":"Austria","Code":"AT"},{"Name":"Azerbaijan","Code":"AZ"},{"Name":"Bahamas","Code":"BS"},{"Name":"Bahrain","Code":"BH"},{"Name":"Bangladesh","Code":"BD"},{"Name":"Barbados","Code":"BB"},{"Name":"Belarus","Code":"BY"},{"Name":"Belgium","Code":"BE"},{"Name":"Belize","Code":"BZ"},{"Name":"Benin","Code":"BJ"},{"Name":"Bhutan","Code":"BT"},{"Name":"Bolivia (Plurinational State of)","Code":"BO"},{"Name":"Bosnia and Herzegovina","Code":"BA"},{"Name":"Botswana","Code":"BW"},{"Name":"Brazil","Code":"BR"},{"Name":"Brunei Darussalam","Code":"BN"},{"Name":"Bulgaria","Code":"BG"},{"Name":"Burkina Faso","Code":"BF"},{"Name":"Burundi","Code":"BI"},{"Name":"Cambodia","Code":"KH"},{"Name":"Cameroon","Code":"CM"},{"Name":"Canada","Code":"CA"},{"Name":"Cabo Verde","Code":"CV"},{"Name":"Central African Republic","Code":"CF"},{"Name":"Chad","Code":"TD"},{"Name":"Chile","Code":"CL"},{"Name":"China","Code":"CN"},{"Name":"Colombia","Code":"CO"},{"Name":"Comoros","Code":"KM"},{"Name":"Congo","Code":"CG"},{"Name":"Congo, Democratic Republic of the","Code":"CD"},{"Name":"Costa Rica","Code":"CR"},{"Name":"Côte d\u0027Ivoire","Code":"CI"},{"Name":"Croatia","Code":"HR"},{"Name":"Cuba","Code":"CU"},{"Name":"Cyprus","Code":"CY"},{"Name":"Czechia","Code":"CZ"},{"Name":"Denmark","Code":"DK"},{"Name":"Djibouti","Code":"DJ"},{"Name":"Dominica","Code":"DM"},{"Name":"Dominican Republic","Code":"DO"},{"Name":"Ecuador","Code":"EC"},{"Name":"Egypt","Code":"EG"},{"Name":"El Salvador","Code":"SV"},{"Name":"Equatorial Guinea","Code":"GQ"},{"Name":"Eritrea","Code":"ER"},{"Name":"Estonia","Code":"EE"},{"Name":"Ethiopia","Code":"ET"},{"Name":"Fiji","Code":"FJ"},{"Name":"Finland","Code":"FI"},{"Name":"France","Code":"FR"},{"Name":"Gabon","Code":"GA"},{"Name":"Gambia","Code":"GM"},{"Name":"Georgia","Code":"GE"},{"Name":"Germany","Code":"DE"},{"Name":"Ghana","Code":"GH"},{"Name":"Greece","Code":"GR"},{"Name":"Grenada","Code":"GD"},{"Name":"Guatemala","Code":"GT"},{"Name":"Guinea","Code":"GN"},{"Name":"Guinea-Bissau","Code":"GW"},{"Name":"Guyana","Code":"GY"},{"Name":"Haiti","Code":"HT"},{"Name":"Honduras","Code":"HN"},{"Name":"Hungary","Code":"HU"},{"Name":"Iceland","Code":"IS"},{"Name":"India","Code":"IN"},{"Name":"Indonesia","Code":"ID"},{"Name":"Iran (Islamic Republic of)","Code":"IR"},{"Name":"Iraq","Code":"IQ"},{"Name":"Ireland","Code":"IE"},{"Name":"Israel","Code":"IL"},{"Name":"Italy","Code":"IT"},{"Name":"Jamaica","Code":"JM"},{"Name":"Japan","Code":"JP"},{"Name":"Jordan","Code":"JO"},{"Name":"Kazakhstan","Code":"KZ"},{"Name":"Kenya","Code":"KE"},{"Name":"Kiribati","Code":"KI"},{"Name":"Korea (Democratic People\u0027s Republic of)","Code":"KP"},{"Name":"Korea, Republic of","Code":"KR"},{"Name":"Kuwait","Code":"KW"},{"Name":"Kyrgyzstan","Code":"KG"},{"Name":"Lao People\u0027s Democratic Republic","Code":"LA"},{"Name":"Latvia","Code":"LV"},{"Name":"Lebanon","Code":"LB"},{"Name":"Lesotho","Code":"LS"},{"Name":"Liberia","Code":"LR"},{"Name":"Libya","Code":"LY"},{"Name":"Liechtenstein","Code":"LI"},{"Name":"Lithuania","Code":"LT"},{"Name":"Luxembourg","Code":"LU"},{"Name":"North Macedonia","Code":"MK"},{"Name":"Madagascar","Code":"MG"},{"Name":"Malawi","Code":"MW"},{"Name":"Malaysia","Code":"MY"},{"Name":"Maldives","Code":"MV"},{"Name":"Mali","Code":"ML"},{"Name":"Malta","Code":"MT"},{"Name":"Marshall Islands","Code":"MH"},{"Name":"Mauritania","Code":"MR"},{"Name":"Mauritius","Code":"MU"},{"Name":"Mexico","Code":"MX"},{"Name":"Micronesia (Federated States of)","Code":"FM"},{"Name":"Morocco","Code":"MA"},{"Name":"Moldova, Republic of","Code":"MD"},{"Name":"Monaco","Code":"MC"},{"Name":"Mongolia","Code":"MN"},{"Name":"Montenegro","Code":"ME"},{"Name":"Mozambique","Code":"MZ"},{"Name":"Myanmar","Code":"MM"},{"Name":"Namibia","Code":"NA"},{"Name":"Nauru","Code":"NR"},{"Name":"Nepal","Code":"NP"},{"Name":"Netherlands","Code":"NL"},{"Name":"New Zealand","Code":"NZ"},{"Name":"Nicaragua","Code":"NI"},{"Name":"Niger","Code":"NE"},{"Name":"Nigeria","Code":"NG"},{"Name":"Norway","Code":"NO"},{"Name":"Oman","Code":"OM"},{"Name":"Pakistan","Code":"PK"},{"Name":"Palau","Code":"PW"},{"Name":"Panama","Code":"PA"},{"Name":"Papua New Guinea","Code":"PG"},{"Name":"Paraguay","Code":"PY"},{"Name":"Peru","Code":"PE"},{"Name":"Philippines","Code":"PH"},{"Name":"Poland","Code":"PL"},{"Name":"Portugal","Code":"PT"},{"Name":"Qatar","Code":"QA"},{"Name":"Romania","Code":"RO"},{"Name":"Russian Federation","Code":"RU"},{"Name":"Rwanda","Code":"RW"},{"Name":"Saint Kitts and Nevis","Code":"KN"},{"Name":"Saint Lucia","Code":"LC"},{"Name":"Saint Vincent and the Grenadines","Code":"VC"},{"Name":"Samoa","Code":"WS"},{"Name":"San Marino","Code":"SM"},{"Name":"Sao Tome and Principe","Code":"ST"},{"Name":"Saudi Arabia","Code":"SA"},{"Name":"Senegal","Code":"SN"},{"Name":"Serbia","Code":"RS"},{"Name":"Seychelles","Code":"SC"},{"Name":"Sierra Leone","Code":"SL"},{"Name":"Singapore","Code":"SG"},{"Name":"Slovakia","Code":"SK"},{"Name":"Slovenia","Code":"SI"},{"Name":"Solomon Islands","Code":"SB"},{"Name":"Somalia","Code":"SO"},{"Name":"South Africa","Code":"ZA"},{"Name":"South Sudan","Code":"SS"},{"Name":"Spain","Code":"ES"},{"Name":"Sri Lanka","Code":"LK"},{"Name":"Sudan","Code":"SD"},{"Name":"Suriname","Code":"SR"},{"Name":"Eswatini","Code":"SZ"},{"Name":"Sweden","Code":"SE"},{"Name":"Switzerland","Code":"CH"},{"Name":"Syrian Arab Republic","Code":"SY"},{"Name":"Tajikistan","Code":"TJ"},{"Name":"Tanzania, United Republic of","Code":"TZ"},{"Name":"Thailand","Code":"TH"},{"Name":"Timor-Leste","Code":"TL"},{"Name":"Togo","Code":"TG"},{"Name":"Tonga","Code":"TO"},{"Name":"Trinidad and Tobago","Code":"TT"},{"Name":"Tunisia","Code":"TN"},{"Name":"Türkiye","Code":"TR"},{"Name":"Turkmenistan","Code":"TM"},{"Name":"Tuvalu","Code":"TV"},{"Name":"Uganda","Code":"UG"},{"Name":"Ukraine","Code":"UA"},{"Name":"United Arab Emirates","Code":"AE"},{"Name":"United Kingdom of Great Britain and Northern Ireland","Code":"GB"},{"Name":"United States of America","Code":"US"},{"Name":"Uruguay","Code":"UY"},{"Name":"Uzbekistan","Code":"UZ"},{"Name":"Vanuatu","Code":"VU"},{"Name":"Venezuela (Bolivarian Republic of)","Code":"VE"},{"Name":"Viet Nam","Code":"VN"},{"Name":"Yemen","Code":"YE"},{"Name":"Zambia","Code":"ZM"},{"Name":"Zimbabwe","Code":"ZW"}]' | |
$countries = $json | ConvertFrom-Json | |
,$countries | |
} | |
function New-ConferenceRoomMailboxReqeustList | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[string] | |
$ListName, | |
[Parameter(Mandatory=$true)] | |
[PnP.PowerShell.Commands.Base.PnPConnection] | |
$Connection | |
) | |
begin | |
{ | |
# idempotent list creation | |
} | |
process | |
{ | |
$list = Get-PnpList -Identity $ListName -Includes Fields, DefaultView.ViewFields -Connection $Connection -ErrorAction Stop | |
if( $null -eq $list ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Provisioning request list: $ListName" | |
$list = New-PnpList -Title $ListName -Template GenericList -OnQuickLaunch -Connection $Connection -ErrorAction Stop | |
$null = Get-PnPProperty -ClientObject $list -Property Fields, DefaultView -Connection $Connection -ErrorAction Stop | |
$null = Get-PnPProperty -ClientObject $list.DefaultView -Property ViewFields -Connection $Connection -ErrorAction Stop | |
Write-Verbose "[$(Get-Date)] - Setting Title field to not be required" | |
$field = Get-PnPField -List $list -Identity "Title" -Connection $Connection -ErrorAction Stop | |
$field.Required = $false | |
$field.SetShowInDisplayForm($false) | |
$field.SetShowInEditForm($false) | |
$field.SetShowInNewForm($false) | |
$field.Update() | |
Write-Verbose "[$(Get-Date)] - Removing Title field from default view" | |
$view = Get-PnPView -List $List -Identity "All Items" -Connection $Connection -ErrorAction Stop | |
if( $view.ViewFields -contains "LinkTitle" ) | |
{ | |
$view.ViewFields.Remove( "LinkTitle" ) | |
$view.Update() | |
} | |
Invoke-PnPQuery -Connection $Connection -ErrorAction Stop | |
} | |
$existingFieldInternalNames = $list.Fields | Select-Object -ExpandProperty InternalName | |
if( $existingFieldInternalNames -notcontains "FirstName" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding FirstName column" | |
$null = Add-PnPField -List $list -DisplayName "First Name" -InternalName "FirstName" -Type Text -AddToDefaultView -Required -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "LastName" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding LastName column" | |
$null = Add-PnPField -List $list -DisplayName "Last Name" -InternalName "LastName" -Type Text -AddToDefaultView -Required -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "EmailAddress" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding EmailAddress column" | |
$null = Add-PnPField -List $list -DisplayName "Email Address" -InternalName "EmailAddress" -Type Text -AddToDefaultView -Required -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "Identity" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding Identity column" | |
$null = Add-PnPField -List $list -DisplayName "Identity" -InternalName "Identity" -Type Text -AddToDefaultView -Required -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "UsageLocation" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding UsageLocation column" | |
$countries = Get-Country | |
$null = Add-PnPField -List $list -DisplayName "Usage Location" -InternalName "UsageLocation" -Type Choice -AddToDefaultView -Required -Choice $countries.Name -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "MailboxDisplayName" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding MailboxDisplayName column" | |
$null = Add-PnPField -List $list -DisplayName "Mailbox Display Name" -InternalName "MailboxDisplayName" -Type Text -AddToDefaultView -Required -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "TimeZone" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding TimeZone column" | |
$timezones = Get-TimeZone -ListAvailable -ErrorAction Stop | Select-Object -ExpandProperty DisplayName | Sort-Object | |
$null = Add-PnPField -List $list -DisplayName "Time Zone" -InternalName "TimeZone" -Type Choice -AddToDefaultView -Required -Choice $timezones -Connection $Connection -ErrorAction Stop | |
} | |
if( $existingFieldInternalNames -notcontains "RequestStatus" ) | |
{ | |
Write-Verbose "[$(Get-Date)] - Adding RequestStatus column" | |
$status = "Pending", "Completed", "Failed" | |
$f = Add-PnPField -List $list -DisplayName "Request Status" -InternalName "RequestStatus" -Type Choice -AddToDefaultView -Required -Choice $status -Connection $Connection -ErrorAction Stop | |
if( $null -ne $f ) | |
{ | |
$f.DefaultValue = "Pending" | |
$f.SetShowInNewForm($false) | |
Invoke-PnPQuery -Connection $Connection | |
} | |
} | |
} | |
end | |
{ | |
} | |
} | |
function New-Password | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[ValidateRange(2,128)] | |
[int] | |
$Length, | |
[Parameter(Mandatory=$true)] | |
[ValidateRange(0,128)] | |
[int] | |
$NumberOfNonAlphanumericCharacters | |
) | |
begin | |
{ | |
# https://referencesource.microsoft.com/#System.Web/Security/Membership.cs,302 | |
$punctuations = "!@#$%^&*()_-+=[{]};:>|./?".ToCharArray() | |
$buf = [byte[]]::new( $Length ) | |
$cBuf = [char[]]::new( $Length ) | |
$count = 0 | |
} | |
process | |
{ | |
if( $NumberOfNonAlphanumericCharacters -gt $Length ) | |
{ | |
throw "NumberOfNonAlphanumericCharacters cannot be greater than Length" | |
} | |
try | |
{ | |
$randomNumberGenerator = [System.Security.Cryptography.RandomNumberGenerator]::Create() | |
$randomNumberGenerator.GetBytes($buf) | |
} | |
catch | |
{ | |
Write-Error "Failed to create an instance of System.Security.Cryptography.RandomNumberGenerator" | |
return | |
} | |
finally | |
{ | |
if( $null -ne $randomNumberGenerator ) | |
{ | |
$randomNumberGenerator.Dispose() | |
} | |
} | |
for($iter = 0; $iter -lt $Length; $iter++ ) | |
{ | |
$i = [int]($buf[$iter] % 87) | |
if( $i -lt 10 ) # 0-9 | |
{ | |
$cBuf[$iter] = [char]([int][char]'0' + $i - 10) | |
} | |
elseif( $i -lt 36) # A-Z | |
{ | |
$cBuf[$iter] = [char]([int][char]'A' + $i - 10) | |
} | |
elseif( $i -lt 62) # a-z | |
{ | |
$cBuf[$iter] = [char]([int][char]'a' + $i - 36) | |
} | |
else # punctuations | |
{ | |
$cBuf[$iter] = $punctuations[$i-62] | |
$count++; | |
} | |
} | |
if( $count -lt $numberOfNonAlphanumericCharacters ) | |
{ | |
$j = $k = 0 | |
$rand = New-Object Random | |
for( $j = 0; $j -lt $numberOfNonAlphanumericCharacters - $count; $j++ ) | |
{ | |
do | |
{ | |
$k = $rand.Next( 0, $length ) | |
} | |
while( -not [Char]::IsLetterOrDigit( $cBuf[$k] ) ) | |
$cBuf[$k] = $punctuations[$rand.Next(0, $punctuations.Length)] | |
} | |
} | |
return [string]::new( $cBuf ) | |
} | |
end | |
{ | |
} | |
} | |
function Test-ConnectedToExhangeOnline | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[string] | |
$ClientId | |
) | |
if( 'Microsoft.Exchange.Management.ExoPowershellSnapin.ConnectionContextFactory' -as [Type] ) | |
{ | |
$contexts = [Microsoft.Exchange.Management.ExoPowershellSnapin.ConnectionContextFactory]::GetAllConnectionContexts() | |
if( $contexts | Where-Object -Property AppId -eq $ClientId ) | |
{ | |
return $true | |
} | |
} | |
return $false | |
} | |
function Get-MailboxRequest | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[string] | |
$ListName, | |
[Parameter(Mandatory=$true)] | |
[PnP.PowerShell.Commands.Base.PnPConnection] | |
$Connection, | |
[Parameter(Mandatory=$false)] | |
[switch] | |
$All | |
) | |
$items = Get-PnPListItem -List $ListName -PageSize 5000 -Connection $Connection | |
$requests = foreach( $item in $items ) | |
{ | |
$countries = Get-Country | |
$countryCode = $countries | Where-Object -Property Name -match $item.FieldValues.UsageLocation | Select-Object -ExpandProperty Code | |
$tz = Get-TimeZone -ListAvailable | Where-Object -Property DisplayName -eq $item.FieldValues.TimeZone | Select-Object -ExpandProperty Id | |
if( -not $tz ) | |
{ | |
$tz = Get-TimeZone | Select-Object -ExpandProperty Id # default to current machine's timezone | |
} | |
$request = New-Object MailboxRequest | |
$request.RequestId = $item.Id | |
$request.FirstName = $item.FieldValues.FirstName | |
$request.LastName = $item.FieldValues.LastName | |
$request.Email = $item.FieldValues.EmailAddress | |
$request.Identity = $item.FieldValues.Identity | |
$request.UsageLocation = $countryCode | |
$request.MailboxDisplayName = $item.FieldValues.MailboxDisplayName | |
$request.RequestStatus = $item.FieldValues.RequestStatus | |
$request.TimeZone = $tz | |
$request | |
} | |
if( $All.IsPresent ) | |
{ | |
$requests | |
} | |
else | |
{ | |
$requests | Where-Object -Property RequestStatus -eq "Pending" | |
} | |
} | |
function Update-MailboxRequestStatus | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[string] | |
$ListName, | |
[Parameter(Mandatory=$true)] | |
[MailboxRequest] | |
$MailboxRequest, | |
[Parameter(Mandatory=$true)] | |
[PnP.PowerShell.Commands.Base.PnPConnection] | |
$Connection | |
) | |
Write-Verbose "[$(Get-Date)] - Updating request $($MailboxRequest.RequestId) request status to $($MailboxRequest.RequestStatus)" | |
$null = Set-PnPListItem -List $ListName -Identity $MailboxRequest.RequestId -Values @{ RequestStatus = $MailboxRequest.RequestStatus } -Connection $Connection | |
} | |
function New-ConferenceRoomMailbox | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[Parameter(Mandatory=$true)] | |
[MailboxRequest] | |
$MailboxRequest, | |
[Parameter(Mandatory=$true)] | |
[SecureString] | |
$MailboxPassword | |
) | |
begin | |
{ | |
} | |
process | |
{ | |
$mailboxName = "{0} {1}" -f $request.FirstName, $request.LastName | |
try | |
{ | |
Write-Verbose "[$(Get-Date)] - Creating mailbox: $($request.Identity)" | |
# create mailbox | |
$mb = New-Mailbox ` | |
-Room ` | |
-Name $mailboxName ` | |
-Alias $request.Identity ` | |
-EnableRoomMailboxAccount $true ` | |
-MicrosoftOnlineServicesID $request.Email ` | |
-RoomMailboxPassword $MailboxPassword ` | |
-ErrorAction Stop | |
$mb | |
Write-Verbose "[$(Get-Date)] - Updating calendar processing options" | |
Set-CalendarProcessing ` | |
-Identity $request.Email ` | |
-AutomateProcessing AutoAccept ` | |
-AllowConflicts $false ` | |
-BookingWindowInDays 548 ` | |
-MaximumDurationInMinutes 1440 ` | |
-AllowRecurringMeetings $true ` | |
-EnforceSchedulingHorizon $true ` | |
-ScheduleOnlyDuringWorkHours $false ` | |
-ConflictPercentageAllowed 0 ` | |
-MaximumConflictInstances 0 ` | |
-ForwardRequestsToDelegates $false ` | |
-DeleteAttachments $true ` | |
-DeleteSubject $true ` | |
-RemovePrivateProperty $false ` | |
-DeleteNonCalendarItems $true ` | |
-TentativePendingApproval $false ` | |
-EnableResponseDetails $true ` | |
-OrganizerInfo $true ` | |
-AllRequestOutOfPolicy $false ` | |
-AllBookInPolicy $true ` | |
-AllRequestInPolicy $false ` | |
-AddAdditionalResponse $false ` | |
-RemoveOldMeetingMessages $true ` | |
-AddNewRequestsTentatively $false ` | |
-ProcessExternalMeetingMessages $true ` | |
-RemoveForwardedMeetingNotifications $false ` | |
-AddOrganizerToSubject $true | |
Write-Verbose "[$(Get-Date)] - Updating calendar configuration" | |
$timezone = $request.TimeZone | |
Set-MailboxCalendarConfiguration ` | |
-Identity $request.Email ` | |
-WorkingHoursTimeZone $request.TimeZone ` | |
-WorkDays 7 ` | |
-WorkingHoursStartTime 08:00 ` | |
-WorkingHoursEndTime 18:00 | |
Write-Verbose "[$(Get-Date)] - Updating calendar permissions" | |
$mailboxFolderIdentity = "{0}:\calendar" -f $request.Email | |
Set-MailboxFolderPermission ` | |
-Identity $mailboxFolderIdentity ` | |
-User Default ` | |
-AccessRights LimitedDetails | |
Write-Verbose "[$(Get-Date)] - Updating password policy" | |
$json = [PSCustomObject] @{ | |
passwordPolicies = "DisablePasswordExpiration" | |
usageLocation = $request.UsageLocation } | ConvertTo-Json | |
Invoke-PnPGraphMethod ` | |
-Method Patch ` | |
-Url "/v1.0/users/$($request.Email)" ` | |
-Content $json.ToString() ` | |
-ErrorAction Stop | |
$request.RequestStatus = "Completed" | |
} | |
catch | |
{ | |
Write-Error "Failed to provision confernence room mailbox. Error: $_" -ErrorAction Continue | |
$request.RequestStatus = "Failed" | |
} | |
} | |
end | |
{ | |
} | |
} | |
# config | |
$clientId = $env:O365_CLIENTID | |
$thumbprint = $env:O365_THUMBPRINT | |
$tenant = $env:O365_TENANT | |
$tennatId = $env:O365_TENANTID | |
$listName = "Mailbox Request" | |
$siteUrl = "https://$tenant.sharepoint.com/sites/EdwardsMailboxRequest" | |
# connect to exo | |
if( -not (Test-ConnectedToExhangeOnline -ClientId $clientId -ErrorAction Stop) ) | |
{ | |
# setup: https://learn.microsoft.com/en-us/powershell/exchange/app-only-auth-powershell-v2?view=exchange-ps#set-up-app-only-authentication | |
Connect-ExchangeOnline ` | |
-AppId $clientId ` | |
-CertificateThumbprint $thumbprint ` | |
-Organization "$tenant.onmicrosoft.com" ` | |
-ErrorAction Stop | |
} | |
# connect to sharepoint site | |
# must have manage (or higher) application perms on target site | |
$connection = Connect-PnPOnline ` | |
-Url $siteUrl ` | |
-ClientId $clientId ` | |
-Thumbprint $thumbprint ` | |
-Tenant $tennatId ` | |
-ErrorAction Stop ` | |
-ReturnConnection | |
# ensure list exists and schema is current | |
New-ConferenceRoomMailboxReqeustList -ListName $listName -Connection $connection -ErrorAction Stop -Verbose | |
# get pending requests from sharepoint list | |
$requests = Get-MailboxRequest -ListName $listName -Connection $connection -ErrorAction Stop -Verbose | |
# process pending request | |
foreach( $request in $requests ) | |
{ | |
Write-Host "[$(Get-Date)] - Provisioning mailbox: $($request.Identity)" | |
try | |
{ | |
$securePassword = New-Password -Length 13 -NumberOfNonAlphanumericCharacters 4 | ConvertTo-SecureString -AsPlainText -Force | |
$mailbox = New-ConferenceRoomMailbox -MailboxRequest $request -MailboxPassword $securePassword -ErrorAction Stop -Verbose | |
Write-Host "[$(Get-Date)] - Provisioned mailbox: $($mailbox.Alias)" | |
} | |
catch | |
{ | |
Write-Error "Failed to provision mailbox: $($request.Identity). Error: $_" -ErrorAction Continue | |
} | |
Update-MailboxRequestStatus -ListName $listName -MailboxRequest $request -Connection $connection -ErrorAction Stop | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment