Outlook Room Finder : supprimer une ville fantôme dans Exchange Online avec PowerShell (Set‑Place, Get‑Place)

Un doublon de ville dans le sélecteur de salles d’Outlook ? Voici une méthode fiable pour faire disparaître une « ville fantôme » de Room Finder en normalisant l’attribut City des boîtes RoomMailbox via PowerShell Exchange Online.

Sommaire

Vue d’ensemble de la question

Dans Room Finder (Outlook / Exchange Online), deux entrées Roundlake apparaissent dans la liste des villes : l’une est vide (aucune salle), l’autre contient les salles réelles. Cette « ville fantôme » n’existe pas dans les Room Lists et reste introuvable avec les commandes PowerShell usuelles orientées groupes. L’objectif est de supprimer l’entrée vide sans toucher aux salles valides.

Pourquoi Room Finder affiche une ville vide

Le panneau Room Finder regroupe les salles par valeurs distinctes de l’attribut City rattaché à chaque RoomMailbox (via l’API Places, exposée par Get-Place/Set-Place). Il n’existe pas de commande pour « supprimer » une ville en tant qu’entité autonome : si la valeur City est incohérente sur au moins une salle (espaces en tête, casse différente, faute d’orthographe, caractère non imprimable), Room Finder créera une entrée distincte. La « ville fantôme » est donc presque toujours le symptôme d’un attribut mal saisi sur une ou plusieurs salles.

Étapes de résolution

ÉtapeActionCommande / Explication
1Lister toutes les boîtes RoomMailbox et leur attribut CityGet-ExoMailbox -RecipientTypeDetails RoomMailbox | Sort-Object DisplayName | Get-Place | Format-Table DisplayName, Building, Floor, City
2Identifier les valeurs anormalesRecherchez :
• espaces en début/fin ( Roundlake) ;
• fautes d’orthographe ou variations de casse (roundlake, Round Lake) ;
• doubles espaces ou caractères invisibles (espace insécable).
3Corriger les attributs fautifsCorrection unitaire : Set-Place -Identity "<Nom‑Salle>" -City "Roundlake" Automatisation (ex. nettoyage des espaces en tête) : Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place | Where-Object City -match '^\s' | ForEach-Object { Set-Place -Identity $_.Identity -City ($_.City.Trim()) }
4Attendre la réplicationLes modifications se propagent généralement en ≤ 24 h. Une fois la synchronisation effectuée, l’entrée de ville vide disparaît de Room Finder.

Pré requis côté administration

  • Module Exchange Online v3 installé et à jour.
  • Rôles : Exchange Administrator ou Place Management.
  • Connexion : Connect-ExchangeOnline -ShowBanner:$false

Diagnostic rapide et inventaire

Avant toute modification, réalisez un inventaire complet des salles et de leurs métadonnées Places. Évitez Format-Table lors de l’export (car il tronque). Utilisez plutôt Select-Object puis export CSV.

$rooms = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
$rooms | Select-Object DisplayName, Identity, Building, Floor, City |
  Sort-Object City, DisplayName |
  Export-Csv -Path ".\Rooms-Inventory-Before.csv" -NoTypeInformation -Encoding UTF8

Repérez les anomalies fréquentes :

  • Espaces parasites : ' Roundlake', 'Roundlake ', 'Round lake'.
  • Variations typographiques : roundlake, Round Lake, ROUNDLAKE.
  • Caractères invisibles (ex. espace insécable U+00A0), tirets spéciaux, etc.

Pour détecter rapidement ces cas :

$suspects = $rooms | Where-Object {
  $_.City -match '^\s|\s$' -or                   # espace en début/fin
  $_.City -match '\s{2,}' -or                    # double espace
  $_.City -match '\u00A0' -or                    # espace insécable
  $_.City -match '^(?i)round\s*lake$' -or        # Round Lake
  $_.City -match '^(?i)roundlake$'               # roundlake
}
$suspects | Select-Object DisplayName, City | Sort-Object City, DisplayName

