{"id":12291,"date":"2022-11-22T08:00:21","date_gmt":"2022-11-22T16:00:21","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/?p=12291"},"modified":"2022-11-30T14:54:48","modified_gmt":"2022-11-30T22:54:48","slug":"using-scripts-for-microsoft-bookings-calendar-and-mailbox","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/using-scripts-for-microsoft-bookings-calendar-and-mailbox\/","title":{"rendered":"Using scripts for Microsoft Bookings calendar and mailbox"},"content":{"rendered":"<p>Microsoft Bookings let&#8217;s enterprise organizations and small business owners manage customer bookings and information with minimal setup. Today, we\u2019re going to take a deeper look at using scripts to get information about your organization\u2019s Bookings calendars and mailboxes.<\/p>\n<p>When creating a <a href=\"https:\/\/learn.microsoft.com\/en-us\/microsoft-365\/bookings\/bookings-faq?view=o365-worldwide#where-do-bookings-calendars-show-up-in-my-microsoft-365-tenant-\">Bookings calendar<\/a>, a scheduling mailbox is also created. This mailbox stores details of the Bookings calendar such as Appointments, Services, Staff Members, and Business details. Tenant admins want to be aware of these mailboxes, the users and usage.<\/p>\n<h2>Common questions tenant\/IT admins may have<\/h2>\n<h3>What are the Bookings calendars in my organization?<\/h3>\n<p>Tenant\/IT admins want the list of all the Bookings calendars in their organization.<\/p>\n<h3>Who are the users of a Booking calendars?<\/h3>\n<p>Tenant admins are concerned about who is using the Bookings calendar within the organization, typically wanting to know which staff members have an &#8220;admin&#8221; role. These admins can modify settings of the calendar and can create and manage appointments for themselves and others.<\/p>\n<h3>Do we have proper admin coverage on the Bookings calendars?<\/h3>\n<p>If a Bookings calendar has no staff members with an \u201cadmin\u201d role, it is considered orphan. This can happen when the existing admins are removed from the calendar or they leave your organization. The content in the calendar is unaffected by this &#8211; the content isn\u2019t tied to any admin\u2019s account, but not having an admin means there&#8217;s nobody with permissions to manage the calendar.<\/p>\n<h3>Is the Booking calendar being used?<\/h3>\n<p>A Bookings calendar is considered \u201cunused\u201d if no appointments have been created on it in a defined period of time. For example, one of our customers shared that if there is no appointment created within one quarter (3 months), they consider the calendar inactive or unused.<\/p>\n<h3>Is the Booking calendar published?<\/h3>\n<p>Tenant admins may want to know if the Bookings calendar is published for customers to create appointments.<\/p>\n<h2>Sample Scripts<\/h2>\n<p>To address these questions, we have created a script which allows tenant admins to gather all this information from PowerShell. Some of these PowerShell commands are derived from existing Bookings Graph APIs and will need the permissions for those APIs.<\/p>\n<p>Please remember that these are guidelines. You should always refer to the latest updates for <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/whats-new-overview\">Microsoft Graph<\/a> and <a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/module\/microsoft.graph.bookings\/?view=graph-powershell-1.0\">Microsoft Graph PowerShell Cmdlets<\/a> to ensure the scripts are using the latest and updated syntax.<\/p>\n<h3>List of Bookings Calendars<\/h3>\n<p>Get the list of Booking calendars from this <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/api\/bookingbusiness-list?view=graph-rest-1.0\">Microsoft Graph API<\/a>. Alternatively, you can use the following commands to get the list of Bookings calendars in the organization:<\/p>\n<p>\u201cGet-Mailbox -RecipientTypeDetails SchedulingMailbox -ResultSize:Unlimited\u201d.<\/p>\n<h3>Initial Script<\/h3>\n<pre class=\"prettyprint\"> #connecting to MgGraph\r\nSelect-MgProfile beta\r\nConnect-MgGraph -Scopes \"User.Read.All\",\"Bookings.Manage.All,Calendars.Read.Shared\" | Out-null\r\n \r\n#Getting the booking business details\r\n$MBInfo = get-mgbookingbusiness -BookingBusinessId $BookingBusinessId\r\n \r\n#getting the appointment and staff related data\r\n$appointments = Get-MgBookingBusinessAppointment -BookingBusinessId $BookingBusinessId -Top 500\r\n$appointmentCount =  $appointments.count\r\n \r\n$StaffData = Get-MgBookingBusinessStaffMember -BookingBusinessId $BookingBusinessId -All\r\n$AdminData = $StaffData | Where-Object -FilterScript {$_.Role -EQ 'administrator'}\r\n$adminStaffCount = $AdminData.count<\/pre>\n<p>In the script above, we connect to Microsoft Graph Booking APIs through PowerShell. We get the appointment and staff data for the Booking Business (denoted in the variable \u201cBookingBusinessId\u201d). We use this as a base for the code snippets below:<\/p>\n<h3>Users, admins, and orphan calendars<\/h3>\n<pre class=\"prettyprint\"> $list = New-Object Collections.Generic.List[String]\r\n foreach($staff in $staffData){\r\n $list.add($staff.displayName + ':' + $staff.Role)\r\n }\r\n $staffMemberList = ($list | Out-string)<\/pre>\n<p>The above gets the list of all users or staff members in the calendar. Note that the staff members tagged with role \u2018administrator\u2019 are the admins of the Bookings calendar. Remember, a Bookings calendar is orphaned if there are no staff members with \u201cadmin\u201d role. The first clue to this is that the variable \u201cadminStaffCount\u201d will be 0. To confirm, we can check if the staff members with the administrator role exists in the organization.<\/p>\n<pre class=\"prettyprint\">$count = 0;\r\nforeach($admin in $AdminData){\r\n \r\n  try {\r\n    $user = Get-MgUser -UserId $admin.EmailAddress -ErrorAction Stop\r\n    if(-not $user.accountEnabled) {\r\n    $count++\r\n  \t}\r\n  }\r\n  catch {\r\n    if ($PSItem.Exception.Code -eq \"Request_ResourceNotFound\") {\r\n    $count++;\r\n  \t}\r\n  }\r\n}\r\n \r\n$orphan = ($adminStaffCount -eq $count)<\/pre>\n<p>The above code fragment checks if the staff member\u2019s email id is enabled and if it exists in organization. If none of the administrators exist (or are ), the calendar is orphan.<\/p>\n<h3>Appointment Counts and Unused Calendars<\/h3>\n<p>One of the ways you can determine if your calendar is unused is to check when the last appointment was created. You may also want to see the count of appointments in the last \u2018n\u2019 months.<\/p>\n<pre class=\"prettyprint\">$today = Get-Date\r\n \r\n$endDate = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId(($today), 'UTC')\r\n$startDate = $endDate.AddMonths(-6)\r\n \r\n$appointmentCountLast6Months = (Get-MgUserCalendarView -UserId $BookingBusinessId -StartDateTime $startDate -EndDateTime $endDate -All).count\r\n \r\n \r\n#---------------------------- Last Appointment Creation Date ----------------------------\r\n$lastCreatedEvent = Get-MgUserEvent -UserId $BookingBusinessId -Top 1\r\n$lastAppointmentCreationDate = $lastCreatedEvent.CreatedDateTime<\/pre>\n<h3>Other information in the Bookings Calendar<\/h3>\n<p>The list of Bookings Calendar attributes can be found <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/api\/resources\/bookingbusiness?view=graph-rest-1.0\">here<\/a>. An example to get some key attributes is given below:<\/p>\n<pre class=\"prettyprint\">$Details = [ordered]@{\r\n      'Display Name' = $MBInfo.DisplayName\r\n      'Id' = $MBInfo.Id\r\n      'Is Published?' = $MBInfo.IsPublished\r\n      'Phone' = $MBInfo.Phone\r\n      'Public Url' = $MBInfo.PublicUrl\r\n      'Website Url' = $MBInfo.WebSiteUrl\r\n \t }<\/pre>\n<h2>Get started with resources<\/h2>\n<p>Read the documentation:<\/p>\n<ul>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/api\/resources\/booking-api-overview?view=graph-rest-1.0\" target=\"_blank\" rel=\"noopener\">Microsoft Bookings documentation<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/microsoftgraph\/find-mg-graph-command?view=graph-powershell-1.0\" target=\"_blank\" rel=\"noopener\">Application permission-based APIs in PowerShell<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/permissions-reference\" target=\"_blank\" rel=\"noopener\">Permission reference<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powershell\/microsoftgraph\/find-mg-graph-command?view=graph-powershell-1.0\" target=\"_blank\" rel=\"noopener\">List permissions needed for specific API or cmdlet<\/a><\/li>\n<\/ul>\n<p>We hope this gives you some ideas on how to use Bookings calendars and mailboxes. Provide feedback and keep reaching out to us with your use cases and requests.<\/p>\n<p>Stay tuned for more updates:<\/p>\n<ul>\n<li>Visit our <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/\">Microsoft Graph Dev Center.<\/a><\/li>\n<li>Follow us on <a href=\"https:\/\/twitter.com\/Microsoft365Dev\">Twitter<\/a><\/li>\n<li>Subscribe to <a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\" target=\"_blank\" rel=\"noopener\">our blog<\/a><\/li>\n<\/ul>\n<p>Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Microsoft Bookings lets enterprise organizations and small business owners manage customer bookings and information with minimal setup. Learn how to use scripts to get information about your organization\u2019s Bookings calendars and mailboxes.<\/p>\n","protected":false},"author":106116,"featured_media":12353,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[160,218],"class_list":["post-12291","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-bookings-api","tag-microsoft-bookings"],"acf":[],"blog_post_summary":"<p>Microsoft Bookings lets enterprise organizations and small business owners manage customer bookings and information with minimal setup. Learn how to use scripts to get information about your organization\u2019s Bookings calendars and mailboxes.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/12291","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/106116"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=12291"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/12291\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/12353"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=12291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=12291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=12291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}