Powershell: Local Profile to Domain Profile Migrator

Posted on: August 13, 2014 Posted by: Philipp Comments: 0

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