How to Use Set-Place to Configure Your Meeting Rooms


Or Making Your Office 365 Meeting Rooms Accessible or How Wheelchair Users Can Find The Best Meeting Rooms In Your Organization etc. – there are many different titles I can think of for this blog post. They are all to do with setting useful properties against your meeting rooms so that your users can find the best rooms.

As of the time of writing (updated July 2020), “Outlook Places” service exposes a client-side UX only in Outlook on the web (OWA) with Outlook for Windows and Mac due by end of August 2020. Given Microsoft’s previous behaviour of flighting Exchange Online features for one client initially before rolling them out to other clients, this is likely to hit Outlook mobile etc. at some point after that. Therefore I recommend that you update all your room properties now using the PowerShell cmdlet Set-Place so that your users are able to find meeting rooms and other resources upon the functionality appearing in their client.

The Exchange Online Management Shell cmdlet Set-Place allows you to configure properties such as if the room is accessible for wheelchair users (hence the title of this blog post), or what AV equipment it holds or indeed how many people the room can hold (comfortably!). As this information, especially in a large organization, is probably known by many different people and requires the input of these different users to maintain a master list, this blog post will look at the process of creating this list and then importing it back into Exchange Online when updated.

Creating A Master Room Metadata List

From Exchange Online Management Shell run the following:

Get-Mailbox -RecipientTypeDetails RoomMailbox -ResultSize Unlimited | Get-Place | Export-CSV OrganizationRooms.csv -NoClobber -NoTypeInformation

Open the file, here called OrganizationRooms.csv in Excel. I removed the first three columns (PSComputerName,RunspaceId,PSShowComputerName) as well as Type, ResourceDelegates, IsManaged, BookingType and Localities and the last four columns (SpaceType, CustomSpaceType, IsValid and ObjectState) from this file and then save it as an Excel file to OneDrive for Business or SharePoint Online and shared it with the relevant facilities management and other interested parties (don’t share it as a CSV file, as multiple users cannot edit a csv file in real time). We wait for this information to be updated. If you wish you could lock out cells from being edited such as Identity and maybe DisplayName so that future updating of existing rooms is easy to do.

Specifically we are looking at information such as location (physical street/city address, building name [for campus type organizations], floor label and GeoCoordinates), AV equipment (such as audio, video, display devices and room phone number), accessibility for wheelchair users, and miscellaneous tags (in the form of a comma separated list such as “Conference Room”,Lecture,“Tiered Seating”) that users could use in their room search. There are tools to generate geo-coordinates from addresses that you can find online (including Google Maps) and they are required as latitude;longitude;altitude (where altitude is optional) – for example “-50.9876;10.1234;100” (and if you have a non-English server you need to ensure the format is correct, for example it might need a comma and not a decimal place, such as “-50,9876;10,1234;100” if you had a French language server – which means this value needs quoting as it has commas inside the value).

Updating Room Metadata in Exchange Online

To upload the new data, save the shared Excel spreadsheet as a CSV file again and run the following Exchange Online Management Shell script. Note that the following script works where the object is created in Exchange Online/M365 and not synced from Active Directory (hybrid). For hybrid see the code further down the page:

# Update conference rooms based on info in OrganizationRooms.csv

Connect-ExchangeOnline -UserPrincipalName exoadmin@tenant.onmicrosoft.com

$rooms = Import-Csv -Path OrganizationRooms.csv

