Title: Message
 
Chris,
 
 Below is a script I wrote earlier for someone posting with the same question.  This script is basically designed to do profile redirection on a remote host, and is based on the assumption that the credentials identified will possess Administrative access to the target host, as well as to both the old and new domains.  It will also expect that WMI is installed and running on your NT 4.0 Domain Controller(s) you are using to identify the old user SID.  I'm currently adding the NTFS security changes necessary for the old profile to be used by the newly identified userid in the event the target user is not a local Administrator.  If you've got additional questions about this, just send them on.
 
NOTE: You can use the lCheck variable (set to 1) to do read-only comparisons of old and new profiles on remote hosts.
 
Hope this helps,
Richard
 
 
 
 
'__________________________________________________________________________________
 
' NAME:     PROFILE.VBS - Profile Redirection Script
'
' REVISION: v1.0   10.19.2002 (script created)
'
' PURPOSE:  When migrating workstations from one domain or forest to another, a new
'           profile is generated for a user, often resulting in the loss of custom
'           settings, legacy application configurations, and an overall look & feel
'           of the desktop.  By replacing the new profile path in the registry with
'           the profile path of the previous userid, a user can (with the correct
'           set of local privileges) continue to use their previous profile.
'
' HOW IT WORKS:
'
' 1. determine the string representations of both the old and new user identities
'    (SIDs) by retrieving the binary sids from both domains and converting them to
'    a string format (w/ WMI's Win32_Account class)
' 2. traverse the registry to SOFTWARE\Microsoft\Windows NT\CurrentVersion\
'    ProfileList\<old-string-sid-here> and retrieve the original ProfileImagePath
'    value (which is the path to the actual profile)
' 3. locate (or add) the new user profile with SOFTWARE\Microsoft\Windows NT\
'    CurrentVersion\ProfileList\<new-string-sid-here>, then modify or add the
'    ProfileImagePath value to include the old profile path you'd retrieved from
'    the previous call.
'
' CAVEATS:
'
' 1. You'll need to be an administrator on both domains, and on the target host,
'    in order to run this script.
' 2. Stored password data is not migrated, this was something I really haven't had
'    time to look into, but I believe that any stored mail/web passwords are linked
'    to the original user's SID.
' 3. Profile redirection can fail, but often just results in the creation of a new
'    profile.
' 4. This method of profile redirection on W2K is unsupported by MSFT.
'
' DISCLAIMER:
'
'  You have a royalty-free right to use, modify, reproduce and distribute this code
'  (and/or any modified version) in any way you find useful, with the agreement
'  that Richard Puckett provide no warranty, obligations or liability for this code.
'  If you reuse or modify this code, you must retain this copyright notice.
'
'
'                       copyright (C) 2002 Richard Puckett
'__________________________________________________________________________________
'__________________________________________________________________________________
 
'                        variables, declares & constants
'__________________________________________________________________________________
 
option explicit
'on error resume next
 
' declares
dim lRet, lCheck, lCompare, lReboot
dim strTarget, strWksUsr, strWksPwd
dim strOldPDC, strOldDom, strOldUsr, strOldAct, strOldPwd, strOldSid, strOldProf
dim strNewPDC, strNewDom, strNewUsr, strNewAct, strNewPwd, strNewSid, strNewProf
dim objRegistry, strRegPath, strProfKey, strProfValue
 
' constants
const HKEY_LOCAL_MACHINE = &H80000002
 
' default registry path
strRegPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
strProfValue = "ProfileImagePath"
 
' set these values to conform to your environment
 
' target workstation information
strTarget = "target_workstation_name"  ' target workstation name
strWksUsr = "userid (optional)"        ' workstation userid (blank for impersonation)
strWksPwd = "password (optional)"      ' workstation password (blank for impersonation)
 
' target userid information for old (existing) profile
strOldUsr = "target_userid"
strOldAct = "domain\userid (optional)" ' old domain userid (blank for impersonation)
strOldPwd = "password (optional)"      ' old domain password (blank for impersonation)
strOldPDC = "domain_controller_name"   ' old domain controller name
strOldDom = "domain_name"              ' old domain name
 
' target userid information for new profile
strNewUsr = "target_userid"
strNewAct = "domain\userid (optional)" ' new domain userid (blank for impersonation)
strNewPwd = "password (optional)"      ' new domain password (blank for impersonation)
strNewPDC = "domain_controller_name"   ' new domain controller name
strNewDom = "domain_name"              ' new domain
 
' read-only check and remote reboot options
lCheck = 1                             ' set to 1 for a read-only comparision
lReboot = 0                            ' set to 1 to reboot the target workstation
 

'_________________________________________________________________________________
'
'                                START SCRIPT
'_________________________________________________________________________________
 
