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 Type, ResourceDelegates, IsManaged, BookingType and Localities columns and the last five columns (SpaceType, CustomSpaceType, Desks, 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

This blog post was originally written in July 2020, but the end-user experience has changed since then. As I updated this in Dec 2023 I see that the “Room Finder” option distinguishes between Buildings and Cities rather than asking the user to choose a “city or room list” and now asks the user to search by building and lists all the cities. The “buildings” are the room lists (special Distribution Groups that contain resource mailboxes) and the “city” is the City property from Get/Set-Place cmdlet.

To view and search for rooms based on these settings you need to wait 24-48 hours from using Set-Place before the property is visible in Outlook, OWA or Teams. You then create a new event in the calendar and click “Search for a room or location>Browse with Room Finder” (in OWA or new Outlook) or “Room Finder” in Outlook or “Add location” in Teams.

The suggested rooms listed are those you have used or attended meetings at recently, but if you click in the “Building” search box (OWA or Outlook) you can either enter a city or room list name (I suggest naming your room lists after buildings) and 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 also possible – 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. So ensure that FloorLabel is correctly updated on all your rooms.

Call To Action

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 appears in the client the users use.

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


Posted

in

, , , , ,

by

Tags:

Comments

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

  1. alain avatar
    alain

    When i change the city from the admin exchange, it is not written in the get-place object.
    How is it possible ?

    1. Brian Reid avatar

      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.

      1. Travis Brink avatar
        Travis Brink

        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

        1. Brian Reid avatar

          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.

  2. Kevin avatar
    Kevin

    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?

    1. Brian Reid avatar

      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!

    2. Brian Reid avatar

      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.

  3. Harald Steindl avatar

    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.

  4. MurLee Nair avatar
    MurLee Nair

    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.

    1. Brian Reid avatar

      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.

  5. Franco avatar
    Franco

    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?

    1. Brian Reid avatar

      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.

  6. Mike avatar
    Mike

    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?

    1. Brian Reid avatar

      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!

      1. Mike avatar
        Mike

        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?

  7. Peter avatar
    Peter

    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

    1. Brian Reid avatar

      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

  8. Todd avatar
    Todd

    I would think this would be simpler to enable “Room Finder” within a hybrid environment. I am trying to follow along with this from Microsoft.
    “Create a room list on an on-premises server, and sync it to the cloud. 
    Create an on-premises room mailbox, and sync it to the cloud. 
    Create a remote synced room mailbox in Exchange Online by running the New-RemoteMailbox cmdlet together with the -Room switch in Exchange Management Shell.
    Add both the on-premises room mailbox and the remote synced room mailbox to the on-premises room list by running the Add-DistributionGroupMember cmdlet in Exchange Management Shell.
    Configure the properties on both room mailboxes by using the Set-User cmdlet in Exchange Management Shell.”
    The rooms have been created for a while. But creating a “Room List”, I would assume a distribution group but then again, maybe not. I tried creating the group in EXO but that did not propagate. So, the first line is to create the “Room List” on-prem, how is that to be interpreted?

    Thanks,
    Todd

    1. Brian Reid avatar

      I’m not sure I follow what you are describing – where did you get this list of instructions from? (you say “from Microsoft” – do you have a URL?)

      That said, you ask at the end “the first line is to create the “Room List” on-prem, how is that to be interpreted” – this would be a RoomList type Distribution List. So “New-DistributionList name -RoomList”. This command works on-premises or in Exchange Online. It only works in PowerShell, there is no GUI option to create or view these objects. The onprem list then needs to be in an OU that syncs to the cloud.

      Also as mentioned in the article though, if you have moved all your users mailboxes to Exchange Online, dont bother creating rooms and roomlists in AD and syncing them – there are more options available to you with a room that exists only as a cloud object.

  9. Alex avatar
    Alex

    Very helpful article thanks, but still not seeing Room Finder work. It’s almost like it’s not enabled being every single field is greyed out and you cannot even see buildings/locations in Room Finder in OWA.

    Created room list in exchange online shell, added my rooms to it, some of them are coming in with really weird identities though like “df068ccf-b79e-4803-a346-17ccaaa50535″… whereas others come in as “UpstairsConferenceRoom” and such…

    I also notice that the rooms can be seen in the Location field in microsoft teams, but not in the OWA whatsoever. It’s very all over the place. My test rooms appear under Resources in EXO, and editing their attributes on-prem then running a delta sync successfully updates in EXO, they’re in a room list and we can confirm this with the shell but we never actually see the room list populate into EXO as a distribution group. Am I just not waiting long enough?

    1. Brian Reid avatar

      “Weird idenities” – that is only becuase these objects where made after Jan 2022. The “name” property of all new objects since Jan 2022 is the GUID of the object and cmdlets show the “name” by default, so you need to do things like “Get-DistributionGroupMember ‘roomlist’ | FL DisplayName” and show the display name and not the name.

      I would recommend that you move your rooms to be cloud only objects and not sync from Active Directory. There are lots of properties that you cannot set for synced room objects that you can for cloud only rooms (i.e. geocoordinates so maps get shown in the mobile client)

      Finally, the room list NEVER appears as a distribution list. It should appear in the Room Finder as a search location after 24/48 hours – see the first two pictures in the above blog. I suggest naming your room lists after buildings/floors/wings etc and not cities, as the “City” property provides the city search and the “room finder” asks users to search by building (aka “room list”). In the hierarchy for the Room Finder, “room lists” appear inside Cities and “room lists” are best done as buildings, or wings, or floors (i.e. all the meeting rooms on floor 1 in a single building could be in one room list).

      Do wait 48 hours for the Places information to update.

  10. Fran1985 avatar
    Fran1985

    Here is your corrected text in English:

    Hello,
    Thank you for all your advice.
    I have a significant problem: I conducted numerous tests with places and rooms. I have a script that does everything I want, and I can find everything in its place in the “room search”.
    My issue is that I want to delete all the rooms (and places) I created for testing. I have deleted all rooms and all distribution lists, but when I execute the “get-place” command, I can still see all the places. They also still appear in the room finder… I deleted everything more than a week ago, and it’s still there. How can I remove these “places”? Thank you very much.

    1. Brian Reid avatar

      To clarify, you deleted the User object (the room mailbox) but a week later can see the same object in Get-Places? Is the mailbox still under retention, or the user object still in Entra ID deleted users? I would make sure that the object is fully deleted (from Entra and no retention on the mailbox) and then see if the Places data disappears.

Leave a Reply to Brian Reid Cancel reply

Your email address will not be published. Required fields are marked *

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