Hey, Scripting Guy! Question

Hey, Scripting Guy! I need to use the Microsoft Group Policy cmdlets and Windows PowerShell 2.0 to test Active Directory replication. Know how?

-- RG

 

Hey, Scripting Guy! Answer

Hello RG,

Microsoft Scripting Guy Ed Wilson here. I had an Office Communicator conversation last night with my friend Brett in Sydney, Australia. He is my Tim Tam and ANZAC biscuit connection, and he has a great personality. He was working with a customer that had a problem with a VBScript script, and I was providing assistance. He happened to mention that it was cold; it turned out it was 57 degrees Fahrenheit outside. It was 107 in Charlotte, North Carolina (I use my Windows PowerShell conversion module to perform the calculations). That is one thing I enjoy about the Australian winters: They happen to be at the same time as the height of summer in Charlotte. Oh well.

RG, the Test-GPOReplication.ps1 script creates a Group Policy object (GPO) on a specific server, and then connects to another server to watch for replication to occur. When replication of the GPO completes, a message to that effect is displayed. The complete Test-GPOReplication.ps1 script is shown here.

Test-GPOReplication.ps1

Param( 
[string]$domain ="nwtraders.com", 
[string]$server = "hyperv.nwtraders.com", 
[string]$replPartner = "dc1.nwtraders.com", 
[string]$gponame = "testGPO" 
) 
Function Get-MyModule 
{ 
Param([string]$name) 
if(-not(Get-Module -name $name)) 
{ 
if(Get-Module -ListAvailable | 
Where-Object { $_.name -eq $name }) 
{ 
Import-Module -Name $name 
$true 
} #end if module available then import 
else { $false } #module not available 
} # end if not module 
else { $true } #module already loaded 
} #end function get-MyModule 
Function Test-Replication 
{ 
Param( 
[string]$gpoName, 
[string]$server, 
[string]$replPartner, 
[string]$domain 
) 
$null = new-gpo -name $gponame -domain $domain -server $server 
while(!$replGPO) 
{ 
$replGPO = Get-GPO -Name $gponame -Server $replPartner -EA "SilentlyContinue" 
start-sleep -Seconds 1 
} #end while 
Get-Date 
} #end function Test-Replication 
# *** Entry Point to Script *** 
If(-not (Get-MyModule -name "GroupPolicy")) { exit } 
$dte = Test-Replication -gpoName $gpoName -server $server ` 
-replPartner $replPartner -domain $domain 
"Replication on $replPartner completed at $($dte)" 
Remove-GPO -Name $gponame -Domain $domain -Server $server

The Test-GPOReplication.ps1 script begins by creating several command-line parameters and assigning default values for those parameters. You will want to change my defaults to something that makes sense on your network. The command-line parameters are shown here:

 

Param(

[string]$domain ="nwtraders.com",

[string]$server = "hyperv.nwtraders.com",

[string]$replPartner = "dc1.nwtraders.com",

[string]$gponame = "testGPO"

)

The Test-GPOReplication.ps1 script incorporates the Get-MyModule function from Sunday’s Weekend Scripter post. The Get-MyModule function looks in the current Windows PowerShell environment to determine if the GroupPolicy module is loaded. If the GroupPolicy module is not loaded, it will load the module. If the module does not exist, an error to that effect is displayed.

Keep in mind that because the Get-MyModule function accepts an input parameter for the name of the module, the function can check for required modules in other scripts. The complete Get-MyModule function is shown here:

 

Function Get-MyModule 
{ 
Param([string]$name) 
if(-not(Get-Module -name $name)) 
{ 
if(Get-Module -ListAvailable | 
Where-Object { $_.name -eq $name }) 
{ 
Import-Module -Name $name 
$true 
} #end if module available then import 
else { $false } #module not available 
} # end if not module 
else { $true } #module already loaded 
} #end function get-MyModule

The Test-Replication function begins by creating a number of parameters:

 

Function Test-Replication

{

Param(

[string]$gpoName,

[string]$server,

[string]$replPartner,

[string]$domain

)

Next, a new GPO is created on a specific server in a specific domain. The values for the name, domain, and server come from the command line when the script is called. The parameters for the function have the same signature as the parameters for the script. The New-GPO cmdlet returns an instance of a Microsoft.Grouppolicy.Gpo .NET Framework class. This clutters the Windows PowerShell console as the script runs, and the instance is stored in the $null variable (which effectively discards it). The code shown here creates the new GPO:

 

$null = new-gpo -name $gponame -domain $domain -server $server

A While statement checks the target server for the newly created GPO to appear. The While statement loops through the script block every second due to the Start-Sleep cmdlet. This looping continues as long as no GPO object is stored in the $replGPO variable. The Get-GPO cmdlet retrieves the newly created GPO from the targeted server. If the GPO does not exist, an error is generated. The silentlycontinue error action prevents the error from displaying. The complete while statement is shown here:

 

while(!$replGPO)

{

$replGPO = Get-GPO -Name $gponame -Server $replPartner -EA "SilentlyContinue"

start-sleep -Seconds 1

} #end while

After the GPO is retrieved from the target server, the current date and time are sent to the calling code, and the function closes. The Get-Date cmdlet retrieves the current timestamp. This section of the script is shown here:

 

Get-Date

} #end function Test-Replication

The entry point to the script calls the Get-MyModule function to determine if the GroupPolicy module is present on the system and can be loaded. If the module is not loaded in the current Windows PowerShell session, it will be loaded. If the GroupPolicy module cannot be loaded, the script exits. This section of the script is shown here:

 

If(-not (Get-MyModule -name "GroupPolicy")) { exit }

Next, the Test-Replication function is called to create the new GPO and to wait for replication to occur. The values for each of the four parameters come from the command-line parameters defined at the beginning of the script. The Test-Replication function returns a datetime object that is stored in the $dte variable. This portion of the script is shown here:

 

$dte = Test-Replication -gpoName $gpoName -server $server `

-replPartner $replPartner -domain $domain

After the Test-Replication function has completed and has returned the datetime object, a message is displayed on the Windows PowerShell console that indicates replication has occurred. This is shown here:

 

Replication on $replPartner completed at $($dte)"

The last thing to do is to remove the testGPO that was created in the Test-Replication function. To remove a GPO, use the Remove-GPO cmdlet as shown here:

 

Remove-GPO -Name $gponame -Domain $domain -Server $server

When the Test-GPOReplication.ps1 script runs, the output shown in the following image appears in the Windows PowerShell ISE.

Image of script output in Windows PowerShell ISE 

RG, that is all there is to using Group Policy cmdlets and Windows PowerShell 2.0 to test Active Directory replication. Group Policy Week will continue tomorrow when we will talk about reporting Group Policy configuration settings.

We would love for you follow us on Twitter or Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys