Expert Solutions: Beginner Event 6 of the 2010 Scripting Games

Bookmark and Share

(Note: These solutions were written for Beginner Event 6 of the 2010 Scripting Games.) 


Beginner Event 6 (Windows PowerShell)

Photo of Jeffery Hicks

Jeffery Hicks is a Microsoft MVP in Windows PowerShell and an IT veteran with almost 20 years of experience, much of it spent as an IT consultant specializing in Windows server technologies. He works today as an independent author, trainer, and consultant. He is also known for his Prof. PowerShell column on Jeff’s latest book is Windows PowerShell 2.0: TFM (SAPIEN Press 2010). He is a moderator at, a subject matter expert at, and a frequent contributor to many scripting-related forums. You can follow what Jeff is up to at and


The most challenging aspect of this event was to read values from a remote registry. Unfortunately, there aren’t any registry-related cmdlets. It is possible to use WMI or the .NET Framework to retrieve remote registry values, but the WMI approach is too cumbersome and slow performing and using the .NET Framework classes requires a higher level of Windows PowerShell experience. However, using the registry PSDrive to retrieve the values is relatively easy. The “trick” to this challenge is to use Windows PowerShell remoting so that I can access the HKLM: PSDrive on each remote machine.

I knew I could use the Invoke-Command cmdlet to run a Windows PowerShell expression on a remote computer. I also discovered through reading documentation that in order to use an IP address as the computername, I needed to include credentials and either configure WinRM on the remote machines to use HTTPS or add the IP addresses as trusted hosts. I used Group Policy to properly configure my network. Needless to say, this solution requires Windows PowerShell 2.0 on all machines with a properly configured WinRM service.

I wrote a scriptblock using Get-ItemProperty to retrieve the required registry values. Because I knew I had to read a couple of values I wrote a small function. This way I only had to write code once, and I could add error handling in case the registry value didn’t exist.

The service properties required WMI because the Get-Service cmdlet returns a .NET Framework version of the service object, which doesn’t include the start mode. Thus, I used Get-WmiObject to query the browser service.

Whenever I write Windows PowerShell, I’m always thinking “objects.” If I write an object to the pipeline I have much more flexibility. So my scriptblock ends by creating a new object, passing it a hash table of properties.

I tested the scriptblock in an elevated Windows PowerShell session. After copying and pasting the scriptblock, I ran it locally:

PS C:Scripts> Invoke-Command -ScriptBlock $scriptblock

IsDomainMaster     : False

BrowserStart       : Manual

MaintainServerList : False

Computername       : SERENITY

BrowserStatus      : Stopped

Now that I know this works, all that remains is to run through the range of IP addresses. Windows PowerShell will treat any number range as an array. That means I can pipe the range to ForEach and construct an IP address. I also included a Write-Host expression to let the administrator know what is happening. This is shown here:

1..254 | foreach {


 Write-Host “Scanning $ip” -ForegroundColor Cyan

The Invoke-Command expression is executed using the scriptblock and a saved administrator credential, which is required when using IP addresses. In this particular scenario, the IP address is considered the computername. Invoke-Command includes a special property called PSComputername, which retains this value. This is very useful when running a command on multiple computers.

Because of the way this property is handled by Windows PowerShell, I used Format-List to select the properties I needed and a custom label so that PSComputername is displayed as IPAddress. I could have simply piped the results of Format-Table to Out-File, but I thought it might be nice to also see the results as they are returned, so I used Tee-Object. This writes objects to the pipeline and saves them to a file.

The following image shows the script in action.

Image of script in action

Here is the script:

#requires -version 2.0


#define a variable to reuse and save typing


#this function can be reused as needed to return

#registry values

Function Get-RegistryValue {

 Param ([string]$RegPath,[string]$Name)

 #turn off the error pipeline for this function


 $data=Get-Itemproperty -Path $Regpath -Name $name

 #the registry item might not exist so check first

 if ($data) {

   #write the registry value to the pipeline

   Write-Output $data.$name


   else {

   write-output “NotFound”


} #end Get-RegistryValue

 #get the registry values

$maintain=Get-RegistryValue -regPath $RegPath -name “MaintainServerList”

$IsDomain=Get-RegistryValue -regPath $RegPath -name “IsDomainMaster”

#use WMI to get the browser service

$browser=Get-WmiObject -Class Win32_Service -filter “Name=’browser'”

#write a custom object to the pipeline specifying a hash table

#of properties

New-Object PSObject -Property @{







} #end Scriptblock

#get domain admin credential required when using an IP address

#with Invoke-Command

$admin=Get-Credential “$env:userdomainadministrator”

#the name of the final text report


#The range 1..254 will write numbers 1 through 254 to the pipeline

1..254 | foreach {


 Write-Host “Scanning $ip” -ForegroundColor Cyan

 Invoke-Command -ComputerName $ip -ScriptBlock $scriptblock -Credential $admin

 } | Format-List @{Label=”IPAddress”;Expression={$_.PSComputername}},`

 Computername,MaintainServerList,IsDomainMaster,Browser* |

 Tee-Object -FilePath $file

 #let the admin know the script if finished.

 write-host “Scan finished. Open $file to see results.” -ForegroundColor Green


Beginner Event 6 (VBScript)

Image of Uros Calakovic

Uros Calakovic, System and Database Administrator
Bijeljina, Bosnia And Herzegovina
My Code Project articles:


Before starting to write the script, it is a good idea to find more information about the problem you are trying to solve. If you are an average system administrator like me, you probably have an idea about what the browser service does, but a quick search reveals more details: the computer browser service lets users browse neighboring computers and their shared resources, the information you see when you open My Network Places. On each network segment, a computer running the browser service is elected to play the role of the master browser.It maintains a list of the available computer names and their shared resources.

In the Event 6 scenario, browser elections are being forced on a network subnet every 15 minutes, causing unnecessary network traffic. The situation can be resolved by setting the IsDomainMaster registry value to False, and setting the MaintainServerList value to No in this registry key:


The task is to inspect every computer on the subnet and make a report that contains:

·         Computer IP address.

·         Computer name.

·         MaintainServerList registry value.

·         IsDomainMaster registry value.

·         Browser Service status.

·         Browser Service start mode.

After getting the requirements, the steps for creating the script look like this:

Create and open a text file into which information will be written.

2.     Connect to every computer in the given range and for each:

a.     Get the computer name.

b.    Get the browser service status and start mode.

c.     Get MaintainServerList and IsDomainMaster registry values.

d.    Write the information to the file.

3.     After visiting all computers, close the file.

The first step is to create and open a file into which the gathered information will be written. In this case, a CSV file is probably the best choice. You can easily open it with Excel and make a nice report. Here is what the code for this step looks like:

strFileName = “C:ScriptsBrowserServiceLog.csv”

blnOverwrite = True

Set objFso = CreateObject(“Scripting.FileSystemObject”)

Set objLogFile = objFso.CreateTextFile(strFileName, blnOverwrite)

‘ The rest of the code goes here


The code creates an instance of the FileSystemObject object and uses its CreateTextFile method to create a text file with the .csv extension. The Overwrite argument is set to True. While testing the script, the CSV file will be created several times, which lets the existing one be overwritten silently.

The second step is to ping all computers w