Correction manuelle sécurisée

Pour une poignée de salles, corrigez à la main, idéalement en prévisualisant d’abord les changements grâce à -WhatIf (offert par de nombreux cmdlets). Set-Place ne supporte pas -WhatIf de façon native, donc validez sur un petit échantillon avant d’appliquer en masse.

# Exemple ciblé
Set-Place -Identity "Conf A1 - Roundlake" -City "Roundlake"
Set-Place -Identity "Training Rm - Roundlake " -City "Roundlake"
Set-Place -Identity "Salle Poly -  Roundlake" -City "Roundlake"

Correction en lot et normalisation

La normalisation garantit que toutes les variantes reviennent strictement à Roundlake. Le script ci-dessous traite les espaces, casse, « Round Lake » et caractères Unicode d’espacement.

function Normalize-City {
  param([string]$Value)
  if ([string]::IsNullOrWhiteSpace($Value)) { return $Value }
  $v = $Value -replace '\u00A0', ' '          # remplace l'espace insécable
  $v = ($v -replace '\s+', ' ').Trim()        # comprime et supprime espaces
  if ($v -match '^(?i)round\s*lake$') { return 'Roundlake' }  # unifie l'écriture
  return $v
}

$changes = @()

$rooms | ForEach-Object {
$current = $*.City
$target  = Normalize-City -Value $current
if ($target -ne $current) {
$changes += [pscustomobject]@{
DisplayName = $*.DisplayName
Identity    = $_.Identity
CityBefore  = $current
CityAfter   = $target
}
}
}

$changes | Export-Csv ".\Rooms-City-Plan.csv" -NoTypeInformation -Encoding UTF8

# Application des corrections

foreach ($c in $changes) {
Write-Host "Fixing $($c.DisplayName): '$($c.CityBefore)' -> '$($c.CityAfter)'" -ForegroundColor Yellow
Set-Place -Identity $c.Identity -City $c.CityAfter
}

# Relevé après corrections

$roomsAfter = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
$roomsAfter | Select-Object DisplayName, Identity, Building, Floor, City |
Export-Csv -Path ".\Rooms-Inventory-After.csv" -NoTypeInformation -Encoding UTF8

Propagation et vérification

Les modifications Places se propagent dans l’écosystème Microsoft 365 (service Places, Room Finder, sélectionneurs de salles) généralement en quelques heures, et typiquement en ≤ 24 h. Pour vérifier :

  • Ouvrez Outlook sur le web, testez le panneau « Rechercher une salle » et la liste des villes.
  • Vérifiez également le client Outlook pour Windows (mode classique ou nouveau), afin d’écarter un effet de cache local.
  • Contrôlez avec Get-Place -Identity "<Nom‑Salle>" que City est bien uniformisé.

Important : effacer le cache personnel des emplacements (clé de registre LocationMRU) n’a aucun effet sur la liste des villes de Room Finder quand le doublon est visible sur plusieurs postes : le problème est côté service et se corrige avec Set-Place sur les salles.

Informations complémentaires utiles

  • Room Finder affiche uniquement les valeurs distinctes de City présentes sur des boîtes de type RoomMailbox. Il n’existe pas de commande pour « supprimer » directement une ville ; il faut aligner (ou vider) l’attribut sur toutes les salles concernées.
  • Pour vérifier les Room Lists : Get-DistributionGroup -RecipientTypeDetails RoomList Get-DistributionGroupMember -Identity "<Room List Name>" Assurez-vous que les groupes sont :
    • universels et mail-enabled ;
    • de type RoomList (sinon : Set-DistributionGroup -Identity "<nom>" -RoomList).
  • Les doublons visibles par tous ne proviennent pas du cache Outlook. Nettoyer la MRU n’agit que sur la liste personnelle, pas sur Room Finder.
  • Pour des corrections massives, exécutez en heures creuses : la modification du champ City n’interrompt pas la disponibilité des salles.