foreach ($room in $rooms) {

	$currentRoom = $room.identity

	Write-Host "Updating"$room.DisplayName

	if ($room.street -eq $null) { $room.street = "" }
	if ($room.city -eq $null  ) { $room.city = "" }
	if ($room.state -eq $null ) { $room.state = "" }
	if ($room.postalcode -eq $null) { $room.postalcode = "" }
	if ($room.CountryOrRegion -eq $null) { $room.CountryOrRegion = "" }

	if ($room.GeoCoordinates -like "*;*") { $room.GeoCoordinates = "" }  # Looks to see if value is formatted properly, latitude;longitude or latitude;longitude;altitude

	if ($room.phone -eq $null) { $room.phone = "" }

	if ($room.capacity -eq [int]$room.capacity) { $room.capacity = [int]$room.capacity }	# needs to be a number, does not work with null like most of the other values here

	if ($room.building -eq $null) { $room.building = "" }

	if ($room.Label -eq $null) { $room.label = "" }

	if ($room.AudioDeviceName -eq $null) { $room.AudioDeviceName = "" }
	if ($room.VideoDeviceName  -eq $null) { $room.VideoDeviceName  = "" }
	if ($room.DisplayDeviceName -eq $null) { $room.DisplayDeviceName = "" }

	if ($room.IsWheelChairAccessible -eq $null) { $room.IsWheelChairAccessible = $false }

	if ($room.Floor -eq $false) { $room.Floor = "" }	# looks to see if contains no number, not null like most of the other values here
	if ($room.FloorLabel -eq $null) { $room.FloorLabel = "" }
	if ($room.FloorLabel -eq "" -and $room.Floor -ne "") {$room.FloorLabel = $room.Floor} # Copy the Floor number to FloorLabel if this value is blank 
	if ($room.tags -eq $null) { $room.tags = "" }

	$addressParams = @{
		Street = $room.street
		City = $room.city
		State = $room.state
		PostalCode = $room.postalcode
		CountryOrRegion = $room.CountryOrRegion
	}

	$geoParams = @{
		GeoCoordinates = $room.GeoCoordinates
	}

	$capacityParams = @{
		Capacity = $room.capacity
	}

	$contactParams = @{
		Phone = $room.Phone
		Building = $room.building
		Label = $room.label
	}

	$deviceParams = @{
		AudioDeviceName = $room.AudioDeviceName 
		VideoDeviceName = $room.VideoDeviceName 
		DisplayDeviceName = $room.DisplayDeviceName 
	}

	$accessibilityParams = @{
		IsWheelChairAccessible = [bool]$room.IsWheelChairAccessible 
	}

	$floorParams = @{
		Floor = $room.Floor 
		FloorLabel = $room.FloorLabel 
		Tags = $room.Tags 
	}

	Set-Place $currentRoom @addressParams

	if ($room.GeoCoordinates -like "*;*") { 
		Write-Host "   Geo..."
		Set-Place $currentRoom @geoParams 	# Only set Geo if there is a valid value to set. Errors if try to set anything else
	}

	if ($room.capacity -is [int]) { 
		Write-Host "   Capacity..."
		Set-Place $currentRoom @capacityParams # only set capacity if the value is a number or it errors
	}

	Write-Host "   Contact..."
	Set-Place $currentRoom @contactParams

	Write-Host "   Device..."
	Set-Place $currentRoom @deviceParams

	Write-Host "   Accessibility..."
	Set-Place $currentRoom @accessibilityParams

	Write-Host "   Floor..."
	Set-Place $currentRoom @floorParams

	# Add room to City/Building distribution group (RoomList objects). Need these made beforehand (New-DistributionList "buildingname" -alias "cityname-buildingname" -RoomList)
	Add-DistributionGroupMember $room.building -Member $room.identity -ErrorAction SilentlyContinue
}

In the above code I have not included attributes from Get-Place that I cannot write back such as IsManaged, BookingType and Localities – I am interested though in knowing what they are used for as they are undocumented, though Localities is the RoomList that the room belongs to?

There are a few other properties that are useful to set related to this information in the CSV file – for example, as you know the City you could provide the TimeZone as an additional column and set the room mailbox to the correct TimeZone otherwise it defaults to “Pacific Standard Time”. See this post on how to get a list of all the timezone values. This code can be used to import a value per room from the CSV file or update all the rooms to a single value such as “GMT Standard Time” as shown.

Working Times (start and end) can be set here as well. This is important if you have the ScheduleOnlyDuringWorkHours Calendar Processing property set.

$rooms = Import-Csv -Path OrganizationRooms.csv

foreach ($room in $rooms) {

	if ($room.timezone -eq $null) { $room.timezone = "GMT Standard Time" }
	Set-MailboxRegionalConfiguration $room.identity -TimeZone $room.timezone
	Set-MailboxCalendarConfiguration $room.identity -WorkingHoursTimeZone $room.timezone -WorkingHoursStartTime 8:00 -WorkingHoursEndTime 18:00
}

If you get back the error “Encountered an internal server error.” then this is because you are trying to update an AADConnect synced object when your directories are in hybrid mode. The correct script to run is further down this page.

The above code just replaces the current values in Exchange Online with the values in the spreadsheet, so the spreadsheet becomes your master.

Note that values with spaces need to be quoted in the CSV – such as tags and various display names. Also it is worth being aware that with conference bridges and Teams meetings, room “capacity” is not always as important as it might sound – a room with a capacity of 3 people will work fine if everyone is remote! Booking multiple rooms for a single meeting is also planned.

Hybrid

If the room object is synced from on-premises Active Directory then you can still use Set-Place to update the object in the cloud, you just cannot set the City, CountryOrRegion, GeoCoordinates, Phone, PostalCode, State, and Street attributes. The way to set these properties is Set-User and that needed to be run against the source of the object (that is on your management Exchange Server on-premises against Active Directory).

The cmdlet to run instead of the above in Exchange Online uses Set-Place as shown:

