Script para cambio de dominio de correo en dirección SMTP primaria de usuarios con buzón

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:

smtp1

2. El script puede ser ejecutado con los parámetros de “oldDomain” y “newDomain”:

smtp4

Cómo alternativa se puede ejecutar sin parámetros y el script solicita los datos necesarios:

smtp2

smtp9

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):

script de cambio de direccion smtp primaria

4. Ejecutamos el comando Get-Mailbox para ver el cambio y verificamos que se mantenga la dirección anterior como secundaria:

script para cambio de direccion de correo primaria

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 $false

if ($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 else

if ($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:

You cannot run this script on the current system
You cannot run this script on the current system

Cannot be loaded because running scripts is disabled on this system

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

get-executionpolicy set-executionpolicy

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

About Daniel Núñez Banega

Consultor IT especializado en Microsoft Exchange, Active Directory y Microsoft 365.
Principales Certificaciones: Microsoft Certified Trainer | Microsoft Certified Solutions Expert | Microsoft Certified Systems Engineer | Microsoft Certified Systems Administrator | Microsoft Certified IT Professional | Microsoft Certified Technology Specialist | Microsoft 365 Certified: Enterprise Administrator Expert | Microsoft 365 Certified: Security Administrator Associate | Microsoft Certified: Cybersecurity Architect Expert | Comptia Pentest+ | EC-Council Certified Ethical Hacker Master

Reader Interactions

Comments

  1. 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!

  2. 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.

  3. 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.

  4. 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 )

  5. 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

  6. 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.

  7. 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

  8. Diana Garcia says

    Hola Daniel gracias por la información.

    como lo podría aplicar si mis buzones están en office 365.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *