Two ways to check if a Registry Key exists using VBScript
Programming October 5th, 2011
The first one is using the method RegRead from WScript.Shell.
If the given key is not found, it will rise an error, so we need to use an On Error Resume Next (which I don’t really like).
We would need to pass to the function a string like HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ (note the trailing \) if we are looking for a Registry Key (those that look like a folder). If we want to check if a value inside a key exists, we would remove the trailing \, like HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\CurrentLevel.
Function RegKeyExists(Key) Dim oShell, entry On Error Resume Next Set oShell = CreateObject("WScript.Shell") entry = oShell.RegRead(Key) If Err.Number <> 0 Then Err.Clear RegKeyExists = False Else Err.Clear RegKeyExists = True End If End Function
The second method uses WMI.
In this case, we would need to pass the Key Hive (Current User, Local Machine, etc) in the form of hex numbers (I declared them as constants). The KeyPath would be something like SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings.
Const HKCR = &H80000000 'HKEY_CLASSES_ROOT Const HKCU = &H80000001 'HKEY_CURRENT_USER Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE Const HKUS = &H80000003 'HKEY_USERS Const HKCC = &H80000005 'HKEY_CURRENT_CONFIG Function KeyExists(Key, KeyPath) Dim oReg: Set oReg = GetObject("winmgmts:!root/default:StdRegProv") If oReg.EnumKey(Key, KeyPath, arrSubKeys) = 0 Then KeyExists = True Else KeyExists = False End If End Function
The difference with this function is that will only check for Registry Keys and not for values.
Tags: VBScript, Windows Registry, WMI
Fixing WMI Service (root\cimv2 namespace missing)
Windows September 26th, 2010
I was working on a VBScript code that uses the Windows Management Instrumentation (WMI) to query the running processes on the local machine, something like this:
strComputer = "." strProcess2Kill = "something.exe" Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process Where Name = " & strProcess2Kill) For Each objProcess In colProcess 'Now we will each one of the running processes "something.exe" objProcess.Terminate() Next
This code works in, at least, Win2k, WinXP, WinVista and Win7 (not sure if works on WinNt 4). The problem I had (as you can see here) was that the box where it should have been deployed (Win2k) showed an 0x8004100E error (Namespace specified cannot be found) on the 4th line of the code.
When I ran the following script to query all the namespaces on root:
strComputer = "." Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root") Set colNameSpaces = objSwbemServices.InstancesOf("__NAMESPACE") For Each objNameSpace In colNameSpaces Wscript.Echo objNameSpace.Name Next
I got this:
DEFAULT SECURITY WMI directory aspnet
As you can see, the CIMV2 namespace was not present and it should have been. So, something was wrong with the WMI installation on that box.
Then, I ran a very nice tool called wmidiag.vbs (pointed by user Uros Calakovic on my StackOverflow question) to diagnose several problems with WMI. Unfortunately, the tool gave me the same error and no proposed solution. He also mention a couple of interesting screencasts that more than one may find useful.
At the end, Google gave me the final answer once again. Reinstalling the WMI into the Windows Registry and rebuilding the WMI Repository did the trick (I did both, but maybe only the Repository rebuilding helped me this time).
In any case, to rebuild the WMI Repository, these are the only required steps:
- Stop the WMI service (net stop winmgmt)
- Go to %windows%/system32/wbem (in my win2k, winnt, on XP would be windows)
- Rename or remove the repository directory
- Start the WMI service again (net start winmgmt)
And for reinstalling WMI, you should run these commands on a console:
winmgmt /clearadap winmgmt /kill winmgmt /unregserver winmgmt /regserver winmgmt /resyncperf
Tags: VBScript, Windows 2000, Windows 7, Windows Vista, Windows XP, WMI
Call a WebService from VBScript
Programming June 29th, 2010
While I was writing some code on VBScript to avoid manual tasks that we currently do with a bunch of files, I needed to automatically upload some information extracted from all these files to a SQL database. One way to do it is using a Web Service that receives the data and store it into the database.
Our Web Service is able to receive the following protocols: SOAP 1.1, SOAP 1.2 and HTTP POST. For simplicity, we are going to use HTTP POST, which receive the parameters in the query string format (param1=value1¶m2=value2&…). In the other protocols (SOAP) we would need to send the parameters in a XML way (which is more powerful but a little more extensive to implement).
The expected HTTP request will be:
POST /WebService.asmx/WebMethod HTTP/1.1 Host: localhost Content-Type: application/x-www-form-urlencoded Content-Length: length param=string
And the response (in XML format):
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://tempuri.org/">string</string>
So, to call the Web Service directly from the VBScript, we can use the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 'The object that will make the call to the WS Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP") 'The object that will receive the answer from the WS Set oXMLDoc = CreateObject("Microsoft.XMLDOM") strParam = "string to pass" 'Tell the name of the subroutine that will handle the response oXMLHTTP.onreadystatechange = getRef("HandleStateChange") 'Initializes the request (the last parameter, False in this case, tells if the call is asynchronous or not oXMLHTTP.open "POST", "http://localhost/WebService.asmx/WebMethod", False 'This is the content type that is expected by the WS using the HTTP POST protocol oXMLHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 'Now we send the request to the WS oXMLHTTP.send "parameter=" & strParam Sub HandleStateChange() Dim szResponse 'When the call has been completed (ready state 4) If oXMLHTTP.readyState = 4 Then szResponse = oXMLHTTP.responseText oXMLDoc.loadXML szResponse 'If the WS response is not in XML format, there is a problem If oXMLDoc.parseError.errorCode <> 0 Then WScript.Echo "ERROR:" WScript.Echo oXMLHTTP.responseText WScript.Echo oXMLDoc.parseError.reason Else WScript.Echo "Result: " & oXMLDoc.getElementsByTagName("string")(0).childNodes(0).Text End If End If End Sub |
The ready state tells us about the connection with the Web Service:
- 0: Uninitialized – open() has not been called yet.
- 1: Loading – send() has not been called yet.
- 2: Loaded – send() has been called, headers and status are available.
- 3: Interactive – Downloading, responseText holds the partial data.
- 4: Completed – Finished with all operations.
Tags: VB, VBScript, Visual Basic, WebService
About