$OrganizationRooms = Import-Csv .\OrganizationRooms.csv
ForEach ($Room in $OrganizationRooms) {
    [Boolean]$IsWheelChairAccessible = [System.Convert]::ToBoolean($Room.IsWheelChairAccessible)
     Set-Place $Room.DisplayName -Capacity $Room.Capacity -Building $Room.Building -Label $Room.Label -AudioDeviceName $Room.AudioDeviceName -VideoDeviceName $Room.VideoDeviceName -DisplayDeviceName $Room.DisplayDeviceName -IsWheelChairAccessible $IsWheelChairAccessible -FloorLabel $Room.FloorLabel -Tags $Room.Tags
}

And the code to run on-premises uses Set-User as shown:

$OrganizationRooms = Import-Csv .\OrganizationRooms.csv
ForEach ($Room in $OrganizationRooms) {
     Set-User $Room.Identity -Street $Room.Street -City $Room.City -State $Room.State -PostalCode $Room.PostalCode -CountryOrRegion $Room.CountryOrRegion -GeoCoordinates $Room.GeoCoordinates -Phone $Room.Phone 
}

Set-Place can be viewed at https://docs.microsoft.com/en-us/powershell/module/exchange/mailboxes/set-place?view=exchange-ps

Exchange Server

All rooms and resources that you manage via the steps in the blog post need to be Exchange Online resources. If the mailbox is still on Exchange Server and not moved to Exchange Online in a hybrid scenario, you are not able query and set the information in Get-Place or Set-Place

But that does not mean you cannot get ready for the day that you move those resources (rooms) to Exchange Online. On Exchange Server you can run the following Exchange Management Shell PowerShell and get a csv file with exactly the same columns as above. Get the spreadsheet filled in as mentioned above and then when you move the room to Exchange Online and update Set-Place and Set-User, the room will be found and updated.

Set-ADServerSettings -ViewEntireForest $true
Get-Mailbox -RecipientTypeDetails RoomMailbox -ResultSize Unlimited | Select Identity,DisplayName,Street,City,State,PostalCode,CountryOrRegion,GeoCoordinates,IsManaged,BookingType,ResourceDelegates,Phone,Capacity,Building,Label,AudioDeviceName,VideoDeviceName,DisplayDeviceName,IsWheelChairAccessible,Floor,FloorLabel,Tags,Localities,SpaceType,CustomSpaceType,IsValid,ObjectState | Export-CSV OrganizationRooms-OnPremises.csv -NoClobber -NoTypeInformation

User Room Search Experience

At the time of writing (July 2020) this experience is rolling out to Outlook, having been in OWA for about a year. The new experience will use the “Outlook Places” backend service, which Set-Place we used above populates.

To view and search for rooms based on these settings you need (for now) to wait 24-48 hours from using Set-Place before the property can be searched. You then create a new event in OWA calendar and click “Search for a room or location” and then click “+ Browse more rooms”.

The suggested rooms listed are those you have used or attended meetings at recently, but if you click in the “Search for a city or room list” box you can either enter a city or room list name (I suggest naming your room lists after buildings) and click “Show all rooms” or click the City or Room List name:

Browse rooms dialog
Browse Rooms by City

This allows the “Filters” option to become available, where you can filter for capacity (rooms larger than) or properties such as audio/video or accessible rooms.

Browse rooms with filter dialog

Once you have set the features you need, click Apply and select the room you need for the meeting. Being able to book multiple rooms for a single meeting is coming to Office 365 in the next few weeks from writing this article as well – imagine booking a meeting where people attend remotely but the remote location is another office.

Note that as of September 2022, the Outlook/OWA search for “Floor” will instead query the FloorLabel property and not the Floor property. Floor is a number, but FloorLabel a string, so searching for “Ground” or “Penthouse” or 2 or 6 etc. will now be possible when it used to only work for numeric floor numbers.

Call To Action

Even though this “places” functionality does not reach all the Office email/calendaring clients (yet), this should not be a reason not to do this categorization work. Its quite easy to generate a list of all the rooms and their current settings (see above) as a spreadsheet. Its more work to update that list, but if you have a list then you can start. Rooms don’t often change their status regarding accessibility etc. but if you start cataloguing your rooms now or add this work to an Exchange Server migration project, then your users will benefit as the functionality reaches the client they use.

If you don’t update your places metadata, then clients will be unable to successfully find meeting rooms.

, , , , ,

