Expert Solutions: Beginner Event 1 of the 2010 Scripting Games

Expert Solutions: Beginner Event 1 of the 2010 Scripting Games

  • Comments 1
  • Likes

Bookmark and Share

 

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

 

Beginner Event 1 (Windows PowerShell)

Image of Steven Murawski

 

Steven Murawski, Community Director—PowerShellCommunity.org


-------------


Reading and writing to the registry is a common task in the Windows world. This challenge can be broken into multiple steps. The first thing we need to do is to find out if the registry key exists. Because Windows PowerShell exposes the registry as a drive, I can use Test-Path cmdlet to check for the key I need to check. If the key is not there, I can create that key. I do need to use the –Force parameter, in case there is more than one key missing in the path. If the key does exist, I check for an existing value. Values for registry keys are exposed as properties on the item. If there is an existing value, I write it out. While this isn’t called for in the challenge, if there was a previous value it could be very important depending on the scenario. Finally, we can write the value to the registry key. 

Image of Windows PowerShell command line

 


When I first wrote this script, I was working interactively from the command line, and then pasting lines from my history into a script. That got me the test of the path, creating the registry key, and setting the value. After I had that in my script editor, I was able to add the conditional logic (the if statement) and the check for the previous value. During this time, I am still using the full key path and name as part of the script. After I added my Write-Host commands, I decided to make this script a bit more general and moved the registry path, the key name, and the value I wanted to write into a parameter. For purposes of this challenge, I set the default values to be the registry key specified and to get the current date and time (using the ToString method to get the date and time in the specified format).


The sections of the script that call to Write-Host could be replaced with some other logging mechanism (writing to a log file or the event log for example). Here is the script:


param(

        $path =  'HKCU:\Software\ScriptingGuys\2010ScriptingGames',

        $KeyProperty = 'LastUpdate',

        $Value = (Get-Date).ToString()

    )

 

if ( -not (Test-Path $path))

{

    Write-Host "Key not found.  Creating registry key - $path."

    New-Item $path -Force | Out-Null

}

else

{

    $Properties = (Get-ItemProperty -Path $path).psobject.properties | Select-Object -ExpandProperty Name

    if ( $Properties -contains $KeyProperty )

    {

        Write-Host "The previous update was:"

        Get-ItemProperty -Path $path | Select-Object -ExpandProperty $KeyProperty

    }

}

Write-Host "Setting the new value: $UpdateTime"

Set-ItemProperty -Path $path -Name $KeyProperty -Value $Value

 

Beginner Event 1 (VBScript)

Image of Rajesh

 


Rajesh is a software development engineer at Microsoft where he works on the Remote Desktop Virtualization (RDV) team. He mainly focuses on management aspects of Remote Desktop Services. He was on the team that implemented Remote Desktop Services Management through Windows PowerShell. He has authored Windows PowerShell scripts to ease the management of Remote Desktop Services. For information related to Remote Desktop Services Management through Windows PowerShell, visit Remote Desktop Services Team Blog.

 


Solution


This scenario involves two steps. The first is to author the script, and the second is to add the script as a logon script on a machine, say as Active Directory Group Policy to execute it on all the machines in the domain. We would be illustrating the first step below.


Authoring the script entails the following three tasks:

  1. Test for the existence of a registry key.
  2. If the registry key is not found, create it.
  3. Optionally, create and update the registry value to current date and time.


We use the WMI class StdRegProv, which contains methods that can manipulate system registry keys and their values. StdRegProv is preinstalled in the WMI namespace root\default and root\cimv2. Now let us see how the three tasks mentioned are achieved using the StdRegProv class.

 


To start with, we need a handle to the instance of the StdregProv class. We do this using GetObject():

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _

    strComputer & "\root\default:StdRegProv")

 


To check the existence of the key, we enumerate all the subkeys of its parent, using the method EnumKey() of StdRegProv, and check if the required key exists:

keyFound = False

oReg.EnumKey HKEY_CURRENT_USER, strParentKeyPath, arrSubKeys

If Not (IsNull(arrSubKeys)) then

    For Each subkey In arrSubKeys

        If subkey=strKeyName Then keyFound = True

    Next

End if

 


If the key is not present, we create the key using the CreateKey() method of StdRegProv:

oReg.CreateKey HKEY_CURRENT_USER, strKeyPath

 


We capture the current time using the function FormatDateTime(). The parameters that are to be passed are Now, which represents current time, and 0, which specifies the format option. The default format option is Short Date and Time. This is shown here:

strValueData = FormatDateTime(Now, 0)

oReg.SetStringValue HKEY_CURRENT_USER, strKeyPath,_

    strValueName, strValueData

 

Script

' DEFINE THE SCRIPT BEHAVIOUR

'==============================================================================

option explicit

 

' DEFINE CONSTANTS TO ACCESS REGISTRY HIVES

'==============================================================================

Const HKEY_CURRENT_USER = &H80000001

const HKEY_LOCAL_MACHINE = &H80000002

 

' DEFINE VARIABLES FOR REGISTRY KEY PATH & VALUE NAMES

'==============================================================================

dim strComputer : strComputer = "."

dim strParentKeyPath : strParentKeyPath = "SOFTWARE\ScriptingGuys"

dim strKeyName : strKeyName = "2010ScriptingGames"

dim strKeyPath : strKeyPath = strParentKeyPath & "\" & strKeyName

dim strValueName : strValueName = "LastUpdate"

dim strValueData : strValueData = FormatDateTime(Now, 0)

 

' GET HANDLE TO StdRegProv CLASS THROUGH WHICH WE MANIPULATE REGISTRY

'==============================================================================

dim oReg : Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _

    & strComputer & "\root\default:StdRegProv")

 

' CHECK IF THE REGISTRY KEY EXISTS

'==============================================================================

dim subkey, arrSubKeys

dim keyFound : keyFound = False

oReg.EnumKey HKEY_CURRENT_USER, strParentKeyPath, arrSubKeys

 

If Not (IsNull(arrSubKeys)) then

    For Each subkey In arrSubKeys

        If subkey=strKeyName Then keyFound = True

    Next

End if

 

' IF KEY IS NOT FOUND THEN CREATE THE KEY

'==============================================================================

If Not (keyFound) then

    WScript.Echo "Registry key not found, creating the key..."

    oReg.CreateKey HKEY_CURRENT_USER, strKeyPath

    WScript.Echo "    Registry key created!"

End if

 

' SET THE VALUE TO CURRENT DATE AND TIME

'==============================================================================

oReg.SetStringValue HKEY_CURRENT_USER, strKeyPath,_

    strValueName, strValueData

WScript.Echo "Registry value updated!"


After the script is executed, the output is as shown in the following image. This is the first execution and hence the key is created.


Image of output of executed script

 


Now the registry will have the key and value created. The registry screen shot is shown in the following image.


Image of the registry key created

 


If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail 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

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • In Steve's Powershell solution, does the param ($variable, $variable2, $variable3) section do anything but make things easy to follow? I haven't seen the term used outside of a function.