wscript.echo "profile migration script started at " & Now & vbCRLF
 
' retrieve the string sid of the old userid from the previous account domain
wscript.echo "attempting to retrieve a SID for " & strOldUsr &  " on " & strOldDom & "..."
 
strOldSid = get_sid(strOldUsr, _
      strOldAct, _
   strOldPwd, _
   strOldDom, _
   strOldPDC)
 
wscript.echo " - the sid for " & strOldDom & "\" & strOldUsr & " is " & strOldSid
wscript.echo "checking for the existence of a profile for " & strOldUsr &  " on " & strTarget & "..."
 
' append the retrieve string sid the Registry profile key
strProfKey = strRegPath & "\" & strOldSid
 
' attempt to read the remote registry for the existing user profile path information
lRet = get_reg_val (strTarget, _
    strWksUsr, _
    strWksPwd, _
    strProfKey, _
    strProfValue, _
    strOldProf)
 
If lRet <> 0 Then
 If lRet = 2 Then
  ' the targeted existing profile path doesn't exist, barf and exit
  wscript.echo " - there does not appear to be a profile for " & strOldUsr &  _
      " on " & strTarget & vbCRLF & "Target Profile Key: " & strProfKey
  wscript.quit
 
 else
  ' some other error has occurred (most likely access-related), barf and exit
  wscript.echo " - error " & lRet & ": An error occurred attempting to access the profile for " & _
      strOldUsr &  " on " & strTarget & vbCRLF & "Target Profile Key: " & strProfKey
  wscript.quit
 
 end if
else
 ' successfully retrieved the first set of values, now start on the second
 wscript.echo " - successfully retrieved the profile path for " & strOldUsr & " on " & strTarget & _
     vbCRLF & "   (" & strOldProf & ")"
 
 wscript.echo "attempting to retrieve a SID for " & strNewUsr &  " on " & strNewDom & "..."
 
 ' attempt to retrieve the string sid of the new userid
 strNewSid = get_sid(strNewUsr, _
    strNewAct, _
    strNewPwd, _
    strNewDom, _
    strNewPDC)
 
 wscript.echo " - the sid for " & strNewDom & "\" & strNewUsr & " is " & strNewSid
 wscript.echo "checking for the existence of a profile for " & strNewUsr &  " on " & strTarget & "..."
 
 ' append the new string sid to the Registry profile key
 strProfKey = strRegPath & "\" & strNewSid
 
 ' attempt to read the remote registry for the new user profile path information, if present
 lRet = get_reg_val (strTarget, _
     strWksUsr, _
     strWksPwd, _
     strProfKey, _
     strProfValue, _
     strNewProf)
 

 If lRet = 0 Then
  wscript.echo " - successfully retrieved the profile path for " & strNewUsr & " on " & strTarget & _
      vbCRLF & "   (" & strNewProf & ")"  
 
  wscript.echo "comparing the two profiles..."
 
  ' do a string comparison of the two returned profile paths
  lCompare = StrComp(strOldProf, strNewProf, 1)
 
  If lCompare <> 0 Then
   ' if different, check to see if this is a read-only comparision, if not, reset the profile path
   wscript.echo " - the two specified User Profile paths are different:" _
      & vbCRLF & "   desired (old) profile path - " & strOldProf _
      & vbCRLF & "   current (new) profile path - " & strNewProf  
  
   ' read-only check if set to 1
   if lCheck = 1 then
    wscript.echo " - read-only value detected, exiting...."
    
    wscript.echo "exiting script..." 
    wscript.quit
 
   else
    wscript.echo "resetting the profile path for " & strNewUsr &  "to " & _
              strOldProf & " on " & strTarget & "..."
    
    ' attempt to write the existing profile path for the old userid to the new userid
    lRet = set_reg_val (strTarget, _
        strWksUsr, _
        strWksPwd, _
        strProfKey, _
        strProfValue, _
        strOldProf)   
    
    If lRet = 0 Then
     wscript.echo " - successfully reset the profile path for " & strNewUsr & " on " & _
            strTarget & " to " & strOldProf
 
     ' bounce the remote target host if set to 1
     if lReboot = 1 then
      wscript.echo "rebooting " & strTarget & "..."
      call bounce (strWksUsr, _
        strTarget, _
        strWksPwd)
     end if  
     
     wscript.echo "exiting script..." 
     wscript.quit
 
    else 
     ' some other error has occurred (most likely access-related), barf and exit
     wscript.echo " - error " & lRet & ": unable to reset the profile path for " & _
         strNewUsr & " on " & strTarget & " to " & strOldProf
     
     wscript.echo "exiting script..." 
     wscript.quit
 
    end if
   end if
  else
   ' no change required, exit
   wscript.echo " - the two specified User Profile paths are the same:" _
      & vbCRLF & "   desired (old) profile path - " & strOldProf _
      & vbCRLF & "   current (new) profile path - " & strNewProf  
   
   wscript.echo "exiting script..." 
   wscript.quit
 
  end if
 else
  if lRet = 2 Then
   ' 2 is an expected return for most new profiles, it often means a user hasn't logged on yet
   wscript.echo " - there does not appear to be a profile for " & strNewUsr &  _
       " on " & strTarget & vbCRLF & "   Target Profile Key: " & strProfKey
   
   ' if 1, read-only and exit
   if lCheck = 1 then
    wscript.echo " - read-only value detected, exiting...."
    
    wscript.echo "exiting script..." 
    wscript.quit
 
   else
    wscript.echo "creating a new profile key for " & strNewUsr & " on " & strTarget & "..." 
 
    ' attempt to create the new profile path key
    lRet = create_reg_key (strTarget, _
        strWksUsr, _
        strWksPwd, _
        strProfKey) 
 
    If lRet = 0 Then
     wscript.echo " - successfully created the profile key " & strProfKey & " for " & _
         strNewUsr & " on " & strTarget
 
     wscript.echo "resetting the profile path for " & strNewUsr &  " to " & _
         strOldProf & "..."
 
     ' attempt to set the profile path value for the new profile key
     lRet = set_reg_val (strTarget, _
         strWksUsr, _
         strWksPwd, _
         strProfKey, _
         strProfValue, _
         strOldProf)   
     
     If lRet = 0 Then
      wscript.echo " - successfully reset the profile path for " & strNewUsr & " on " & _
          strTarget & " to " & strOldProf
 
      ' reboot the host if set to 1
      if lReboot = 1 then
       wscript.echo "rebooting " & strTarget & "..."
       call bounce (strWksUsr, _
         strTarget, _
         strWksPwd)
      end if  
 
      wscript.echo "exiting script..."      
      wscript.quit
     
     else 
      ' some other error has occurred (most likely access-related), barf and exit
      wscript.echo " - error " & lRet & ": unable to reset the profile path for " & _
          strNewUsr & " on " & strTarget & " to " & strOldProf
      
      wscript.echo "exiting script..." 
      wscript.quit
 
     end if
    else  
     ' some other error has occurred (most likely access-related), barf and exit
     wscript.echo " - error " & lRet & ": unable to create the profile key " & strProfKey & _
         " for " & strNewUsr & " on " & strTarget
     
     wscript.echo "exiting script..." 
     wscript.quit
 
    end if
   end if
  else
   ' some other error has occurred (most likely access-related), barf and exit
   wscript.echo " - error " & lRet & ": An error occurred attempting to access the profile for " & _
       strNewUsr &  " on " & strTarget & vbCRLF & "   Target Profile Key: " & strProfKey
   
   wscript.echo "exiting script..." 
   wscript.quit
 
  end if
 end if