17 responses to “How to Use Set-Place to Configure Your Meeting Rooms”

    • The Exchange Admin Console (EAC) does not update the Places Service metadata – you need to use Set-Place. The EAC updates the “user” object. That is, ‘Get-User “room” | FL City’ should return the city you set in EAC.

      • When Address, City, State, Zip, etc is set by set-user, it will appear in the place commands within about 24 hours. If you have an on-prem mailbox, that is the only way to set those.
        “Note : In hybrid environments, this cmdlet doesn’t work on the following properties on synchronized room mailboxes: City, CountryOrRegion, GeoCoordinates, Phone, PostalCode, State, and Street.” https://docs.microsoft.com/en-us/powershell/module/exchange/set-place?view=exchange-ps

        • In a hybrid environment, any cmdlet that sets properties that are mastered on-premises needs to be run on-premises. This does not change this. Set-Place updates cloud only attributes, so is run in the cloud even for on-premises synced objects. Set-User updates Azure AD, and so needs to be run where the object is mastered.

  1. I tried using the FloorLabel property for Set-Place and I don’t see how it’s useful when trying to search for the room. I’m trying to use this for rooms that are in Mezzanine floors in some locations. Since you can’t use a decimal number for the Floor attribute, the next best thing is to just use a Mezzanine label for the floor. Any ideas?

    • Not every “Places” attribute is searchable in OWA/Outlook. Some of these will be for information only, so in this case Floor = 1 and Floor Label = “Ground” might help someone who is a visitor to the UK see that the room is on the ground floor even though we would say Floor 1 in this country!

    • Note that as of September 2022, the Outlook/OWA search for “Floor” will instead query the FloorLabel property and not the Floor property. Floor is a number, but FloorLabel a string, so searching for “Ground” or “Penthouse” or 2 or 6 etc. will now be possible when it used to only work for numeric floor numbers.

  2. Hello,
    Regarding -bookingtype parameter
    I am pretty confident, that this is taken over from the Set/Get-Calenderprocessing side of things.
    *Standard* means, there is Autobooking enabled aka you can invite the room by email and it will auto-book a meeting.
    *Reserved* means, there is no such auto-booking going on. The only way of booking such a (serviced) room is by someone with write permissions to directly enter an appointment into the room’s calendar.

  3. How is the Localities field populated. I have a room mailbox for which the Localities are showing abc@xyz.com however, for few it is just {}.

    I tried to set it up using the set-place but the switch -localities is not completing.

    • You don’t set localities using Set-Place. That is why I remove it from the spreadsheet I suggest you create in the blog post. The Localities field is a record of the email address(es) of the Room List that the room belongs to. So you create a new Room List (a distribution group) from PowerShell with New-DistributionGroup “Oxford” -RoomList and then add your rooms in Oxford city to this group. Get-Place will now show oxford@xyz.com as the Locality.

  4. In testing I’ve created a building that I now would like to be removed/deleted. I can’t seem to locate anything in either MS documentation or online. Would anyone happen to know how to do so?

    • Buildings are Distribution Lists created as Type=Room. So just delete the distribution list you created. It can only be seen via PowerShell and not in the admin centers, so you need to delete it there. The change will make it to the client within 48 hours. Its also possible you have set a room with a Place property for Building. Check all your Room objects, Get-Place for each of them (again, in PowerShell) and look for one where the Building is your test value. Changes again are 48 hours.

  5. Is the text you add to the AudioDeviceName, VideoDeviceName, and DisplayDeviceName attributes searchable in Room Finder? Where does this text appear in the user interface, if at all?

    • So the actual details are not searchable. If you set a value for them then you can search for ‘audio’ or ‘video’ etc for a room that has something audio or something video. The details are then available when hovering over the icons for the discovered rooms. For example, when I add audio or video to a room and no-one knows the details of what is present I use the value “Available”. This then shows the room as having these devices, but the details shows “Available” instead of “BENQ Digital Whiteboard” (for example) or “80” Plasma Screen” (another example, though probably less useful than just indicating the device is available!

      • Thanks for the confirmation. I don’t see the details when hovering over the icons for the rooms in the Room Finder window nor in the Outlook contact card when you hover over the room after it is added to the invite. I wonder if there is a configuration change required for this to work?

  6. Hi,

    I have an issue for some Room Mailboxes about availability which is not correct when using room finder

    When i check get-place, i can see there is no information about BookingType and IsManaged it’s blank but for some Room Mailboxes it’s Ok and it works for it, however when i check get-calendarprocessing, everything is correct about AutoAccept and No delegates

    All room mailboxes have same informations.

    Do you know how to fix this ? It appears at the beginning of the year and the only modification was about workinghours

    • Are you saying that after a “workinghours” change on the room, the rooms now have the wrong availability – that is where there are meetings the room says it is free and visa versa (for example)? The only thing I can think here that you would need to check is that you got the timezone correct. If the room has a different timezone that what you expect, its availability will be correct but it will be offset by the timezone difference

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.