forked from ForensiT/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Migrate-BySid.ps1
169 lines (114 loc) · 4.26 KB
/
Migrate-BySid.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Internal script variables DO NOT change
$Filter = $null
$LookupFile = $null
$Reboot = $false
######################################################################################################################
# Set your script variables here
# Uncomment the filter that you want to use
#$Filter = "LocalSids"
#$Filter = "DomainSids"
#$Filter = "AzureSids"
#If you are filtering by Domain SIDs, set the domain RID for your domain
#$DomainRID = "S-1-5-21-2010793018-3992016981"
# Set $PassByFolderName to $True to migrate using the profile folder name, or $False to migrate using the user Sid
# Note: Reserved for future use. Setting to $False is not currently supported.
$PassByFolderName = $True
# If you want to use a lookup file, specify that here
#$LookupFile = ".\Users.csv"
######################################################################################################################
# Functions
# The function requires the csv file to have a header: Oldname,NewName
function Get-NewNameFromLookupFile
{
param ([Parameter(Mandatory=$true)][string]$LookupFile, [Parameter(Mandatory=$true)][string]$OldName)
$Header = 'OldName', 'NewName'
$lookup = import-csv $lookupFile -Header $Header
ForEach ($row in $lookup){
if($($row.OldName) -eq $oldName)
{
return $($row.NewName)
break
}
}
}
######################################################################################################################
if($Filter -eq $null){
Write-Warning "You need to edit this script to configure your migration settings before it can be run."
exit
}
if(($Filter -eq "DomainSids") -and ($DomainRID -eq $null)){
Write-Warning "Domain RID has not been set."
exit
}
# We can filter local accounts by getting the SID for the Administrator account, and finding the RID
$AdminSID = (Get-LocalUser | Where-Object {$_.SID -like 'S-1-5-*-500'}).SID
$LocalMachineRID = $AdminSID.Value.subString(0, $AdminSID.Value.Length - 4)
#Enumerate profiles in the registry
$keys = Get-ChildItem -Path 'Registry::HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
foreach ($key in $keys) {
$sid = $key.PSChildName
# Filter out System SIDs and Administrator accounts
if(($sid.Length -eq 8) -Or ($sid -Like 'S-1-5-80-*') -Or ($sid -Like '*-500')){
continue
}
if($Filter -eq "LocalSids"){
# Filter on local accounts
if($sid -NotLike $LocalMachineRID +'*'){
continue
}
}
elseif($Filter -eq "DomainSids"){
# Filter on domain RID
if($sid -NotLike $DomainRID +'*'){
continue
}
}
elseif($Filter -eq "AzureSids"){
# Filter on Azure SIDs
if($sid -NotLike 'S-1-12-*'){
continue
}
}
# Get the profile folder name
$profileImagePath = (Get-ItemProperty -Path Registry::$key).ProfileImagePath
$profileName = Split-Path $profileImagePath -leaf
if($PassByFolderName -eq $True){
$SourceAccount = $profileName
}
else{
$SourceAccount = $Sid
}
# Remove any suffix from the folder name
$_Temp = $profileName.split(".")
if(-Not $_Temp[0] -eq ""){
$LookupName = $_Temp[0]
}
else{
$LookupName = $profileName
}
# Get new user name if we are using a lookup file
$newUserName = $null
if($LookupFile -ne $null){
$newUserName = Get-NewNameFromLookupFile $LookupFile $LookupName
}
# If we don't have a new name, use the current name
if($newUserName -eq $null){
$newUserName = $LookupName
}
# Call Profwiz.exe...
$profwiz = Start-Process -FilePath "./Profwiz.exe" -ArgumentList "/SOURCEPROFILE $SourceAccount /TARGETACCOUNT $newUserName /NOREBOOT" -wait -PassThru
#... and wait for it to finish
$profwiz.WaitForExit();
# If there is an error print it
if ($profwiz.ExitCode -ne 0) {
Write-Warning "$_ exited with status code $($profwiz.ExitCode)"
}
else{
$Reboot = $true
}
}
#Reboot the machine
if($Reboot -eq $true){
Restart-Computer
}