Powershell : DFS Cleanup 🧽


If you are using an Active Directory Domain (ADDS) and you have the challenge I’ve tried to distribute shares and profiles over various servers then you will also be using Distributed File System (DFS).

‼️ WARNING

DFS is integrated into ADDS, this means if you do not have a valid backup and proceed to override your DFS data with incorrect information the only way to recover would be to do an authoritative restore on ADDS - regardless of experience, always take back ups!!!!!

DFS 101 

The purpose of DFS (no, not the furniture company, for the UK) is to provide an absolute path to a location known as a Path, and then distribute that location to various shares using SMB, this is known as the FolderTarget.

There are two components to DFS, you have the name space server, this is the one that integrates into act the directory and provide you a distributed namespace, which is where this article focuses on.
 
You also have a replication service known as DFS-R, while this is a handy feature, which enables you to replicate the same folder structure across two different servers it can also be quite temperamental and while it’s absolutely perfect to replicate SYSVOL which is actually used to do just that, however, this year cannot be edited by admins, when you start adding admin options, if set up incorrectly, you may find it will give you more headaches than solutions.

Why this entry?

The reason for this guide is many people would like to keep ADDS Running housekeeping tasks to remove older users or expire accounts that haven’t been used in a while, however, many times DFS will completely get overlooked, which means, for example if you are using DFS for user profile shares That will be a strong chance that you have more users in DFS and you have an ADDS.

Progression v Reality ⛅️ 

The other reason this maintenance needed to be done so I thought I’d do an entry about it, Is obviously with the world at the moment going cloud first the logical choice is OneDrive - however, as many people will find out the hard way OneDrive is not the universal fix for everything, and it can cause a whole different raft of problems that DFS would never have caused.

Everyone seems to be rushing to get in the line to get to OneDrive and move into the cloud, however many people forget about the legacy systems that require these, what is considered legacy technologies, while we will not abandon DFS as it’s required for the old applications that require certain scenarios to be true.

Example? Well if you have a non-routable domain like bear.local and you have excel macros that point at that domain, moving that particular excel spreadsheet to OneDrive without a VPN will cause failures as it’s trying to look up non-routable domains, not to mention the 900 Accounts that are still pointing at a bit of hardware in a data center that’s taking up 16U rack space.

Export DFS Namespace πŸ¦„

First, to get a handle on the scope of the situation we first need to export the current DFS namespace:
dfsutil /root:\\bear.local\honey/export:exportedroot.txt /verbose
This command will Export all the DFS structure and give you a Text file called exportedroot.txt - this will be output to the folder specified in the command, so in my case, it will be the current directory I’m running the command from.

Import DFS namespace πŸ‰ 

This is not technically part of what I was doing, but if you’re looking to make a large amount of changes to DFS, you can edit this text file to reflect the changes you like to make and then to make it live you simply just run this command.

Note : Please do not modify the export file and use that as your imported file, if you do that, you won’t have a backup of your old data and if you make a mistake, you can cause system instability, Instead, give this file a different name like I have done here.
dfsutil /root:\\bear.local\honey /import: importdfs.txt /set /verbose
When you run this command, it will import and override everything in DFS with the contents of this file, please ensure the data is correct.

Back to the mission

Right, so now we have the text file with the DFS data inside we now need to look the Path and the FolderTargets that we need to update, so spooling though a large text file is not ideal, so lets get Powershell to do the heavy lifting here for us, however first we need to know what we are looking for to get the script to extract.

If we open the text file what we are looking to target and find a match for this this extract for in this case one user:

<Link Name="Users\Bear.Admin1" Comment="Bear Admin No.1" State="1" Timeout="300" >
<Target Server="honeypot.bear.local" Folder="users$\Bear.Admin1" State="2" />
</Link>

So from this lets highlight all the sections we require which in this case if the Target Server and the State which here is 2 as highlighted below as all the other is not required:

<Link Name="Users\Bear.Admin1" Comment="Bear Admin No.1" State="1" Timeout="300" >
<Target Server="honeypot.bear.local" Folder="users$\Bear.Admin1" State="2" />
</Link>

This is it visually first we need to find the share then we need to choose "Add Folder Target"


Then we need to add a new folder target for the share:


We are then looking to see two folder targets one enabled and one disabled, the enabled one is where the data currently is, and the disabled one is where the data will be located after this update.


