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:
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
Bear1
Bear5
Bear6
Bear16
Bear32
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"
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.
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.
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:
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
Bear5, Folder Does not Exist
Bear6, Folder Does not Exist
Bear16, Folder Does not Exist
Bear32, 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
Then for every folder it wants to create you will get this displayed to which you have to enter "y"
# 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."
}