- Published on
User Home Profile and Redirected Folder Migration
- Authors
- Name
- Jackson Chen
#Requires -RunAsAdministrator
cls
# Import module
Import-Module ActiveDirectory
#******************************** List of Company Names ********************************
# LAB Company Name
$LAB_Company = "LAB"
# Other Companies
<# To be udpated #>
#***********************************************************************************
#******************************** List of Company File Servers ********************************
# LAB DFS File Servers
$LAB_DFS_fileserver = "PDC-LAB-FileSrv01"
$LAB_DFS_fileserver_replica = "SDC-LAB-FileSrv01"
# Other DFS File Servers
<# To be udpated #>
#******************************************************************************************
#******************************** List of Company Folder Redirected Folders ********************************
# LAB - User Redirected Folders
$LAB_ExistRedirectedFolders = "\\ExistingFileSrv01\E$\Data\Users\RedirectedFolders"
# Other Companies - User Redirected Folders
<# To be udpated #>
#***********************************************************************************
# Variables
$Date = Get-Date -Format "yyyy-MM-dd"
$timestamp = Get-Date -UFormat "%d/%m/%Y %R"
$datestamp = Get-Date -UFormat "%d/%m/%Y"
$Computer = $env:COMPUTERNAME
$Domain = "lab"
$DomainFQDN = "lab.net"
$LAB_User_Migration_List = "\\$Computer\D$\Inputs\LAB_User_Folder_migration_User_List\LAB_Folder_Migration_Users.csv"
$Report = "\\$Computer\D$\Logs\LAB_User_Folder_Migration_Reports\LAB-User-Folder-Migration-Report-$Date.txt"
# Company Users Home and Profile parent folders
$UsersHomePath = "E$\DATA\Home"
$UsersProfilePath = "F$\DATA\Profile"
#******************************************************
# Function: Create User Home and Profile Root Folders
#
# Purpose:
# Create user home and pofile root folders
#
#******************************************************
Function CreateUserHomeProfileRootFolders ([array]$folders, [string]$UserName) {
ForEach ($folder in $folders) {
# Create user home and profile root folders if not exist
If (!(Test-Path $folder)) {
Try {
Write-Host "Create user home and profile root folder: $folder"
New-Item -Path $folder -ItemType Directory -Force
Start-Sleep 2
# Update report
<#
TBA
#>
# Change owner to user
# Initial user creation does not change Owner to user
# Grant user Full permission
# Obtain the existing folder ACL
$Folder_ACL = Get-Acl -Path $folder
# Set FULL permission, and apply to "This folder, subfolders and files"
$Permissions = "$Domain\$UserName", 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
# Add the new FileSystemAccessRule to apply
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $Permissions
# Add the new ACL to the existing folder
$Folder_ACL.SetAccessRule($AccessRule)
# Apply the new ACL to the new folder
$Folder_ACL | Set-Acl -Path $folder -Confirm:$false
# Record update to log file
"`nSuccessfully create user root folder: $folder" | Add-Content $Report
"`nFolder permission update: $Domain\$RequiredUser has been granted Modify permission to $folderPath" | Add-Content $Report
}
Catch {
Write-Host "Failed to create user root folder: $folder" -ForegroundColor Red
# Update report
"`nFailed to create user root folder: $folder" | Add-Content $Report
}
}
}
}
#******************************************************
# Function: Create User Home and Profile Sub-Folders
#
# Purpose:
# Create sub-folders under user home and profile folder
# It will inherit the permission from parent folder
#
#******************************************************
Function CreateUserHomeProfileSubFolders ([array]$folders) {
ForEach ($folder in $folders) {
# Create user home and profile root folders if not exist
If (!(Test-Path $folder)) {
Try {
Write-Host "Create sub-folder: $folder"
New-Item -Path $folder -ItemType Directory -Force
"`nSuccessfully create sub-folder: $folder" | Add-Content $Report
}
Catch {
Write-Host "Fail to create user sub-folder: $folder" -ForegroundColor Red
"`nFail to create user sub-folder: $folder" | Add-Content $Report
}
}
}
}
#******************************************************
# Function: Migrate User Home Drive
#
# Purpose:
# Migrate user home drive to new Company file server
#
#******************************************************
Function MigrateUserHomeFolder ([string]$ExistHomeDir, [string]$NewHomeDir) {
Write-Host "Migrate user home drive`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistHomeDir'"
$DestPath = "'$NewHomeDir'"
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
# Using invoke-express to call robocopy
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user Home drive." | Add-Content $Report
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $Report
}
#******************************************************
# Function: Migrate User Profile Folders
#
# Purpose:
# Migrate user Profile V2 and V6 folders
#
#******************************************************
Function MigrateUserProfile ([string]$ExistProfileDir, [string]$NewProfileDir) {
Write-Host "Migrate user profile`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistProfileDir'"
$DestPath = "'$NewProfileDir'"
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user Profile." | Add-Content $Report
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $Report
}
#******************************************************
# Function: Migrate User Redirected Folders
#
# Purpose:
# Migrate user redirected folders
#
#******************************************************
Function MigrateUserRedirectedFolders ([string]$ExistingDir, [string]$NewDir) {
Write-Host "Migrate user redirected folders`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistingDir'"
$DestPath = "'$NewDir'"
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user redirected folder." | Add-Content $Report
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $Report
}
#******************************************************
# Function: Migrate User Home Sub-folder Redirected Folders
#
# Purpose:
# The following redirected folders are under Home drive
# Contacts
# Desktop
# Downloads
# Favorites
# Links
#
#******************************************************
Function MigrateUserHomeSubFolders ([array]$ExistSubFolders, [string]$NewRootDir) {
# Continue if user home drive exists
If (Test-Path -Path $NewRootDir) {
$NewContacts = $NewRootDir + '\' + 'Contacts'
$NewDesktop = $NewRootDir + '\' + 'Desktop'
$NewDownloads = $NewRootDir + '\' + 'Downloads'
$NewFavorites = $NewRootDir + '\' + 'Favorites'
$NewLinks = $NewRootDir + '\' + 'Links'
# Process each sub-folder
ForEach ($Subfolder in $ExistSubFolders) {
# Continue if the existing subfolder exists
If (Test-Path -Path $Subfolder) {
# Process Contacts folder
If ($Subfolder -like "*Contacts*") {
$DestPath = "'$NewContacts'"
Write-Host "Migrate Contacts" -ForegroundColor Green
}
# Process Desktop folder
ElseIf ($Subfolder -like "*Desktop*") {
$DestPath = "'$NewDesktop'"
Write-Host "Migrate Desktop" -ForegroundColor Green
}
# Process Downloads folder
ElseIf ($Subfolder -like "*Downloads*") {
$DestPath = "'$NewDownloads'"
Write-Host "Migrate Downloads" -ForegroundColor Green
}
# Process Favorites folder
ElseIf ($Subfolder -like "*Favorites*") {
$DestPath = "'$NewFavorites'"
Write-Host "Migrate Favorites" -ForegroundColor Green
}
# Process Links folder
ElseIf ($Subfolder -like "*Links*") {
$DestPath = "'$NewLinks'"
Write-Host "Migrate Links" -ForegroundColor Green
}
$SourcePath = $Subfolder
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath`n"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user redirected folder." | Add-Content $Report
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $Report
}
Else {
Write-Host "The existing redirected subfolder does not exist: $Subfolder" -ForegroundColor Yellow
}
}
}
Else {
Write-Host "The user new home drive does not exist: $NewRootDir" -ForegroundColor Red
}
}
#***************************************************************************
# Function: Migrate User My Documents Folder
#
# Purpose:
# Migrate user My Documents folder
#
# Excluding the exiting following folders in user My Documents directory
# My Music
# My Pictures
# My Vidoes
#***************************************************************************
Function MigrateUserMyDocuments ([string]$ExistingDir, [string]$NewDir) {
Write-Host "Migrate user My Documents`n" -ForegroundColor Yellow
$NewDocumentsPath = $NewDir + '\' + 'Documents'
# Source and destination path
$SourcePath = "'$ExistingDir'"
$DestPath = "'$NewDocumentsPath'"
$Options = "/S /E"
$ExcludeFolders = "'My *'"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options /XD $ExcludeFolders"
# Update log file
"`nSuccessfully migration user My Documents." | Add-Content $Report
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $Report
}
#***************************************************************************
# Function: Update User Home and Profile Active Directory Attributes
#
# Purpose:
# Update user home and profile path Active Directory attributes
#***************************************************************************
Function UpdateUserHomeProfileAttributes ([string]$RequiredUser, [string]$Companyname) {
$HomeDir = "\\$($DomainFQDN)\home\$($Companyname)\$($RequiredUser)"
$ProfileDir = "\\$($DomainFQDN)\profile\$($Companyname)\$($RequiredUser)\Profile"
Write-Host "Please wait... Update user Home and Profile path for user $RequiredUser`n" -ForegroundColor Yellow
Write-Host "`tThe new Home drive path: $HomeDir`n`tThe new Profile path: $ProfileDir"
Try {
Set-ADUser -Identity $RequiredUser -ProfilePath $ProfileDir
Set-ADUser -Identity $RequiredUser -HomeDirectory $HomeDir
Start-Sleep 10 # Wait for update to take effect
# Update log file
"`nSuccessfully update user Home and Profile path." | Add-Content $Report
"`nThe new Home drive path: $HomeDir`n`tThe new Profile path: $ProfileDir" | Add-Content $Report
}
Catch {
Write-Host "Not able to update user Home and Profile path." -ForegroundColor Red
"`nError: Failed to update user Home and Profile path." | Add-Content $Report
}
}
#**********************************************************
#
# Main
#
#**********************************************************
# Import LAB groups CSN file
$UsersInfo = Import-Csv $LAB_User_Migration_List
# Process if input user list file is not empty
If ($UsersInfo -ne $null) {
# Update log file
"`nMigrate User Home, Profile and Redirected Folders on $timestamp" | Add-Content $Report
"" | Add-Content $Report
# Process file security groups
ForEach ($Userinfo in $UsersInfo) {
$Company = $UserInfo.Company_name
$UserName = $UserInfo.User_Login_Name
# CSD Operations Section
If ($Company -like $LAB_Company) {
# Update file server to required Company file server
$FileServer = $LAB_DFS_fileserver
# User redirected folders
$RedirectedFoldersExisting = $LAB_ExistRedirectedFolders
}
<#
# TBA for other Company file servers
ElseIf {
# TBA
}
#>
# Update user home and folder folders according to Company file server
# Home drive and subfolders
$UserHomeRoot = '\\' + $FileServer + '\' + $UsersHomePath + '\' + $UserName
$UserContacts = $UserHomeRoot + '\' + 'Contacts'
$UserDesktop = $UserHomeRoot + '\' + 'Desktop'
$UserDocuments = $UserHomeRoot + '\' + 'Documents'
$UserDownloads = $UserHomeRoot + '\' + 'Downloads'
$UserFavorites = $UserHomeRoot + '\' + 'Favorites'
$UserLinks = $UserHomeRoot + '\' + 'Links'
$UserPictures = $UserHomeRoot + '\' + 'My Pictures'
$UserMusic = $UserHomeRoot + '\' + 'My Music'
$UserVidoes = $UserHomeRoot + '\' + 'My Videos'
# Profile folder and subfolders
# Profile.V2 & Profile.V6
$UserProfileRoot = '\\' + $FileServer + '\' + $UsersProfilePath + '\' + $UserName
$UserProfileV2 = $UserProfileRoot + '\' + 'Profile.V2'
$UserProfileV6 = $UserProfileRoot + '\' + 'Profile.V6'
$UserV2AppData = $UserProfileV2 + '\' + 'AppData'
$UserV6AppData = $UserProfileV6 + '\' + 'AppData'
# All required user folders
$UserRootFolders = ($UserHomeRoot, $UserProfileRoot)
$SubFolders = ($UserContacts, $UserDesktop, $UserDocuments, $UserDownloads, $UserFavorites, $UserLinks, $UserPictures, $UserMusic, $UserVidoes, $UserProfileV2, $UserProfileV6, $UserV2AppData, $UserV6AppData)
# User Redirected Folders
# Existing Redirected Folders
$UserExistingRdrAppData = $RedirectedFoldersExisting + $UserName + '\' + 'Application Data'
$UserExistingRdrContacts = $RedirectedFoldersExisting + $UserName + '\' + 'Contacts'
$UserExistingRdrDesktop = $RedirectedFoldersExisting + $UserName + '\' + 'Desktop'
$UserExistingRdrDownloads = $RedirectedFoldersExisting + $UserName + '\' + 'Downloads'
$UserExistingRdrFavorites = $RedirectedFoldersExisting + $UserName + '\' + 'Favorites'
$UserExistingRdrLinks = $RedirectedFoldersExisting + $UserName + '\' + 'Links'
# Verify whether the user is valid user
$UserExist = $false
Try {
Write-Host "Verify required user: $UserName" -ForegroundColor Green
$UserExist = Get-ADUser -Identity $UserName -ErrorAction SilentlyContinue
}
Catch {
Write-Host "Error: The user $UserName does not exist, please verify and try again." -ForegroundColor Red
"`nError: The user $UserName does not exist, please verify and try again" | Add-Content $Report
}
# Continue if the user exist in Active Directory
If ($UserExist) {
$User = Get-ADUser -Identity $UserName -Properties *
$UserDisplayName = $User.DisplayName
$UserLoginName = $User.SamAccountName
# User Existing Home Directory
$UserExistHomeDirectory = $user.HomeDirectory
# User Existing V2 and V6 profile
$UserExistProfilePath = $user.ProfilePath
$UserExistProfileV2Path = $UserExistProfilePath + '.V2'
$UserExistProfileV6Path = $UserExistProfilePath + '.V6'
# Inform support team the progress
# Write-Host "Process valid user: $UserName`n" -ForegroundColor Yellow
Write-Host "Process request LAB User: Company Name - $Company `t&`t User Display Name: $UserDisplayName `t&`t User Login Name: $UserLoginName"
"`nProcess request LAB User: Company Name - $Company `t&`t User Display Name: $UserDisplayName `t&`t User Login Name: $UserLoginName" | Add-Content $Report
"User Existing Home Drive Path: $UserExistHomeDirectory" | Add-Content $Report
"User Existing Profile Path: $UserExistProfilePath" | Add-Content $Report
"" | Add-Content $Report
<#
Migration User Home Drive and Profile
#>
# Create user Home and Profile root folders and assgin user FULL permission
CreateUserHomeProfileRootFolders $UserRootFolders $UserName
# Create user home and profile sub-folders
# It will inherit the permission from user Home and Profile root folders
CreateUserHomeProfileSubFolders $SubFolders
# Migrate user home folders
If (Test-Path -Path $UserExistHomeDirectory) {
MigrateUserHomeFolder $UserExistHomeDirectory $UserHomeRoot
}
Else {
Write-Host "$UserName does not have existing home drive. No Home drive migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing home drive. No Home drive migration required for the user." | Add-Content $Report
}
# Migrate user V2 profile
If (Test-Path -Path $UserExistProfileV2Path) {
MigrateUserProfile $UserExistProfileV2Path $UserProfileV2
}
Else {
Write-Host "$UserName does not have existing V2 profile. No V2 profile migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing V2 profile. No V2 profile migration required for the user." | Add-Content $Report
}
# Migrate user V6 profile
If (Test-Path -Path $UserExistProfileV6Path) {
MigrateUserProfile $UserExistProfileV6Path $UserProfileV6
}
Else {
Write-Host "$UserName does not have existing V6 profile. No V6 profile migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing V6 profile. No V6 profile migration required for the user." | Add-Content $Report
}
<#
Migration User Redirected Fodlers
#>
<#
Migrate user Application Data
Application Data folder will not be redirected as part of new file server migration.
Migrate or copy the Application Data to AppData under Profile.V2 and Profile.V6
#>
If (Test-Path -Path $UserExistingRdrAppData) {
MigrateUserRedirectedFolders $UserExistingRdrAppData $UserV2AppData
MigrateUserRedirectedFolders $UserExistingRdrAppData $UserV6AppData
}
Else {
Write-Host "Application Data folder does not exist for $UserName, no Application Data migration required for user." -ForegroundColor Yellow
"`nApplication Data folder does not exist for $UserName, no Application Data migration required for user." | Add-Content $Report
}
<#
The following folders will be migrated to under user Home drive
Contacts
Desktop
Downloads
Favorites
Links
#>
$UserExistingRdrFolders = ($UserExistingRdrContacts,
$UserExistingRdrDesktop,
$UserExistingRdrDownloads,
$UserExistingRdrFavorites,
$UserExistingRdrLinks
)
$UserNewHomeFolder = $UserHomeRoot
MigrateUserHomeSubFolders $UserExistingRdrFolders $UserNewHomeFolder
<#
Migrae user My Documents folders
Currently LAB user Documents folder is redirected to user Home drive
This is not a recommended redirection as the following folders will be redirected to user My Documents
My Pictures
My Music
My Vidoes
#>
$UserExistingRdrDocuments = $UserExistHomeDirectory
MigrateUserMyDocuments $UserExistingRdrDocuments $UserNewHomeFolder
# Update user home and profile Active Directory attributes
UpdateUserHomeProfileAttributes $UserName $Company
# Add migrated user to required Active Directory security group
}
# Inform the support team to check the user for the user folder migration
Else {
Write-Host "The user: $UserName does not existing in LAB, please verify the user name." -ForegroundColor Red
"`nThe user: $UserName does not existing in LAB, please verify the user name." | Add-Content $Report
}
}
}
User Home and Profile Migration and Reset Existing Folder Access Permission
This script will reset the existing user Home and Profile folder access permission before migration.
#Requires -RunAsAdministrator
cls
# Import module
Import-Module ActiveDirectory
#******************************** List of Site Codes ********************************
# RequierdSite Site Code
$RequierdSite_Name = "RequierdSite"
# Other Site Codes
<# To be udpated #>
#***********************************************************************************
#******************************** List of Sites File Servers ********************************
# RequierdSite DFS File Servers
$RequierdSite_DFS_fileserver = "PDC-FS-01"
$RequierdSite_DFS_fileserver_replica = "SDC-FS-01"
# Other Site DFS File Servers
<# To be udpated #>
#******************************************************************************************
#******************************** List of SITE Folder Redirected Folders ********************************
# RequierdSite - User Redirected Folders
$RequierdSite_ExistHomeRedirectedFolders = "\\LAB\public\home\"
$RequierdSite_ExistProfileRedirectedFolders = "\\LAB\public\profiles\"
# Other Site - User Redirected Folders
<# To be udpated #>
#***********************************************************************************
#******************************** List of SITE Folder Redirect GPO Groups ********************************
# RequierdSite - User Redirected Folders
$RequierdSite_FolderRedirect_Group = 'RES-AD-GP-Windows7-User - RequierdSite - Redirected Folders - Migration'
# Other Site - User Redirected Folders
<# To be udpated #>
#***********************************************************************************
# Variables
$Date = Get-Date -Format "yyyy-MM-dd"
$timestamp = Get-Date -UFormat "%d/%m/%Y %R"
$datestamp = Get-Date -UFormat "%d/%m/%Y"
$Computer = $env:COMPUTERNAME
$Domain = "LAB"
$DomainFQDN = "LAB.LOCAL"
$Required_User_Migration_List = "\\$Computer\D$\Inputs\Required_User_Folder_migration_User_List\Required_Folder_Migration_Users.csv"
$Report = "\\$Computer\D$\Logs\Required_User_Folder_Migration_Reports\Required-User-Folder-Migration-Report-$Date.txt"
# SITE Users New Home and Profile parent folders
$UserRootPath = "E$\DATA\Users\"
#******************************************************
# Function: Create User Home and Profile Root Folders
#
# Purpose:
# Create user home and pofile root folders
#
#******************************************************
Function CreateUserHomeProfileRootFolders ([array]$folders, [string]$UserName) {
ForEach ($folder in $folders) {
# Create user home and profile root folders if not exist
If (!(Test-Path $folder)) {
Try {
Write-Host "Create user home and profile root folder: $folder"
New-Item -Path $folder -ItemType Directory -Force
Start-Sleep 2
# Grant user Full permission
# Obtain the existing folder ACL
$Folder_ACL = Get-Acl -Path $folder
# Set FULL permission, and apply to "This folder, subfolders and files"
$Permissions = "$Domain\$UserName", 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
# Add the new FileSystemAccessRule to apply
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $Permissions
# Add the new ACL to the existing folder
$Folder_ACL.SetAccessRule($AccessRule)
# Apply the new ACL to the new folder
$Folder_ACL | Set-Acl -Path $folder -Confirm:$false
# Record update to log file
"`nSuccessfully create user root folder: $folder" | Add-Content $UserFolerMigrationReport
"`nFolder permission update: $Domain\$RequiredUser has been granted Modify permission to $folderPath" | Add-Content $UserFolerMigrationReport
}
Catch {
Write-Host "Failed to create user root folder: $folder" -ForegroundColor Red
# Update report
"`nFailed to create user root folder: $folder" | Add-Content $UserFolerMigrationReport
}
}
}
}
#******************************************************
# Function: Create User Home and Profile Sub-Folders
#
# Purpose:
# Create sub-folders under user home and profile folder
# It will inherit the permission from parent folder
#
#******************************************************
Function CreateUserHomeProfileSubFolders ([array]$folders) {
ForEach ($folder in $folders) {
# Create user home and profile root folders if not exist
If (!(Test-Path $folder)) {
Try {
Write-Host "Create sub-folder: $folder"
New-Item -Path $folder -ItemType Directory -Force
"`nSuccessfully create sub-folder: $folder" | Add-Content $UserFolerMigrationReport
}
Catch {
Write-Host "Fail to create user sub-folder: $folder" -ForegroundColor Red
"`nFail to create user sub-folder: $folder" | Add-Content $UserFolerMigrationReport
}
}
}
}
#******************************************************
# Function: Migrate User Home Drive
#
# Purpose:
# Migrate user home drive to new SITE file server
#
#******************************************************
Function MigrateUserHomeFolder ([string]$ExistHomeDir, [string]$NewHomeDir) {
Write-Host "Migrate user home drive`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistHomeDir'"
$DestPath = "'$NewHomeDir'"
$Options = "/S /E"
# Exclude "My Documents" folder, it will be migrated to "Documents" folder
$ExcludeFolders = "'My Documents'"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options /XD $ExcludeFolders"
# Update log file
"`nSuccessfully migration user Home drive." | Add-Content $UserFolerMigrationReport
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $UserFolerMigrationReport
}
#******************************************************
# Function: Migrate User Profile Folders
#
# Purpose:
# Migrate user Profile V2 and V6 folders
#
#******************************************************
Function MigrateUserProfile ([string]$ExistProfileDir, [string]$NewProfileDir) {
Write-Host "Migrate user profile`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistProfileDir'"
$DestPath = "'$NewProfileDir'"
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user Profile." | Add-Content $UserFolerMigrationReport
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $UserFolerMigrationReport
}
#******************************************************
# Function: Migrate User Redirected Folders
#
# Purpose:
# Migrate user redirected folders
#
#******************************************************
Function MigrateUserRedirectedFolders ([string]$ExistingDir, [string]$NewDir) {
Write-Host "Migrate user redirected folders`n" -ForegroundColor Yellow
# Source and destination path
$SourcePath = "'$ExistingDir'"
$DestPath = "'$NewDir'"
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user redirected folder." | Add-Content $UserFolerMigrationReport
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $UserFolerMigrationReport
}
#******************************************************
# Function: Migrate User Home Sub-folder Redirected Folders
#
# Purpose:
# The following redirected folders are under Home drive
# Contacts
# Desktop
# Downloads
# Favorites
# Links
#
#******************************************************
Function MigrateUserHomeSubFolders ([array]$ExistSubFolders, [string]$NewRootDir) {
# Continue if user home drive exists
If (Test-Path -Path $NewRootDir) {
$NewContacts = $NewRootDir + '\' + 'Contacts'
$NewDesktop = $NewRootDir + '\' + 'Desktop'
$NewDocuments = $NewRootDir + '\' + 'Documents'
$NewDownloads = $NewRootDir + '\' + 'Downloads'
$NewFavorites = $NewRootDir + '\' + 'Favorites'
$NewLinks = $NewRootDir + '\' + 'Links'
# Process each sub-folder
ForEach ($Subfolder in $ExistSubFolders) {
# Continue if the existing subfolder exists
If (Test-Path -Path $Subfolder) {
# Process Contacts folder
If ($Subfolder -like "*Contacts*") {
$DestPath = "'$NewContacts'"
Write-Host "Migrate Contacts" -ForegroundColor Green
}
# Process Desktop folder
ElseIf ($Subfolder -like "*Desktop*") {
$DestPath = "'$NewDesktop'"
Write-Host "Migrate Desktop" -ForegroundColor Green
}
# Process My Documents folder
# My Documents will be migrate to Documents
ElseIf ($Subfolder -like "*My Documents*") {
$DestPath = "'$NewDocuments'"
Write-Host "Migrate Desktop" -ForegroundColor Green
}
# Process Downloads folder
ElseIf ($Subfolder -like "*Downloads*") {
$DestPath = "'$NewDownloads'"
Write-Host "Migrate Downloads" -ForegroundColor Green
}
# Process Favorites folder
ElseIf ($Subfolder -like "*Favorites*") {
$DestPath = "'$NewFavorites'"
Write-Host "Migrate Favorites" -ForegroundColor Green
}
# Process Links folder
ElseIf ($Subfolder -like "*Links*") {
$DestPath = "'$NewLinks'"
Write-Host "Migrate Links" -ForegroundColor Green
}
$SourcePath = $Subfolder
$Options = "/S /E"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath`n"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options"
# Update log file
"`nSuccessfully migration user redirected folder." | Add-Content $UserFolerMigrationReport
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $UserFolerMigrationReport
}
Else {
Write-Host "The existing redirected subfolder does not exist: $Subfolder" -ForegroundColor Yellow
}
}
}
Else {
Write-Host "The user new home drive does not exist: $NewRootDir" -ForegroundColor Red
}
}
#******************************************************
# Function: Add Migrated User to Folder Redirected Group
#
# Purpose:
# Add Migrated User to Folder Redirected Group
#
#******************************************************
Function AddMigratedUserFolderRedirectGroup ([string]$GroupName, [string]$RequiredUser) {
Write-Host "`nUpdate user folder migration group membership`n" -ForegroundColor Yellow
If (Get-ADGroup -Identity $GroupName) {
Try {
Add-ADGroupMember -Identity $GroupName $RequiredUser
Write-Host "Add $RequiredUser to Active Directory group: $GroupName"
# Update log file
"`nSuccessfully add $RequiredUser to Active Directory group: $GroupName" | Add-Content $UserFolerMigrationReport
}
Catch {
Write-Host "Not able to add $RequiredUser to group: $GroupName" -ForegroundColor Red
"`nNot able to add $RequiredUser to group: $GroupName" | Add-Content $UserFolerMigrationReport
}
}
}
#***************************************************************************
# Function: Migrate User My Documents Folder
#
# Purpose:
# Migrate user My Documents folder
#
# Excluding the exiting following folders in user My Documents directory
# My Music
# My Pictures
# My Vidoes
#***************************************************************************
Function MigrateUserMyDocuments ([string]$ExistingDir, [string]$NewDir) {
Write-Host "Migrate user My Documents`n" -ForegroundColor Yellow
$NewDocumentsPath = $NewDir + '\' + 'Documents'
# Source and destination path
$SourcePath = "'$ExistingDir'"
$DestPath = "'$NewDocumentsPath'"
$Options = "/S /E"
$ExcludeFolders = "'My *'"
Write-Host "SourcePath: `n$SourcePath `nDestPath: `n$DestPath"
Invoke-Expression "Robocopy.exe $SourcePath $DestPath $Options /XD $ExcludeFolders"
# Update log file
"`nSuccessfully migration user My Documents." | Add-Content $UserFolerMigrationReport
"`nSourcePath: `n$SourcePath `nDestPath: `n$DestPath" | Add-Content $UserFolerMigrationReport
}
#***************************************************************************
# Function: Update User Home and Profile Active Directory Attributes
#
# Purpose:
# Update user home and profile path Active Directory attributes
#***************************************************************************
Function UpdateUserHomeProfileAttributes ([string]$RequiredUser, [string]$SiteCode) {
$HomeDir = "\\$($DomainFQDN)\Users\$($SiteCode)\$($RequiredUser)\Home"
$ProfileDir = "\\$($DomainFQDN)\Users\$($SiteCode)\$($RequiredUser)\LAB\Profile"
Write-Host "Please wait... Update user Home and Profile path for user $RequiredUser`n" -ForegroundColor Yellow
Write-Host "`tThe new Home drive path: $HomeDir`n`tThe new Profile path: $ProfileDir"
Try {
Set-ADUser -Identity $RequiredUser -ProfilePath $ProfileDir
Set-ADUser -Identity $RequiredUser -HomeDirectory $HomeDir
Start-Sleep 10 # Wait for update to take effect
# Update log file
"`nSuccessfully update user Home and Profile path." | Add-Content $UserFolerMigrationReport
"`nThe new Home drive path: $HomeDir`n`tThe new Profile path: $ProfileDir" | Add-Content $UserFolerMigrationReport
}
Catch {
Write-Host "Not able to update user Home and Profile path." -ForegroundColor Red
"`nError: Failed to update user Home and Profile path." | Add-Content $UserFolerMigrationReport
}
}
#************************************************************************************************************************************
# Function: Get Only Inheritted Access ACL
#
# Purpose:
# This functions returns an ACL (Access Control List) with any ACEs (Access Control Entries) not inherritted (i.e. explicit)
#************************************************************************************************************************************
function Get-OnlyInherittedAces ($itemACL){
# Set rule protection to allow inheritence ($False = allow inheritance, $False = this is ignored as inheritence is allowed).
$itemACL.SetAccessRuleProtection($False, $False)
# Remove any ACEs which are not inheritted from the ACL.
$itemACL.Access | where{$_.isinherited -like $False} | foreach{
$itemACL.purgeaccessrules($_.IdentityReference);
}
# Return ACL with explicit ACEs removed.
return $itemACL
}
#***********************************************************************************************
# Function: Get Only Inheritted Access ACL
#
# Purpose:
# This functions forcibly resets every item's ACL, even if it already has the correct ACL
#***********************************************************************************************
function Set-UserAclAndOwnership([string]$Folder,[string]$UserName) {
# Get the user folder to be process
$userFolder = Get-Item ($Folder)
# Get the name of the folder.
$userFolderName = $userFolder.Name
Write-Host ("`r`n`t> Taking Ownership & Getting Full Control - $Folder")
# Sets ownership and gives full control (recursively) to the Administrators group so that ACLs can be set without access denied errors.
# NOTE: Native PowerShell commands are not used here as they do not always have the ability to completely override ACLs.
takeown /F $userFolder.FullName /A /R /D Y | Out-Null
icacls $userFolder.FullName /grant BUILTIN\Administrators:F /t | Out-Null
Write-Host ("`t`t- Please wait ...`r`n`t> Setting Correct ACLs on Child Items") -ForegroundColor Green
# Create new ACL for the parent folder.
$paAcl = New-Object System.Security.AccessControl.DirectorySecurity
# Add an ACE to the ACL to give user Full Control.
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($UserName,"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$paAcl.AddAccessRule($rule)
# Add and ACE to the ACL to give RESl-FS-File-FL Full Control.
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("RESp-FS-File-FL", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$paAcl.AddAccessRule($rule)
# Add and ACE to the ACL to give RESl-FS-File-FL Read and Excecute.
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("RESp-FS-File-RO", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
$paAcl.AddAccessRule($rule)
# Add an ACE to the ACL to give BUILTIN\Administrators Full Control.
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$paAcl.AddAccessRule($rule)
# Add and ACE to the ACL to give SYSTEM Full Control.
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$paAcl.AddAccessRule($rule)
# Disable ACL inherritance.
$paAcl.SetAccessRuleProtection($True, $False)
# Set the ACL of the user's home folder to the new ACL.
$userFolder.SetAccessControl($paAcl)
# This loop makes every child item inherit ACEs from its parent and then removes non-inheritted ones.
# -Force is used to inlcude hidden items and system files.
Get-ChildItem -Recurse -Force $userFolder.FullName | foreach{
$_.SetAccessControl((Get-OnlyInherittedAces($_.GetAccessControl())))
}
Write-Host ("`t`t- DONE <`r`n`t> Giving Ownership to " + $userFolderName)
# Make user the owner of their home folder now that the ACL have been set.
icacls $userFolder.FullName /setowner $UserName /t /c /q | Out-Null
Write-Host ("`t`t- DONE - Grant $UserName full permission on $userFolderName") -ForegroundColor Green
}
#**********************************************************
#
# Main
#
#**********************************************************
# Import Required user list file
$UsersInfo = Import-Csv $Required_User_Migration_List
# Process if input user list file is not empty
If ($UsersInfo -ne $null) {
# Update log file
"`nMigrate User Home, Profile and Redirected Folders on $timestamp" | Add-Content $Report
"" | Add-Content $Report
# Process file security groups
ForEach ($Userinfo in $UsersInfo) {
#SiteCode = $UserInfo.Site_Code # If in the future there are more sites
$SiteCode = $RequierdSite_Name # Currently there is only RequierdSite site
$UserName = $UserInfo.User_Login_Name
# Update user folder migration report
$UserFolerMigrationReport = "\\$Computer\D$\Logs\Required_User_Folder_Migration_Reports\$UserName-Home-Profile-Folder-Migration-Report-$Date.txt"
"`nMigrate User Home, Profile and Redirected Folders on $timestamp" | Add-Content $UserFolerMigrationReport
"" | Add-Content $UserFolerMigrationReport
# RequierdSite Site Users
If ($SiteCode -like $RequierdSite_Name) {
# Update file server to required Site file server
$FileServer = $RequierdSite_DFS_fileserver
# Existing User redirected root folders
$ExistHomeRedirectedFolders = $RequierdSite_ExistHomeRedirectedFolders
$ExistProfileRedirectedFolders = $RequierdSite_ExistProfileRedirectedFolders
# User New Home and Profile Parent Path
$UsersFolderParentPath = "E$\DATA\Users\RequierdSite"
# Folder Redirect GPO Group
$GroupFoldersRedirect = $RequierdSite_FolderRedirect_Group
}
<#
# TBA for other Site file servers
ElseIf {
# TBA
}
#>
# Update user home and folder folders according to Site file server
# Home drive and subfolders
$UserHomeRoot = '\\' + $FileServer + '\' + $UsersFolderParentPath + '\' + $UserName + '\' + 'Home'
$UserContacts = $UserHomeRoot + '\' + 'Contacts'
$UserDesktop = $UserHomeRoot + '\' + 'Desktop'
$UserDocuments = $UserHomeRoot + '\' + 'Documents'
$UserDownloads = $UserHomeRoot + '\' + 'Downloads'
$UserFavorites = $UserHomeRoot + '\' + 'Favorites'
$UserLinks = $UserHomeRoot + '\' + 'Links'
$UserPictures = $UserHomeRoot + '\' + 'My Pictures'
$UserMusic = $UserHomeRoot + '\' + 'My Music'
$UserVidoes = $UserHomeRoot + '\' + 'My Videos'
# Profile folder and subfolders
# Profile.V2 & Profile.V6
$UserProfileRoot = '\\' + $FileServer + '\' + $UsersFolderParentPath + '\' + $UserName + '\' + 'LAB'
$UserProfileV2 = $UserProfileRoot + '\' + 'Profile.V2'
$UserProfileV6 = $UserProfileRoot + '\' + 'Profile.V6'
$UserV2AppData = $UserProfileV2 + '\' + 'AppData'
$UserV6AppData = $UserProfileV6 + '\' + 'AppData'
# All required user folders
$UserRootFolders = ($UserHomeRoot, $UserProfileRoot)
$SubFolders = ($UserContacts, $UserDesktop, $UserDocuments, $UserDownloads, $UserFavorites, $UserLinks, $UserPictures, $UserMusic, $UserVidoes, $UserProfileV2, $UserProfileV6, $UserV2AppData, $UserV6AppData)
# User Redirected Folders
# Existing Redirected Folders
# Existing User redirected folders
<#
Currently all Required users are having Desktop and Favorites are redirected to
\\LAB\public\profiles\<UserLoginName>
#>
$UserExistingRdrAppData = $ExistHomeRedirectedFolders + $UserName + '\' + 'Application Data'
$UserExistingRdrContacts = $ExistHomeRedirectedFolders + $UserName + '\' + 'Contacts'
$UserExistingRdrDesktop = $ExistProfileRedirectedFolders + $UserName + '\' + 'Desktop'
$UserExistingRdrMyDocuments = $ExistHomeRedirectedFolders + $UserName + '\' + 'My Documents'
$UserExistingRdrDocuments = $ExistHomeRedirectedFolders + $UserName + '\' + 'Documents'
$UserExistingRdrDownloads = $ExistHomeRedirectedFolders + $UserName + '\' + 'Downloads'
$UserExistingRdrFavorites = $ExistProfileRedirectedFolders + $UserName + '\' + 'Favorites'
$UserExistingRdrLinks = $ExistHomeRedirectedFolders + $UserName + '\' + 'Links'
# Verify whether the user is valid user
$UserExist = $false
Try {
Write-Host "Verify required user: $UserName" -ForegroundColor Green
$UserExist = Get-ADUser -Identity $UserName -ErrorAction SilentlyContinue
}
Catch {
Write-Host "Error: The user $UserName does not exist, please verify and try again." -ForegroundColor Red
"`nError: The user $UserName does not exist, please verify and try again" | Add-Content $UserFolerMigrationReport
}
# Continue if the user exist in Active Directory
If ($UserExist) {
$User = Get-ADUser -Identity $UserName -Properties *
$UserDisplayName = $User.DisplayName
$UserLoginName = $User.SamAccountName
# User Existing Home Directory
$UserExistHomeDirectory = $user.HomeDirectory
# User Existing V2 and V6 profile
$UserExistProfilePath = $user.ProfilePath
$UserExistProfileV2Path = $UserExistProfilePath + '.V2'
$UserExistProfileV6Path = $UserExistProfilePath + '.V6'
# Inform support team the progress
# Write-Host "Process valid user: $UserName`n" -ForegroundColor Yellow
Write-Host "Process request Required User: Site Code - $SiteCode `t&`t User Display Name: $UserDisplayName `t&`t User Login Name: $UserLoginName"
"`nProcess request Required User: Site Code - $SiteCode `t&`t User Display Name: $UserDisplayName `t&`t User Login Name: $UserLoginName" | Add-Content $UserFolerMigrationReport
"User Existing Home Drive Path: $UserExistHomeDirectory" | Add-Content $UserFolerMigrationReport
"User Existing Profile Path: $UserExistProfilePath" | Add-Content $UserFolerMigrationReport
"" | Add-Content $UserFolerMigrationReport
# Update summary migration report
"Process request Required User: Site Code - $SiteCode `t&`t User Display Name: $UserDisplayName `t&`t User Login Name: $UserLoginName" | Add-Content $Report
<#
Create User New Home Drive and Profile Directories
#>
# Create user Home and Profile root folders and assgin user FULL permission
CreateUserHomeProfileRootFolders $UserRootFolders $UserName
# Create user home and profile sub-folders
# It will inherit the permission from user Home and Profile root folders
CreateUserHomeProfileSubFolders $SubFolders
<#
Migration User Home Drive and Profile to new file server
#>
# Migrate user home folders
If (Test-Path -Path $UserExistHomeDirectory) {
# Reset user Home drive access ACL
Set-UserAclAndOwnership $UserExistHomeDirectory $UserLoginName
MigrateUserHomeFolder $UserExistHomeDirectory $UserHomeRoot
}
Else {
Write-Host "$UserName does not have existing home drive. No Home drive migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing home drive. No Home drive migration required for the user." | Add-Content $UserFolerMigrationReport
}
# Migrate user V2 profile
If (Test-Path -Path $UserExistProfileV2Path) {
# Reset user Profile V2 access ACL
Set-UserAclAndOwnership $UserExistProfileV2Path $UserLoginName
MigrateUserProfile $UserExistProfileV2Path $UserProfileV2
}
Else {
Write-Host "$UserName does not have existing V2 profile. No V2 profile migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing V2 profile. No V2 profile migration required for the user." | Add-Content $UserFolerMigrationReport
}
# Migrate user V6 profile
If (Test-Path -Path $UserExistProfileV6Path) {
# Reset user Profile V2 access ACL
Set-UserAclAndOwnership $UserExistProfileV6Path $UserLoginName
MigrateUserProfile $UserExistProfileV6Path $UserProfileV6
}
Else {
Write-Host "$UserName does not have existing V6 profile. No V6 profile migration required for the user." -ForegroundColor Yellow
"`n$UserName does not have existing V6 profile. No V6 profile migration required for the user." | Add-Content $UserFolerMigrationReport
}
<#
Migration User Redirected Folders
#>
<#
Migrate user Application Data:
1. Application Data folder will not be redirected as part of new file server migration.
2. Migrate or copy the Application Data to AppData under Profile.V2 and Profile.V6
#>
If (Test-Path -Path $UserExistingRdrAppData) {
MigrateUserRedirectedFolders $UserExistingRdrAppData $UserV2AppData
MigrateUserRedirectedFolders $UserExistingRdrAppData $UserV6AppData
}
Else {
Write-Host "Application Data folder does not exist for $UserName, no Application Data migration required for user." -ForegroundColor Yellow
"`nApplication Data folder does not exist for $UserName, no Application Data migration required for user." | Add-Content $UserFolerMigrationReport
}
<#
The following folders will be migrated to inside user Home drive
Contacts
Desktop
Documents
Downloads
Favorites
Links
Currently the user Desktop and Favorite folder are redirected to
\\LAB\public\profiles\<UserLoginName>
#>
$UserDesktopFavoritesRdrFolderRoot = $ExistProfileRedirectedFolders + $UserName
If (Test-Path -Path $UserDesktopFavoritesRdrFolderRoot) {
# Reset user Profile access ACL
Set-UserAclAndOwnership $UserDesktopFavoritesRdrFolderRoot $UserLoginName
}
$UserExistingRdrFolders = ($UserExistingRdrContacts,
$UserExistingRdrDesktop,
$UserExistingRdrDownloads,
$UserExistingRdrFavorites,
$UserExistingRdrLinks
)
$UserNewHomeFolder = $UserHomeRoot
MigrateUserHomeSubFolders $UserExistingRdrFolders $UserNewHomeFolder
<#
Migrae user My Documents or Documents folders
1. My Documents will be migrated to "Documents" folder
2. Documents will be migrated to "Documents" folder
#>
# Migrate user "My Documents" folder if exist
If (Test-Path -Path $UserExistingRdrMyDocuments) {
MigrateUserMyDocuments $UserExistingRdrMyDocuments $UserDocuments
}
# Migrate user "Documents" folder if exist
ElseIf (Test-Path -Path $UserExistingRdrDocuments) {
MigrateUserMyDocuments $UserExistingRdrDocuments $UserDocuments
}
# Update user home and profile Active Directory attributes
UpdateUserHomeProfileAttributes $UserName $SiteCode
# Add migrated user to RES-AD-GP-User.... Folder Redirect Enable Group
AddMigratedUserFolderRedirectGroup $GroupFoldersRedirect $UserName
}
# Inform the support team to check the user for the user folder migration
Else {
Write-Host "The user: $UserName does not existing in Required, please verify the user name." -ForegroundColor Red
"`nThe user: $UserName does not existing in Required, please verify the user name." | Add-Content $UserFolerMigrationReport
}
}
}