How to make this more useful for my situation

Hi Team

I have found a script from a poshcode user called Themoblin and as he has posted here I thought this was a good place to ask for some advice. Being new to Powershell but ultimately keen to learn I grabbed a script to change a users profile and home drive server details inside AD when migrating servers.
I added a section to search only in one OU (we have 20,000 user objects and the AD OU structure is very flat…) but I would now like to find out how to get it to only act on the users that need the old server name changed Here is the script as it stands now

Import-Module Activedirectory

#Lower Case!!
$oldserver = “oldserver”

#Lower Case!!
$newserver = “newserver”

$users = get-aduser -filter * -SearchBase “OU=xx,OU=xx,DC=xx,DC=xx,DC=xx,DC=xx,DC=xx” -properties homedirectory,profilepath

foreach ($user in $users) {
$name = $user.name
$DN = $user.distinguishedname
$profilepath = $user.profilepath
$homedirectory = $user.homedirectory

if ($profilepath -like "*$oldserver*")
	{

#Add -whatif to next line before running the script to see what would happen
Set-Aduser $DN -profilepath $profilepath.ToLower().replace($oldserver,$newserver)
}
else {
Write-Host -foregroundcolor RED “User $name does not have roaming profile on $oldserver”
}

if ($homedirectory -like "*$oldserver*")
	{

#Add -whatif to next line before running the script to see what would happen
Set-Aduser $DN -homedirectory $homedirectory.ToLower().replace($oldserver,$newserver)
}
else {
Write-Host -foregroundcolor RED “User $name does not have a Home directory on $oldserver”
}
}

What I am thinking is one of 2 things, both I am struggling with what to actually search for to help me get the desired result.
1st Thought: Filter the first array ($users) further to only pass through users whose homedirectory or profilepath contain $oldserver

2nd Thought: Pre-export all users with this detail and break up into smaller files, and feed in a CSV/text file as the input to allow for a ‘batch processing’ mode

We have some sites with 10 users on low bandwith, to larger hospital sites with a few thousand users who will need to be migrated. Option 2 may be the better method of getting this done, but as I said, quite new to powershell and it been quite silly of me to have taken this long to get a real interest in it.

Any advice on where to start, or if someone can explain how to get what I’m after, so that I can try to learn how to do it myself? If this is simple then you can guess what sort of a newbie I am to all of this

It would be better to only query the desired users from AD in the first place, something the -filter or -ldapfilter parameters of Get-ADUser can accomplish for you. That way you’re not spinning through unnecessary data. I’m pretty sure -filter supports -like as an operator, although you’d need to experiment a bit from the command-line.

Hopefully I understand this correctly. Part 1: You’re attempting to find all Active Directory users who have an old server name used in their HomeDirectory path or in their ProfilePath. Part 2: you want that path replaced with exactly the same thing except for the server name to be the new server. Correct?

Here’s a fairly simple script to accomplish that task:

$OldServer = 'OldServer'
$NewServer = 'NewServer'

Import-Module ActiveDirectory
Get-ADUser -Filter "Enabled -eq 'true' -and HomeDirectory -like '*$OldServer*' -or ProfilePath -like '*$OldServer*'" -Properties HomeDirectory, ProfilePath |
ForEach-Object {
    if ($_.HomeDirectory -like "*$OldServer*") {
        Set-ADUser -Identity $_.DistinguishedName -HomeDirectory $($_.HomeDirectory -replace $OldServer, $NewServer)
    }
    if ($_.ProfilePath -like "*$OldServer*") {
        Set-ADUser -Identity $_.DistinguishedName -ProfilePath $($_.ProfilePath -replace $OldServer, $NewServer)
    }
}

If you want something a little more advanced, you can save the following script as a ps1 file and run the file specifying the names of the old and new server via parameter input. You can specify if you want the users who are changed to be returned via the PassThru parameter and you can also specify the WhatIf parameter to see which users will be changed before actually making the changes:

#Requires -Modules ActiveDirectory

[CmdletBinding()]
param (
    [ValidateNotNullOrEmpty()]
    [string]$OldServer = 'OldServer',

    [ValidateNotNullOrEmpty()]
    [string]$NewServer = 'NewServer',

    [switch]$PassThru,

    [switch]$WhatIf
)

$Params = @{}
If ($PSBoundParameters['PassThru']) {
            $Params.PassThru = $true
}

If ($PSBoundParameters['WhatIf']) {
            $Params.WhatIf = $true
}


Get-ADUser -Filter "Enabled -eq 'true' -and HomeDirectory -like '*$OldServer*' -or ProfilePath -like '*$OldServer*'" -Properties HomeDirectory, ProfilePath |
ForEach-Object {
    if ($_.HomeDirectory -like "*$OldServer*") {
        Set-ADUser -Identity $_.DistinguishedName -HomeDirectory $($_.HomeDirectory -replace $OldServer, $NewServer) @Params
    }
    if ($_.ProfilePath -like "*$OldServer*") {
        Set-ADUser -Identity $_.DistinguishedName -ProfilePath $($_.ProfilePath -replace $OldServer, $NewServer) @Params
    }
}

These scripts are something I came up with in just a few minutes so I would recommend thoroughly testing them before attempting to use them in production (at your own risk).

Thanks for the input guys. I’ll research what Don was talking about as it looks like there is a very good example of it from Mike.
My explanation of the second option was a little wayward. Essentially I was thining of extracting all of the users with their home directory and profile path information from AD and building indivifual lists for each server that is to be migrated. Using that list of usernames I could then look to do the larger sites in batches.
I’m guessing thats what the passthru parameter is for?

Lots of information here for me to get my head around. I think I need to start spending a bit more time with Powershell. Really appreciate the assistance

Not sure who posted it, but I noticed that a copy of the code I provided was posted on PoshCode.org: [url]http://poshcode.org/5367[/url]
I’m honestly flattered, although a link to this post would have been appreciated.
Just so everyone is aware, the code I provided is not an updated version of the code that was posted by the person who started this thread. It’s code I wrote from scratch to solve the problem that was posted as I understood it.

I will be writing a future blog article on my blog at http://mikefrobbins.com where I will be not only discussing this code but a way to once and for all resolve the problem of server paths such as this one where you’ll never need to change these sorts of hard coded paths ever again even if the server name changes. It’s something I’ve used for years in the datacenters I support and I’m not talking about a DNS hack.

Sorry Mike I quickly popped it up there as I thought it would be very helpful to other people. i have amended the description. Apologies for rushing it in the first place as I should have done it right.