Now we need a script to search that file for all the honeypot.bear.local targets with the status of 2 so this is the script for that:

# Define the path to your text file
$filePath = "exportedroot.txt"

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $targetServer = $matches[1]
        $folder = $matches[2] -replace '/', ''  
        $state = "2"
        Write-Output "Target Server: $targetServer, Folder: $folder, State: $state"
    }
}

When you run that script it will return an output like this, which is the data we require but it needs a cleanup, but that will list all the filepatch thats will need to be updated.

Target Server: honeypot.bear.local, Folder: users$\Bear1, State: 2
Target Server: honeypot.bear.local, Folder: users$\Bear5, State: 2
Target Server: honeypot.bear.local, Folder: users$\Bear6, State: 2
Target Server: honeypot.bear.local, Folder: users$\Bear16, State: 2
Target Server: honeypot.bear.local, Folder: users$\Bear32, State: 2

We are not able to do anything with that data as all we need is the samAccoutName for this next section, not all the other data, then we can use the variable set in other commands, but the data needs to be valid else the script will fail, so this is where we move to the next script:

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $folder = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $users += $folder
    }
}

# Display the list of users
$users

This will cleanup the data from the previous script and you will get an output that should look something like this:

Bear1
Bear5
Bear6
Bear16
Bear32

Excellent we can use this data for the next part of the scripting to get the update done, so for now these users will be stored in the variable name $users - so now we can move on to the assessment stage which will assess how many items we are talking about, but we are only interested in enable accounts (if they are for users) and as the DFS data is not linked to ADDS accounts I would like to know how many do not exist.

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create variables to store the counts
$enabledCount = 0
$disabledCount = 0
$notFoundCount = 0

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $username = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $username = $username.Trim() # Ensure no leading or trailing whitespace

        # Attempt to get the user's enabled status from Active Directory
        try {
            $user = Get-ADUser -Identity $username -Properties Enabled -ErrorAction Stop
            if ($user.Enabled) {
                $enabledCount++
            } else {
                $disabledCount++
            }
        } catch {
            Write-Warning "User '$username' not found in Active Directory."
            $notFoundCount++
        }
    }
}

# Display the counts
"Number of Enabled Accounts: $enabledCount"
"Number of Disabled Accounts: $disabledCount"
"Number of Accounts Not Found: $notFoundCount"

When you run this you will get a list of accounts that are enabled/disabled/none existent which is handy, now you have the numbers we can move forward, the numbers are below:

Number of Enabled Accounts: 594
Number of Disabled Accounts: 168
Number of Accounts Not Found: 107

Export the Invalid/Disabled Accounts

So you can get a handle of the issue you need these accounts exported to a CSV so that you can do some further processing, therefore lets get that done with more Powershell, the script for this is below:

# Define the path to your text file
$filePath = "exportedroot.txt"
# Define the path to the CSV output file
$outputCsvPath = "disabled_and_non_existent_accounts.csv"

# Create a list to store the results
$results = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(SVM00\.stwater\.intra)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $username = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $username = $username.Trim() # Ensure no leading or trailing whitespace

        # Attempt to get the user's enabled status from Active Directory
        try {
            $user = Get-ADUser -Identity $username -Properties Enabled -ErrorAction Stop
            if (-not $user.Enabled) {
                # If the user is disabled, add to the results list
                $results += [pscustomobject]@{
                    Username = $username
                    Status   = "Disabled"
                }
            }
        } catch {
            # If the user is not found, add to the results list
            $results += [pscustomobject]@{
                Username = $username
                Status   = "Not Found"
            }
        }
    }
}

# Export the results to a CSV file
$results | Export-Csv -Path $outputCsvPath -NoTypeInformation

# Output completion message
"Export complete. Disabled and non-existent accounts have been exported to $outputCsvPath"

This will then export a CSV file with all the accounts and their status in the second column as below:


Now you can see the account and the status so "Disabled" or "Not Found" and the account is the bit blurred out.

DFS Namespace Administration Commands

Now we need to know the commands that the script will use to automate these actions, so these are the commands we will require to get the script to automate this process.

Create a New FolderTarget : Offline

New-DfsnFolderTarget -Path '\\bear.local\users\Bear1' -TargetPath '\\bearclaws.bear.local\Users\Bear1' -State Offline

