{"id":51773,"date":"2009-12-17T00:01:00","date_gmt":"2009-12-17T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/12\/17\/hey-scripting-guy-can-i-share-my-microsoft-outlook-calendar-via-e-mail\/"},"modified":"2009-12-17T00:01:00","modified_gmt":"2009-12-17T00:01:00","slug":"hey-scripting-guy-can-i-share-my-microsoft-outlook-calendar-via-e-mail","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-can-i-share-my-microsoft-outlook-calendar-via-e-mail\/","title":{"rendered":"Hey, Scripting Guy! Can I Share My Microsoft Outlook Calendar via E-Mail?"},"content":{"rendered":"<p class=\"MsoNormal\"><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><font size=\"2\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/font><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! I really like the ability to export my calendar into a shareable format with Microsoft Outlook. It is really cool, but can I accomplish this by using a Windows PowerShell script?<\/p>\n<p class=\"MsoNormal\">&#8212; MB<\/p>\n<p class=\"MsoNormal\"><br>&nbsp;<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello MB, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. In 30 minutes, I have a Live Meeting with Karen, our TechNet Site manager, and Craig, the Scripting Editor. Because I do not want to get too involved in something and miss this very important meeting, I thought I would answer some of the e-mail that was sent to <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><span><font face=\"Segoe\">scripter@microsoft.com<\/font><\/span><\/a>. Often, the e-mail is easy to answer, and those tend to be incorporated into a Quick-Hits Friday post. At other times, the answers are more involved, and I flag those until I have a bit more time to work on the solution. <\/p>\n<p class=\"MsoNormal\">MB, your e-mail was one that I have had flagged for quite some time. I am glad it was a rainy day in Charlotte, and I had the morning to work on your script. When the script worked perfectly the first time (which is often unusual), I was stoked! The Scripting Wife who was downstairs messing around on Facebook sent me an instant message that asked, &ldquo;Are you ok?&rdquo; Let us spare the superlatives and get down to the code. This script is cool. The complete EmailCalendar.ps1 script is seen here.<\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>EmailCalendar.ps1<\/strong><\/p>\n<p class=\"CodeBlockScreened\"><span><font><font face=\"Lucida Sans Typewriter\">#Requires -version 2.0<br>Add-Type -AssemblyName microsoft.office.interop.outlook <br>$olFolders = &#8220;Microsoft.Office.Interop.Outlook.OlDefaultFolders&#8221; -as [type]<br>$olCalendarDetail = &#8220;Microsoft.Office.Interop.Outlook.olCalendarDetail&#8221; -as [type]<br>$olCalendarMailFormat = &#8220;Microsoft.Office.Interop.Outlook.olCalendarMailFormat&#8221; -as [type]<br>$outlook = New-Object -ComObject outlook.application<br>$namespace<span>&nbsp; <\/span>= $Outlook.GetNameSpace(&#8220;mapi&#8221;)<br>$folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar)<br>$CalendarSharing=$folder.GetCalendarExporter()<br>$CalendarSharing.CalendarDetail = $olCalendarDetail::olFreeBusyOnly<br>$CalendarSharing.startDate = Get-Date<br>$CalendarSharing.endDate = (Get-Date).addDays(7)<br>$CalendarSharing.RestrictToWorkingHours = $true<br>$CalendarSharing.IncludeAttachments = $false<br>$CalendarSharing.IncludePrivateDetails = $false<br>$MailItem = $CalendarSharing.ForwardAsICal($olCalendarMailFormat::olCalendarMailFormatDailySchedule)<br>$MailItem.Recipients.Add(&#8220;Scripter@Microsoft.Com&#8221;)<br>$MailItem.Send()<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The first thing that is done in the EmailCalendar.ps1 script is to load the <b>Microsoft.Office.Interop.Outlook<\/b> interop assembly. To do this, use the <b>Add-Type <\/b>cmdlet. This was covered in detail in <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/12\/14\/hey-scripting-guy-december-14-2009.aspx\"><span>Monday&rsquo;s Hey, Scripting Guy! post<\/span><\/a>. <\/p>\n<p class=\"MsoNormal\">After the Outlook interop assembly is loaded, add a couple of enumerations. The three Outlook enumerations that are created are the <a href=\"http:\/\/bit.ly\/7m8zMA\"><font face=\"Segoe\">OlDefaultFolders<\/font><\/a>, <a href=\"http:\/\/bit.ly\/5xIAgl\"><font face=\"Segoe\">OlCalendarDetail<\/font><\/a>, and <a href=\"http:\/\/bit.ly\/605wUm\"><font face=\"Segoe\">OlCalendarMailFormat<\/font><\/a>. All three enumerations are documented on MSDN, and you can refer to those pages to see additional options for modifying the behavior of the script. For example, you might want to change the level of calendar detail by using a different enumeration value for <b>OlCalendarDetail<\/b>. Adding the Outlook interop assembly and the three type enumerations is seen here. <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">#Requires &ndash;Version 2.0<br>Add-Type -AssemblyName microsoft.office.interop.outlook <br>$olFolders = &#8220;Microsoft.Office.Interop.Outlook.OlDefaultFolders&#8221; -as [type]<br>$olCalendarDetail = &#8220;Microsoft.Office.Interop.Outlook.olCalendarDetail&#8221; -as [type]<br>$olCalendarMailFormat = &#8220;Microsoft.Office.Interop.Outlook.olCalendarMailFormat&#8221; -as [type]<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Next, you need to create an instance of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219938.aspx\">Outlook.Application COM object<\/a>. The <b>Outlook.Application<\/b> object is the main object that is used when scripting Microsoft Outlook. It provides a number of methods and properties that can be used in creating some powerful scripts. The <b>Application<\/b> object represents the entire Outlook application. After it is created, the <b>Application <\/b>object is stored in the <b>$outlook<\/b> variable: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$outlook = New-Object -ComObject outlook.application<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Now that you have an instance of the Outlook Application object, you can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219904.aspx\">GetNamespace method<\/a> to return a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219955.aspx\">NameSpace objec<\/a>t. The only type of namespace that is permitted to be returned by the <b>GetNameSpace<\/b> method is &ldquo;mapi.&rdquo; The returned namespace object is stored in the <b>$namespace<\/b> variable, as seen here. <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$namespace<span>&nbsp; <\/span>= $Outlook.GetNameSpace(&#8220;mapi&#8221;)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The Namespace object contains the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219900.aspx\">GetDefaultFolder method<\/a> that accepts an OlDefaultFolders enumeration as its input value. The returned <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb176362.aspx\">folder object<\/a> is stored in the $folder variable.<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">When you have a folder object, you can call the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb147820.aspx\"><font face=\"Segoe\">GetCalendarExporter method<\/font><\/a>, which does not accept any arguments. The returned <b>CalendarSharing<\/b> object is stored in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb147820.aspx\"><font face=\"Segoe\">$CalendarSharing variable<\/font><\/a>:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$CalendarSharing=$folder.GetCalendarExporter()<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The <b>CalendarSharing<\/b> object has a number of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb208286.aspx\"><font face=\"Segoe\">properties<\/font><\/a> that can be configured to control the way the Microsoft Outlook calendar is shared. Most of the properties are configured in the EmailCalendar.ps1 script. You may want to review the properties on MSDN if the script does not behave exactly as you would like it to behave. <\/p>\n<p class=\"MsoNormal\">The first property to configure is the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb206841.aspx\"><font face=\"Segoe\">CalendarDetail property<\/font><\/a>. The <b>CalendarDetail<\/b> accepts an instance of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb208061.aspx\"><font face=\"Segoe\">OlCalendarDetail enumeration<\/font><\/a>. There are three options: Free and busy with the subject, free and busy only, or full details. The actual enumeration values are documented on MSDN. For the EmailCalendar.ps1 script, I decided to only share free and busy time and to not share the details or subjects of the meetings. This is seen here: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$CalendarSharing.CalendarDetail = $olCalendarDetail::olFreeBusyOnly<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The next two properties to set on the <b>CalendarSharing<\/b> object are the <b>startDate<\/b> property and the <b>endDate<\/b> property. These two properties are expressed as <b>datetime<\/b> objects and are easily created using the <b>Get-Date<\/b> cmdlet. If you want to share a portion of the calendar from the past, use <b>addDays<\/b> with a negative value, as shown here: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:Usersed.NWTRADERS&gt; (get-date).adddays(-7)<\/p>\n<p>Wednesday, November 25, 2009 3:31:46 PM<\/p>\n<p>PS C:Usersed.NWTRADERS&gt; (get-date).adddays(+7)<\/p>\n<p>Wednesday, December 09, 2009 3:31:54 PM<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">For the EmailCalendar.ps1 script I decided to share the calendar appointments from the current date to seven days in the future. This is seen here. <\/p>\n<p class=\"CodeBlock\"><span><br><font face=\"Lucida Sans Typewriter\">$CalendarSharing.startDate = Get-Date<br>$CalendarSharing.endDate = (Get-Date).addDays(7)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The next three properties to configure are self explanatory. Do you want to restrict the calendar to working hours? Do you wish to include attachments? Do you want your calendar to include private details? Each of these properties accepts a Boolean <b>$true<\/b> or <b>$false<\/b>, as shown here.<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$CalendarSharing.RestrictToWorkingHours = $true<\/p>\n<p>$CalendarSharing.IncludeAttachments = $false<\/p>\n<p>$CalendarSharing.IncludePrivateDetails = $false<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Now you are ready to configure the e-mail message that will send the calendar to your designated recipient. To do this, use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb175037.aspx\"><font face=\"Segoe\">ForwardAsICal method<\/font><\/a> from the <b>CalendarSharing<\/b> object. If you did not want to send the calendar in an e-mail, you could also save the calendar as an <b>iCalendar <\/b>(.ics) file by using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb175038.aspx\"><font face=\"Segoe\">SaveAsICal method<\/font><\/a>. The <b>ForwardAsIcal<\/b> method requires an instance of an <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb208062.aspx\"><font face=\"Segoe\">OlCalendarMailFormat enumeration<\/font><\/a> value that will determine if the calendar will be configured as a daily schedule or an event schedule. For the EmailCalendar.ps1 script, I decided to create a daily schedule. Feel free to play with the format to see which meets your needs the best. To create an event schedule format, you would use this enumeration value:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$olCalendarMailFormat::olCalendarMailFormatEventList<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb219953.aspx\">MailItem object<\/a> that is created by using the <b>ForwardAsICal<\/b> method is stored in the <b>$MailItem<\/b> variable as shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$MailItem = $CalendarSharing.ForwardAsICal($olCalendarMailFormat::olCalendarMailFormatDailySchedule)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">There is only one thing that must be configured for the <b>MailItem<\/b> object: the recipient&rsquo;s e-mail address. After you have used the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb175488.aspx\"><font face=\"Segoe\">Add method<\/font><\/a>&mdash;from the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb147616.aspx\"><font face=\"Segoe\">Recipients collection<\/font><\/a> that is returned by the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb175516.aspx\">Recipients property<\/a> of the <b>MailItem<\/b> object&mdash;to add the recipient to the <b>MailItem<\/b>, call the <b>Send<\/b> method and your calendar will speed on its way to its destination. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$MailItem.Recipients.Add(&#8220;Scripter@Microsoft.Com&#8221;)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$MailItem.Send()<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Your recipient will receive a really cool e-mail message, as seen here:<\/p>\n<p class=\"Fig-Graphic\"><span><img decoding=\"async\" title=\"Image of e-mail message received by recipient\" alt=\"Image of e-mail message received by recipient\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1217\/hsg-12-17-09-01.jpg\" width=\"600\" height=\"399\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1217\/hsg-12-17-09-01.jpg\"><font face=\"Segoe\"><\/font><\/a><\/span><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">When your recipient opens the e-mail message, they will be able to see the details you selected when you exported the calendar. The details from our script are seen here:<\/p>\n<p class=\"Fig-Graphic\"><span><img decoding=\"async\" title=\"Image of details of exported calendar\" alt=\"Image of details of exported calendar\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1217\/hsg-12-17-09-02.jpg\" width=\"600\" height=\"385\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1217\/hsg-12-17-09-02.jpg\"><font face=\"Segoe\"><\/font><\/a><\/span><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">MB, that is all there is to sharing your Outlook Calendar via Windows PowerShell. This also concludes Microsoft Outlook Week on the TechNet Script Center. Join us tomorrow for Quick-Hits Friday. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/span><\/b><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Hey, Scripting Guy! I really like the ability to export my calendar into a shareable format with Microsoft Outlook. It is really cool, but can I accomplish this by using a Windows PowerShell script? &#8212; MB &nbsp; Hello MB, Microsoft Scripting Guy Ed Wilson here. In 30 minutes, I have a Live Meeting with [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[212,49,3,45],"class_list":["post-51773","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-outlook","tag-office","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Hey, Scripting Guy! I really like the ability to export my calendar into a shareable format with Microsoft Outlook. It is really cool, but can I accomplish this by using a Windows PowerShell script? &#8212; MB &nbsp; Hello MB, Microsoft Scripting Guy Ed Wilson here. In 30 minutes, I have a Live Meeting with [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51773","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51773"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51773\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=51773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}