Author Posts

March 9, 2015 at 4:48 pm

I am pretty new at powershell but I am trying to write a script to gather all the Domain Controllers and then Loop through them adding a new DFSN Root Target. I can't my current object to resolve correctly in the -TargetPath parameter of the script. I can get it to work if I replace the variable manually. I am totally lost on this by now and would love some help.

#Get a list of all Domain Controllers
Get-ADDomainController -Filter * | Select Name |

#Start For-Each Loop
% {

#Displays the server currently being accessed
write-host "Starting Process on:" $_.name

#Create a new directory
invoke-command -computername $_.name -scriptBlock {new-item C:\DFSRoots\UsersNetBackup -type directory}

#Share the Directory
invoke-command -computername $_.name -scriptBlock {new-smbshare -name UsersNetBackup -Path C:\DFSRoots\UsersNetBackup -FullAccess Everyone}

#Add current server to the DFS using the new directory and share just created
invoke-command -computername $_.name -scriptBlock {new-DfsnRootTarget -Path "\\yourdomain\UsersNetBackup" -TargetPath "\\$($_.name)\UsersNetBackup"}

[blockquote]the above line is where my script errors out
[/blockquote]

#Shows the current server again after everything is done.
Write-Host "Done with Processes on:" $_.name
}

#Everyting is done. If there are no errors, you did a good job 🙂
Write-Host "Done will all servers"

March 9, 2015 at 7:31 pm

I think this is one of the powershell "Gotchas". The problem is variables created outside the scriptblock curly braces aren't recognized inside the braces. Therefore you have to pass it the variable as you would a parameter to a function. Example:

Invoke-Command -ComputerName $_.Name -ScriptBlock { param($ServerName); New-DfsnRootTarget -Path "\\yourdomain\UsersNetBackup" -TargetPath "\\$Servername\UsersNetBackup" } -ArgumentList $_.Name

Notice how outside the braces the server's name is represented as "$_.Name". Then it's passed in to the scriptblock as an argument and loaded into a new variable called "$ServerName" via the param block.

For more info on variable scope type this in your shell:

Get-Help about_scopes

March 10, 2015 at 3:52 am

You are a life saver Jeff 🙂

I was reading through the about_scopes as you indicated and noticed that the method your suggest is from Powershell 2 and there is a newer way (both should work though). I am pasting Example 5 from the help file for reference. I will test all this today and let everyone know the results:

Example 5: Using a Local Variable in a Remote Command

To indicate that a variable in a remote command was created in the
local session, use the Using scope modifier. By default, Windows
PowerShell assumes that the variables in remote commands were created
in the remote session.

The syntax is:
$Using:

For example, the following commands create a $Cred variable in the
local session and then use the $Cred variable in a remote command:

$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}

The Using scope was introduced in Windows PowerShell 3.0.

In Windows PowerShell 2.0, to indicate that a variable was created in
the local session, use the following command format.

$Cred = Get-Credential
Invoke-Command $s {param($c) Remove-Item .\Test*.ps1 -Credential $c} -ArgumentList $Cred

March 10, 2015 at 5:30 am

Thanks again Jeff,

I was able to get the script to work using the Powershell 3 commands. I had to assign a variable to $_.name to using inside the scriptblock but it worked here is the completed script:

#Get a list of all Domain Controllers
Get-ADDomainController -Filter * | Select Name |

#Start For-Each Loop
% {

#Displays the server currently being accessed
write-host "Starting Process on:" $_.name

#Create a new directory
invoke-command -computername $_.name -scriptBlock {new-item C:\DFSRoots\UsersNetBackup -type directory}

#Share the Directory
invoke-command -computername $_.name -scriptBlock {new-smbshare -name UsersNetBackup -Path C:\DFSRoots\UsersNetBackup -FullAccess Everyone}
$Currentcomputer = $_.name

[blockquote]Above is the new variable[/blockquote]

#Add current server to the DFS using the new directory and share just created
invoke-command -computername $_.name -scriptBlock {New-DfsnRootTarget -Path "\\yourdomain\UsersNetBackup" -TargetPath "\\$($Currentcomputer)\UsersNetBackup" $Using:Currentcomputer}

[blockquote]Notice the powershell 3 commands at the end of the scriptblock[/blockquote]

#Shows the current server again after everything is done.
Write-Host "Done with Processes on:" $_.name
}

#Everyting is done. If there are no errors, you did a good job 🙂
Write-Host "Done Creating Namespace Servers"

March 10, 2015 at 10:47 am

Great! Glad you got it. In my environment, the vast majority of my Win7 machines are still on PoSh 2.0 so even though there are way more delicious features in 3, 4 and 5 I generally stick to what is most compatible.