Yeah it seems there is information everywhere about getting the DEFAULT calendar… I believe you’ll probably need .GetSharedDefaultFolder() or .OpenSharedItem() but I haven’t had success with it yet. I’ll keep trying as I have time. If you figure it out, please share!
Take note of the where-object to get the desired shared calendar. You can also target “My Calendars” and “Other Calendars” group as commented. This was really interesting to learn, thanks for asking the question.
Something else you should know is if your powershell is running as admin, your outlook should be too. (or closed) I’ve also had some issues in the past trying to do some of these outlook methods with certain versions of office 365 Outlook.
OK yes it definitely depends on outlook being open. I had a feeling the way I was using the activeexplorer, navigation pane, and navigation folders, was all dependent on the outlook window itself. With outlook closed, first thing I had to do is at the $namespace = mapi command I had to choose an outlook profile. Second thing is have the outlook window open. There has got to be another, better way. Are you needing to do this on your own calendar only? Would the requirement to have outlook open make this not acceptable?
OK I am not sure how to attach a file here or if i can, so apologies for how long it is. I wrote a function so you can specify what owner, date range, details that you want. I added a couple of examples that should help you to use it. My only fear is the formatting getting messed up from the forum. I need to get this uploaded to the gallery but I want to do a lot more testing first. I was able to use this to export 3 different shared calendars and i tried many combinations of options.
Function Export-OutlookSharedCalendar{
<#
.Synopsis
Allows a user to export a shared calendar from their outlook.
.DESCRIPTION
Allows a user to export a shared calendar from their outlook.
.NOTES
Name: Export-OutlookSharedCalendar.ps1
Author: Doug Maurer
Version: 1.0.0.3
DateCreated: 2020-04-08
DateUpdated: 2020-04-08
.LINK
.INPUTS
None
.OUTPUTS
An ics file of the calendar
.PARAMETER Owner
The actual owner of the shared calendar
.PARAMETER Path
Full path for the exported file, including the filename.
.PARAMETER StartDate
The start date of the desired export period
.PARAMETER EndDate
The end date of the desired export period
.PARAMETER Detail
The level of calendar detail to export.
.PARAMETER RestrictToWorkingHours
Used to restrict the export to working hours
.PARAMETER IncludePrivateDetails
Switch for including private details of the calendar items
.PARAMETER IncludeAttachments
Switch for including attachments with the calendar items
.EXAMPLE
Export-OutlookSharedCalendar -Owner 'first.last@contoso.com' -Path 'c:\temp\contoso shared calendar.ics' -startdate 01/01/2019 -enddate 09/01/2019 -detail FullDetails -AllowClobber
Description
-----------
Exports specific items from shared calendar owned by first.last@constoso.com from the default (or chosen) outlook profile and exports it to 'c:\temp\contoso shared calendar.ics'
.EXAMPLE
Export-OutlookSharedCalendar -Owner 'first.last@contoso.com' -Path 'c:\users\windowsuser\documents\exporttest.ics' -detail FreeBusyOnly -RestrictToWorkingHours
#>
[cmdletbinding()]
Param(
[alias('CalendarOwner')]
[Parameter(Mandatory=$true)]
$Owner,
[Parameter(Mandatory=$true)]
$Path,
[datetime]$StartDate,
[datetime]$EndDate,
[Parameter()][ValidateSet("FreeBusyOnly","FreeBusyAndSubject","FullDetails")]$Detail = "FreeBusyOnly",
[switch]$RestrictToWorkingHours = $false,
[switch]$IncludeAttachments = $false,
[switch]$IncludePrivateDetails = $false,
[switch]$AllowClobber = $false
)
# load the required .NET types
Add-Type -AssemblyName 'Microsoft.Office.Interop.Outlook'
# access Outlook object model
$outlook = New-Object -ComObject outlook.application
# connect to the appropriate location
$namespace = $outlook.GetNameSpace('MAPI')
#create a recipient object representing the owner of the shared calendar you want to export
$calendarowner = $owner # can be the full smtp address (what i prefer), display name, or alias.
$recipient = $namespace.CreateRecipient($calendarowner)
$null = $recipient.Resolve()
#specify the type of folder object we are wanting to work with
$olFolderCalendar = [Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderCalendar
#get the specified user/specified default folder
$CalendarFolder = $namespace.GetSharedDefaultFolder($recipient, $olFolderCalendar)
#Set up the exporter
$calendarsharing = $CalendarFolder.GetCalendarExporter()
#assign any switches first, because detail may override these settings
if($RestrictToWorkingHours){$CalendarSharing.RestrictToWorkingHours = $true}
if($IncludeAttachments){$CalendarSharing.IncludeAttachments = $true}
if($IncludePrivateDetails){$CalendarSharing.IncludePrivateDetails = $true}
switch($Detail){
"FreeBusyOnly" {
$CalendarSharing.CalendarDetail = 0
$CalendarSharing.IncludeAttachments = $false
$CalendarSharing.IncludePrivateDetails = $false
}
"FreeBusyAndSubject" {
$CalendarSharing.CalendarDetail = 1
$CalendarSharing.IncludeAttachments = $false
$CalendarSharing.RestrictToWorkingHours = $false
}
"FullDetails" {
$CalendarSharing.CalendarDetail = 2
$CalendarSharing.RestrictToWorkingHours = $false
}
}
if($startdate){
$CalendarSharing.startDate = $startdate
if($enddate){
$CalendarSharing.endDate = $enddate
}else{
$CalendarSharing.endDate = (get-date)
}
} else {
$CalendarSharing.startDate = [datetime]"01/01/1970"
$CalendarSharing.endDate = (get-date)
}
#export the calendar
if($pathtest = [bool](Test-Path $Path) -and ($AllowClobber -eq $false)){write-error "File $path already exists and AllowClobber not specified";break}
if($pathtest){Remove-Item $path -Force}
$MailItem = $CalendarSharing.SaveAsICal($Path)
}
Cannot convert argument “0”, with value: “System.__ComObject”, for “GetSharedDefaultFolder” to type “Microsoft.Office.Interop.Outlook.Recipient”: “Cannot convert the “System.__ComObject” value of type “Syst em.__ComObject#{00063045-0000-0000-c000-000000000046}” to type “Microsoft.Office.Interop.Outlook.Recipient”.” At C:\TEMP\test.ps1:13 char:52 + $CalendarFolder = $namespace.GetSharedDefaultFolder <<<< ($recipient, $olFolderCalendar) + CategoryInfo : NotSpecified: ( , MethodException + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
I assume by mailbox owner you mean the owner’s email. I’m not sure why it’s saying it can’t convert the com object to recipient. What version of exchange and what version of outlook are you using?