Si en el Room Finder de Outlook (Exchange Online) ves una ciudad duplicada en All Cities —una con salas y otra vacía—, la causa casi siempre es un valor incoherente en el atributo City
de alguna sala. A continuación te explico cómo detectarlo, corregirlo y evitar que vuelva a ocurrir.
Contexto y síntoma
En la experiencia de reserva de salas (Room Finder / Buscar salas) el servicio agrupa automáticamente las salas por su atributo de lugar (City
). Cuando dos salas comparten una ciudad escrita de forma distinta —por ejemplo, con un espacio inicial (" Roundlake"
) o doble espacio, mayúsculas inconstantes o caracteres “invisibles”— el servicio interpreta que se trata de ciudades diferentes. El resultado es una ciudad “duplicada” bajo All Cities, donde una entrada suele aparecer vacía (sin salas) o con un subconjunto de salas que no debería estar separado.
Causa principal: valores inconsistentes de City
El caso más frecuente es un espacio en blanco al inicio o al final del nombre de la ciudad. Por ejemplo:
" Roundlake"
(nota el espacio inicial)"Roundlake "
(espacio final)"Roundlake"
(valor correcto)
Room Finder trata cada variante como una ciudad distinta, por lo que verás “Roundlake” dos veces (o más). Este problema también puede aparecer por:
- Mayúsculas/minúsculas inconsistentes (
roundlake
vs.Roundlake
). - Espacios dobles o caracteres separadores no convencionales (p. ej., no‑breaking space
U+00A0
). - Salas con
City
vacío o nulo (se agrupan de forma distinta o pueden quedar “sucias” en los filtros).
Diagnóstico rápido con PowerShell (EXO V3)
Conéctate a Exchange Online PowerShell y ejecuta estas comprobaciones. Necesitas permisos para leer y actualizar lugares (Places).
# Conexión (si aún no lo has hecho)
Connect-ExchangeOnline
1) Listar salas con su ciudad actual
Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Sort-Object DisplayName |
Get-Place |
Format-Table DisplayName, Building, Floor, City
Busca espacios iniciales/finales u otras incoherencias:
# 2) Detectar espacios al inicio o al final
Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Get-Place |
Where-Object { $_.City -match '^\s+|\s+$' } |
Format-Table DisplayName, City
Para visualizar “duplicados lógicos” (ciudades que solo difieren por espacios), agrupa por el valor normalizado con Trim()
:
$places = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
$places | Group-Object { $_.City.Trim() } |
Select-Object Name, Count,
@{n='Salas';e={$_.Group.DisplayName -join ', '}} |
Format-Table -AutoSize
Tabla de referencia: síntoma → causa → cómo comprobar
Síntoma | Causa probable | Comprobación |
---|---|---|
Ciudad duplicada bajo All Cities | Espacio inicial/final o doble espacio en City | Where-Object { $_.City -match '^\s+|\s+$' } |
Dos ciudades con grafías casi iguales | Mayúsculas/minúsculas inconsistentes | Comparar $.City vs. $.City.ToLower() |
Ciudad “vacía” sin salas | Salas antiguas con City vacío o valor oculto | Filtrar [string]::IsNullOrWhiteSpace($_.City) |
Ciudad separada pese a “mismos” caracteres | Separadores Unicode (p. ej., NBSP) | Normalizar con regex \p{Zs} y Trim() |
Solución recomendada: normalizar City
Corrección mínima (para una ciudad concreta)
Si sabes cuál debe ser el valor definitivo (por ejemplo, Roundlake
), corrige solo las entradas que difieran por espacios:
# Normalizar a "Roundlake"
$target = "Roundlake"
Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Get-Place |
Where-Object { $.City -ne $target -and $.City.Trim() -eq $target } |
ForEach-Object {
Set-Place -Identity $_.Identity -City $target
}
Notas prácticas:
-Identity
deSet-Place
acepta el buzón de la sala (alias/SMTP). Si lo necesitas, usaPrimarySmtpAddress
.- Si también hay variaciones de mayúsculas (
roundlake
), añade un filtro a.ToLower()
para cubrirlas.
Corrección robusta (cubriendo espacios & mayúsculas & separadores)
La siguiente función normaliza el nombre de ciudad eliminando espacios extra (incluidos separadores Unicode), recortando extremos y, opcionalmente, homogeneizando el caso:
function Normalize-City {
param([string]$City, [switch]$ToTitleCase)
if ([string]::IsNullOrWhiteSpace($City)) { return $null }
# Sustituye cualquier secuencia de separadores de espacio Unicode por un solo espacio
$c = $City -replace '\p{Zs}+', ' '
$c = $c.Trim()
if ($ToTitleCase) {
$ti = [System.Globalization.CultureInfo]::InvariantCulture.TextInfo
$c = $ti.ToTitleCase($c.ToLower())
}
return $c
}
Vista previa de normalización (no cambia nada aún)
$preview = Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Get-Place |
Select-Object Identity, DisplayName, City,
@{n='CityNormalized';e={ Normalize-City -City $_.City -ToTitleCase }}
$preview | Where-Object { $.City -ne $.CityNormalized } |
Format-Table DisplayName, City, CityNormalized -AutoSize
Si la vista previa es correcta, aplica los cambios:
$preview | Where-Object { $.City -ne $.CityNormalized } |
ForEach-Object {
Set-Place -Identity $.Identity -City $.CityNormalized
}
Estrategia por “lista canónica” (recomendado en organizaciones grandes)
Para evitar variaciones futuras, define una lista canónica de ciudades permitidas (por ejemplo, las de tu directorio corporativo) y haz que el script solo aplique valores de esa lista. Así previenes “Londres”, “London”, “LON”, etc.
# Ejemplo simple de lista canónica
$CanonicalCities = @(
"Roundlake",
"Madrid",
"Buenos Aires",
"Ciudad de México",
"Santiago"
)
$places = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
foreach ($p in $places) {
$normalized = Normalize-City -City $p.City -ToTitleCase
if ($null -ne $normalized) {
# Encuentra la mejor coincidencia exacta tras normalizar
$match = $CanonicalCities | Where-Object { $_ -eq $normalized }
if ($match) {
if ($p.City -ne $match) {
Set-Place -Identity $p.Identity -City $match
}
} else {
# Opcional: reporta valores no canónicos para revisión manual
[PSCustomObject]@{
Identity = $p.Identity
DisplayName = $p.DisplayName
CityOriginal = $p.City
CityNormalized = $normalized
Status = "No coincide con lista canónica"
}
}
}
}
Validación tras el cambio
- Propagación: la actualización puede tardar en reflejarse en Room Finder. La mayoría de cambios se ven pronto, pero presupón que puede llevar hasta ~24 horas en el servicio y clientes.
- Clientes: cierra y vuelve a abrir Outlook; en clientes de escritorio, las cachés de sala/ubicación pueden diferirse del servicio por un tiempo.
- Revisión: vuelve a ejecutar los listados de diagnóstico para confirmar que ya no hay variaciones de
City
.
Checklist de “si el problema persiste”
La duplicidad de ciudades rara vez está relacionada con Room Lists, pero ya que participan en la experiencia de búsqueda, conviene revisarlas:
# Ver listas de salas existentes
Get-DistributionGroup -RecipientTypeDetails RoomList |
Format-Table DisplayName, PrimarySmtpAddress
Ver miembros de una lista de salas concreta
Get-DistributionGroupMember -Identity "<RoomListName>" |
Format-Table Name, PrimarySmtpAddress
Comprueba además:
- Que todas las salas relevantes tienen
City
asignado y normalizado (Set-Place -City
). - Que no quedaron salas obsoletas o de prueba con valores “raros”.
- Que no hay mayúsculas/minúsculas diversas para la misma ciudad (decide una convención y aplícala en lote).
Qué no suele ayudar
- Limpiar
LocationMRU
en el registro del equipo cliente solo afecta a sugerencias locales de ubicación en Outlook. No modifica ni la lista de ciudades ni los atributos de los lugares en el servicio. - Eliminar “la ciudad” desde el cliente: no existe un objeto de ciudad independiente que puedas borrar. La lista se construye a partir del atributo
City
de cada sala.
Buenas prácticas para evitar regresiones
- Automatiza la normalización en tu proceso de alta de salas:
- Valida la ciudad contra una lista canónica.
- Aplica
Trim()
y normaliza separadores. - Unifica el caso (p. ej., Title Case o mayúsculas).
- Audita periódicamente (por ejemplo, semanalmente) y envía un reporte con diferencias detectadas.
- Documenta un estándar (nombres oficiales de ciudades, acentos, idioma) y compártelo con quien crea/edita salas.
Script de auditoría listo para usar
Este guion genera un informe de posibles incoherencias y propone el valor normalizado:
# Requiere: Connect-ExchangeOnline
function Normalize-City {
param([string]$City)
if ([string]::IsNullOrWhiteSpace($City)) { return $null }
$c = $City -replace '\p{Zs}+', ' '
$c = $c.Trim()
return $c
}
$report = Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Get-Place |
Select-Object Identity, DisplayName, @{n='CityOriginal';e={$_.City}},
@{n='CityNormalized';e={ Normalize-City -City $_.City }},
@{n='TieneEspaciosExtremos';e={ $_.City -match '^\s+|\s+$' }},
@{n='LowerCase';e={ $_.City.ToLower() }},
@{n='TrimLower';e={ (Normalize-City -City $_.City).ToLower() }}
$report |
Sort-Object CityNormalized, DisplayName |
Format-Table -AutoSize
Corrección masiva con salvaguardas
Este ejemplo solo corrige valores en los que la normalización no cambia el “contenido” (es decir, quita espacios o separadores raros), sin forzar cambios de idioma o de nomenclatura:
$places = Get-ExoMailbox -RecipientTypeDetails RoomMailbox | Get-Place
foreach ($p in $places) {
$original = $p.City
$normalized = $null
if (-not [string]::IsNullOrWhiteSpace($original)) {
$normalized = ($original -replace '\p{Zs}+', ' ').Trim()
}
# Solo corrige si el valor difiere por espacios/separadores
if ($null -ne $normalized -and $original -ne $normalized) {
Write-Host "Set-Place -Identity $($p.Identity) -City '$normalized'"
Set-Place -Identity $p.Identity -City $normalized
}
}
Deshacer cambios (rollback)
Antes de aplicar correcciones masivas, exporta un CSV con el valor original para poder revertir si es necesario:
$backup = Get-ExoMailbox -RecipientTypeDetails RoomMailbox |
Get-Place |
Select-Object Identity, DisplayName, City
$path = Join-Path $env:TEMP "backup-places-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"
$backup | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
Write-Host "Copia de seguridad guardada en $path"
Para restaurar desde el CSV:
$restore = Import-Csv $path
$restore | ForEach-Object {
Set-Place -Identity $.Identity -City $.City
}
Verificación de extremo a extremo
- Ejecuta el inventario y confirma que todas las salas de la ciudad comparten exactamente el mismo
City
. - Comprueba Room Lists (si las usas) para asegurar que las salas correctas están en la lista adecuada.
- Valida en Outlook Web y en Outlook para escritorio que solo aparece una entrada de la ciudad en All Cities.
Preguntas frecuentes
¿Puedo “borrar” la ciudad vacía?
No directamente. La lista de ciudades se genera a partir de los valores City
de las salas. Al normalizar los valores, la ciudad duplicada desaparece sola.
¿Cuánto tarda en actualizarse?
Depende de la propagación del servicio y de la caché del cliente. Considera que puede tardar hasta ~24 horas en verse reflejado en todos los clientes.
¿Las mayúsculas importan?
Según el cliente, pueden generar agrupaciones separadas si coexisten con espacios u otros caracteres. Estandariza el caso para evitar sorpresas.
¿Debo tocar las Room Lists?
No para resolver la duplicación de ciudades, pero sí conviene revisar membresías si, además, notas que faltan salas al filtrar por listas.
Resumen ejecutivo
- Problema: Ciudad duplicada en Room Finder causada por espacios, separadores o variaciones en
City
de las salas. - Solución: Auditar con
Get-Place
, normalizar (recortar/unificar) conSet-Place
y permitir la propagación. - Soporte: Revisar Room Lists si aún aparece una ciudad “fantasma” y asegurar membresías correctas.
Apéndice: diferencias útiles y consideraciones
Get-Place
vs.Get-ExoMailbox
: el primero devuelve metadatos físicos (City, Building, Floor); el segundo identifica buzones de tipo sala para encadenar el pipeline.- Campo correcto a editar:
Set-Place -City
(no confundas con propiedades de dirección en otras herramientas). - Permisos: asegúrate de tener privilegios para administrar lugares (admin de Exchange o permisos delegados adecuados).
- Internacionalización: decide si tu estándar incluye acentos y títulos de caso; aplícalo consistentemente.
- Control de calidad continuo: agenda un trabajo periódico que ejecute la auditoría y te alerte de nuevas desviaciones.
Conclusión: la duplicación de ciudades en Room Finder no es un misterio del servicio, sino la consecuencia de datos inconsistentes. Con una auditoría breve y una normalización cuidadosa de City
, la experiencia de reserva vuelve a ser coherente y fácil de usar.