Last active
June 11, 2021 08:51
-
-
Save AlexAsplund/93285b6a3c62be559eeec3abec4f3c4b to your computer and use it in GitHub Desktop.
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
<# | |
.Synopsis | |
Script that imports a public folder calendar to a mailbox. | |
.DESCRIPTION | |
Script that imports a public folder calendar to a mailbox. | |
Need EWS api installed and Offce365 admin rights | |
.EXAMPLE | |
This will give the $ExchangeCredential.Username account FullAccess permissions to meetingresource1@contoso.com | |
After that it wil take the calendar from -PublicFolderPath and copy the items in it to meetingresource1@contoso.com calendar. | |
The last two actions renames the public folder calendar to 'Not used - *DATE* - <DisplayName>' | |
.\Import-CalendarFromPublicFolder.ps1 -ExchangeCredential $ExchangeCredential -Office365AdminCredential $Office365AdminCredential -PublicFolderPath 'HR\Resources\Meetingroom 1' -ResourceMailAddress meetingresource1@contoso.com -ChangePermissions | |
#> | |
param( | |
[parameter(Mandatory)] | |
[pscredential]$ExchangeCredential, | |
[parameter(Mandatory)] | |
[pscredential]$Office365AdminCredential, | |
[parameter(Mandatory)] | |
[string]$PublicFolderCalendarPath, | |
[parameter(Mandatory)] | |
[string]$ResourceMailAddress, | |
[int]$ItemLimit = 999999, | |
[switch]$ChangePermissions | |
) | |
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll" | |
######################################### | |
# Functions | |
######################################### | |
function Connect-EWS { | |
param( | |
[parameter(Mandatory = $True)] | |
[PSCredential] | |
$Credential, | |
[parameter(Mandatory = $True)] | |
[string] | |
$Domain, | |
[parameter(Mandatory = $True)] | |
[string] | |
$AutoDiscoverUrl | |
) | |
# Set the domain in networkcredential - don't know if this is the way to do it but it works. | |
$Credential.GetNetworkCredential().Domain = $Domain | |
# Create ExchangeCredential from regular [PSCredential] | |
$ExchangeCredential = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($Credential.Username, $Credential.GetNetworkCredential().Password, $Credential.GetNetworkCredential().Domain) | |
# Create the exchange service object | |
$ExchangeService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService | |
# Not sure if this is needed | |
$ExchangeService.UseDefaultCredentials = $true | |
# Add the ExchangeCredential to the ExchangeService | |
$ExchangeService.Credentials = $ExchangeCredential | |
# {$true} is needed if it's office 365 with a redirect on the autodiscovery. I think there's a lot more secure ways to check if | |
# a redirection is correct. | |
$ExchangeService.AutodiscoverUrl($AutoDiscoverUrl, {$true}) | |
return $ExchangeService | |
} | |
######################################### | |
# Connect to Office365 | |
######################################### | |
if($ChangePermissions){ | |
try{ | |
Write-Output "Connecting to Exchange Online" | |
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Office365AdminCredential -Authentication Basic -AllowRedirection | |
Import-PSSession $Session -DisableNameChecking | |
} | |
catch{ | |
Write-Error $_ | |
Write-Error "Error connecting to office 365" | |
Break | |
} | |
Try{ | |
Write-Output "Fetching mailbox" | |
$Mailbox = Get-Mailbox $ResourceMailAddress | |
} | |
catch{ | |
Write-Error "Error fetching mailbox" | |
Write-Error $_ | |
Break | |
} | |
Try { | |
Write-Output "Adding permissions" | |
$Mailbox | Add-MailboxPermission -User $ExchangeCredential.UserName -AccessRights FullAccess -InheritanceType All -AutoMapping $false | |
} | |
catch{ | |
Write-Error "Error setting permissions on mailbox" | |
Write-Error $_ | |
Break | |
} | |
} | |
######################################### | |
# Connect to EWS | |
######################################### | |
$ExchangeService = Connect-EWS -Credential $ExchangeCredential -Domain ($ExchangeCredential.UserName -replace "^(.+)(@.+)$",'$2') -AutoDiscoverUrl $ExchangeCredential.UserName | |
######################################### | |
# Resolve public folder calendar | |
######################################### | |
$WellKnownPublicFolderName = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot | |
$PublicFolderRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($ExchangeService, $WellKnownPublicFolderName) | |
$PublicFolderView = [Microsoft.Exchange.WebServices.Data.FolderView]::new($ItemLimit) | |
$FolderPath = ($PublicFolderCalendarPath -split "\\") | |
$Folder = $Null | |
$FolderPath | foreach { | |
$FolderName = $_ | |
$ParentFolder = $Folder | |
if($Folder -eq $Null){ | |
$Folder = $PublicFolderRoot.FindFolders($PublicFolderView) | ? {$_.DisplayName -eq $FolderName} | |
} | |
else{ | |
$Folder = $Folder.FindFolders($PublicFolderView) | ? {$_.DisplayName -eq $FolderName} | |
} | |
} | |
######################################### | |
# Get Resource folder ID | |
######################################### | |
$WellKnownFolderCalendar = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar | |
$ResourceFolder = [Microsoft.Exchange.WebServices.Data.FolderId]::new($WellKnownFolderCalendar, $ResourceMailAddress) | |
$ResourceCalendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($ExchangeService, $ResourceFolder) | |
$ResourceCalendarId = $ResourceCalendar.Id | |
######################################### | |
# Copy items to folder | |
######################################### | |
$Items = $Folder.FindItems([Microsoft.Exchange.WebServices.Data.ItemView]::new(1000000)) | ? {$_.Start -ge (Get-Date).AddDays(-30)} | |
foreach($Item in $Items){ | |
Try{ | |
$Item.Copy($ResourceCalendarId) | |
Write-Output "Copied|$($ResourceCalendarId.UniqueId)|$($Path)|ID: $($Item.Id.UniqueId)" | |
} | |
catch{ | |
Write-Output "Error Copying Appointment|$($ResourceCalendarId.UniqueId)|$($Path)|ID: $($Item.Id.UniqueId)" | |
} | |
} | |
####################################### | |
# Rename old calendar | |
####################################### | |
$Date = Get-Date -Format "yyyy-MM-dd" | |
$Folder.DisplayName = ("Not used - $Date - "+$Folder.DisplayName) | |
try{ | |
$Folder.Update() | |
} | |
catch{ | |
Write-Output "Error Renaming Old Calendar|$($Folder.DisplayName)" | |
} | |
###################################### | |
# Remove mailbox permission | |
###################################### | |
if($ChangePermissions){ | |
$Mailbox | Remove-MailboxPermission -User $ExchangeCredential.UserName -AccessRights FullAccess -InheritanceType All | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment