Dfs Namespace folder properties error using powershell

Copper Contributor

Here are the error while creating the DFS namespace:

please help me to get the solution or the PowerShell script

get-dfsnroot : Cannot get DFS folder properties on "\\\-DFS"
At C:\install\DFS1.ps1:394 char:8
+ if(get-dfsnroot -path \\$DomainShort\$DFSRootName-DFS | get-dfsnr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_DFSNamespace:ROOT\Microsoft\...FT_DFSNamespace) [Get-DfsnRoot], CimException
+ FullyQualifiedErrorId : Windows System Error 87,Get-DfsnRoot

get-dfsnroot : One or more parameter values passed to the method were invalid.
At C:\install\DFS1.ps1:394 char:8
+ if(get-dfsnroot -path \\$DomainShort\$DFSRootName-DFS | get-dfsnr ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_DFSNamespace:ROOT\Microsoft\...FT_DFSNamespace) [Get-DfsnRoot], CimException
+ FullyQualifiedErrorId : MI RESULT 4,Get-DfsnRoot

17 Replies
#---------------------------------------------------------------------------
#Name = DFSroot
#Version = 1.00
#Author = Vinod Kumar Lohar
#Purpose = Hosting P drive for Techops sites in IN.YKGW.NET
#---------------------------------------------------------------------------


<#


.DESCRIPTION
The script if for: Creating DFS roots in remote sites, hubs and for INTL roots for nvstop.net domain.
Installation Log will be created in C:\Install folder

Example usage:
.\DFSroot.ps1 - It will create DFS root for site parsed from server hostname- e.g:
Executed on server: POC-WIN2022-SRV will create POC-DFS root

.\DFSroot.ps1 POC - It will create DFS root POC-DFS



.NOTES
Prerequisites:

-Must be executed on elevated window.
-Must be executed on Windows Server 2012 and higher.


What is built in:

-Checking prerequisites
-Installation of DFS components is included.
-Creation of DFS root directory structure.
-Setting up permissions for directories
-Creation of Backup commands and Scheduled Tasks.
-Logging to log file in C:\Install folder


#>



#params
param(
[string]$SiteCode = $null,
[string]$multipleDFS = "single"
)
$sitecode = $SiteCode.ToUpper()
import-module ServerManager

$date=get-date -format "yyyy.MM.dd-hh.mm.ss"
$LogFilePath="C:\install\DFSroot(creation)_logfile_$date.txt"
" " > $LogFilePath
$error = $false

#terminate function
function terminate{

log "Script would terminate now"
pause
log "***********************************Script terminated (DFS creation canceled)*********************************"
log '*************************************************************************************************************'

exit

}

#Function that displays message and stores into the logfile
function log($mesage,$message2){
$time=get-date -Format "hh.mm.ss"
$output=$time+" "+ $mesage+" "+$message2
$output>>$LogFilePath
write-host $output

}
function logNoTimestamp($mesage,$message2){
$time=get-date -Format "hh.mm.ss"
$output=$mesage+" "+$message2
$output>>$LogFilePath
write-host $output

}

#checking if server is configured to use FQDN
function DFSFQDN{
IF((Get-DfsnServerConfiguration localhost).UseFqdn -eq $False)
{
log "Server is being configured for FQDN"
Set-DfsnServerConfiguration -ComputerName localhost -UseFqdn $true
}
Else
{
log "Server is using FQDN"

}


}

#checking if script is runned as elevated rights
function checkRunAsAdmin{
$myIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$wp = New-Object Security.Principal.WindowsPrincipal($myIdentity)
if (-not $wp.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
log "This script requires administrative privileges, please re-launch with elevated credentials"
pause
terminate
}
}



#Function that verify if server have proper OS installed and if it is proper member server
function verifyServer {
$computer=Get-WMIObject win32_computersystem
if(($computer).domainrole -ne 3){
return $false
}

elseif([version](Get-CimInstance Win32_OperatingSystem).version -lt 6.2){
return $false
}

else{
return $true
}
}

#Function that wait for keyboard hit

function pause{

if (((Get-Host).Name) -eq 'ConsoleHost'){
#log -NoNewLine "Press any key to continue"
#$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Start-Sleep -Seconds 1
log ""
} else {
Start-Sleep -Seconds 1
}
}

#Initialization of Site type DFS
function InitSite{
log "DFS Site Init: Start"

log "New-Item(Creating new directory):",(New-Item -ItemType directory -path C:\DFS\$DFSRootName-DFS\DATA)

}
#Function that checks if provided feature is installed

function checkifFeatureInstalled($Featurename){
if((get-windowsfeature $Featurename).installed){
return $true
}
else{ return $false
}
}



#Function that gets domain name
function getDomain{
return (Get-WmiObject Win32_ComputerSystem).domain
}

function success($param){
if($param -eq $true){
log ''
log "At least one link was not created successfully. Please check the log file"
log '*************************************************************************************************************'
log '***********************************DFS created but with some errors!!!***************************************'
log '*************************************************************************************************************'
}
else{
log 'all success'
log '*************************************************************************************************************'
log '***************************************DFS created successfully!!!!!!!!**************************************'
log '*************************************************************************************************************'
}

}

function backup ($DFSRoot){
if(!(test-path C:\Install\DFS-SAVE)){ log "New-Item(Creating Directory):" ,(new-item -ItemType Directory C:\Install\DFS-SAVE)}
if(!(test-path C:\Install\DFS-BACKUP)){ log "New-Item(Creating Directory):" , (new-item -ItemType Directory C:\Install\DFS-BACKUP)}
"dfscmd /view \\$ServerDomain\$DFSRoot-dfs /batch > c:\install\DFS-SAVE\$DFSRoot-DFS-%1.txt" | out-file C:\Install\DFS-BACKUP\Backup-DFS.bat -Encoding ASCII -Append
get-content C:\Install\DFS-BACKUP\Backup-DFS.bat | sort -u | set-content -path C:\Install\DFS-BACKUP\Backup-DFS.bat
$content = [IO.File]::ReadAllText("C:\install\DFS-BACKUP\Backup-DFS.bat")
log "Printing C:\install\DFS-BACKUP\Backup-DFS.bat file content that will be used for creating backup files"
log "*************************Starting file content: C:\install\DFS-BACKUP\Backup-DFS.bat*************************"
logNoTimestamp $content
log '**********************************************End of file content********************************************'
$days= @(("Monday", "MON"), ("Tuesday","TUE"),("Wednesday","WED"),("Thursday","THU"),("Friday","FRI"),("Saturday","SAT"),("Sunday","SUN"))
foreach($day in $days){
$long=$day[0]
$short=$day[1]
$output= schtasks /create /tn DFSDump_$long /tr "C:\INSTALL\DFS-BACKUP\Backup-DFS.bat $long" /SC WEEKLY /D $short /ST 23:00 /ru "SYSTEM" /F
log "SCHTASKS: $output"
}




}

#Main Program
cls
log '*************************************************************************************************************'
log '***************************************DFS root creation script**********************************************'
log '*************************************************************************************************************'
log Activating DFS
log ''

#check if script is runned as elevated user
checkRunAsAdmin



#check if server is a proper member server, proper OS version and member server
if(verifyServer){
log "Server OS version and membership verified successfully, script will continue"
pause
}
else{
log "Server OS version and membership verified uncsuccessfully, script will terminate now "
pause
terminate

}







#Getting Domain information from server properties and hostname
$Computername=($env:COMPUTERNAME).ToUpper()

$ServerDomain=(getDomain).ToLower()

$DomainSplited=$ServerDomain -split "\."
$DomainPrefix= $ServerDomain -split "\." | select -first 1
$DomainSuffix= $ServerDomain -split "\." | select -last 1

if($DomainSplited.Count -eq 2){
$ServerDomainRoot=$false
$DFSRootName=$SiteCode
$DomainxName=$ServerDomain
$DomainShort=$DomainPrefix+ $DomainSuffix
}

else{

}


log ""
log "Server domain is: $ServerDomain"
log "Server computername is: $Computername"
log "Domain prefix is: $DomainPrefix"
log "Domain suffix is: $DomainSuffix"
log "If it is root domain: $ServerDomainRoot"
log "DFSroot name is: $DFSRootName"
log "DomxName is: $DomainxName"
log "NB domain is: $DomainShort"
log "Multiple Site DFS init: $multipleDFS"
log ''
log '*************************************************************************************************************'
log '************************************Starting to Install DFS components***************************************'
pause

$LogFilePathOld=$LogFilePath
$LogFilePath="C:\install\DFSroot_$DFSRootName(creation)_logfile_$date.txt"
rename-item $LogFilePathOld $LogFilePath



#instaling DFS features

if(!(checkifFeatureInstalled("FS-DFS-Namespace"))){
log "Installing FS-DFS-Namespace feature"
Add-WindowsFeature FS-DFS-Namespace
}
else{
log "FS-DFS-Namespace feature already installed"
}
if(!(checkifFeatureInstalled("FS-DFS-Replication"))){
log "Installing FS-DFS-Replication feature"
Add-WindowsFeature FS-DFS-Replication
}
else{
log "FS-DFS-Replication feature already installed"
}
if(!(checkifFeatureInstalled("RSAT-DFS-Mgmt-Con"))){
log "Installing RSAT-DFS-Mgmt-Con feature"
Add-WindowsFeature RSAT-DFS-Mgmt-Con
}
else{
log "RSAT-DFS-Mgmt-Con feature already installed"
}



#check for existing root on the server
if(get-dfsnroot -computerName $ComputerName | where { $_.Path -like "*\\$Domainshort\$DFSRootName-DFS*"}){
log "DFS root exist- script will now terminate"
terminate
}
log "DFS root not found- script will continue"
pause

#check if root exist in domain
$mode=$null
if(get-dfsnroot -path "\\$DomainShort\$DFSRootName-DFS" -erroraction silentlycontinue){
log "DFS root exist in domain- script will create replica"
$mode="Replica"
}
else{
log "DFS share not exist in domain - script will create new root"
$mode="Fresh"
}

#creating folder structure
if(!(test-path c:\dfs)){
log "New-Item(Creating Directory):",( New-Item -ItemType directory -path C:\DFS )
}
else{
if($multipleDFS -eq "multipleDFS"){
log "Folder c:\dfs already exist, script will continue because of multiple site DFS init"
log '*****************************************Multiple site DFS init**********************************************'



}
else{
log "Folder c:\dfs already exist, script will now terminate"
log "If you want to create another Site DFS on this server, please run the script like: .\DFSroot.ps1 SITE multipleDFS"
log "Where SITE is sitecode of DFS root that need to be created e.g: .\DFSroot.ps1 CMM multipleDFS"


terminate
}
}

if(!(test-path c:\dfs\$DFSRootName-DFS)){
log "New-Item(Creating Directory):",(New-Item -ItemType directory -path c:\dfs\$DFSRootName-DFS)
}

#checking dfsconfiguration
DFSFQDN

#creating data folder
initsite

$output = icacls C:\DFS\$DFSRootName-DFS /inheritance:r
log "ICACLS: $output"
$output = icacls C:\DFS\$DFSRootName-DFS --% /grant Administrators:(OI)(CI)F Everyone:(CI)(RX)
log "ICACLS: $output"

$output = net share $DFSRootName-DFS=C:\DFS\$DFSRootName-DFS /GRANT:'Everyone,Full'
log "Net Share: $output"

#Execute initialization if current DFS will be replica of existing one.

if($mode -eq "Replica"){
log '*************************************************************************************************************'
log '**********************************************Replica Mode***************************************************'
log "Linking DFS Root $DFSRootName-DFS"

log (New-DfsnRootTarget -TargetPath "\\$Computername\$DFSRootname-DFS" -ErrorAction SilentlyContinue)
if(get-dfsnroot -path \\$DomainShort\$DFSRootName-DFS | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {
log '*************************************************************************************************************'
log "****************************************Creating backup functionalities**************************************"
backup($DFSRootName)
success($error)
}
else{

log "DFS replica creation not successfull"

terminate
}
}
else{
log '*************************************************************************************************************'
log '**********************************************New root mode**************************************************'
log "New root, start initialize it"
log "New-DfsnRoot: " ,(New-DfsnRoot -TargetPath "\\$Computername\$DFSRootname-DFS" -Type DomainV2)
if(get-dfsnroot -path \\$DomainShort\$DFSRootName-DFS | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {

log ''
log '*************************************************************************************************************'
log "****************************************Creating backup functionalities**************************************"
log ''
backup($DFSRootName)
success($error)
}
else{
log "DFS root creation not successfull- script will now terminate"
terminate
}
}
above the script, which I have

@Vinodkumarlohar 

 

In lines 376 and 394 you have statements that look like this:

 

if(get-dfsnroot -path \\$DomainShort\$DFSRootName-DFS | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {

 

Where you have not enclosed the value following -Path in double quotes as you should have. The value should look like this:

 

# It should look like this:
-path "\\$DomainShort\$DFSRootName-DFS"

# Not what you have, which is this:
-path \\$DomainShort\$DFSRootName-DFS

 

Given it's a long script, I've only focused on your first error, as there's a good chance the rest are related.

 

Cheers,

Lain

@LainRobertson 
Thank you so much for your quick response.

however, I am still getting the same error after adding the double quotes.

 

 

 

get-dfsnroot : Cannot get DFS folder properties on "\\\-DFS"
At C:\install\DFS1.ps1:393 char:8
+ if(get-dfsnroot -path "\\$DomainShort\$DFSRootName-DFS" | get-dfs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_DFSNamespace:ROOT\Microsoft\...FT_DFSNamespace) [Get-DfsnRoot], CimException
+ FullyQualifiedErrorId : Windows System Error 87,Get-DfsnRoot

get-dfsnroot : One or more parameter values passed to the method were invalid.
At C:\install\DFS1.ps1:393 char:8
+ if(get-dfsnroot -path "\\$DomainShort\$DFSRootName-DFS" | get-dfs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_DFSNamespace:ROOT\Microsoft\...FT_DFSNamespace) [Get-DfsnRoot], CimException
+ FullyQualifiedErrorId : MI RESULT 4,Get-DfsnRoot

also I am executing the script using syntax as below

dfs.ps1 abc multipledfs

dfs.ps1 = long script
abc = namespace name
multipledfs

@Vinodkumarlohar 

 

Okay, if you're running the following within both those lines and still getting that error then that means the $DomainShort and $DFSRootName variables are set to $null (or an empty string).

 

get-dfsnroot -path "\\$DomainShort\$DFSRootName-DFS"

 

As the error clearly states that what you're passing in via the "-path" parameter is a string value of "\\\-DFS".

 

Cheers,

Lain

@LainRobertson  

Here "abc" is the user input value which should be store in the $DFSRootName 

 

so after execute the script it will create the path of namespace \\domainName\abc-DFS.

 

.DESCRIPTION
The script if for: Creating DFS roots in sites and for ABC roots for domain.
Installation Log will be created in C:\Install folder

Example usage:
.\DFSroot.ps1 - It will create DFS root for site parsed from server hostname- e.g:
Executed on server: dc.net will create abc-DFS root

.\DFSroot.ps1 ABC - It will create DFS root ABC-DFS

@Vinodkumarlohar 

 

That might be how it's designed, but that's not how things are working for you at the moment. It's also worth pointing out that your call to New-DfsnRoot uses a different variable for the namespace, so if you're expecting the Get-DfsnRoot to find the same object, it won't unless $ComputerName equals $DomainShort.

 

Anyhow, based on the error text from calling "get-dfsnroot", those variables are empty or null.

 

Funnily enough though, when I try and reproduce the error, I get a different error code. I get an error 1722 (pictured below) while you're getting an 87, which implies something else is going on for you as well. But the first issue to solve is why you are passing in a string of "\\\-DFS".

 

LainRobertson_0-1701680699944.png

 

Perhaps have a look at your log file and see if the line previous to "get-dfsnroot" is logging a value for $DFSRootName, as my assumption is that it will be null/empty in that logging line as well.

 

Cheers,

Lain

@Vinodkumarlohar 

 

Error 87 is LDAP_FILTER_ERROR.

 

I'm unable to even begin to guess as to why you're receiving that.

 

 

But as I say, the bigger initial issue appears to be the string being passed in via "-path", as "\\\-DFS" is never going to work.

 

Cheers,

Lain

Is it possible to conclude this script by specifying the exact permissions needed, ensuring its compatibility to run in any domain environment for the creation of a namespace?

@Vinodkumarlohar 

 

I'm not sure I understand the question.

 

If you're talking about the permissions needed by the user to execute the script, then they need to be a member of Domain Admins. If you're running it locally on a domain controller then you'd need to ensure you run the PowerShell session as an administrator (not necessary if you're running it remotely from a workstation).

 

If you're talking about setting the permissions on the DFS-N share and underlying file system directories, then of course, you can set whatever permissions you like at either level. If you want the script to be portable between domains/forests, you'd have to stick to using built-in Active Directory groups like Domain Users, etc.

 

Cheers,

Lain

I made some changes in the script and replaced the $DomainShort with $ServerDomain The script is also executing without any error, but the namespace (ABC) not being created, and we have provided the input (ABC) to the script. It should be created as ABC-DFS.

@LainRobertson also I have commented the variable #$DomainShort in the script

@Vinodkumarlohar 

 

If you can upload a copy of the updated script - preferably using the "Insert code sample" option from the TechCommunity menu so we can more easily read it - then we can see if we can help further.

 

LainRobertson_0-1701748187477.png

 

 

Cheers,

Lain

@LainRobertson  Hi I have uploaded the updated script 

#---------------------------------------------------------------------------
#Name       = DFSroot
#Version    = 1.00
#Author     = Vinod Kumar Lohar
#Purpose    = Hosting P drive for Techops sites in IN.YKGW.NET
#---------------------------------------------------------------------------


<#
 

.DESCRIPTION
The script if for: Creating DFS roots in remote sites, hubs and for INTL roots for nvstop.net domain.
Installation Log will be created in C:\Install folder

Example usage:
.\DFSroot.ps1 - It will create DFS root for site parsed from server hostname- e.g:
Executed on server: POC-WIN2022-SRV will create POC-DFS root

.\DFSroot.ps1 POC - It will create DFS root POC-DFS


 
.NOTES
Prerequisites:

-Must be executed on elevated window.
-Must be executed on Windows Server 2012 and higher.


What is built in:

-Checking prerequisites
-Installation of DFS components is included.
-Creation of DFS root directory structure.
-Setting up permissions for directories
-Creation of Backup commands and Scheduled Tasks.
-Logging to log file in C:\Install folder

 
#>



#params
param(
[string]$SiteCode        = $null,
    [string]$multipleDFS     = "single"
)
$sitecode = $SiteCode.ToUpper()
import-module ServerManager

$date=get-date -format "yyyy.MM.dd-hh.mm.ss"
$LogFilePath="C:\install\DFSroot(creation)_logfile_$date.txt"
" " > $LogFilePath
$error = $false

#terminate function
function terminate{
   
   log "Script would terminate now"
   pause
   log "***********************************Script terminated (DFS creation canceled)*********************************"
   log '*************************************************************************************************************'
   
   exit
   
}

#Function that displays message and stores into the logfile
function log($mesage,$message2){
    $time=get-date -Format "hh.mm.ss"
    $output=$time+" "+ $mesage+" "+$message2
    $output>>$LogFilePath
    write-host $output

}
function logNoTimestamp($mesage,$message2){
    $time=get-date -Format "hh.mm.ss"
    $output=$mesage+" "+$message2
    $output>>$LogFilePath
    write-host $output

}

#checking if server is configured to use FQDN
function DFSFQDN{
IF((Get-DfsnServerConfiguration localhost).UseFqdn -eq $False)
{
log "Server is being configured for FQDN"
Set-DfsnServerConfiguration -ComputerName localhost -UseFqdn $true
}
Else
{
log "Server is using FQDN"

}


}

#checking if script is runned as elevated rights
function checkRunAsAdmin{
    $myIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $wp = New-Object Security.Principal.WindowsPrincipal($myIdentity)
    if (-not $wp.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
        log "This script requires administrative privileges, please re-launch with elevated credentials"
        pause
    terminate
    }
}



#Function that verify if server have proper OS installed and if it is proper member server
function verifyServer {
    $computer=Get-WMIObject win32_computersystem
    if(($computer).domainrole -ne 3){
        return $false
    }
   
    elseif([version](Get-CimInstance Win32_OperatingSystem).version -lt 6.2){
        return $false
    }
   
    else{
        return $true
    }
}

#Function that wait for keyboard hit

function pause{

  if (((Get-Host).Name) -eq 'ConsoleHost'){
      #log -NoNewLine "Press any key to continue"
      #$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
      Start-Sleep -Seconds 1
      log ""
  } else {
  Start-Sleep -Seconds 1
}
}

#Initialization of Site type DFS
function InitSite{
    log "DFS Site Init: Start"

    log "New-Item(Creating new directory):",(New-Item -ItemType directory  -path C:\DFS\$DFSRootName-DFS\DATA)

}
#Function that checks if provided feature is installed

function checkifFeatureInstalled($Featurename){
    if((get-windowsfeature $Featurename).installed){
        return $true
    }
    else{ return $false
    }
}



#Function that gets domain name
function getDomain{
    return (Get-WmiObject Win32_ComputerSystem).domain
}

function success($param){
    if($param -eq $true){
    log ''
    log "At least one link was not created successfully. Please check the log file"
    log '*************************************************************************************************************'
    log '***********************************DFS created but with some errors!!!***************************************'
    log '*************************************************************************************************************'
    }
    else{
    log 'all success'
    log '*************************************************************************************************************'
    log '***************************************DFS created successfully!!!!!!!!**************************************'
    log '*************************************************************************************************************'
    }

}

function backup ($DFSRoot){
    if(!(test-path C:\Install\DFS-SAVE)){ log "New-Item(Creating Directory):" ,(new-item -ItemType Directory C:\Install\DFS-SAVE)}
    if(!(test-path C:\Install\DFS-BACKUP)){ log "New-Item(Creating Directory):" , (new-item -ItemType Directory C:\Install\DFS-BACKUP)}
    "dfscmd  /view \\$ServerDomain\$DFSRoot-dfs /batch > c:\install\DFS-SAVE\$DFSRoot-DFS-%1.txt" | out-file C:\Install\DFS-BACKUP\Backup-DFS.bat -Encoding ASCII -Append
get-content C:\Install\DFS-BACKUP\Backup-DFS.bat  | sort -u | set-content -path C:\Install\DFS-BACKUP\Backup-DFS.bat
    $content = [IO.File]::ReadAllText("C:\install\DFS-BACKUP\Backup-DFS.bat")
    log "Printing C:\install\DFS-BACKUP\Backup-DFS.bat file content that will be used for creating backup files"
    log "*************************Starting file content: C:\install\DFS-BACKUP\Backup-DFS.bat*************************"
    logNoTimestamp $content
    log '**********************************************End of file content********************************************'
    $days= @(("Monday", "MON"), ("Tuesday","TUE"),("Wednesday","WED"),("Thursday","THU"),("Friday","FRI"),("Saturday","SAT"),("Sunday","SUN"))
    foreach($day in $days){
        $long=$day[0]
        $short=$day[1]
        $output= schtasks /create /tn DFSDump_$long /tr "C:\INSTALL\DFS-BACKUP\Backup-DFS.bat $long" /SC WEEKLY /D $short /ST 23:00 /ru "SYSTEM" /F
        log "SCHTASKS:  $output"
    }



   
}

#Main Program
cls
log '*************************************************************************************************************'
log '***************************************DFS root creation script**********************************************'
log '*************************************************************************************************************'
log Activating DFS
log ''

#check if script is runned as elevated user
checkRunAsAdmin



#check if server is a proper member server, proper OS version and member server
if(verifyServer){
    log "Server OS version and membership verified successfully, script will continue"
    pause
}
else{
    log "Server OS version and membership verified uncsuccessfully, script will terminate now "
    pause
    terminate
   
}







#Getting Domain information from server properties and hostname
$Computername=($env:COMPUTERNAME).ToUpper()

$ServerDomain=(getDomain).ToLower()

$DomainSplited=$ServerDomain -split "\."
$DomainPrefix= $ServerDomain -split "\." | select -first 1
$DomainSuffix= $ServerDomain -split "\." | select -last 1

if($DomainSplited.Count -eq 2){
    $ServerDomainRoot=$false
    $DFSRootName=$SiteCode
    $DomainxName=$ServerDomain
    #$DomainShort=$DomainPrefix+ $DomainSuffix
}

else{

}


log ""
log "Server domain is:          $ServerDomain"
log "Server computername is:    $Computername"
log "Domain prefix is:          $DomainPrefix"
log "Domain suffix is:          $DomainSuffix"
log "If it is root domain:      $ServerDomainRoot"
log "DFSroot name is:           $DFSRootName"
log "DomxName is:               $DomainxName"
#log "NB domain is:              $DomainShort"
log "Multiple Site DFS init:    $multipleDFS"
log ''
log '*************************************************************************************************************'
log '************************************Starting to Install DFS components***************************************'
pause

$LogFilePathOld=$LogFilePath
$LogFilePath="C:\install\DFSroot_$DFSRootName(creation)_logfile_$date.txt"
rename-item $LogFilePathOld $LogFilePath


#instaling DFS features

if(!(checkifFeatureInstalled("FS-DFS-Namespace"))){
    log "Installing FS-DFS-Namespace feature"
    Add-WindowsFeature FS-DFS-Namespace
}
else{
    log "FS-DFS-Namespace feature already installed"
}
if(!(checkifFeatureInstalled("FS-DFS-Replication"))){
    log "Installing FS-DFS-Replication feature"
    Add-WindowsFeature FS-DFS-Replication
}
else{
    log "FS-DFS-Replication feature already installed"
}
if(!(checkifFeatureInstalled("RSAT-DFS-Mgmt-Con"))){
    log "Installing RSAT-DFS-Mgmt-Con feature"
    Add-WindowsFeature RSAT-DFS-Mgmt-Con
}
else{
    log "RSAT-DFS-Mgmt-Con feature already installed"
}



#check for existing root on the server
if(get-dfsnroot -computerName $ComputerName  | where { $_.Path -like "*\\$ServerDomain\$DFSRootName-DFS*"}){
    log "DFS root exist- script will now terminate"
    terminate
}
log "DFS root not found- script will continue"
pause

#check if root exist in domain
$mode=$null
if(get-dfsnroot -path "\\$ServerDomain\$DFSRootName-DFS" -erroraction silentlycontinue){
    log "DFS root exist in domain- script will create replica"
    $mode="Replica"
}
else{
    log "DFS share not exist in domain - script will create new root"
    $mode="Fresh"
}

#creating folder structure
if(!(test-path c:\dfs)){
    log "New-Item(Creating Directory):",( New-Item -ItemType directory  -path C:\DFS )
}
else{
    if($multipleDFS -eq "multipleDFS"){
        log "Folder c:\dfs already exist, script will continue because of multiple site DFS init"
        log '*****************************************Multiple site DFS init**********************************************'
       

         
    }
    else{
        log "Folder c:\dfs already exist, script will now terminate"
        log "If you want to create another Site DFS on this server, please run the script like: .\DFSroot.ps1 SITE multipleDFS"
        log "Where SITE is sitecode of DFS root that need to be created e.g: .\DFSroot.ps1 CMM multipleDFS"
       

        terminate
    }
}

if(!(test-path c:\dfs\$DFSRootName-DFS)){
    log "New-Item(Creating Directory):",(New-Item -ItemType directory  -path c:\dfs\$DFSRootName-DFS)
}

#checking dfsconfiguration
DFSFQDN

#creating data folder
initsite

$output = icacls C:\DFS\$DFSRootName-DFS /inheritance:r
log "ICACLS: $output"
$output = icacls C:\DFS\$DFSRootName-DFS --% /grant Administrators:(OI)(CI)F Everyone:(CI)(RX)
log "ICACLS: $output"
 
$output = net share $DFSRootName-DFS=C:\DFS\$DFSRootName-DFS /GRANT:'Everyone,Full'
log "Net Share: $output"

#Execute initialization if current DFS will be replica of existing one.

if($mode -eq "Replica"){
    log '*************************************************************************************************************'
    log '**********************************************Replica Mode***************************************************'
    log "Linking DFS Root $DFSRootName-DFS"

    log (New-DfsnRootTarget -TargetPath  "\\$Computername\$DFSRootname-DFS" -ErrorAction SilentlyContinue)
    if(get-dfsnroot -path "\\$ServerDomain\$DFSRootName-DFS" | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {
        log '*************************************************************************************************************'
        log "****************************************Creating backup functionalities**************************************"
        backup($DFSRootName)
        success($error)
    }
    else{
         
        log "DFS replica creation not successfull"
       
        terminate
    }
}
else{
    log '*************************************************************************************************************'
    log '**********************************************New root mode**************************************************'
    log "New root, start initialize it"
    log "New-DfsnRoot: " ,(New-DfsnRoot -TargetPath "\\$Computername\$DFSRootname-DFS" -Type DomainV2)
    if(get-dfsnroot -path "\\$ServerDomain\$DFSRootName-DFS" | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {

    log ''
    log '*************************************************************************************************************'
    log "****************************************Creating backup functionalities**************************************"
    log ''
    backup($DFSRootName)
    success($error)
    }
    else{
        log "DFS root creation not successfull- script will now terminate"
        terminate
    }
    }

Here is the outcome log

 
08.43.30 ************************************************************************************************************* 
08.43.30 ***************************************DFS root creation script********************************************** 
08.43.31 ************************************************************************************************************* 
08.43.31 Activating DFS
08.43.31  
08.43.31 Server OS version and membership verified successfully, script will continue 
08.43.32  
08.43.32 Server domain is:          in.ykgw.net 
08.43.32 Server computername is:    POC-WIN2022-SRV 
08.43.32 Domain prefix is:          in 
08.43.32 Domain suffix is:          net 
08.43.32 If it is root domain:       
08.43.32 DFSroot name is:            
08.43.32 DomxName is:                
08.43.32 Multiple Site DFS init:    multipledfs 
08.43.32  
08.43.32 ************************************************************************************************************* 
08.43.32 ************************************Starting to Install DFS components*************************************** 
08.44.04 FS-DFS-Namespace feature already installed 
08.44.05 FS-DFS-Replication feature already installed 
08.44.06 RSAT-DFS-Mgmt-Con feature already installed 
08.44.06 DFS root not found- script will continue 
08.44.07 DFS share not exist in domain - script will create new root 
08.44.07 New-Item(Creating Directory): C:\DFS 
08.44.07 New-Item(Creating Directory): C:\dfs\-DFS 
08.44.07 Server is using FQDN 
08.44.07 DFS Site Init: Start 
08.44.07 New-Item(Creating new directory): C:\DFS\-DFS\DATA 
08.44.07 ICACLS: processed file: C:\DFS\-DFS Successfully processed 1 files; Failed processing 0 files 
08.44.07 ICACLS: processed file: C:\DFS\-DFS Successfully processed 1 files; Failed processing 0 files 
08.44.07 Net Share: -DFS was shared successfully.  
08.44.07 ************************************************************************************************************* 
08.44.07 **********************************************New root mode************************************************** 
08.44.07 New root, start initialize it 
08.44.08 New-DfsnRoot:  MSFT_DFSNamespace (NamespacePath = "\\in.ykgw.net\-DFS") 
08.44.08  
08.44.08 ************************************************************************************************************* 
08.44.08 ****************************************Creating backup functionalities************************************** 
08.44.08  
08.44.08 New-Item(Creating Directory): C:\Install\DFS-SAVE 
08.44.08 New-Item(Creating Directory): C:\Install\DFS-BACKUP 
08.44.08 Printing C:\install\DFS-BACKUP\Backup-DFS.bat file content that will be used for creating backup files 
08.44.08 *************************Starting file content: C:\install\DFS-BACKUP\Backup-DFS.bat************************* 
dfscmd  /view \\in.ykgw.net\-dfs /batch > c:\install\DFS-SAVE\-DFS-%1.txt
 
08.44.08 **********************************************End of file content******************************************** 
08.44.08 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Monday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Tuesday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Wednesday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Thursday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Friday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Saturday" has successfully been created. 
08.44.09 SCHTASKS:  SUCCESS: The scheduled task "DFSDump_Sunday" has successfully been created. 
08.44.09 all success 
08.44.09 ************************************************************************************************************* 
08.44.09 ***************************************DFS created successfully!!!!!!!!************************************** 
08.44.09 ************************************************************************************************************* 

@Vinodkumarlohar 

 

Looking at the log file, it doesn't look like it should based on what you described when running the script using "ABC" for the site code parameter.

 

The variables references for lines 13 to 15 are null, which makes sense since the value passed in for $ServerDomain is "in.ykgw.net", meaning the if() block on line 249 is going to use the empty code branch since $DomainSplited.Count will equal 3, not 2.

 

The key takeaway here is that the $DFSRootName variable will remain as $null, as the value you passed into the script for $SiteCode is not being used at all.

 

I find lines 391 and 392 possibly confusing, since two separate locations are being referenced:

 

  1. \\$Computername\$DFSRootname-DFS
  2. \\$ServerDomain\$DFSRootName-DFS

 

Perhaps they're supposed to be different but I'd assumed line 392 was a checking process for whether line 391 worked. As it stands now though, the two statements are entirely unrelated.

 

It's best to avoid using "ErrorAction:SilentlyContinue" if you expect to see errors or expect to control flow. Only use the SilentlyContinue action if you don't care about the outcome at all.

 

If fact, if you expect to control flow, you should be using "-ErrorAction:Stop" in conjunction with a try ... catch block.

 

 

Cheers,

Lain

Hello,

 

Is it possible for you to assist in resolving this script? I've exhausted all my efforts, and having your help would be greatly appreciated. If feasible, we could connect remotely to address and resolve the issues within the script. This assistance would be immensely helpful to me.

here is the script

#---------------------------------------------------------------------------
#Name       = DFSroot
#Version    = 1.00
#Author     = Vinod Kumar Lohar
#Purpose    = Hosting P drive for Techops sites in IN.YKGW.NET
#---------------------------------------------------------------------------


<#
 

.DESCRIPTION
The script if for: Creating DFS roots in remote sites, hubs and for INTL roots for nvstop.net domain.
Installation Log will be created in C:\Install folder

Example usage:
.\DFSroot.ps1 - It will create DFS root for site parsed from server hostname- e.g:
Executed on server: POC-WIN2022-SRV will create POC-DFS root

.\DFSroot.ps1 POC - It will create DFS root POC-DFS


 
.NOTES
Prerequisites:

-Must be executed on elevated window.
-Must be executed on Windows Server 2012 and higher.


What is built in:

-Checking prerequisites
-Installation of DFS components is included.
-Creation of DFS root directory structure.
-Setting up permissions for directories
-Creation of Backup commands and Scheduled Tasks.
-Logging to log file in C:\Install folder

 
#>



#params
param(
[string]$SiteCode        = $null,
    [string]$multipleDFS     = "single"
)
$sitecode = $SiteCode.ToUpper()
import-module ServerManager

$date=get-date -format "yyyy.MM.dd-hh.mm.ss"
$LogFilePath="C:\install\DFSroot(creation)_logfile_$date.txt"
" " > $LogFilePath
$error = $false

#terminate function
function terminate{
   
   log "Script would terminate now"
   pause
   log "***********************************Script terminated (DFS creation canceled)*********************************"
   log '*************************************************************************************************************'
   
   exit
   
}

#Function that displays message and stores into the logfile
function log($mesage,$message2){
    $time=get-date -Format "hh.mm.ss"
    $output=$time+" "+ $mesage+" "+$message2
    $output>>$LogFilePath
    write-host $output

}
function logNoTimestamp($mesage,$message2){
    $time=get-date -Format "hh.mm.ss"
    $output=$mesage+" "+$message2
    $output>>$LogFilePath
    write-host $output

}

#checking if server is configured to use FQDN
function DFSFQDN{
IF((Get-DfsnServerConfiguration localhost).UseFqdn -eq $False)
{
log "Server is being configured for FQDN"
Set-DfsnServerConfiguration -ComputerName localhost -UseFqdn $true
}
Else
{
log "Server is using FQDN"

}


}

#checking if script is runned as elevated rights
function checkRunAsAdmin{
    $myIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $wp = New-Object Security.Principal.WindowsPrincipal($myIdentity)
    if (-not $wp.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)) {
        log "This script requires administrative privileges, please re-launch with elevated credentials"
        pause
    terminate
    }
}



#Function that verify if server have proper OS installed and if it is proper member server
function verifyServer {
    $computer=Get-WMIObject win32_computersystem
    if(($computer).domainrole -ne 3){
        return $false
    }
   
    elseif([version](Get-CimInstance Win32_OperatingSystem).version -lt 6.2){
        return $false
    }
   
    else{
        return $true
    }
}

#Function that wait for keyboard hit

function pause{

  if (((Get-Host).Name) -eq 'ConsoleHost'){
      #log -NoNewLine "Press any key to continue"
      #$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
      Start-Sleep -Seconds 1
      log ""
  } else {
  Start-Sleep -Seconds 1
}
}

#Initialization of Site type DFS
function InitSite{
    log "DFS Site Init: Start"

    log "New-Item(Creating new directory):",(New-Item -ItemType directory  -path C:\DFS\$DFSRootName-DFS\DATA)

}
#Function that checks if provided feature is installed

function checkifFeatureInstalled($Featurename){
    if((get-windowsfeature $Featurename).installed){
        return $true
    }
    else{ return $false
    }
}



#Function that gets domain name
function getDomain{
    return (Get-WmiObject Win32_ComputerSystem).domain
}

function success($param){
    if($param -eq $true){
    log ''
    log "At least one link was not created successfully. Please check the log file"
    log '*************************************************************************************************************'
    log '***********************************DFS created but with some errors!!!***************************************'
    log '*************************************************************************************************************'
    }
    else{
    log 'all success'
    log '*************************************************************************************************************'
    log '***************************************DFS created successfully!!!!!!!!**************************************'
    log '*************************************************************************************************************'
    }

}

function backup ($DFSRoot){
    if(!(test-path C:\Install\DFS-SAVE)){ log "New-Item(Creating Directory):" ,(new-item -ItemType Directory C:\Install\DFS-SAVE)}
    if(!(test-path C:\Install\DFS-BACKUP)){ log "New-Item(Creating Directory):" , (new-item -ItemType Directory C:\Install\DFS-BACKUP)}
    "dfscmd  /view \\$ServerDomain\$DFSRoot-dfs /batch > c:\install\DFS-SAVE\$DFSRoot-DFS-%1.txt" | out-file C:\Install\DFS-BACKUP\Backup-DFS.bat -Encoding ASCII -Append
get-content C:\Install\DFS-BACKUP\Backup-DFS.bat  | sort -u | set-content -path C:\Install\DFS-BACKUP\Backup-DFS.bat
    $content = [IO.File]::ReadAllText("C:\install\DFS-BACKUP\Backup-DFS.bat")
    log "Printing C:\install\DFS-BACKUP\Backup-DFS.bat file content that will be used for creating backup files"
    log "*************************Starting file content: C:\install\DFS-BACKUP\Backup-DFS.bat*************************"
    logNoTimestamp $content
    log '**********************************************End of file content********************************************'
    $days= @(("Monday", "MON"), ("Tuesday","TUE"),("Wednesday","WED"),("Thursday","THU"),("Friday","FRI"),("Saturday","SAT"),("Sunday","SUN"))
    foreach($day in $days){
        $long=$day[0]
        $short=$day[1]
        $output= schtasks /create /tn DFSDump_$long /tr "C:\INSTALL\DFS-BACKUP\Backup-DFS.bat $long" /SC WEEKLY /D $short /ST 23:00 /ru "SYSTEM" /F
        log "SCHTASKS:  $output"
    }



   
}

#Main Program
cls
log '*************************************************************************************************************'
log '***************************************DFS root creation script**********************************************'
log '*************************************************************************************************************'
log Activating DFS
log ''

#check if script is runned as elevated user
checkRunAsAdmin



#check if server is a proper member server, proper OS version and member server
if(verifyServer){
    log "Server OS version and membership verified successfully, script will continue"
    pause
}
else{
    log "Server OS version and membership verified uncsuccessfully, script will terminate now "
    pause
    terminate
   
}







#Getting Domain information from server properties and hostname
$Computername=($env:COMPUTERNAME).ToUpper()

$ServerDomain=(getDomain).ToLower()

$DomainSplited=$ServerDomain -split "\."
$DomainPrefix= $ServerDomain -split "\." | select -first 1
$DomainSuffix= $ServerDomain -split "\." | select -last 1

if($DomainSplited.Count -eq 2){
    $ServerDomainRoot=$false
    $DFSRootName=$SiteCode
    $DomainxName=$ServerDomain
    #$DomainShort=$DomainPrefix+ $DomainSuffix
}

else{

}


log ""
log "Server domain is:          $ServerDomain"
log "Server computername is:    $Computername"
log "Domain prefix is:          $DomainPrefix"
log "Domain suffix is:          $DomainSuffix"
log "If it is root domain:      $ServerDomainRoot"
log "DFSroot name is:           $DFSRootName"
log "DomxName is:               $DomainxName"
#log "NB domain is:              $DomainShort"
log "Multiple Site DFS init:    $multipleDFS"
log ''
log '*************************************************************************************************************'
log '************************************Starting to Install DFS components***************************************'
pause

$LogFilePathOld=$LogFilePath
$LogFilePath="C:\install\DFSroot_$DFSRootName(creation)_logfile_$date.txt"
rename-item $LogFilePathOld $LogFilePath


#instaling DFS features

if(!(checkifFeatureInstalled("FS-DFS-Namespace"))){
    log "Installing FS-DFS-Namespace feature"
    Add-WindowsFeature FS-DFS-Namespace
}
else{
    log "FS-DFS-Namespace feature already installed"
}
if(!(checkifFeatureInstalled("FS-DFS-Replication"))){
    log "Installing FS-DFS-Replication feature"
    Add-WindowsFeature FS-DFS-Replication
}
else{
    log "FS-DFS-Replication feature already installed"
}
if(!(checkifFeatureInstalled("RSAT-DFS-Mgmt-Con"))){
    log "Installing RSAT-DFS-Mgmt-Con feature"
    Add-WindowsFeature RSAT-DFS-Mgmt-Con
}
else{
    log "RSAT-DFS-Mgmt-Con feature already installed"
}



#check for existing root on the server
if(get-dfsnroot -computerName $ComputerName  | where { $_.Path -like "*\\$ServerDomain\$DFSRootName-DFS*"}){
    log "DFS root exist- script will now terminate"
    terminate
}
log "DFS root not found- script will continue"
pause

#check if root exist in domain
$mode=$null
if(get-dfsnroot -path "\\$ServerDomain\$DFSRootName-DFS" -erroraction silentlycontinue){
    log "DFS root exist in domain- script will create replica"
    $mode="Replica"
}
else{
    log "DFS share not exist in domain - script will create new root"
    $mode="Fresh"
}

#creating folder structure
if(!(test-path c:\dfs)){
    log "New-Item(Creating Directory):",( New-Item -ItemType directory  -path C:\DFS )
}
else{
    if($multipleDFS -eq "multipleDFS"){
        log "Folder c:\dfs already exist, script will continue because of multiple site DFS init"
        log '*****************************************Multiple site DFS init**********************************************'
       

         
    }
    else{
        log "Folder c:\dfs already exist, script will now terminate"
        log "If you want to create another Site DFS on this server, please run the script like: .\DFSroot.ps1 SITE multipleDFS"
        log "Where SITE is sitecode of DFS root that need to be created e.g: .\DFSroot.ps1 CMM multipleDFS"
       

        terminate
    }
}

if(!(test-path c:\dfs\$DFSRootName-DFS)){
    log "New-Item(Creating Directory):",(New-Item -ItemType directory  -path c:\dfs\$DFSRootName-DFS)
}

#checking dfsconfiguration
DFSFQDN

#creating data folder
initsite

$output = icacls C:\DFS\$DFSRootName-DFS /inheritance:r
log "ICACLS: $output"
$output = icacls C:\DFS\$DFSRootName-DFS --% /grant Administrators:(OI)(CI)F Everyone:(CI)(RX)
log "ICACLS: $output"
 
$output = net share $DFSRootName-DFS=C:\DFS\$DFSRootName-DFS /GRANT:'Everyone,Full'
log "Net Share: $output"

#Execute initialization if current DFS will be replica of existing one.

if($mode -eq "Replica"){
    log '*************************************************************************************************************'
    log '**********************************************Replica Mode***************************************************'
    log "Linking DFS Root $DFSRootName-DFS"

    log (New-DfsnRootTarget -TargetPath  "\\$Computername\$DFSRootname-DFS" -ErrorAction SilentlyContinue)
    if(get-dfsnroot -path "\\$ServerDomain\$DFSRootName-DFS" | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {
        log '*************************************************************************************************************'
        log "****************************************Creating backup functionalities**************************************"
        backup($DFSRootName)
        success($error)
    }
    else{
         
        log "DFS replica creation not successfull"
       
        terminate
    }
}
else{
    log '*************************************************************************************************************'
    log '**********************************************New root mode**************************************************'
    log "New root, start initialize it"
    log "New-DfsnRoot: " ,(New-DfsnRoot -TargetPath "\\$Computername\$DFSRootname-DFS" -Type DomainV2)
    if(get-dfsnroot -path "\\$DomainShort\$DFSRootName-DFS" | get-dfsnroottarget | where {$_.Targetpath -like "*$Computername*"}) {

    log ''
    log '*************************************************************************************************************'
    log "****************************************Creating backup functionalities**************************************"
    log ''
    backup($DFSRootName)
    success($error)
    }
    else{
        log "DFS root creation not successfull- script will now terminate"
        terminate
    }
    }