Dépannage et cas particuliers

Présence d’un seul caractère invisible

Un espace insécable (U+00A0) ou un caractère de contrôle peut suffire à créer une ville distincte. Pour l’identifier :

$rooms | Where-Object { $_.City -match '\u00A0' } |
  Select-Object DisplayName, City

Ou visualiser chaque caractère en code numérique :

$rooms | Select-Object DisplayName,
  @{n='CityChars'; e={ ($_.City.ToCharArray() | ForEach-Object { [int]$_ }) -join ',' }}

Mettre la ville à vide pour un sous-ensemble

Dans certains modèles, vous pouvez souhaiter vider l’attribut City (ex. salles itinérantes). Selon la politique interne, fixez City à une valeur standard (ex. Global) plutôt que vide, pour éviter des entrées null ambiguës. Si vous devez vraiment vider la valeur, testez sur une salle pilote et validez le comportement dans Room Finder de votre tenant.

Contrôle qualité préventif

Ajoutez un contrôle périodique (mensuel) qui signale toute nouvelle valeur de ville et les anomalies :

$report = $roomsAfter | Group-Object City |
  Sort-Object Name |
  Select-Object @{n='City';e={$_.Name}}, @{n='Count';e={$_.Count}}
$report | Format-Table -Auto

Normalisation multi‑sites

Pour les organisations multi‑sites, maintenez une table de correspondance (mapping) des noms de villes autorisés :

$allowed = @('Roundlake','Paris','Berlin','Tokyo')
$bad = $roomsAfter | Where-Object { $_.City -and ($allowed -notcontains $_.City) }
$bad | Select-Object DisplayName, City | Sort-Object City, DisplayName

Script prêt à l’emploi

Ce script assemble inventaire, détection, plan de remédiation et application contrôlée. Il journalise les actions et produit des CSV avant/après.

# Requires: Exchange Online PowerShell v3
param(
  [Parameter(Mandatory=$false)][string]$TargetCity = 'Roundlake',
  [switch]$Apply
)

function Normalize-City {
param([string]$Value, [string]$Canonical)
if ([string]::IsNullOrWhiteSpace($Value)) { return $Value }
$v = $Value -replace '\u00A0', ' '     # espace insécable -> espace normal
$v = ($v -replace '\s+', ' ').Trim()
if ($v -match '^(?i)' + [regex]::Escape($Canonical) + '$') { return $Canonical }
if ($v -match '^(?i)' + [regex]::Escape(($Canonical -replace 'lake','\s*lake')) + '$') { return $Canonical }
return $v
}

$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$log   = ".\RoomCityFix-$stamp.log"
$inv1  = ".\Rooms-Before-$stamp.csv"
$plan  = ".\City-Plan-$stamp.csv"
$inv2  = ".\Rooms-After-$stamp.csv"

"[$(Get-Date)] Starting inventory" | Out-File $log -Encoding UTF8
$rooms = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
$rooms | Select-Object DisplayName, Identity, Building, Floor, City |
Export-Csv $inv1 -NoTypeInformation -Encoding UTF8

$todo = foreach ($r in $rooms) {
$newCity = Normalize-City -Value $r.City -Canonical $TargetCity
if ($newCity -ne $r.City) {
[pscustomobject]@{
DisplayName = $r.DisplayName
Identity    = $r.Identity
CityBefore  = $r.City
CityAfter   = $newCity
}
}
}

if (-not $todo) {
"[$(Get-Date)] Nothing to change." | Tee-Object -FilePath $log -Append
return
}

$todo | Export-Csv $plan -NoTypeInformation -Encoding UTF8
"[$(Get-Date)] Planned $($todo.Count) changes. See $plan" | Tee-Object -FilePath $log -Append