Create a New FolderTarget : Online

Note : If you create the FolderTarget as online this will then be immediately available to the user, so just ensure that you have the data in there - else DFS will show people the empty folder!

New-DfsnFolderTarget -Path '\\bear.local\users\Bear1' -TargetPath '\\bearclaws.bear.local\Users\Bear1' -State Online

Change the Status of an Offline FolderTarget to Online (used after its been created already)

Note : If you create the folder Offline you will not be able to set it Online with the New-DfsnFolderTarget command, you need the Set-DfsnFolderTarget command

Set-DfsnFolderTarget -Path '\\bear.local\users\Bear1' -TargetPath '\\bearclaws.bear.local\Users\Bear1' -State Online

Remove the TargetPath from DFS Namespace

Note : If you delete the FolderTarget and there are no others valid, then it will delete the folder as well, so ensure you create a new one before deleting the old one!

Remove-DfsnFolderTarget -Path '\\bear.local\users\Bear1' -TargetPath '\\bearclaws.bear.local\Users\Bear1'

Now we have the commands we can do something about those non-valid accounts and the disabled accounts - in this instance I have decided to remove the path from DFS namespace configuration for both non-valid and disabled accounts - call it housekeeping.

Delete Non-Valid accounts from DFS Namespace

Lets get to deleting the accounts from DFS namespace for the invalid accounts, for that we will use this script:

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create variables to store the counts
$enabledCount = 0
$disabledCount = 0
$notFoundCount = 0
$deletionCount = 0

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $username = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $username = $username.Trim() # Ensure no leading or trailing whitespace

        # Attempt to get the user's enabled status from Active Directory
        try {
            $user = Get-ADUser -Identity $username -Properties Enabled -ErrorAction Stop
            if ($user.Enabled) {
                $enabledCount++
            } else {
                $disabledCount++
            }
        } catch {
            Write-Warning "User '$username' not found in Active Directory."
            $notFoundCount++
            # Confirmation prompt to remove DFSN folder target
            $confirmation = Read-Host "Do you want to remove the DFSN folder target for user '$username'? (Y/N)"
            if ($confirmation -eq "Y" -or $confirmation -eq "y") {
                # Run the command to remove DFSN folder target for the account not found
                $targetPath = "\\honeypot.bear.local\users`$\$username"
                $dfsPath = "\\bear.local\Users\$username"
                Remove-DfsnFolderTarget -Path $dfsPath -TargetPath $targetPath
                Write-Output "Removed DFSN folder target for user: $username"
                $deletionCount++
            } else {
                Write-Output "Folder link removal cancelled for user: $username"
            }
        }
    }
}

# Display the counts
"Number of Enabled Accounts: $enabledCount"
"Number of Disabled Accounts: $disabledCount"
"Number of Accounts Not Found: $notFoundCount"
"Number of DFSN Folder Targets Deleted: $deletionCount"

Once the script completes all the non-valid accounts which are not in ADDS will be removed from the DFS configuration namespace and you will get a deletion count of how many TargetFolder items have been disabled, the deletion and the count is in bold.

Note : Once you have done this remember to get another DFS export if you wish these results to reflect in your script, remember you script is using the text file not ADDS.

Generate a New DFS Export 

Now you have done some cleanup to remove the "invalid" and "disabled" accounts from DFS Namespace you no longer need to filter these accounts - as the new filtered and cleaned data will be available in the exported file, this command we give you a new file, in my example I have overridden the old file with all the disabled/inactive accounts (as its not required)

dfsutil /root:\\bear.local\honey/export:exportedroot.txt /verbose

Check Folder Availability on "new SMB" destination

We now need to see if the folder that is present on the old SMB file system is present on the new SMB file system, as if there is no folder present you will not be able to create the TargetFolder as you will receive an error as its not there, so lets cycle though all the users and see which ones have folders and which ones do not, with this:

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users and their folder existence status
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB share
$basePath = "\\bearclaws.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $folder = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $folder = $folder.Trim() # Ensure no leading or trailing whitespace
        $folderPath = Join-Path -Path $basePath -ChildPath $folder

        # Diagnostic output
        Write-Output "Checking path: $folderPath"

        if (Test-Path -Path $folderPath) {
            $users += "$folder, Folder Exists"
        } else {
            $users += "$folder, Folder Does Not Exist"
        }
    }
}

