Learn about Windows PowerShell
(Note: These solutions were written for Beginner Event 1 of the 2010 Scripting Games.)
Beginner Event 1 (Windows PowerShell)
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.
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)
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:
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
' IF KEY IS NOT FOUND THEN CREATE THE KEY
If Not (keyFound) then
WScript.Echo "Registry key not found, creating the key..."
WScript.Echo " Registry key created!"
' SET THE VALUE TO CURRENT DATE AND TIME
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.
Now the registry will have the key and value created. The registry screen shot is shown in the following image.
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
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.