end if
 

wscript.quit
 

'__________________________________________________________________________________
 
'                                WMI Functions
'__________________________________________________________________________________
 

' Create a Registry key in HKEY_LOCAL_MACHINE
'__________________________________________________________________________________
'
function create_reg_key (strWksta, strUsr, strPwd, strRegKey)
'__________________________________________________________________________________
 
 dim objWbemLocator, objWmiCon, objReg, RetVal
 set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
 
 if len(strUsr) = 0 then 
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default")
 else
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default", _
      strUsr, _
      strPwd)
 
  objWmiCon.Security_.AuthenticationLevel = 2
 
 end if
 
 objWmiCon.Security_.ImpersonationLevel = 3
 
 Set objReg = objWmiCon.Get("StdRegProv")
 
 RetVal = objReg.CreateKey (HKEY_LOCAL_MACHINE, _
       strRegKey)
 
 create_reg_key = RetVal
 
 set objWbemLocator = Nothing
 set objWmiCon = Nothing
 set objReg = Nothing
 
end function
 
 
 
' Set a REG_EXPAND_SZ value in HKEY_LOCAL_MACHINE
'__________________________________________________________________________________
'
function set_reg_val (strWksta, strUsr, strPwd, strRegKey, strRegVal, strNewVal)
'__________________________________________________________________________________
 
 dim objWbemLocator, objWmiCon, objReg, RetVal
 set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
 
 if len(strUsr) = 0 then 
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default")
 else
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default", _
      strUsr, _
      strPwd)
 
  objWmiCon.Security_.AuthenticationLevel = 2
 
 end if
 
 objWmiCon.Security_.ImpersonationLevel = 3
 
 Set objReg = objWmiCon.Get("StdRegProv")
 
 RetVal = objReg.SetExpandedStringValue (HKEY_LOCAL_MACHINE, _
       strRegKey, _
       strRegVal, _
       strNewVal)
 
 set_reg_val = RetVal
 
 set objWbemLocator = Nothing
 set objWmiCon = Nothing
 set objReg = Nothing
 
