Mark,
Below is a script I wrote last year as sort of a WMI
proof-of-concept/learning experience that performs user profile redirection.
It points a new userid (in this case, a migrated user in Active Directory)
to an existing profile (their previous profile) on the same host. This may
not be exactly what you are looking for, but many of the functions in this
script can be used to direct a user's profile path at an alternate location.
You might also consider populating the 'profile' attribute on the user
object itself (using IADsUser in ADSI), if you were considering pointing the
user at a custom location for profile information.
Hope this helps,
Richard
### BEGIN CODE ###
'___________________________________________________________________________
_______
' NAME: PROFILE.VBS - Profile Redirection Script
'
' REVISION: v1.0 10.18.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 currently 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 for 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
### END CODE ###
>
>
> -----Original Message-----
> From: Abbiss, Mark [mailto:[EMAIL PROTECTED]]
> Sent: Monday, January 27, 2003 9:53 AM
> To: '[EMAIL PROTECTED]'
>
> Dear All,
>
> We are about to embark on a phased migration of our users
> from NT to W2K. We have a useful little program (SecureCopy)
> that is excellent at moving files, folders, permissions etc
> into the new domain but would now like to find a method,
> other than doing it by hand, to modify the path to the
> home/profile directories for the users being migrated.
>
> Does any one know of a (preferably free) tool/script that can
> help us do this ?
>
> Many thanks,
>
> Mark Abbiss
> List info : http://www.activedir.org/mail_list.htm
> List FAQ : http://www.activedir.org/list_faq.htm
> List archive:
> http://www.mail-archive.com/activedir%40mail.activedir.org/
>
List info : http://www.activedir.org/mail_list.htm
List FAQ : http://www.activedir.org/list_faq.htm
List archive: http://www.mail-archive.com/activedir%40mail.activedir.org/