PowerShell - Pick a Domain Controller
I use a global variable to pick a Domain Controller so that I’m not constantly bouncing back and forth between Domain Controllers when running scripts. This helps to mitigate errors due to replication delays (normally, just a few seconds).
For Example, when you’re scripting and try to run Set-ADUser command followed immediately by a Get-ADUser command without specifying the -Server property as the same server for both commands, you may end up setting the change on one server and confirming the change was set (possibly a nano-second later) on a different server. This would lead to your confirmation to return as false.
To draw it out a little clearer … take the following command:
While ((Get-ADUser $SamAccountName -Properties HomeDrive).HomeDrive -eq $null) { Write-Host "Setting HomeDrive & Home Directory ..." Set-ADUser $SamAccountName -HomeDrive "H:" -HomeDirectory "\HOME-SERVERHOME$SamAccountName" } Write-Host "Moving on ..."
Without specifying -Server, the command might result in the following output:
Setting HomeDrive & Home Directory ... Setting HomeDrive & Home Directory ... Setting HomeDrive & Home Directory ... Setting HomeDrive & Home Directory ... Moving on ...
If I do specify -Server, as shown:
While ((Get-ADUser $SamAccountName -Server $myDC -Properties HomeDrive).HomeDrive -eq $null) { Write-Host "Setting HomeDrive & Home Directory ..." Set-ADUser $SamAccountName -Server $myDC -HomeDrive "H:" -HomeDirectory "\HOME-SERVERHOME$SamAccountName" } Write-Host "Moving on ..."
I get the following output, everytime:
Setting HomeDrive & Home Directory ... Moving on ...
I set $myDC in my $Profile with a global variable and calling the Set-DC function I’ve written below.
[string] $global:myDC = "" Set-myDC Write-Debug "myDC: $myDC"
Of course, you could just set the $myDC statically, but what fun is that? Here’s my solution:
<# .SYNOPSIS Sets the myDC global variable. .DESCRIPTION Gets a list of domain controllers and takes one from the list. .PARAMETER Return If set, will return the FQDN of a DC, other than the globally set DC, intead of setting it globally. Useful for targetting another DC without changing the globally used DC. .INPUTS .OUTPUTS Sets $global:CASITS_UNTDC discovered FQDN. If -Return is used, $global:myDC is not set and the discovered FQDN is returned as a string. .EXAMPLE Set-myDC .EXAMPLE $myDC = Set-myDC -Return .NOTES .LINK go.vertigion.com/PowerShell-Set-myDC #> function Set-myDC { param( [Parameter( HelpMessage = "If set, will return the result intead of setting globally." )] [switch] $Return ) $DCList = $null while ($DCList -eq $null) { $DCList = Get-ADDomainController -Filter * | Select HostName } if ($Return.isPresent) { $DC = '' while ($DC -eq $myDC) { $DC = $DCList[$(Get-Random -Minimum 0 -Maximum ($DCList | Measure-Object).Count)].HostName } return $DC } else { $global:myDC = $DCList[$(Get-Random -Minimum 0 -Maximum ($DCList | Measure-Object).Count)].HostName } }
Hope it helps others out there. Just add the function to your PowerShell Profile or as a Functions in a script to make it available!