# Display the list of users and their folder status
$users

This should the output which after it has listed all the paths to check, it will give you the summary at the bottom like this, and from this we have 4 folders that are not present on the new SMB share:

Bear1, Folder Exists
Bear5, Folder Does not Exist
Bear6, Folder Does not Exist
Bear16
, Folder Does not Exist
Bear32
, Folder Does not Exist

Create folder on new SMB share for users without one

This one is simple, as its only creating a folder on a SMB share, therefore no confirmation is really required for this as its a empty folder, so lets get that done with this script.

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users and their folder existence status
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB share
$basePath = "\\bearclaws.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $folder = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $folder = $folder.Trim() # Ensure no leading or trailing whitespace
        $folderPath = Join-Path -Path $basePath -ChildPath $folder

        # Diagnostic output
        Write-Output "Checking path: $folderPath"

        if (Test-Path -Path $folderPath) {
            $users += "$folder, Folder Exists"
        } else {
            try {
                # Attempt to create the folder
                New-Item -ItemType Directory -Path $folderPath -Force
                $users += "$folder, Folder Did Not Exist, Folder Created"
            } catch {
                $users += "$folder, Folder Did Not Exist, Failed to Create Folder: $_"
            }
        }
    }
}

# Display the list of users and their folder status
$users

This should then create all the foldersm however if you would like a confirm here as well then use this code to ask you 

# Ask for confirmation before creating the folder
            $confirmation = Read-Host "Folder '$folderPath' does not exist. Do you want to create it? (Y/N)"
            if ($confirmation -eq 'Y' -or $confirmation -eq 'y')

Then for every folder it wants to create you will get this displayed to which you have to enter "y"

Folder '\\bear.local\Users\Bear5' does not exist. Do you want to create it? (Y/N): y

Create new DFS TargetFolder links : In Offline mode

When we need to create the new the TargetPath for all the users (remember this should be using the data that is valid, this was covered earlier) and this will create the new FolderTarget as offline this is the script:

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB share
$basePath = "\\bearclaws.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches and store the user names
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $user = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $user = $user.Trim() # Ensure no leading or trailing whitespace
        $users += $user
    }
}

# Display the list of users for debugging purposes
Write-Output "Users extracted:"
$users | ForEach-Object { Write-Output $_ }

# Define the target server and target path
$targetServer = '\\bearclaws.bear.local\Users'
$state = 'Offline'

# Loop through each user in the $users list to update the DFS target
foreach ($user in $users) {
    $path = "\\honeypot.bear.local\Users\$user"
    $targetPath = "$targetServer\$user"

    # Confirm with the user before applying the change
    $confirmation = Read-Host ("Do you want to update the DFS target for user $user? (y/n)")
    if ($confirmation -eq 'y') {
        Set-DfsnFolderTarget -Path $path -TargetPath $targetPath -State $state
        Write-Output "Updated DFS target for user $user."
    } else {
        Write-Output "Skipped DFS target update for user $user."
    }
}

Script to Create and Create Folder and then create the DFS TargetPath

I am not usually one for "mutiple item" scripts as it can become harder to debug if something does wrong, this this script will check for the folder and where applicable create it then it will also create the TargetPath with the status is disabled, however this script does not confirm at all.

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users and their folder existence status
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB share
$basePath = "\\bearclaws.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches and check folder existence
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $folder = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $folder = $folder.Trim() # Ensure no leading or trailing whitespace
        $folderPath = Join-Path -Path $basePath -ChildPath $folder

        # Diagnostic output
        Write-Output "Checking path: $folderPath"

        if (Test-Path -Path $folderPath) {
            $users += "$folder, Folder Exists"
        } else {
            # Ask for confirmation before creating the folder
            $confirmation = Read-Host "Folder '$folderPath' does not exist. Do you want to create it? (Y/N)"
            if ($confirmation -eq 'Y' -or $confirmation -eq 'y') {
                try {
                    # Attempt to create the folder
                    New-Item -ItemType Directory -Path $folderPath -Force
                    $users += "$folder, Folder Did Not Exist, Folder Created"
                } catch {
                    $users += "$folder, Folder Did Not Exist, Failed to Create Folder: $_"
                }
            } else {
                $users += "$folder, Folder Did Not Exist, Creation Skipped"
            }
        }
    }
}

