The easiest way of doing this is using dfsutil.exe to export the namespace to an xml file on both servers, read them, compare and then make a readable output of the differences.
Export namespace to an xml:
$command = "dfsutil /root:$dfsrt /export:c:\temp\$filename /api"
writelog 0 "running command: $command"
$err = invoke-expression $command
Pick up the content with PowerShell but only the part we need and store it in our custom object for later use (pointer name and target):
$tmpXMLcontent = ([xml] [string]::join("`n",(get-content c:\temp\$filename))).root.link | %{$_.name}
$script:sObject.DFS_Links = $tmpXMLcontent
When we have this from both DFS servers, we can compare them and store differences in separate variables:
$notOnFirstHost = compare $objcoll[0].DFS_links $objcoll[1].DFS_links -SyncWindow 100000 | ?{$_.SideIndicator -ieq "=>;"} | %{$_.InputObject}
$notOnSecondHost = compare $objcoll[0].DFS_links $objcoll[1].DFS_links -SyncWindow 100000 | ?{$_.SideIndicator -ieq "<="} | %{$_.InputObject}
Now go through the content of the 2 variables and create our custom object collection with the results, e.g.:
$notOnFirstHost | %{
$obj = "" | select DFS_Link,$objColl[0].ComputerName,$objColl[1].ComputerName
$obj.DFS_Link = $_
$obj."$($objColl[0].ComputerName)" = "Doesn't exist"
$obj."$($objColl[1].ComputerName)" = "Exists"
$resColl += $obj
}
If we want to make the data even more detailed, we can look up the target folder of the particular DFS link from the xml dump to see where it is supposed to point to:
function lookupDFSTarget($fdfslink, $fdfsdumpfile, $fxmlcontent){
$retvalArr = @()
$targets = $fxmlcontent | ?{$_.name -ieq $fdfslink} | %{$_.target}
$targets | %{
$tmpstr = ("\\" + $_.server + "\" + $_.folder)
$retvalArr += $tmpstr
}
$retval = [string]::Join(";", $retvalArr)
return $retval
}
The output is something like this:
The full script (usage compare-dfslinks.ps1 -dfsroots \\c3podfs1\root,c3podfs2\root -lookup)
param ( [string] $dfsroots = "",
[string] $log = "",
[switch] $lookupTarget = $false)
$logfile = new-item -type file "C:\temp\compare-dfslinks.log" -force
#### Function for creating log entries in a logfile and on standard output
function writeLog ([int]$type, [string]$message, [string]$modifier) { #usage: writeLog 0 "info or error message"
# $modifier: <nonew | extend>
# Value nonew: writes the output the the console and the logfile without carriage return
# Value raw: writes the message to the output without date and
# both values can be used e.g. for writting to the console and logfile and put a status message at the end of the line as a second step
$date = get-date -uformat "%Y/%m/%d %H:%M:%S"
if($modifier -eq "extend"){
switch ($type) {
"0" {$color = "Green"}
"1" {$color = "Yellow"}
"2" {$color = "Red"}
}
}
else{
switch ($type) {
"0" {$message = $date + ", INF, " + $message; $color = "Green"}
"1" {$message = $date + ", WAR, " + $message; $color = "Yellow"}
"2" {$message = $date + ", ERR, " + $message; $color = "Red"}
}
}
if($modifier -eq "nonew"){
write-host $message -ForegroundColor $color -NoNewLine
$bytes = [text.encoding]::ascii.GetBytes($message)
$bytes | add-content $logfile -enc byte
}
else{
write-host $message -ForegroundColor $color
Add-Content $logfile $message
}
}
#### Function to lookup DFS target of a DFS link from dump xml
function lookupDFSTarget($fdfslink, $fdfsdumpfile, $fxmlcontent){
$retvalArr = @()
$targets = $fxmlcontent | ?{$_.name -ieq $fdfslink} | %{$_.target}
$targets | %{
$tmpstr = ("\\" + $_.server + "\" + $_.folder)
$retvalArr += $tmpstr
}
$retval = [string]::Join(";", $retvalArr)
return $retval
}
$objColl = $dfscontent = $resColl = @()
$k = 1
$dfsrootlist = $null
$dfsrootsArr = @($dfsroots.split(" "))
$dfsrootlist += $dfsrootsArr
$dfsrootlistlength = $dfsrootlist.length
if($dfsrootlistlength -gt 0){
if($dfsrootlistlength -eq 2){
foreach($dfsrt in $dfsrootlist){
Write-Progress -id 1 -activity "Performing DFS checks" -Status "Processing DFS Master $k of $dfsrootlistlength : $dfsrt " -PercentComplete ($k/$dfsrootlistlength * 100) -currentoperation "checking DFS..."
$filename = $dfsrt.replace("\\","")
$filename = $filename.replace("\","_") + ".xml"
$srvname = $dfsrt.split("\")[2]
$script:sObject = new-Object -typename System.Object
$script:sObject | add-Member -memberType noteProperty -name ComputerName -Value $srvname
$script:sObject | add-Member -memberType noteProperty -name DFS_Links -Value ""
$script:sObject | add-Member -memberType noteProperty -name DFS_dump_file -Value ""
if($filename -and (Test-Path "c:\temp\$filename")){
Remove-Item c:\temp\$filename -Force
}
$script:sObject.DFS_dump_file = "c:\temp\$filename"
$command = "dfsutil /root:$dfsrt /export:c:\temp\$filename"
writelog 0 "running command: $command"
$err = invoke-expression $command
$tmpXMLcontent = ([xml] [string]::join("`n",(get-content c:\temp\$filename))).root.link | %{$_.name}
$script:sObject.DFS_Links = $tmpXMLcontent
$objColl += $script:sObject
$k++
}
}
}
else{
writeLog 2 "No DFS server is specified."
}
writelog 0 "Running compare between the 2 xmls"
$notOnFirstHost = compare $objcoll[0].DFS_links $objcoll[1].DFS_links -SyncWindow 100000 | ?{$_.SideIndicator -ieq "=>"} | %{$_.InputObject}
$notOnSecondHost = compare $objcoll[0].DFS_links $objcoll[1].DFS_links -SyncWindow 100000 | ?{$_.SideIndicator -ieq "<="} | %{$_.InputObject}
if($notOnFirstHost -or $notOnSecondHost){
if($notOnFirstHost){
$xmlcontent = $null
if($lookupTarget) {$xmlcontent = ([xml] [string]::join("`n",(get-content $($objColl[1].DFS_dump_file)))).root.link}
$notOnFirstHost | %{
if($lookupTarget) {$obj = "" | select DFS_Link,DFS_Target,$objColl[0].ComputerName,$objColl[1].ComputerName}
else {$obj = "" | select DFS_Link,$objColl[0].ComputerName,$objColl[1].ComputerName}
$obj.DFS_Link = $_
$obj."$($objColl[0].ComputerName)" = "Doesn't exist"
$obj."$($objColl[1].ComputerName)" = "Exists"
if($lookupTarget){$obj.DFS_Target = lookupDFSTarget $_ ($($objColl[1].DFS_dump_file)) $xmlcontent }
$resColl += $obj
}
}
if($notOnSecondHost){
$xmlcontent = $null
if($lookupTarget) {$xmlcontent = ([xml] [string]::join("`n",(get-content $($objColl[0].DFS_dump_file)))).root.link}
$notOnSecondHost | %{
if($lookupTarget) {$obj = "" | select DFS_Link,DFS_Target,$objColl[0].ComputerName,$objColl[1].ComputerName}
else {$obj = "" | select DFS_Link,$objColl[0].ComputerName,$objColl[1].ComputerName}
$obj.DFS_Link = $_
$obj."$($objColl[1].ComputerName)" = "Doesn't exist"
$obj."$($objColl[0].ComputerName)" = "Exists"
if($lookupTarget){$obj.DFS_Target = lookupDFSTarget $_ ($($objColl[0].DFS_dump_file)) $xmlcontent }
$resColl += $obj
}
}
}
else{
writelog 1 ("No differences between links on " + $srvArr[0] + " and " + $srvArr[1] )
}
$resColl
sdfsdf
No comments:
Post a Comment