end function
 
 
 
' Read a REG_EXPAND_SZ value from HKEY_LOCAL_MACHINE
'__________________________________________________________________________________
'
function get_reg_val (strWksta, strUsr, strPwd, strRegKey, strRegVal, strRegRet)
'__________________________________________________________________________________
 
 dim objWbemLocator, objWmiCon, objReg, RetVal
 set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
 
 if len(strUsr) = 0 then 
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default")
 else
  set objWmiCon = objwbemLocator.ConnectServer _
      (strWksta, _
      "root\default", _
      strUsr, _
      strPwd)
 
  objWmiCon.Security_.AuthenticationLevel = 2
 
 end if
 
 objWmiCon.Security_.ImpersonationLevel = 3
 
 Set objReg = objWmiCon.Get("StdRegProv")
 
 RetVal = objReg.GetExpandedStringValue (HKEY_LOCAL_MACHINE, _
       strRegKey, _
       strRegVal, _
       strRegRet)
 
 get_reg_val = RetVal
 
 set objWbemLocator = Nothing
 set objWmiCon = Nothing
 set objReg = Nothing
 
end function
 
 
 
' Retrieve a SID fror a user using a WQL Query with Win32_Account
'__________________________________________________________________________________
'
function get_sid (strAcct, strUsr, strPwd, strDom, strDC)
'__________________________________________________________________________________
 
 dim objWbemLocator, objWmiCon, objQuery, objSid, strQry
 set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
 
 strQry = "SELECT SID FROM Win32_Account WHERE Name = '" _
    & strAcct & _
    "' AND Domain = '" _
    & strDom & "'"
 
 if len(strUsr) = 0 then 
  set objWmiCon = objwbemLocator.ConnectServer _
      (strDC, _
      "root\cimv2")
 else
  set objWmiCon = objwbemLocator.ConnectServer _
      (strDC, _
      "root\cimv2", _
      strUsr, _
      strPwd)
 
  objWmiCon.Security_.AuthenticationLevel = 2
 
 end if
 
 objWmiCon.Security_.ImpersonationLevel = 3
 set objQuery = objWmiCon.ExecQuery(strQry, "WQL")
 
 for each objSid in objQuery
  get_sid = objSid.Sid
 next
 
 set objWbemLocator = Nothing
 set objWmiCon = Nothing
 set objQuery = Nothing
 set objSid = Nothing
 
end function
 
 
 
' Reboot a target workstation
'__________________________________________________________________________________
'
function bounce (strUsr, strPwd, strPC)
'__________________________________________________________________________________
 
 dim objWbemLocator, objWmiCon, objWMIos, objOS, strQry
 set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
 
 strQry = "SELECT * FROM Win32_OperatingSystem"
 
 if len(strUsr) = 0 then 
  set objWmiCon = objwbemLocator.ConnectServer _
      (strPC, _
      "root\cimv2")
 else
  set objWmiCon = objwbemLocator.ConnectServer _
      (strPC, _
      "root\cimv2", _
      strUsr, _
      strPwd)
 
  objWmiCon.Security_.AuthenticationLevel = 2
 
 end if
 
 objWmiCon.Security_.ImpersonationLevel = 3
 objWmiCon.Security_.Privileges.AddAsString ("SeRemoteShutdownPrivilege")
 
 set objWMIos = objWmiCon.ExecQuery(strQry)
 
 For Each objOS in objWMIos
  ObjOS.Reboot()
 Next
 
 set objWbemLocator = Nothing
 set objWmiCon = Nothing
 set objWMIos = Nothing
 set objOS = Nothing
 
end function
 
 
-----Original Message-----
From: cflesher [mailto:[EMAIL PROTECTED]]
Sent: Friday, October 25, 2002 3:52 PM
To: [EMAIL PROTECTED]
Subject: [ActiveDir] Profile question

First time postee, long time fan......
 
We are currently in the process of migrating users from NT4 domains to 2000. While most of the nodes are NT4 workstation, some are running 2000 workstation. My question is, once a user goes from connecting to an NT4 domain to a 2000 domain from a 2000 workstation, is there a scripting method to have the user use their old profile for their new logon. Obviously, one can copy profiles by hand. I'm looking for a way to automate this. Just looking for a few hints.....
 
Thanks.....
 
Chris Flesher
The University of Chicago
NSIT/DCS
1-773-834-8477
 

Reply via email to