[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 100
  • Last Modified:

powershell code needs amending

Dear Experts,

I have this excellent code written by one you experts and did the job for me. However, I need to change it get inputs from .csv file for user names ( firstname.surname) and move their home drives from old server (server1) to new server ( server2, retaining the permissions on the home folders and finally change their home drive path in AD ( from server1 to server2.

Could you help me on this please? thanks
$oldRootServerPath = "\\localhost\share\"
$newRootServerPath = "\\localhost\share2\"
$errorLog = "C:\Users\Administrator\Desktop\error.txt"
$copyLog = "C:\Users\Administrator\Desktop\copy.txt"
$sourceOU = "OU=TestCompany,OU=Clients,OU=zUsers,DC=myDC,DC=local"

function WriteError($message)
{
    $stamp = Get-Date
    $error = $stamp.ToString() + " -- " + $message
    Add-Content -Path $errorLog -Value $error
}

function WriteCopy($message)
{
    $stamp = Get-Date
    $msg = $stamp.ToString() + " -- " + $message
    Add-Content -Path $copyLog -Value $msg
}


function CopyHomeDirectory($source)
{
    $newRoot = $source -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    if (!(Test-Path $newRoot)) 
    {
        New-Item -ItemType Directory $newRoot
        $acl = Get-Acl $source
        Set-Acl -Path $newRoot -AclObject $acl
    }
    $folders = Get-ChildItem $source -Recurse | ?{$_.PSIsContainer}
    foreach ($folder in $folders)
    {
        try {
        $oldFolder = $folder.FullName
        $acl = Get-Acl $oldFolder
        $newFolder = $oldFolder -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
        if (!(Test-Path $newFolder)) {
            New-Item -ItemType Directory $newFolder
            Set-Acl -Path $newFolder -AclObject $acl
            }
        }
        catch {
        $eMessage = "Could not copy folder " + $oldFolder
        WriteError($eMessage)
        $errors++
        }
    }

        $files = Get-ChildItem $source -Recurse | ?{!$_.PsIsContainer}
        foreach ($file in $files)
        {
            try {
            $oldFile = $file.FullName
            $acl = Get-Acl $oldFile
            $newFile = $oldFile -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
            Copy-Item $oldFile -Destination $newFile
            Set-Acl -Path $newFile -AclObject $acl
            }
            catch {
            $eMessage = "Could not copy file " + $oldFile
            WriteError($eMessage)
            $errors++
            }
        }


}

$users = Get-ADUser -Filter * -SearchBase $sourceOU -Properties homeDirectory | ?{$_.homeDirectory} | select  sAMAccountName,homeDirectory

foreach ($user in $users)
{
    $errors = 0
    $path = $user.homeDirectory.ToString()
    CopyHomeDirectory($path)
    $copyMsg = "Copy completed for " + $path + " -- " + $errors + " errors occurred."
    WriteCopy($copyMsg)
    $newPath = $path -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    Set-AdUser -Identity $user.sAMAccountName -HomeDrive "H:" -HomeDirectory $newPath
}

Open in new window

0
kuzum
Asked:
kuzum
  • 4
  • 2
  • 2
1 Solution
 
QlemoDeveloperCommented:
What's the exact structure of the CSV file? Can you show a short mock-up example?
Am I correct that you want to change the script from searching in a specific OU to using specific names coming from the CSV?
0
 
QlemoDeveloperCommented:
Assuming you have a CSV file like
FirstName,SurName
Charles,Bronson
River,Phoenix

Open in new window

replace line 5 with the complete path to it:
$userfile = 'C:\Users\Administrator\Desktop\Users.CSV'

Open in new window

and line 70 with
$users = Import-CSV $userfile | % { Get-ADUser -Filter {GivenName -eq $_.FirstName -and SurName -eq $_.SurName} -Properties homeDirectory | ?{$_.homeDirectory} | select  sAMAccountName,homeDirectory

Open in new window

0
 
kuzumAuthor Commented:
Qlemo,

thanks for your response.  Yes, you are right. instead of searching for a OU, it should read through the csv file and copy the home folders to new server, Of course with permissions and change the home folder path in AD for those users. ,  ( I do not want home folders to be deleted in old location)

csv file sample is attached.
Doc3.docx
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

 
kuzumAuthor Commented:
basically, csv file will be Firstname.surname
0
 
Dustin SaundersDirector of OperationsCommented:
These changes will perform the search:

@line5
$userfile = 'C:\Users\Administrator\Desktop\name.CSV'

Open in new window


@line70
$users = Import-CSV $userfile | % {Get-ADUser -Filter "sAMAccountName -eq '$($_.SamAccountName)'" -Properties homeDirectory | ?{$_.homeDirectory} | select  sAMAccountName,homeDirectory }

Open in new window


The whole thing:
$oldRootServerPath = "\\localhost\share\"
$newRootServerPath = "\\localhost\share2\"
$errorLog = "C:\Users\Administrator\Desktop\error.txt"
$copyLog = "C:\Users\Administrator\Desktop\copy.txt"
$userfile = 'C:\Users\Administrator\Desktop\name.CSV'

function WriteError($message)
{
    $stamp = Get-Date
    $error = $stamp.ToString() + " -- " + $message
    Add-Content -Path $errorLog -Value $error
}

function WriteCopy($message)
{
    $stamp = Get-Date
    $msg = $stamp.ToString() + " -- " + $message
    Add-Content -Path $copyLog -Value $msg
}


function CopyHomeDirectory($source)
{
    $newRoot = $source -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    if (!(Test-Path $newRoot)) 
    {
        New-Item -ItemType Directory $newRoot
        $acl = Get-Acl $source
        Set-Acl -Path $newRoot -AclObject $acl
    }
    $folders = Get-ChildItem $source -Recurse | ?{$_.PSIsContainer}
    foreach ($folder in $folders)
    {
        try {
        $oldFolder = $folder.FullName
        $acl = Get-Acl $oldFolder
        $newFolder = $oldFolder -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
        if (!(Test-Path $newFolder)) {
            New-Item -ItemType Directory $newFolder
            Set-Acl -Path $newFolder -AclObject $acl
            }
        }
        catch {
        $eMessage = "Could not copy folder " + $oldFolder
        WriteError($eMessage)
        $errors++
        }
    }

        $files = Get-ChildItem $source -Recurse | ?{!$_.PsIsContainer}
        foreach ($file in $files)
        {
            try {
            $oldFile = $file.FullName
            $acl = Get-Acl $oldFile
            $newFile = $oldFile -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
            Copy-Item $oldFile -Destination $newFile
            Set-Acl -Path $newFile -AclObject $acl
            }
            catch {
            $eMessage = "Could not copy file " + $oldFile
            WriteError($eMessage)
            $errors++
            }
        }


}

$users = Import-CSV $userfile | % {Get-ADUser -Filter "sAMAccountName -eq '$($_.SamAccountName)'" -Properties homeDirectory | ?{$_.homeDirectory} | select  sAMAccountName,homeDirectory }

foreach ($user in $users)
{
    $errors = 0
    $path = $user.homeDirectory.ToString()
    CopyHomeDirectory($path)
    $copyMsg = "Copy completed for " + $path + " -- " + $errors + " errors occurred."
    WriteCopy($copyMsg)
    $newPath = $path -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    Set-AdUser -Identity $user.sAMAccountName -HomeDrive "H:" -HomeDirectory $newPath
}

Open in new window


Be sure to take that top line out of your CSV (#TYPE Selected.Microsoft.ActiveDirectory.Management.ADUsers)
0
 
kuzumAuthor Commented:
Hi Dustin,

is it also possible to add what-if in the end and run it first please?
0
 
Dustin SaundersDirector of OperationsCommented:
This should be in 'test mode'.  There are 3 whatif(s)
$oldRootServerPath = "\\localhost\share\"
$newRootServerPath = "\\localhost\share2\"
$errorLog = "C:\Users\Administrator\Desktop\error.txt"
$copyLog = "C:\Users\Administrator\Desktop\copy.txt"
$userfile = 'C:\Users\Administrator\Desktop\name.CSV'

function WriteError($message)
{
    $stamp = Get-Date
    $error = $stamp.ToString() + " -- " + $message
    Add-Content -Path $errorLog -Value $error
}

function WriteCopy($message)
{
    $stamp = Get-Date
    $msg = $stamp.ToString() + " -- " + $message
    Add-Content -Path $copyLog -Value $msg
}


function CopyHomeDirectory($source)
{
    $newRoot = $source -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    if (!(Test-Path $newRoot)) 
    {
        New-Item -ItemType Directory $newRoot
        $acl = Get-Acl $source
        Set-Acl -Path $newRoot -AclObject $acl
    }
    $folders = Get-ChildItem $source -Recurse | ?{$_.PSIsContainer}
    foreach ($folder in $folders)
    {
        try {
        $oldFolder = $folder.FullName
        $acl = Get-Acl $oldFolder
        $newFolder = $oldFolder -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
        if (!(Test-Path $newFolder)) {
            New-Item -ItemType Directory $newFolder 
            Set-Acl -Path $newFolder -AclObject $acl
            }
        }
        catch {
        $eMessage = "Could not copy folder " + $oldFolder
        WriteError($eMessage)
        $errors++
        }
    }

        $files = Get-ChildItem $source -Recurse | ?{!$_.PsIsContainer}
        foreach ($file in $files)
        {
            try {
            $oldFile = $file.FullName
            $acl = Get-Acl $oldFile
            $newFile = $oldFile -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
            Copy-Item $oldFile -Destination $newFile -whatif
            Set-Acl -Path $newFile -AclObject $acl -whatif
            }
            catch {
            $eMessage = "Could not copy file " + $oldFile
            WriteError($eMessage)
            $errors++
            }
        }


}

$users = Import-CSV $userfile | % {Get-ADUser -Filter "sAMAccountName -eq '$($_.SamAccountName)'" -Properties homeDirectory | ?{$_.homeDirectory} | select  sAMAccountName,homeDirectory }

foreach ($user in $users)
{
    $errors = 0
    $path = $user.homeDirectory.ToString()
    CopyHomeDirectory($path)
    $copyMsg = "Copy completed for " + $path + " -- " + $errors + " errors occurred."
    WriteCopy($copyMsg)
    $newPath = $path -replace [regex]::Escape($oldRootServerPath),$newRootServerPath
    Set-AdUser -Identity $user.sAMAccountName -HomeDrive "H:" -HomeDirectory $newPath -whatif
}

Open in new window


@line80
Set-AdUser -Identity $user.sAMAccountName -HomeDrive "H:" -HomeDirectory $newPath -whatif

Open in new window


@line57-58
Copy-Item $oldFile -Destination $newFile -whatif
            Set-Acl -Path $newFile -AclObject $acl -whatif

Open in new window


Test mode will create directories but simulate the file copy (@line-57-58 restricts this) so you don't have to wait for the copy to finish to confirm results.  Remove these 3 or run the previous code when ready to migrate.
0
 
kuzumAuthor Commented:
excellent work
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 4
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now