Powershell: Local Profile to Domain Profile Migrator
This script is an exemple how a migration from a Novell Profile or Local Profile to a Domain Profile with Powershell could work
does only work on Windows XP/Windows7
The user should be a member of the local admins to run this script without error.
Novell: Don´t forgett to disable Dynamic Local User on the Workstation you wish to migrate
The Script does the following
1.) Get the new SID of the Domain-User
2.) Grant Fullaccess to the logged on User Registry Hive
3.) Grant Fullaccess to the logged on User Profile
4.) copy the Profile Mapping and change the SID
Now you can Join the Computer to the Domain and for the User everything seems to be like before.
#Const cls $ErrorActionPreference = "SilentlyContinue" $LDAPServer ="192.168.178.165" #Domain Controller $User="browse@mydomain.de" #User $Pass='BrowseUser1' #Pass #MAIN function main (){ $MProfiles = LocalProfile #Call Function to get all local Profile´s on the local machine foreach ($MProfile in $MProfiles){ if ($MProfile.User -like ""){ #The Username is needed to get the SID from the Domain, If empty continue with next User write-host "User empty, next..." -ForegroundColor Red continue } "Local User $($MProfile.User)" "ProfilePath $($MProfile.Profilepath)" "Local SID $($MProfile.SID)" $NewSID = Find-User $MProfile.User.Split("\")[1] #Call Function to Find User at the Active Directory "Domain SID $($NewSID[1].value)" if ($MProfile.User.Split("\")[1] -match $env:USER){ #The Script runs in the local User Context, so the Script only continues if the ADS User match with the local User "Set Domain SID on UserHive" $HiveACL = Get-Acl HKCU:\ $ACE_Hive = New-Object System.Security.AccessControl.RegistryAccessRule ($NewSID[1],'FullControl',('ContainerInherit','ObjectInherit'),'None','Allow') $HiveACL.AddAccessRule($ACE_Hive) set-acl HKCU:\ $HiveACL "Change Owner to $($env:USERNAME)" $ProfileACL = Get-acl $MProfile.Profilepath $Owner = New-Object system.Security.Principal.NTAccount($env:USERNAME) $profileACL.setowner($Owner) set-acl $MProfile.Profilepath $profileACL "Set Domain SID on Profile-Data" $ProfileACL = Get-acl $MProfile.Profilepath $ACE_Profile = New-Object System.Security.AccessControl.FileSystemAccessRule ($NewSID[1],'FullControl',('ContainerInherit','ObjectInherit'),'None','Allow') $ProfileACL.AddAccessRule($ACE_Profile) Set-Acl $MProfile.Profilepath $ProfileACL "Create new Profile Mapping" copy-item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$($MProfile.SID)" "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$($NewSID[1].value)" set-Itemproperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$($NewSID.value)" -Name Sid -Value $NewSID[0] } else {"User not logged in, exiting"} } } #Functions function Find-User ($user2find){ $domain = New-Object directoryservices.directoryentry("LDAP://$LDAPServer",$User,$Pass) $searcher = New-Object system.directoryservices.directorysearcher $searcher.Searchroot = $domain $searcher.filter = "(&(objectClass=user)(sAMAccountName=$user2find))" $result = $searcher.Findall() $sidbinary= $result.properties.objectsid[0] $sid = (new-object System.Security.Principal.SecurityIdentifier($sidbinary,0)) return $sidbinary,$sid } function LocalProfile{ $ArrayProfile = @() $profiles = gci "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | where {$_.Name -match "S-1-5-21"} foreach ($profile in $profiles){ $Path = Get-ItemProperty $profile.Name.replace("HKEY_LOCAL_MACHINE","HKLM:") $objSID = New-Object System.Security.Principal.SecurityIdentifier ($profile.PSChildName) $objUser=$objSID.Translate([System.Security.Principal.NTAccount]) $Array = New-Object -TypeName PSObject $Array | Add-Member -Type NoteProperty -Name User -Value $objUser.Value $Array | Add-Member -Type NoteProperty -Name ProfilePath -Value $Path.ProfileImagePath $Array | Add-Member -Type NoteProperty -Name SID -Value $profile.PSChildName $ArrayProfile += $Array } return $ArrayProfile } #Call MAIN Function main