How to make this more useful for my situation

This topic contains 5 replies, has 3 voices, and was last updated by Profile photo of Hayden Searle Hayden Searle 2 years, 3 months ago.

  • Author
    Posts
  • #17988
    Profile photo of Hayden Searle
    Hayden Searle
    Participant

    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

  • #18000
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

  • #18008
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    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).

  • #18009
    Profile photo of Hayden Searle
    Hayden Searle
    Participant

    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

  • #18026
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    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 [url]http://mikefrobbins.com[/url] 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.

  • #18029
    Profile photo of Hayden Searle
    Hayden Searle
    Participant

    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.

You must be logged in to reply to this topic.