PowerShell: Cmdlets para cambiar el caso en atributos de usuario de Active Directory
Posted by urpiano en sábado 5 \05\+01:00 May \05\+01:00 2012
¿No te gusta cómo están dados de alta los usuarios en Active Directory, en concreto que estén en mayúsculas y los quieres en minúsculas, o viceversa? ¿O te gustaría que estuviesen En Plan Títulos? ¿Quieres poder cambiar esto de un plumazo? Estos Cmdlets que presento aquí te pueden servir de ayuda.
En concreto se trata de tres Cmdlets, uno de ellos de apoyo a los otros dos. A los modos de formatear el texto los llamaremos Casos (del Inglés Case), y los tres Cmdlets reciben un parámetro -Case que es el tipo de caso que queremos establecer. Los valores que se le pueden pasar al parámetro -Case son:
- ToLower: todo minúsculas («este es un ejemplo»).
- ToUpper: todo mayúsculas («ESTE ES UN EJEMPLO»).
- ToTitle: primera letra de cada palabra en mayúscula, el resto en minúsculas («Este Es Un Ejemplo»).
Los Cmdlets son:
- Set-Case: este Cmdlet es llamado desde los otros dos y se encarga de obtener el caso deseado de la cadena que se le pase. Por tanto, es necesario que se incluya este Cmdlet para poder usar los otros dos.
- Set-AdUserNameCase: este Cmdlet se encarga de cambiar el nombre del usuario al caso deseado. Cambiar el nombre de un usuario implica cambiar su RDN (RelativeDistinguishedName), que es la parte que queda al nombre distinguido del usuario si le quitamos la parte del nombre distinguido del contenedor que le alberga (el RDN de «CN=Pi, Filemón,OU=Agentes,DC=tia,DC=org» es «CN=Pi, Filemón»); por tanto, al cambiar el RDN estamos cambiando el nombre distinguido del usuario y esto por tanto no es el cambio de un atributo sin más, si no que es mover la cuenta del usuario, por ello se debe usar el método MoveTo del contenedor que alberga la cuenta de usuario, no establecer el cambio en el propio objeto del usuario. Al usar el Cmdlet Set-Case, es requerido que éste esté presente.
- Set-AdUserAttributeCase: este Cmdlet es el de más alto nivel de todos, de hecho puede ser perfectamente el único que invoquemos, debido a que llama tanto a Set-Case como a Set-AdUserName (en este último caso lo llama cuando se pasa el modificador -RDN o el modificador -All, debido a que implican cambiar el caso del nombre del usuario y por tanto su RDN y eso precísamente es lo que hace Set-AdUserNameCase). Esto quiere decir que es requerido que ambos Cmdlets estén presentes para poder ejecutar Set-AdUserAttributeCase. Los atributos del objeto usuario que puede cambiar este Cmdlet son:
- RDN: RelativeDistinguishedName, nombre del objeto usuario en Active Diretory (no confundir con el nombre propio del usuario; éste es un atributo, aquel un identificador).
- Pestaña General
- givenName: nombre propio.
- initials: iniciales.
- sn: apellidos.
- displayName: nombre para mostrar.
- Description: descripción.
- physicalDeliveryOfficeName: oficina.
- Pestaña Address
- streetAddress: dirección.
- postOfficeBox: apartado postal.
- l: ciudad.
- st: estado o provincia.
- postalCode: código postal.
- Pestaña Organization
- title: cargo.
- department: departamento.
- company: empresa.
He mostrado la anterior lista clasificada por pestaña debido a que se puede indicar al Cmdlet que se cambien los atributos de una esas pestañas de las propiedades del usuario en Active Directory Users and Computers, sin que esto sea exclusivo (sólo se pueda poner una pestaña), pues es acumulativo, lo que permite especificar más de una. Por último, si se pasa el modificador -All se cambiarán todos los atributos y el RDN.
Los Cmdlets incluyen ayuda, pego a continuación la ayuda de cada uno de ellos con el modificador -Detailed. Esta ayuda se basa en la prestación de ayuda basada en comentarios de PowerShell 2.0 ¿Qué todavía tienes la versión 1.0 y no la 2.0? ¿A qué esperas para instalarla si es mucho mejor?):
Cmdlet | Ayuda |
Set-Case |
|
Set-AdUserNameCase |
|
Set-AdUserAttributeCase |
|
Este es el código de los Cmdlets:
Function Set-Case([Parameter(Position=0,HelpMessage="Cadena a ser cambiada")] [System.String] $Value, [Parameter(Position=1, ` HelpMessage="Caso a establecer (predeterminado `"ToTitle`")")] [ValidateSet("ToLower", "ToTitle", "ToUpper")] [System.String] $Case = "ToTitle") { # Si no se recibe una cadena vacía o un nulo. If([string]::IsNullOrEmpty($Value) -eq $false) { # La devolución de la función depende del caso. Switch($Case) { # Si el caso es ToLower, pasamos a minúsculas el texto. "ToLower"{$Value.ToLower()} # Si el caso es ToTitle, pasamos a titular el texto. "ToTitle"{(Get-Culture).TextInfo.ToTitleCase($Value.ToLower())} # Si el caso es ToUpper, pasamos a mayúsculas el texto. "ToUpper"{$Value.ToUpper()} } } # Si el texto recibido es nulo o cadena vacía la función devuelve el # texto intacto Else { $Value } <# .SYNOPSIS Devuelve la cadena recibida modificada al caso establecido. .DESCRIPTION Esta función recibe una cadena y devuelve la misma cadena con el caso establecido en el parámetro "Case". Los casos posibles son: - ToLower: todo minúsculas ("este es un ejemplo"). - ToUpper: todo mayúsculas ("ESTE ES UN EJEMPLO"). - ToTitle (predeterminado): Primera letra de cada palabra en mayúscula, el resto en minúsculas ("Este Es Un Ejemplo"). .PARAMETER Value Cadena a ser cambiada. .PARAMETER Case Caso a establecer. Los valores admitidos son "ToLower", "ToTitle" y "ToUpper" (predeterminado "ToTitle"). .EXAMPLE PS C:\> Set-Case "esto es un ejemplo" Esto Es Un Ejemplo Pone en caso titular la cadena "esto es un ejemplo". .EXAMPLE PS C:\> Set-Case "esto es un ejemplo" -Case ToUpper ESTO ES UN EJEMPLO Pone en mayúsculas la cadena "esto es un ejemplo". .EXAMPLE PS C:\> Set-Case "ESTO ES UN EJEMPLO" -Case ToLower esto es un ejemplo Pone en minúsculas la cadena "ESTO ES UN EJEMPLO". .INPUTS System.String .OUTPUTS System.String .LINK https://urpiano.wordpress.com .LINK http://freyes.svetlian.com .NOTES Author: Fernando Reyes López MS-MVP © Mayo de 2012 #> } Function Set-AdUserNameCase { [CmdletBinding()] param ( [Parameter(Position=0, Mandatory=$true,ValueFromPipeLine=$true,` HelpMessage="Usuario a ser cambiado.")] [Alias("U","Usr","Usuario")] $User, [Parameter(Position=1, ` HelpMessage="Caso a establecer (predeterminado `"ToTitle`")")] [ValidateSet("ToLower", "ToTitle", "ToUpper")] [System.String] $Case = "ToTitle" , [Parameter(HelpMessage="Presenta mensajes y resumen de ejecución")] [Alias("R","Resumen")] [Switch] $Info, [Parameter(HelpMessage="Evita la devolución booleana de la función")] [Alias("NB")] [Switch] $NoBoolean ) Begin { # Almacenamos la configuración del comportamiento ante errores que no # interrumpen y la establecemos para que sí interrumpan; esto nos # permitirá el uso de Try/Catch con este tipo de errores. $Accion = $ErrorActionPreference $ErrorActionPreference = "Stop" # Iniciamos contadores $Procesados = 0 $Exitos = 0 $Fracasos = 0 $NoEncontrados = 0 } Process { # Obtenemos el tipo de dato recibido como parámetro User $Tipo = $User.PsBase.GetType() # Revisaremos el tipo para obrar en consecuencia Switch($Tipo.Name) { # Si el tipo es String, se trata de un nombre distinguido que # utilizaremos para obtener el objeto del usuario en AD, si es un objeto # SearchResult su propiedad Rath contiene la URI LDAP del usuario, que # utilizaremos para obtenerlo. {$Tipo.Name -eq "String" -or $Tipo.Name -eq "SearchResult"} { # Si es una cadena, es necesario preceder con el identificador de # protocolo al nombre distinguido. If($Tipo.Name -eq "String") { # Evitaremos las líneas vacías del fichero If([String]::IsNullOrEmpty($User.Trim(' ')) -eq $True) { Return } Else { $Ruta = "LDAP://$User" } } # Si es un objeto SearchResult, la propiedad Path permite # obtener el usuario usándola como URI LDAP Else { $Ruta = $User.Path } # Incrementamos el contador de procesados. $Procesados++ # Intentamos obtener el usuario. $Usuario = New-Object ` System.DirectoryServices.DirectoryEntry($Ruta) # Si el nombre es nulo, significa que no se ha podido obtener el # usuario If($Usuario.Name -eq $null) { # Si hay que mostrar información, mostramos el error. If($Info) { Write-Host -ForegroundColor Red -BackgroundColor Black ` "No se ha podido obtener el usuario $($Ruta.SubString(7,$Ruta.Length - 7))" } # Incrementamos el contador de no encontrados. $NoEcontrados++ # Si hay que omitir la devolución booleana la omitimos. If($NoBoolean) { $Return } Else { Return $false } } } # Si el tipo de usuario es DirectoryEntry lo asignamos directamente, ya # que es el tipo que utiliza la función para realizar el cambio de # nombre "DirectoryEntry" { $Usuario = $User $Procesados++ } # Si se ha recibido otro tipo distinto de los tres anteriores se sale # de la función con false y se muestra un mensaje indicando que no está # soportado Default { # Incrementamos los contadores de procesados y de fracasos. $Procesados++ $Fracasos++ # Si hay que mostrar información, mostramos el error. If($Info) { Write-Host -ForegroundColor Red -BackgroundColor Black ` "El tipo $($Tipo.FullName) no está soportado como parámetro User" } # Si hay que omitir la devolución booleana la omitimos. If($NoBoolean) { $Return } Else { Return $false } } } # Intentamos obtener el contenedor en el que está el usuario Try { $OU = $Usuario.PsBase.Get_Parent() } # Si no se ha podido obtener el contenedor, se sale de la función Catch { # Si hay que mostrar información, mostramos el error. If($Info) { Write-Host -ForegroundColor Red -BackgroundColor Black ` "Error al obtener el contenedor de $($User.distinguishedName)" } # Incrementamos el contador de no encontrados. $NoEncontrados++ # Si hay que omitir la devolución booleana la omitimos. If($NoBoolean) { $Return } Else { Return $false } } # Una vez tenemos el usuario vamos a obtener el resultado de aplicar el caso # a su nombre Switch($Case) { # Mayúsculas "ToUpper" { $Nombre = ([string]$Usuario.Name).ToUpper() } # Minúsculas "ToLower" { $Nombre = ([string]$Usuario.Name).ToLower() } # Titular "ToTitle" { $Nombre = (Get-Culture).TextInfo.ToTitleCase(` ([string]$Usuario.Name).ToLower()) } } # Intentamos renombrar al usuario (realmente esto implica moverlo, dado que # está cambiando el RDN). Try { $Usuario.PsBase.MoveTo($OU,"CN=$Nombre") } # Si se produce error se sale de la función devolviendo False. Catch { # Incrementamos el contador de fracasos. $Fracasos++ # Si hay que mostrar información, mostramos el error. If($Info) { Write-Host -ForegroundColor Red -BackgroundColor Black ` "Error al intentar renombrar $($Usuario.Name) como $Nombre" Write-Host $Error[0] } # Si hay que omitir la devolución booleana la omitimos. If($NoBoolean) { $Return } Else { Return $false } } # Restauramos el comportamiento ante errores que no interrumpen. $Exitos++ # Si hay que mostrar información, mostramos el éxito. If($Info) { Write-Host -ForegroundColor Green -BackgroundColor DarkBlue ` "$($Usuario.Name)`: Cambiado con éxito" } # Todo ha ido bien, la función devuelve True. # Si hay que omitir la devolución booleana la omitimos. If($NoBoolean) { $Return } Else { Return $true } } End { # Restauramos el comportamiento ante errores que no interrumpen $ErrorActionPreference = $Accion # Si hay que mostrar información, mostramos el resumen. If($Info) { Write-Host Write-Host "Usuarios procesados : $Procesados" Write-Host "Usuarios no encontrados : $NoEncontrados" Write-Host "Usuarios cambiados con éxito : $Exitos" Write-Host "Usuarios que no se pudieron cambiar: $Fracasos" } } <# .SYNOPSIS Cambia el caso del nombre de un usuario. .DESCRIPTION Esta función permite cambiar el nombre (RelativeDistinguishedName o RDN) de un usuario de active directory para que cumpla con el caso recibido como parámetro. Los casos posibles son: - ToLower: todo minúsculas ("pi, filemon"). - ToUpper: todo mayúsculas ("PI, FILEMON"). - ToTitle (predeterminado): Primera letra de cada palabra mayúscula, el resto en minúsculas ("Pi, Filemon"). La función permite canalización, lo que hace que se puedan procesar en bloque varios usuarios. Además permite varios tipos de objeto para el parámetro de usuario (cadena, DirectoryEntry y SearchResult) lo junto con la canalización permite redireccionar, por ejemplo, un fichero de texto con los nombres distinguidos de los usuarios, uno por línea, a ser cambiados, o los resultados obtenidos con un objeto DirectorySearcher de una búsqueda LDAP de usuarios. .PARAMETER User Usuario al que se cambiará el nombre. Puede recibir tres tipos de objeto: - Cadena: en este caso se debe tratar del nombre distinguido de un usuario. - DirectoryEntry: en este caso se tratará de un objeto usuario directamente. - SearchResult: en este caso se trata de un objeto obtenido al realizar, con un objeto DirectorySearcher, una consulta LDAP de usuarios. Este parámetro permite canalización y los alias "U", "Usr" y "Usuario". .PARAMETER Case Caso que se establecerá en el nombre del usuario; los tipos son: - ToUpper: cambiará el nombre a todo mayúsculas. - ToLower: cambiará el nombre a todo minúsculas. - ToTitle: cambiará el nombre de forma que la primera letra de cada palabra sea mayúscula y las restantes minúsculas. Este es el caso predeterminado. .PARAMETER Info Presenta mensajes y resumen de ejecución. Este parámetro admite los alias "R" y "Resumen". .PARAMETER NoBoolean Evita la devolución booleana de la función. Este parámetro admite el alias "NB". .EXAMPLE PS C:\> Set-AdUserNameCase "cn=filemón pi,ou=Agentes,dc=tia,dc=org" True En este ejemplo se cambia "filemón pi" a "Filemón Pi". .EXAMPLE PS C:\> Set-AdUserNameCase "cn=filemón pi,ou=Agentes,dc=tia,dc=org" ToUpper True En este ejemplo se cambia "filemón pi" a "FILEMÓN PI". .EXAMPLE PS C:\> Set-AdUserNameCase -User "cn=filemón pi,ou=Agentes,dc=tia,dc=org" -Case ToUpper True En este ejemplo se cambia "filemón pi" a "FILEMÓN PI". .EXAMPLE PS C:\> Get-Content c:\listados\usrs_a_cambiar.txt | Set-AdUserNameCase En este ejemplo se cambia a título los nombres de los usuarios cuyos nombres distinguidos están contenidos, uno por línea, en el fichero de texto c:\listados\usrs_a_cambiar.txt. Se devolverá True en los éxitos y False en los fracasos. .EXAMPLE PS C:\>$OU = [ADSI] "LDAP://ou=Agentes,dc=tia,dc=org" PS C:\>$Busc = [System.DirectoryServices.DirectorySearcher]$OU PS C:\>$Busc.Filter = "(&(objectClass=user)(objectCategory=person))" PS C:\>$Busc.SearchScope = "Subtree" PS C:\>$Busc.FindAll()| Set-AdUserNameCase -Info -NB Cambia a título los nombres de los usuarios obtenidos al realizar una búsqueda de usuarios en la unidad organizativa ou=Agentes,dc=tia,dc=org y todas las contenidas en la misma. Se mostrará un resumen por pantalla y se omitirá la devolución Booleana. .INPUTS System.String, System.DirectoryServices.DirectoryEntry, System.DirectoryServices.SearchResult .OUTPUTS System.Boolean .LINK https://urpiano.wordpress.com .LINK http://freyes.svetlian.com .NOTES Author: Fernando Reyes López MS-MVP © Mayo de 2012 #> } Function Set-AdUserAttributeCase { [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$true,ValueFromPipeLine=$true,` HelpMessage="Usuario a ser cambiado.")] [Alias("U","Usuario")] $User, [Parameter(Position=1,` HelpMessage="Caso que se establecerá (ToUpper, ToLower o ToTitle).")] [ValidateSet("ToLower", "ToTitle", "ToUpper")] [System.String] $Case = "ToTitle", [parameter(` HelpMessage="Cambia todos los atributos del usuario, incluído el RDN.")] [Alias("A","Todo")] [Switch] $All, [parameter(HelpMessage="Cambia el RDN del usuario.")] [Alias("CN","Mover")] [Switch] $RDN, [parameter(` HelpMessage="Cambia todos los atributos de la pestaña General del usuario.")] [Alias("G")] [Switch] $General, [parameter(HelpMessage="Cambia el nombre propio del usuario.")] [Alias("Nombre","FirstName","FN")] [Switch] $givenName, [parameter(HelpMessage="Cambia las iniciales del usuario.")] [Alias("I","MN","Iniciales")] [Switch] $initials, [parameter(HelpMessage="Cambia los apellidos del usuario.")] [Alias("Apellidos","LastName")] [Switch] $sn, [parameter(HelpMessage="Cambia el nombre para mostrar del usuario.")] [Alias("MostrarComo","DN")] [Switch] $DisplayName, [parameter(HelpMessage="Cambia la descripción del usuario.")] [Alias("D","Descripcion")] [Switch] $Description, [parameter( HelpMessage="Cambia la oficina del usuario.")] [Alias("Office","Oficina","Off")] [Switch] $physicalDeliveryOfficeName, [parameter(` HelpMessage="Cambia todos los atributos de la pestaña Address del usuario.")] [Alias("Direccion","Add")] [Switch] $Address, [parameter(HelpMessage="Cambia la dirección del usuario.")] [Alias("Calle","Street")] [Switch] $streetAddress, [parameter(HelpMessage="Cambia el apartado de correos del usuario.")] [Alias("AppPostal")] [Switch] $postOfficeBox, [parameter(HelpMessage="Cambia la ciudad del usuario.")] [Alias("Ciudad","Locality")] [Switch] $City, [parameter(HelpMessage="Cambia la provincia del usuario.")] [Alias("Province","Provincia")] [Switch] $State, [parameter(HelpMessage="Cambia el código postal del usuario.")] [Alias("ZIP","CodigoPostal")] [Switch] $postalCode, [parameter(` HelpMessage="Cambia todos los atributos de la pestaña Organization del usuario.")] [Alias("Org","Organizacion")] [Switch] $Organization, [parameter(HelpMessage="Cambia el cargo del usuario.")] [Alias("Titulo","Cargo")] [Switch] $Title, [parameter(HelpMessage="Cambia el departamento del usuario.")] [Alias("Departamento")] [Switch] $Department, [parameter(HelpMessage="Cambia la compañía del usuario.")] [Switch] $Company ) # Bloque de inicio de la función, en el que se establece el comportamiento # ante errores que no detienen la ejecución para que sí lo hagan (permite # el uso de Try/Catch en este tipo de errores) y se inician las variables # de recuento del proceso Begin { # Almacenamos la acción ante errores que no provocan terminación. $AccionError = $ErrorActionPreference # Hacemos que los errores que no provocan terminación sí lo hagan. Esto # lo hacemos para que funcione Try/Catch con ellos. $ErrorActionPreference = "Stop" # Iniciamos los recuentos de usuarios procesados. En primer lugar los # usuarios procesados. $Procesados = 0 # El número de usuarios procesados con éxito. Significa que no se # produjeron errores, independientemente de si se realizaron cambios o # no. $Exitos = 0 # El número de usuarios procesados en los que se produjo algún error. $Fracasos = 0 # Número de usuarios recibidos que no se encontraron en Active # Directory. $NoEncontrados = 0 # Número de usuarios en los que no era necesario efectuar ningún cambio, # dado que el caso de sus atributos ya corresponde con el caso que se # desea establecer. $SinCambiosARealizar = 0 # Número total de usuarios en los que se efectuó algún cambio. $TotalCambiados = 0 # Volcamos los encabezados. "Usuario`tResultado" } # Bloque de proceso de usuario. Process { # Incrementamos el contador de procesados. $Procesados++ # Revisamos el tipo de origen que trae el usuario. En primer lugar si # se trata del objeto usuario en sí. If(($User.GetType()).Name -eq "DirectoryEntry") { # Asignamos el usuario directamente. $Usuario = $User } # Se mira si se trata de una cadena (se supone que es el nombre # distinguido del usuario) o un objeto SearchResult (obtenido al # efectuar una búsqueda con un objeto DirectorySearcher). ElseIf(($User.GetType()).Name -eq "String" -or ` ($User.GetType()).Name -eq "SearchResult") { If(($User.GetType()).Name -eq "String") { # Por si el usuario proviene de una canalización de cadenas, # ya sea de un array directamente o de un fichero de texto leído # con Get-Content, y el elemento actual es una cadena vacía, en # este If se saltará al siguiente elemento, sin tener en cuenta # este elemento en los recuentos. Para evitar el recuento del # elemento, se resta uno al contador de procesados. If([System.String]::IsNullOrEmpty($User.Trim(' '))) { $Procesados-- Return } # Si se trata de una cadena, establecemos como ruta LDAP del # objeto la cadena recibida con el identificador de protocolo # LDAP delante. $Ruta = "LDAP://$User" } Else { # Si se trata de un SearchResult, su propiedad Path ya trae la # ruta LDAP perfectamente montada, y por tanto la asignamos sin # más. $Ruta = $User.Path } # Obtendremos el usuario; por si hay errores lo haremos en un Try. Try { # Obtenemos el usuario. $Usuario = New-Object ` System.DirectoryServices.DirectoryEntry($Ruta) } Catch { # El usuario no se ha podido obtener. Incrementamos el número # de usuarios no encontrados. $NoEncontrados++ # Obtenemos el índice de último error. $Indice = $Error.Count -1 # Iniciamos el mensaje de error. $Mensaje = "" # Montamos el identificador del error en el mensaje. $Mensaje = "$($error[$Indice].FullyQualifiedErrorId) (" # Montamos el mensaje de error. $Mensaje = "$Mensaje$($error[$Indice].Message.ToString()))" # Montamos la salida del log. "$User`tNo Encontrado`: $Mensaje" # Vamos al siguiente usuario. Return } } # Iniciamos la booleana que registrará si se ha producido algún cambio. $HayCambios = $false # Iremos cambiando los atributos según pestaña de las propiedades del # objeto usuario en Active Directory Users and Computers. En todos los # atributos, sólo los cambiaremos si no presentan el caso que se desea # establecer (si se van a establecer mayúsculas y ya está está en # mayúsculas no se cambiarán). Para saber si se han producido cambios, # en el caso de que se produzca un cambio a continuación se pondrá a # $true la variable $HayCambios. # En primer lugar la pestaña general. Primero el atributo de nombre # propio. If($givenName -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.givenName) -eq $false)` -and ((Set-Case $Usuario.givenName $Case) -cne $Usuario.givenName)) { $Usuario.Put("givenName",(Set-Case $Usuario.givenName $Case)) $HayCambios = $true } # Ahora las iniciales If($initials -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.initials) -eq $false)` -and ((Set-Case $Usuario.initials $Case) -cne $Usuario.initials)) { $Usuario.Put("initials",(Set-Case $Usuario.initials $Case)) $HayCambios = $true } # Ahora los apellidos If($sn -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.sn) -eq $false)` -and ((Set-Case $Usuario.sn $Case) -cne $Usuario.sn)) { $Usuario.Put("sn",(Set-Case $Usuario.sn $Case)) $HayCambios = $true } # Ahora el nombre para mostrar If($DisplayName -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.displayName) -eq $false)` -and ((Set-Case $Usuario.displayName $Case) -cne $Usuario.displayName)) { $Usuario.Put("displayName",(Set-Case $Usuario.displayName $Case)) $HayCambios = $true } # Ahora la descripción If($Description -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.Description) -eq $false)` -and ((Set-Case $Usuario.Description $Case) -cne $Usuario.Description)) { $Usuario.Put("Description",(Set-Case $Usuario.Description $Case)) $HayCambios = $true } # Ahora la oficina If($physicalDeliveryOfficeName -or $All -or $General ` -and ([string]::IsNullOrEmpty($Usuario.physicalDeliveryOfficeName) ` -eq $false)` -and ((Set-Case $Usuario.physicalDeliveryOfficeName $Case) -cne ` $Usuario.physicalDeliveryOfficeName)) { $Usuario.Put("physicalDeliveryOfficeName", ` (Set-Case $Usuario.physicalDeliveryOfficeName $Case)) $HayCambios = $true } # Ahora se procesan las propiedades de la pestaña Address. En primer # lugar la calle If($streetAddress -or $All -or $Address ` -and ([string]::IsNullOrEmpty($Usuario.streetAddress) -eq $false)` -and ((Set-Case $Usuario.streetAddress $Case) -cne ` $Usuario.streetAddress)) { $Usuario.Put("streetAddress", ` (Set-Case $Usuario.streetAddress $Case)) $HayCambios = $true } # Ahora el apartado de correos If($postOfficeBox -or $All -or $Address ` -and ([string]::IsNullOrEmpty($Usuario.postOfficeBox) -eq $false)` -and ((Set-Case $Usuario.postOfficeBox $Case) -cne ` $Usuario.postOfficeBox)) { $Usuario.Put("postOfficeBox", ` (Set-Case $Usuario.postOfficeBox $Case)) $HayCambios = $true } # Ahora la ciudad If($City -or $All -or $Address ` -and ([string]::IsNullOrEmpty($Usuario.l) -eq $false)` -and ((Set-Case $Usuario.l $Case) -cne $Usuario.l)) { $Usuario.Put("l",(Set-Case $Usuario.l $Case)) $HayCambios = $true } # Ahora el estado/provincia If($State -or $All -or $Address ` -and ([string]::IsNullOrEmpty($Usuario.st) -eq $false)` -and ((Set-Case $Usuario.st $Case) -cne $Usuario.st)) { $Usuario.Put("st",(Set-Case $Usuario.st $Case)) $HayCambios = $true } # Ahora el código postal If($postalCode -or $All -or $Address ` -and ([string]::IsNullOrEmpty($Usuario.postalCode) -eq $false)` -and ((Set-Case $Usuario.postalCode $Case) -cne $Usuario.postalCode)) { $Usuario.Put("postalCode",(Set-Case $Usuario.postalCode $Case)) $HayCambios = $true } # Ahora se procesan las propiedades de la pestaña Organization. En # primer lugar el título If($Title -or $All -or $Organization ` -and ([string]::IsNullOrEmpty($Usuario.title) -eq $false)` -and ((Set-Case $Usuario.title $Case) -cne $Usuario.title)) { $Usuario.Put("title",(Set-Case $Usuario.title $Case)) $HayCambios = $true } # Ahora el departamento If($Department -or $All -or $Organization ` -and ([string]::IsNullOrEmpty($Usuario.department) -eq $false)` -and ((Set-Case $Usuario.department $Case) -cne $Usuario.department)) { $Usuario.Put("department",(Set-Case $Usuario.department $Case)) $HayCambios = $true } # Por último la compañía If($Company -or $All -or $Organization ` -and ([string]::IsNullOrEmpty($Usuario.company) -eq $false)` -and ((Set-Case $Usuario.company $Case) -cne $Usuario.company)) { $Usuario.Put("company",(Set-Case $Usuario.company $Case)) $HayCambios = $true } # Se realizarán los cambios si es que se han producido. También se # entrará en este If si hay que cambiar el RDN y no es el actual igual # al resultante de aplicar el caso establecido. If($HayCambios -or (($All -or $RDN) -and ` ((Set-Case $Usuario.Name -Case $Case) -cne $Usuario.Name))) { # Tanto el guardar los cambios producidos hasta ahora como el cambio # del RDN los haremos en un Try/Catch. Try { # Con esta booleana controlaremos si se han producido cambios. $Control = $false # Si se han producido cambios en los atributos, los guardamos If($HayCambios) { $Usuario.SetInfo() # Marcamos que ha habido cambios. $Control = $true } # Si hay que cambiar el RDN. If(($All -or $RDN) -and ` ((Set-Case $Usuario.Name -Case $Case) -cne $Usuario.Name)) { # Cambiamos el RDN llamando a la función correspondiente, # enviando la devolución de la misma al limbo :-) Set-AdUserNameCase $Usuario -NoBoolean -Case $Case # Marcamos que ha habido cambios. $Control = $true } # Como todo ha ido bien incrementamos el contador de éxitos. $Exitos++ # Si se ha producido algún cambio. If($Control) { # Incrementamos el contador de usuarios cambiados $TotalCambiados++ # Volcamos el resultado "$($Usuario.Name)`tCambiado" } # Si no se han producido cambios. Else { # Incrementamos el contador de usuarios que no requerían # cambios. $SinCambiosARealizar++ # Volcamos el resultado. "$($Usuario.Name)`tNo Había cambios" } } # Si se produce error. Catch { # Incrementamos el contador de fracasos. $Fracasos++ # Obtenemos el índice del último error. $Indice = $Error.Count -1 # Iniciamos el mensaje de error. $Mensaje = "" # Ponemos el identificador de error en el mensaje. $Mensaje = "$($Error[$Indice].FullyQualifiedErrorId) (" # Si hay mensaje en el error, lo agregamos al mensaje. If($Error[$Indice].Message -ne $null) { $Mensaje = "$Mensaje$($Error[$Indice].Message.ToString()))" } # si no hay mensajer en el error, terminamos el mensaje. Else { $Mensaje = "$Mensaje)" } # Volcamos la información en el log. "$($Usuario.Name)`tNo Cambiado`: $Mensaje" } } # El usuario no tenía cambios que ser realizados. Else { # Incrementamos el contador de usuario que no debían ser cambiados. $SinCambiosARealizar++ # Incrementamos el contador de usuarios procesados sin errores. $Exitos++ # Volcamos la información en el log. "$($Usuario.Name)`tNo Había cambios" } } End { # Restauramos la acción ante errores que no interrumpen $ErrorActionPreference = $AccionError # Mostramos los recuentos si se ha procesado al menos un usuario. If($Procesados -gt 0) { # Mensaje de procesados si hay más de uno. If($Procesados -gt 1) { Write-Host "Procesados $Procesados usuarios" } # Mensaje de procesados si sólo hay uno. Else { Write-Host "Procesado $Procesados usuario" } } # No se han procesado usuario, se muestra el mensaje correspondiente. Else { Write-Host "No se han procesado ningún usuario" Break } # Si no se han encontrado más de un usuario, se muestra el mensaje # correspondiente. If($NoEncontrados -gt 1) { Write-Host "$NoEncontrados usuarios no se pudieron encontrar" } # Si no se ha encontrado un usuario, se muestra el mensaje # correspondiente. ElseIf($NoEncontrados -eq 1) { Write-Host "$NoEncontrados usuario no se pudo encontrar" } # Si se han encontrado todos los usuarios, se muestra el mensaje # correspondiente. Else { Write-Host "Todos los usuarios se pudieron encontrar" } # Si se ha procesado sin errores más de un usuario, se muestra el # mensaje correspondiente. If($Exitos -gt 1) { Write-Host "$Exitos usuarios procesados con éxito" } # Si se ha procesado sin errores un usuario, se muestra el mensaje # correspondiente. ElseIf($Exitos -eq 1) { Write-Host "$Exitos usuario procesado con éxito" } # Si no hay usuarios procesados sin errores, se muestra el mensaje # correspondiente. Else { Write-Host "Ningún usuario se ha procesado con éxito" } # Si se ha procesado con errores más de un usuario, se muestra el # mensaje correspondiente. If($Fracasos -gt 1) { Write-Host "$Fracasos usuarios no se pudieron cambiar" } # Si se ha procesado con errores un usuario, se muestra el mensaje # correspondiente. ElseIf($Fracasos -eq 1) { Write-Host "$Fracasos usuario no se pudo cambiar" } # Si no hay usuarios procesados con errores, se muestra el mensaje # correspondiente. Else { Write-Host "No falló el cambio de ningún usuario" } # Si se han cambiado más de un usuario, se muestra el mensaje # correspondiente. If($TotalCambiados -gt 1) { Write-Host "$TotalCambiados usuarios cambiados" } # Si se ha cambiado sólo un usuario, se muestra el mensaje # correspondiente. ElseIf($TotalCambiados -eq 1) { Write-Host "$TotalCambiados usuario cambiados" } # Si ningún usuario se ha cambiado, se muestra el mensaje # correspondiente. Else { Write-Host "Ningún usuario se ha cambiado" } # Si no requería cambios más de un usuario, se muestra el mensaje # correspondiente. If($SinCambiosARealizar -gt 1) { Write-Host "$SinCambiosARealizar usuarios no tenían cambios que realizar" } # Si no requería cambios un solo usuario, se muestra el mensaje # correspondiente. ElseIf($SinCambiosARealizar -eq 1) { Write-Host "$SinCambiosARealizar usuario no tenía cambios que realizar" } # Si todos los usuarios requerían cambios, se muestra el mensaje # correspondiente. Else { Write-Host "Ningún usuario no tenía cambios que realizar" } } <# .SYNOPSIS Cambia el caso de atributos de un usuario de Active Directory. .DESCRIPTION Esta función permite cambiar el caso de determinados atributos de Active Directory. Un conjunto de switches permiten establecer qué cambios se producirán. Estos Switches permiten establecer que se cambien todos los atributos, sólo los de determinada pestaña de las propiedades del usuario o sólo un atributo en concreto. No son excluyentes uno de otro, si no al contrario, son acumulativos, lo que permite establecer con exactitud qué atributos se cambiarán. Las pestañas de las propiedades del usuario que se pueden establecer y sus atributos correspondientes son: - General: Nombre propio, iniciales, apellidos, nombre para mostrar, descripción y oficina. - Address: Dirección (calle), apartado de correos, ciudad, estado y código postal. - Organization: Cargo, departamento y compañía. Aparte de los anteriores atributos, se puede también cambiar el nombre del objeto usuario (esto es moverlo, pues cambia su RDN y por tanto su nombre distinguido) con el switch -RDN. La función permite tres tipos de objetos de entrada: - String: en este caso se está recibiendo una cadena con el nombre distinguido del usuario. - DirectoryEntry: en este caso se está recibiendo el objeto usuario directamente. - SearchResult: en este caso se está recibiendo el resultado de una búsqueda realizada con un objeto DirectorySearcher. La función admite canalización, lo que permite redireccionar un array de cadenas (cada elemento del array es el nombre distinguido de un usuario), un fichero de texto (leído con Get-Content) con un nombre distinguido por línea, una colección de objetos DirectoryEntry de usuario o la devolución del método FindAll de un objeto DirectorySearcher, procesándose todos los usuarios implicados. .PARAMETER User Nombre distinguido, objeto DirectoryEntry de usuario u objeto SearchResult de usuario del usuario a ser cambiado. Este parámetro admite los alias "U" y "Usuario". .PARAMETER Case Caso que se establecerá. Puede ser ToUpper (todo mayúsculas), ToLower (todo minúsculas) o ToTitle (primera letra de cada palabra mayúscula y el resto minúsculas). Si se omite se asume ToTitle. .PARAMETER All Si se pasa este modificador, todos los atributos son cambiados, así como el RDN del usuario. Este parámetro admite los alias "A" y "Todo". .PARAMETER RDN Si se pasa este modificador, se cambia el RDN del usuario (esto implica mover el usuario, pues cambia su nombre distinguido). Este parámetro admite los alias "CN" y "Mover". .PARAMETER General Si se pasa este modificador, todos los atributos de la pestaña General de las propiedades del usuario son cambiados. Este parámetro admite el alias "G". Los atributos afectados son Nombre propio, Iniciales, Apellidos, Nombre para mostrar, Descripción y Oficina. .PARAMETER givenName Si se pasa este modificador, se cambia el nombre propio del usuario. Este parámetro admite los alias "Nombre", "FirstName" y "FN". .PARAMETER initials Si se pasa este modificador, se cambian las iniciales del usuario. Este parámetro admite los alias "I", "MN" e "Iniciales". .PARAMETER sn Si se pasa este modificador, se cambian los apellidos del usuario. Este parámetro admite los alias "Apellidos" y "LastName". .PARAMETER DisplayName Si se pasa este modificador, se cambia el nombre para mostrar del usuario. Este parámetro admite los alias "MostrarComo" y "DN". .PARAMETER Description Si se pasa este modificador, se cambia la descripción del usuario. Este parámetro admite los alias "D" y "Descripcion". .PARAMETER physicalDeliveryOfficeName Si se pasa este modificador, se cambia la oficina del usuario. Este parámetro admite los alias "Office", "Oficina" y "Off". .PARAMETER Address Si se pasa este modificador, todos los atributos de la pestaña Address de las propiedades del usuario son cambiados. Este parámetro admite los alias "Direccion" y "Add". Los atributos implicados son Calle, Apartado de correos, Ciudad, Estado/Provincia y Código postal .PARAMETER streetAddress Si se pasa este modificador, se cambia la dirección del usuario. Este parámetro admite los alias "Calle" y "Street". .PARAMETER postOfficeBox Si se pasa este modificador, se cambia el apartado de correos del usuario. Este parámetro admite el alias "AppPostal". .PARAMETER City Si se pasa este modificador, se cambia la ciudad del usuario. Este parámetro admite los alias "Ciudad" y "Locality". .PARAMETER State Si se pasa este modificador, se cambia la provincia del usuario. Este parámetro admite los alias "Province" y "Provincia". .PARAMETER postalCode Si se pasa este modificador, se cambia el código postal del usuario. Este parámetro admite los alias "ZIP" y "CodigoPostal". .PARAMETER Organization Si se pasa este modificador, todos los atributos de la pestaña Organization de las propiedades del usuario son cambiados. Este parámetro admite los alias "Org" y "Organizacion". Los atributos implicados son: cargo, departamento y compañía. .PARAMETER Title Si se pasa este modificador, se cambia el cargo del usuario. Este parámetro admite los alias "Titulo" y "Cargo". .PARAMETER Department Si se pasa este modificador, se cambia el departamento del usuario. Este parámetro admite el alias "Departamento". .PARAMETER Company Si se pasa este modificador, se cambia la compañía del usuario. .EXAMPLE PS C:\>$DN = 'cn=Mortadelo,ou=Agentes,dc=tia,dc=org' PS C:\>Set-AdUserAttributeCase -User $DN -All Cambia todos los atributos del usuario a caso tipo título. .EXAMPLE PS C:\>$DN = 'cn=Mortadelo,ou=Agentes,dc=tia,dc=org' PS C:\>Set-AdUserAttributeCase -User $DN -General -Case ToLower Cambia todos los atributos de la pestaña General del usuario a minúsculas. .EXAMPLE PS C:\>$Lista = 'c:\listados\usuarioscambiar.txt' PS C:\>Get-Content $Lista | Set-AdUserAttributeCase -General -Case ToLower Cambia a minúsculas todos los atributos de la pestaña General de los usuarios cuyos nombres distinguidos están contenidos en el fichero c:\listados\usuarioscambiar.txt, uno por línea. .EXAMPLE PS C:\>$OU = [ADSI] "LDAP://ou=Agentes,dc=tia,dc=org" PS C:\>$Busc = [System.DirectoryServices.DirectorySearcher]$OU PS C:\>$Busc.Filter = "(&(objectClass=user)(objectCategory=person))" PS C:\>$Busc.SearchScope = "Subtree" PS C:\>$Busc.FindAll()| Set-AdUserAttributeCase -G -Org Cambia a título todos los atributos de las pestañas General y Organization de los usuarios obtenidos al realizar una búsqueda de usuarios en la unidad organizativa ou=Agentes,dc=tia,dc=org y todas las contenidas en la misma. .NOTES Author: Fernando Reyes López © 05/2012 .INPUTS System.String,System.DirectoryServices.DirectoryEntry, System.DirectoryServices.SearchResult .OUTPUTS System.String .LINK http://freyes.svetlian.com .LINK https://urpiano.wordpress.com #> }
John Ramirez said
Caballero mil gracias por la info yo solo requiero cambiar el Display Name que segmento del script necesito correr
urpiano said
Tienes que llamar al script pasándole el modificador -DisplayName
sergio said
solo quiero cambiar el IpPhone a los usuarios :)