if ($Apply) {
foreach ($c in $todo) {
"[$(Get-Date)] Fixing $($c.DisplayName): '$($c.CityBefore)' -> '$($c.CityAfter)'" |
Tee-Object -FilePath $log -Append
Set-Place -Identity $c.Identity -City $c.CityAfter
}
$roomsAfter = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
$roomsAfter | Select-Object DisplayName, Identity, Building, Floor, City |
Export-Csv $inv2 -NoTypeInformation -Encoding UTF8
"[$(Get-Date)] Completed. After-inventory: $inv2" | Tee-Object -FilePath $log -Append
} else {
"[$(Get-Date)] Dry run: review $plan then re-run with -Apply" |
Tee-Object -FilePath $log -Append
}

Utilisation :

# Simulation (dry run)
.\Fix-RoomCity.ps1 -TargetCity 'Roundlake'

# Application réelle

.\Fix-RoomCity.ps1 -TargetCity 'Roundlake' -Apply

Validation dans Room Finder

  1. Attendez la complétion de la réplication (quelques heures, jusqu’à 24 h).
  2. Dans Outlook, créez un rendez-vous et ouvrez le sélecteur de salle.
  3. Contrôlez la liste des villes : l’entrée vide Roundlake doit avoir disparu, la bonne persiste avec ses salles.

Comparaison avant / après

ÉtatExemples de valeurs CityImpact dans Room Finder
Avant' Roundlake', 'Round Lake', 'roundlake', 'Roundlake 'Deux entrées « Roundlake » dont une sans salles.
Après'Roundlake' (uniforme pour toutes les salles)Une seule entrée « Roundlake », contenant toutes les salles concernées.

Questions fréquentes

Peut-on supprimer directement une ville de Room Finder ?
Non. Room Finder est un résumé des valeurs City au niveau des salles. Il faut corriger ou vider City sur les boîtes RoomMailbox source.

Et si je ne trouve aucune salle avec City anormal ?
Vérifiez les caractères invisibles (insécables), exportez en CSV et inspectez la longueur, ou comparez $_.City à $_.City.Trim(). Un seul caractère caché suffit.

Faut-il modifier les Room Lists ?
Seulement si vos groupes ne sont pas du type RoomList. Les Room Lists ne créent pas de ville fantôme à elles seules, mais elles déterminent l’organisation logique des salles.

Le cache Outlook peut-il être responsable ?
S’il s’agit d’un phénomène global (visible sur plusieurs postes), non. La cause est côté service. Le cache personnel n’affecte que la liste privée d’emplacements (MRU).

Combien de temps pour voir le changement ?
Généralement en quelques heures, jusqu’à 24 h. Si nécessaire, vérifiez dans Outlook sur le web puis sur le client de bureau.

Checklist express

  • Se connecter à Exchange Online avec les rôles adéquats.
  • Lister toutes les salles via Get-ExoMailbox | Get-Place.
  • Identifier espaces, casse, fautes, caractères invisibles sur City.
  • Corriger avec Set-Place (manuel ou script de normalisation).
  • Attendre la réplication ≤ 24 h et valider dans Room Finder.

Résumé

La « ville fantôme » dans Room Finder provient d’une incohérence sur l’attribut City d’au moins une salle. En auditant les boîtes RoomMailbox avec Get-Place, puis en nettoyant et normalisant les valeurs via Set-Place (espaces, casse, fautes, caractères Unicode), vous ramenez toutes les salles sur une écriture unique (Roundlake dans l’exemple). Après synchronisation (≤ 24 h), l’entrée vide disparaît de Room Finder et la liste des villes redevient fiable. Ce processus est idempotent, peu risqué et améliore durablement l’expérience de réservation des salles.


En bref : la ville fantôme provenait d’un espace en tête de la valeur City sur une seule boîte ; en nettoyant cette valeur via Set‑Place, la duplication a disparu après synchronisation.

Sommaire