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!
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!