En un escenario ideal no habría necesidad de utilizar un script para modificar el dominio utilizado en la dirección de correo primaria de los usuarios. Las políticas de direcciones de correo de Exchange son sencillas de utilizar y funcionan muy bien. Sin embargo, hay casos donde la estructura no está claramente definida, con muchos usuarios y potencialmente muchas excepciones derivando en que quizás no sea viable un cambio a nivel de política.
El script a ver en esta entrada (Change-PrimarySmtpAddress) permite modificar el dominio de correo SMTP utilizado en la dirección primaria de usuarios con buzón reemplazando la parte de dominio (@dominio.com) con un dominio de correo diferente (se debe haber creado el dominio aceptado en la organización de Exchange).
La dirección anterior se mantiene como secundaria con la finalidad de continuar recibiendo mail, con el paso del tiempo esto puede ser modificado.
El script fue validado sobre Exchange 2010 y Exchange 2013. Como sistema operativo se probó con Windows Server 2008 R2 / 2012 (Exchange 2010) y Windows Server 2012 / 2012R2 (Exchange 2013).
Tareas que realiza el script
1. Busca usuarios con buzón que utilicen en la dirección de correo SMTP primaria el dominio a reemplazar
2. Si no existe un dominio de correo aceptado con el nombre del nuevo dominio, se detiene la ejecución. Esto se puede ver en pantalla o en el log
3. Si no existen buzones con el dominio viejo a reemplazar, se detiene la ejecución (se ve en pantalla y se registra en el log)
4. En caso de cumplir con todas las condiciones se reemplaza la dirección primaria y se registra en el log (manteniendo la anterior como secundaria)
Change-PrimarySmtpAddress
El script puede ser descargado desde el repositorio de scripts de Microsoft u opcionalmente se puede copiar el texto (más adelante) y pegarlo en un archivo con extensión .ps1.
1. En la captura de pantalla a continuación utilizamos el comando Get-AcceptedDomain para confirmar la existencia del nuevo dominio de correo (adatum.com en este caso). Adicionalmente vemos la dirección de correo primaria actual de los usuarios con el comando Get-Mailbox:
2. El script puede ser ejecutado con los parámetros de “oldDomain” y “newDomain”:
Cómo alternativa se puede ejecutar sin parámetros y el script solicita los datos necesarios:
3. El log se guarda en la misma ruta donde se ejecutó el script (por lo que se debe tener permisos de escritura en esta ubicación):
4. Ejecutamos el comando Get-Mailbox para ver el cambio y verificamos que se mantenga la dirección anterior como secundaria:
Como todo cambio en producción se recomienda probar en ambiente controlado antes de realizar un cambio que pueda afectar de forma masiva.
Código del script
###############################################################
# #
# Script for modifying the primary smtp address domain name on user mailboxes #
# Written by: Daniel Núñez Banega #
# Blog: Http://AprendiendoExchange.com #
# Version: 1.0 #
# Last Updated: 19/7/2014 #
# #
###############################################################
#————————————————————–
#Parameters
Param
(
[Parameter(Mandatory=$true)] [string]$oldDomain,
[Parameter(Mandatory=$true)] [string]$newDomain
)$script:nl = «`r`n»
Clear-host
$error.Clear()
$countErr = 0
$countMbxs = 0
$timeStamp = get-date -f yyyy_MM_dd_hh_mm
$logFile = «logsmtp-» + $Timestamp + «.txt»# Log header
«OLD,NEW» | Out-File $logFile# Mailbox collection
$mailboxes = @(get-mailbox -ResultSize unlimited | where{$_.PrimarySmtpAddress -like «*@$oldDomain» -and$_.RecipientTypeDetails -eq «UserMailbox»})
# Check if accepted domain exists in the organization
if (([bool](Get-AcceptedDomain -errorAction SilentlyContinue | where{$_.DomainName -eq $newDomain})) -eq$false)
{
Write-warning «Cannot find an accepted domain for: $newDomain»
«Cannot find an accepted domain for: $newDomain» | out-file $logFile -append
$countErr++
}# Check if no users uses the former domain name in primary smtp address
elseif (!$mailboxes.count)
{
write-warning «Cannot find any mailbox with primary smtp domain $oldDomain»
«Cannot find any mailbox with primary smtp domain $oldDomain» | out-file $logFile -append
}# Start processing
else
{
write-host «Processing…» -foregroundColor Green
foreach ($mbx in $mailboxes){
$error.clear()
$count = $error.Count
$smtp = $mbx.PrimarySmtpAddress
$oldSmtp = $smtp.ToString()
$alias = $smtp.Local
$newSmtp = «$alias@$newDomain»$log = «$oldSmtp,$newSmtp»
# Set new primary SMTP address using old local part and new domain
Set-Mailbox $mbx -PrimarySmtpAddress $newSMTP -confirm:$false -EmailAddressPolicyEnabled $falseif ($error.Count -ne $count)
{
[string]$problema = $error[0].Exception
write-host $problema
$problema | out-file $logFile -Append
$countErr = 1
}
else
{
$log | out-file $logFile -Append
write-host $log
$countMbxs++
}
} # close foreach
} # close elseif ($countErr -ne 0)
{
write-warning «The process finished with errors»
}else
{
$nl
write-host «The process finished succesfully» -ForegroundColor Cyan
}
write-host «$countMbxs mailboxes processed» -ForegroundColor Cyan
$location = Get-Location
write-host «Saved log location: $location\$logFile» -ForegroundColor Cyan
Si se recibe un error relacionado a execution policy…
A tener en cuenta que el servidor donde corran el script debe tener una política de ejecución que permita ejecutar scripts no firmados, de lo contrario van a recibir un error:
Para ver la política actual de ejecución utilizamos el comando Get-ExecutionPolicy, para modificar utilizamos Set-ExecutionPolicy:
Por ejemplo para que por política no se restrinja nada ejecutamos:
Set-ExecutionPolicy unrestricted
De forma predeterminada en Exchange esta política viene en Remote Signed.
Por más info ver el siguiente artículo:
Actualización 9/5/2015: Para modificar únicamente usuarios de una OU específica se puede descargar la siguiente versión del script:
https://gallery.technet.microsoft.com/scriptcenter/Change-users-mailboxes-e5fa3af8
Miguel says
hola, antes que todo muy bueno el blog!
tengo una consulta en realación a este script. puedo aplicarlo solamente a una OU?
gracias!
Aprendiendo Exchange says
Hola Miguel, gracias por los comentarios. Te cuento que acabo de subir una nueva versión para que lo haga por OU: https://gallery.technet.microsoft.com/scriptcenter/Change-users-mailboxes-e5fa3af8
Esta versión lleva un parámetro adicional (-ou) y a continuación le indicas la OU específica. Atención que lo hace de forma recursiva, es decir que también aplica a las sub OU que pueda tener.
En breve actualizo esta entrada.
saludos!
Miguel says
Funciona de maravillas! gracias y nuevamente te felicito por la pagina.
saludos,
Miguel
Aprendiendo Exchange says
Excelente Miguel!! muchas gracias
saludos!
jesus says
es posible cambiar las direcciones de emails por otras. por ejemplo tengo un email jperez.1234@midominio.com y lo deseo cambiar por 1234@@midominio.com, ya tengo en excel todo el listado de los emails que quiero actualizar. cual es el procedimiento a seguir?
Daniel Núñez Banega says
Hola Jesús, es posible. Dependiendo de si vas a reemplazar o agregar la nueva dirección el procedimiento (en general conviene mantener la anterior como secundaria por si te siguen enviando correo en la dirección vieja). En cualquier caso seguramente tengas que recurrir a elaborar un script que se ajuste al requerimiento específico. En principio tendrías que importar la planilla y utilizar el cmdlet Set-Mailbox para hacer los cambios a nivel de SMTP.
Rogelio Joseph says
Buenos días, un favor quiero crear buzones de forma masiva a usuarios que ya existen en el AD mediante Shell. Por favor que son como 1000 usuarios.
Daniel Núñez Banega says
Rogelio, en el siguiente artículo se ve el tema de creación de buzones para usuarios existentes:
https://aprendiendoexchange.com/crear-un-buzon-de-usuario-en-exchange-2013
alexoandro says
Primero felicitarte por las aportaciones que nos haces.Tengo exchange en office 365.
Mi empresa ha cambiado de dominio y quiere cambiar los nombres de los buzones por la nomenclatura nombre.apellido@nuevodominio.es hasta ahora las cuentas están como inicialnombreapellido@midominioviejo.es.
Bien yo esto lo hice a modo de prueba con el entorno web y primero tuve que crear el dominio y luego cambiar el nombre de la cuenta de office 365 de mi usuario y luego añadir el smtp del dominio nuevo y ponerlo como principal hasta aquí esta funcionando bien .
Ahora me gustaría poder hacer el resto con powershell pero no me sirve tal cual esta este script o bueno tendría que hacer un segundo script para cambiar el nombre de los buzones y los nombres de los usuarios de office 365.
Aparte también vi en tu web como hacerlo con una política por el administrador de exchange , yendo a flujo de correo y directivas de direcciones pero eso en mi entorno no me aparece , solo tengo reglas seguimiento de mensajes dominios aceptados dominios remotos y conectores. ( estoy como administrador )
Daniel Núñez Banega says
Hola Alexandro, el script esta diseñado para entornos on premises o híbridos. Te paso el link al repositorio de scripts de Microsoft, quizás encuentres uno ya armado o al menos para usar como ejemplo:
https://gallery.technet.microsoft.com/scriptcenter/
MANUEL says
Hola muy bueno el Blog
Consulta, como puedo lista por powershell todos los usuarios de Exchange 2010 con todas sus cuentas SMTP, porque tenemos usuarios con 1,2,3 smtp.
Gracias
Juan Francisco says
Hola, esta muy bueno el Script, pero se puede hacer lo mismo invocando a un archvio .csv ?
Daniel Núñez Banega says
Hola Juan Francisco, habría que hacer algunos ajustes para usar un archivo CSV. En particular al trabajar con la variable que usamos para almacenar la colección de buzones.
Te dejo el link a un artículo que muestra cómo usar el cmdlet Import-CSV:
https://aprendiendoexchange.com/tip-15-crear-objetos-a-partir-de-csv
Diego Ramirez says
Cordial saludo.
Hay alguna manera de editar o agregar el atributo proxyAddresses en el que se encuentra el SMTP:xxxxxxxx@dominio.com que tiene cada usuario de AD.
Quisiera saber el nombre exacto del atributo proxyAddresses para realizar la prueba con un scrip que tengo.
No se si ya esta dando la respuesta pero soy nuevo en el tema
Daniel Núñez Banega says
Hola Diego, el atributo de AD se llama ProxyAddresses, este sería editable de múltiples formas aunque dependiendo del requerimiento te recomendaría usar las herramientas de Exchange (dependiendo del caso el nombre del parámetro a utilizar). Por ejemplo, si es un buzón podrías usar el cmdlet Set-Mailbox con el parámetro PrimarySMTPAddress y especificar la dirección SMTP principal, con el parámetro EmailAddresses podrías editar otras direcciones también.
Luis Hernandez says
Muchas gracias por la información, lo que que detallas, justamente es lo que necesito hacer en este momento, pero tengo el inconveniente que a pesar que he copiado y creado un nuevo archivo con el script indicado, tal cual, al generarlo me muestra los siguientes errores:
get-mailbox : El término ‘get-mailbox’ no se reconoce como nombre de un cmdlet, función, archivo de script o programa ejecutable. Compruebe si escribió correctamente el nombre o, si incluyó una ruta de acceso, compruebe que dicha ruta es correcta e inténtelo de nuevo.
Get-AcceptedDomain : El término ‘Get-AcceptedDomain’ no se reconoce como nombre de un cmdlet, función, archivo de script o
programa ejecutable. Compruebe si escribió correctamente el nombre o, si incluyó una ruta de acceso, compruebe que dicha
ruta es correcta e inténtelo de nuevo.
Lo estoy haciendo desde mi servidor de correo directamente, pero el resultado sigue siendo el mismo
Daniel Núñez Banega says
Hola Luis, por el error me da la impresión de que estás ejecutándolo en una sesión de powershell común.
Deberías usarlo dentro del shell de Exchange (EMS).
Luis Hernandez says
Excelente Daniel, en efecto, estaba cometiendo ese error, hice una segunda prueba en el EMS, y funciona sin problema, me has ahorrado el cambio manual para 1500 cuentas.
Me surge una duda, si en determinado momento necesitara excluir determinado grupo de usuarios, digamos que sean 100, ¿existe alguna forma de hacerlo, o consideras que con ellos si tendria que hacer el rollback de manera manual?
Quedo en espera de tus recomendaciones
Daniel Núñez Banega says
Hola Luis, excelente. En cuanto a la exclusión que planteas la podrías hacer de varias formas, la más sencilla sería editar la variable $mailboxes para filtrar buzones que cumplan una cierta condición que tendrías que definir.
Por ejemplo podrías asignarle a los buzones un valor sobre un CustomAttribute «nomodificar» y en la variable $mailboxes en la parte del «where» especificar que solo entran los buzones que no tienen el valor en el CustomAttribute en cuestión.
En el artículo de Introducción a Powershell se explica el uso de «Where», te dejo el link:
https://aprendiendoexchange.com/introduccion-a-powershell
Diana Garcia says
Hola Daniel gracias por la información.
como lo podría aplicar si mis buzones están en office 365.