Inicio Cuenta Buscar
Migración de Perfiles de usuario en Windows Vista

Cuando proponemos un cambio de dominio dentro del plan de migración encontramos distintas tareas que acometer y la complejidad de cada una de ellas.

La migración de perfiles, evitando pérdidas de información y configuración de los usuarios es uno de los hitos que normalmente son más costosos de acometer. Este script que os propongo ha sido probado y utilizado para realizar las copia de perfiles para usuarios que han sido migrados de dominio. Este método necesita de 3 a 10 segundos por perfil (en función de la máquina en la que lo realicemos).

El script espera como argumentos el nombre de los dominios afectados, origen y destino.

Primero busca en el registro que perfiles tiene creados en la máquina identificando el SID de cada uno de ellos. Por cada SID se realiza la consulta para determinar si el SID encontrado pertenece a un usuario del dominio origen y de ser así, buscaremos el SID del usuario en el dominio destino\usuario.

Si el usuario existe en el dominio destino conseguiremos su SID y lo aplicaremos al perfil. De esta forma realizamos la migración de perfiles en un simple paso.

Este script se puede publicar en la política de máquina usando una política de grupo, afectando a las máquinas de la correspondiente Unidad Organizativa. Mezclando este este script con otro para el cambio de membresía de dominio para la máquina realizará todo el trabajo para cada máquina en dos simples pasos.

NOTA: Para poder usar este script es necesario instalar un parche para añadir el proveedor WMI Win32_UserProfile. Este parche será añadido en el Service Pack 1, previo Service Pack podemos instalar el parche para añadir esta funcionalidad.

Os dejo el enlace a la Knowledge Base de Microsoft en el que habla de esta nueva funcionalidad http://support.microsoft.com/kb/930955/es-es.

Option Explicit

On Error Resume Next

Dim sComputer, oWMI, oRegistry, sRegistryPath, arrKeys, sSubKey, sKey, sSubPath
Dim sValue, oAccountSID, sDomainOld, sDomainNew, sUser, oAccountOld, oAccountNew
Dim sSIDOld, sSIDNew

Const HKEY_LOCAL_MACHINE = &H80000002

'''''''''''''''''''''''''''''''''''''''''''''''''''
sComputer = "."

If WScript.Arguments.Count <> 2 Then
 WScript.Echo "Error: perfiles.vbs <dominio antiguo> <dominio nuevo>"
 WScript.Quit
Else
 sDomainOld = UCase(WScript.Arguments(0))
 sDomainNew = UCase(WScript.Arguments(1))
 WScript.Echo "Domain Origen: " & sDomainOld
 WScript.Echo "Dominio Destino: " & sDomainNew
 WScript.Echo "--"
End If

'''''''''''''''''''''''''''''''''''''''''''''''''''

Set oWMI = GetObject("winmgmts:\\" & sComputer & "\root\cimv2")
Set oRegistry= GetObject("winmgmts:\\" & sComputer & "\root\default:StdRegProv")
 
sRegistryPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
oRegistry.EnumKey HKEY_LOCAL_MACHINE, sRegistryPath, arrKeys
 
For Each sSubkey In arrKeys

  sKey = "ProfileImagePath"
  sSubPath = sRegistryPath & "\" & sSubkey
  oRegistry.GetExpandedStringValue HKEY_LOCAL_MACHINE, sSubPath, sKey, sValue
   
 ' Buscamos el dominio y usuario en el registro 

 Set oAccountSID = oWMI.Get ("Win32_SID.SID='" & sSubkey &"'")
 WScript.Echo "Cuenta:" & Trim(oAccountSID.ReferencedDomainName) & "\" & _
  Trim(oAccountSID.AccountName) & _
  vbCrLf & "Perfil: " & sValue & _
  vbcrlf & "SID   : " & sSubKey

 ' si el dominio encontrado se corresponde con el dominio de referencia ....
 If Ucase(oAccountSID.ReferencedDomainName) = UCase(sDomainOld) Then

  sUser = oAccountSID.AccountName

  ' Obtenemos el objeto de usuario actual
  Set oAccountOld = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
         & sComputer & "\root\cimv2:Win32_UserAccount." _
         & "Domain='" & Trim(sDomainOld) & "',Name='" & Trim(sUser) & "'")   
  
  ' Obtenemos el objeto destino
  Set oAccountNew = oWMI.Get ("Win32_UserAccount.Name='" & sUser & _
   "',Domain='" & sDomainNew & "'")

  If Err.number <> 0 then
   ' Si el error es distinto de 0 significa que o no se ha podido conectar o que el usuario no existe en destino

   WScript.Echo  "RESULT : Not found on target domain."  & vbCrLf & "--"
   err.Clear
  Else
   ' SID de ambas cuentas
   sSIDOld = oAccountOld.SID
   sSIDNew = oAccountNew.SID

   ' Cambio de propietario
   Set oProfile = GetObject("winmgmts:\\" & sComputer & _
    "\root\CIMV2").Get("Win32_UserProfile.SID=""" & sSIDOld & """")
   Set oParameters = oProfile.Methods_("ChangeOwner").InParameters.SpawnInstance_()
      
   oParameters.Properties_.Item("Flags") = 0
   oParameters.Properties_.Item("NewOwnerSID") = sSIDNew
      
   Set oOutParams = GetObject("winmgmts:\\" & sComputer & _
    "\root\CIMV2").ExecMethod("Win32_UserProfile.SID=""" & _
    sSIDOld & """", "ChangeOwner", oParameters)

   If Err.number  <> 0 Then
    WScript.Echo "ERROR : Usuario " & sUser & ": " &  Err.Number & " - " & Err.Description
    Err.Clear
   Else
    WScript.Echo "RESULT : Usuario modificado."  & vbCrLf & "--"
   End If
 
  End If ' If Err.number <> 0 then
 Else
  WScript.Echo "RESULT : No se modificará." & vbCrLf & "--"
 
 End If ' If Ucase(oAccountSID.ReferencedDomainName) = UCase(sDomainOld) Then

Next

WScript.Echo vbcrlf & "--Script finalizado."

Bienvenidos a IT Scripting!

Después mucho tiempo haciendo scripts para administrar Windows diariamente, me he decidido a hacer mi pequeña aportación de información. Me gustaría que este blog os pueda ayudar y os resulte interesante volver.

Día a día es necesario realizar infinitas tareas y nuestro objetivo para ganar tiempo y eficacia es intentar empaquetarlas para que nos faciliten nuestro trabajo. Informes, búsquedas en visores de eventos, creación de usuarios, buzones de correo, mantenimiento de seguridad, monitorización de procesos... y un largo etcétera.

Durante este tiempo iré añadiendo los scripts que considere interesantes en VBScript y PowerShell. Utilizando WMI, componentes externos, ADSI y todos aquellos scripts que puedan ser útiles.