# Display the list of users and their folder status
$users

# Define the target server and target path
$targetServer = '\\bearclaws.bear.local\Users'
$state = 'Offline'

# Create a dummy $userupdate list for the example
$userupdate = $users | ForEach-Object { $_.Split(',')[0].Trim() }  # Extract the usernames

# Loop through each user in the $userupdate list to update the DFS target
foreach ($user in $userupdate) {
    $path = "\\stwater.intra\stw\UserData\Users\$user"
    $targetPath = "$targetServer\$user"
    
    # Confirm with the user before applying the change
    $confirmation = Read-Host "Do you want to update the DFS target for user $user? (y/n)"
    if ($confirmation -eq 'y') {
        Set-DfsnFolderTarget -Path $path -TargetPath $targetPath -State $state
        Write-Output "Updated DFS target for user $user."
    } else {
        Write-Output "Skipped DFS target update for user $user."
    }
}

Copy the Data from the old SMB Share to the new SMB share

This will take the variable we used before and then start a robocopy to the new location, this will do this for each users that requires there data to be copied to the new location.

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB share
$basePath = "\\honeypot.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches and store the user names
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $user = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $user = $user.Trim() # Ensure no leading or trailing whitespace
        $users += $user
    }
}

# Display the list of users for debugging purposes
Write-Output "Users extracted:"
$users | ForEach-Object { Write-Output $_ }

# Define the source and target servers
$sourceServer = '\\honeypot.bear.local\Users'
$targetServer = '\\bearclaws.bear.local\Users'

# Loop through each user in the $users list to copy the data using robocopy
foreach ($user in $users) {
    # Additional debug statement to check if user is not empty
    if ([string]::IsNullOrWhiteSpace($user)) {
        Write-Output "Encountered an empty or null username. Skipping this user."
        continue
    }

    $sourcePath = "$sourceServer\$user"
    $targetPath = "$targetServer\$user"

    # Log the user being processed
    Write-Output "Copying data for user $user."

    # Run the robocopy command to copy the data
    robocopy $sourcePath $targetPath /E /Z /COPY:DATS /R:0 /W:0 /ipg:1
    if ($LASTEXITCODE -le 3) {
        Write-Output "Successfully copied data for user $user."
    } else {
        Write-Output "Error copying data for user $user. Robocopy exit code: $LASTEXITCODE"
    }
}

Enable the DFS TargetFolder links : Promote to Online (and take legacy one offline)

This step will then take the Offline folder pointing at the new location and set it Online which means the data will be live in the new location not the old, and then turn the old location to offline which then means the data will be live in the new location.

# Define the path to your text file
$filePath = "exportedroot.txt"

# Create an empty array to store the users
$users = @()

# Read the content of the file
$fileContent = Get-Content -Path $filePath

# Define the base path for the SMB shares
$newBasePath = "\\dyingtree.bear.local\Users"
$oldBasePath = "\\honeypot.bear.local\Users"

# Define a regex to match the target server and state pattern
$regex = '<Target Server="(honeypot\.bear\.local)" Folder="users\$([^"]+)" State="2" />'

# Process each line to find matches and store the user names
foreach ($line in $fileContent) {
    if ($line -match $regex) {
        $user = $matches[2] -replace '/', '' -replace '^\\', '' # Remove the leading backslash
        $user = $user.Trim() # Ensure no leading or trailing whitespace
        $users += $user
    }
}

# Display the list of users for debugging purposes
Write-Output "Users extracted:"
$users | ForEach-Object { Write-Output $_ }

# Loop through each user in the $users list to update the DFS targets
foreach ($user in $users) {
    $path = "\\bear.local\Users\$user"
    $newTargetPath = "$newBasePath\$user"
    $oldTargetPath = "$oldBasePath\$user"

    # Bring the new path online
    Set-DfsnFolderTarget -Path $path -TargetPath $newTargetPath -State Online
    Write-Output "Updated new DFS target for user $user to online."

    # Bring the old path offline
    Set-DfsnFolderTarget -Path $path -TargetPath $oldTargetPath -State Offline
    Write-Output "Updated old DFS target for user $user to offline."
}

Previous Post Next Post

Ω†Ω…ΩˆΨ°Ψ¬ Ψ§Ω„Ψ§ΨͺΨ΅Ψ§Ω„