VBS Windows 64bit/32bit registry read problem - windows

What I am trying to achieve I feel should be fairly simple yet it is driving me totally insane.
Background:
We run a system monitoring tools across our clients which has the ability to run .vbs scripts remotely. This works very well normally.
What I am trying to achieve currently is being able to read a line from the registry on both 32bit versions of windows and 64 bit versions.
The Client side.exe which monitors the machine runs as a 32bit process on BOTH platforms (This is the trick).
I want to read a key from HKEY_LOCAL_MACHINE\SOFTWARE\ for example. My script works perfectly fine on 32bit. example: objRegistry.RegRead("HKEY_LOCAL_MACHINE\Software\anything")
The problem I have is when I run this same line on a 64bit folder is is automatically looking in the wow64node folder. Example: objRegistry.RegRead("HKEY_LOCAL_MACHINE\Software\wow64node\").
I need to have it checking in EXACTLY the same place.
The key it is reading is part of a program that runs both 32bit and 64bit versions which is why it is not installed in the wow64node folder.
At this point I am unable to run the .VBS script as a 64bit process which would solve my problem entirely as it would then not look in the wow64node folder.
If anyone has any ideas at all please let me know.

I solved it using this piece of code.
Const HKEY_LOCAL_MACHINE = &H80000002
sPath = ReadRegStr (HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\ASP.NET\2.0.50727.0", "Path", 64)
WScript.Echo sPath
' Reads a REG_SZ value from the local computer's registry using WMI.
' Parameters:
' RootKey - The registry hive (see http://msdn.microsoft.com/en-us/library/aa390788(VS.85).aspx for a list of possible values).
' Key - The key that contains the desired value.
' Value - The value that you want to get.
' RegType - The registry bitness: 32 or 64.
'
Function ReadRegStr (RootKey, Key, Value, RegType)
Dim oCtx, oLocator, oReg, oInParams, oOutParams
Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
oCtx.Add "__ProviderArchitecture", RegType
Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")
Set oInParams = oReg.Methods_("GetStringValue").InParameters
oInParams.hDefKey = RootKey
oInParams.sSubKeyName = Key
oInParams.sValueName = Value
Set oOutParams = oReg.ExecMethod_("GetStringValue", oInParams, , oCtx)
ReadRegStr = oOutParams.sValue
End Function
Thank you Helen for your help!

Instead of WshShell.RegRead, use the WMI StdRegProv class — it allows you to specify whether you want to read from the 32-bit or 64-bit registry. Check out this MSDN article for more info and examples:
Requesting WMI Data on a 64-bit Platform

Related

how to post a file or stdout into a http server?

I would like to execute some command then send them into my web server for analysis.
somethink like :
wmic csproduct get | wget http://someserver/cgi-bin/hello.pl
Except that wget is not delivered out-of-the-box by Microsoft.
How can I make the same using stuff that are delivered with Windows 2000 and futher? Can vbscript do the job?
Since you executing some commands to get your information, may be it would be more native to use a command shell environment?
How about PowerShell?
(New-Object System.Net.WebClient).UploadString("http://someserver/cgi-bin/hello.pl", (Get-WMIObject Win32_BIOS) )
read about the UploadString() method here
If you still want to stick to a vbscript solution, here is a sample code which accepts a text from stdin and posts it to your server:
Dim inp, http_req
inp = inp & WScript.StdIn.ReadAll()
WScript.Echo "Input: " & inp
Set http_req = CreateObject("WinHTTP.WinHTTPRequest.5.1")
http_req.open "POST", "http://someserver/cgi-bin/hello.pl", false
http_req.setRequestHeader "Content-Type", "text/plain"
http_req.send inp
The minimum requirements seems to be Windows 2000 Professional with SP3 , i personnaly tested the script with Windows XP.

VBS Reg error in Win7 32bit & 64bit

I have made the following script in VBS but although it does work in windows xp & vista, I cant get it to work in win7 both 32 & 64 bit.
set myclip = createobject("clipbrd.clipboard")
bcode = myclip.gettext
if len(bcode) > 0 then
set wb = getobject("C:\DB.xlsx")
wb.sheets("1").range("a2").value = bcode
myclip.clear
myclip.settext wb.sheets("1").range("c2")
set wb = nothing
end if
set myclip = nothing
Through elevated cmd regsvr32 I get the
Regsvr32 DllRegisterServer in clipboard.dll succeded.
However when I try to run the vbs I get the following error:
Line: 1 Char: 1 ActiveX component can't create object 'clipbrd.clipboard' Code: 800A01AD S
Any ideas how to get passed it?
If it registered, but can't be instantiated there may be something it expects to be able to access during creation that it cannot access. There is a comment where you got this from:
"Note the constants i copied from msdn may not all be correct, or are outdated, see
http://msdn.microsoft.com/en-us/library/ebwdx8yh.aspx"
Based on that I suspect that one of the constant he copied from msdn is no longer available in Windows 7, or has changed, and that because of that it throws an error during creation.
Just a guess, but worth checking if you have VBS source.

Install inf driver with VBScript on Windows 7

I am trying to write a VBS script that install an USB/Ethernet adapter on Windows 7.
I've got a .INF file for this device.
I first tried:
Dim WshShell, res
Set WshShell = WScript.CreateObject("WScript.Shell")
res = WshShell.Run(WshShell.ExpandEnvironmentStrings( "%SystemRoot%" ) & "\System32\InfDefaultInstall.exe "" C:\Users\Me\Driver.inf """, 1, True)
res equaled 2.
Then I searched another way to do that and I found:
Dim WshShell, res
Set WshShell = WScript.CreateObject("WScript.Shell")
res = WshShell.Run(WshShell.ExpandEnvironmentStrings( "%SystemRoot%" ) & "\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 ""Driver.inf""", 1, True)
res equals 0 but I've got an error popup Installation failed.
What's wrong with my code? For the record, the script is launched with administration rights.
EDIT
I've tried to execute the first command directly in prompt and got: The inf file you selected does not support this method of installation..
Nothing happens with second command in prompt.
This is very weird because I can install the driver "manually" when I launch the device manager and select the inf file (with a warning: Windows can't verify the publisher of this driver software.):
Once the driver is installed, the class installer property shows NetCfgx.dll,NetClassInstaller. Could it be used?
I also tried with devcon with no success (program returns devcon.exe failed).
How about this way:
1)If you're using "Windows 7", why not take advantage of the driver pre-staging utility that is built right into the OS? W7 ships with a driver utility called "PNPUTIL". Issuing a command as such will add the drivers:
PNPUTIL -a "X:\Path to Driver File\Driver.inf"
This will process the INF and copy the CAT/SYS/INF (and any DLL, EXE, etc) into the "DriverStore" folder... which is the same place Windows stores all the in-built drivers ready for auto plug-and-play instalaltion.
2)If that's not an option for you, look for "DPInst.exe" (or "DPInst64.exe" for 64-bit systems). These are available as part of the Windows PDK (available free from Microsoft) and will process all INFs in the location you put the file and attempt to pre-stage them. This method tries to copy files to the "Drivers", "CatRoot", and "INF" locations which are not as reliable... and it can occassionally fail to copy required DLLs to "System32" folders etc... but 99% of the time (for simple drivers) it just works. I can arrange to send them to you if you can't find them.
Since I found the option (1) above, that has been my best friend. I use option 2 to isntall Canon USB printers and scanners on our base images, etc... so I know that works too.
I had same problem and solved it by explicitly using ASCII version of InstallHinfSection entry point:
res = WshShell.Run("%Comspec% /C %SystemRoot%\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSectionA DefaultInstall 132 ""Driver.inf""", 1, True)
There is probably a better solution, though (like hinting at the script engine which unicode/ASCII flavor to use).
Also I'm using EN-US system so this workaround may fail on more exotic locales.
Try this:
res = WshShell.Run("%Comspec% /C %SystemRoot%\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 ""Driver.inf""", 1, True)

Script IIS 5.1 installation on Windows XP

I found an idea for scripting the installation of IIS7 on Vista
I'm looking for a similar solution for IIS 5.1 on Windows XP. Any ideas?
Create your unattend text file. Check the following document on the Windows
Server CD for all relevant options:
support\tools\deploy.cab -- unattend.doc on W2K, or ref.chm for XP/W2K3
It looks something like this; here are some common ones you can pick from:
[Components]
iis_common = ON
iis_inetmgr = ON
iis_www = ON
iis_ftp = ON
iis_doc = ON
iis_htmla = ON
iis_pwmgr = ON
mts_core = ON
fp = OFF
fp_extensions = OFF
iis_smtp = OFF
iis_nntp = OFF
2.
Set Registry key at
HKLM\Software\Microsoft\Windows\CurrentVersion\Setup\SourcePath = ""
i.e.
SourcePath="\server\share"
where \server\share\i386 contains Windows files.
3.
Run:
SYSOCMGR.EXE /i:sysoc.inf /r /n /u:
Make sure the identity which runs this command has access to \server\share
--

Reset password for renamed Administrator account

I need to create a .VBS script to reset the Windows local administrator password on a large group of computers. My problem is that some of our sites have renamed the administrator account for security reasons. Does anyone have a script which changes the password of the administrator account based on the SID of the original Administrator account?
Using the fact that local admin's SID always ends with -500:
strComputer="." ' local computer by default
Set objUser=GetObject("WinNT://" & strComputer & "/" & GetAdminName & ",user")
objUser.SetPassword "New local admin password"
objUser.SetInfo
Function GetAdminName
'This function was written using information from Table J.1 from the Windows XP resource Kit
'http://www.microsoft.com/resources/documentation/Windows/XP/all/reskit/en-us/Default.asp?url=/resources/documentation/Windows/XP/all/reskit/en-us/prnc_sid_cids.asp
Set objNetwork = CreateObject("Wscript.Network") 'get the current computer name
objComputerName = objNetwork.ComputerName
Set objwmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & objComputerName)
qry = "SELECT * FROM Win32_Account where Domain = '" & cstr(objComputerName) & "'"
'set query, making sure to only look at local computer
For Each Admin in objwmi.ExecQuery(qry)
if (left(admin.sid, 6) = "S-1-5-" and right(admin.sid,4) = "-500") then 'look for admin sid
GetAdminName = admin.name
end if
next
end Function
There's a tool floating around somewhere called LookupAccountName (with source!) that given the SID of the builtin adminitrator will give you its name.
You're probably going to end up writing C++ code to pull this one off reasonably well.
Like Joshua says, I don't think you can do this with windows scripting host only, you could use it download something and execute it:
A custom app that calls LookupAccountSid(S-1-5-domain-500 SID or enum admin group)+NetUserSetInfo to reset the password (Needs to run this as admin)
http://home.eunet.no/pnordahl/ntpasswd/ (Reset at boot)
Dump the SAM hashes and crack the password (Cain,John the Ripper,L0phtCrack etc)
#DmitryK's answer is good, and I didn't know any of that stuff. But I do know that this sort of thing is usually cleaner in PowerShell, so I ported it.
For example, the whole GetAdminName function can be written:
$adminName = (gwmi win32_account | ? { $.SID.StartsWith( 'S-1-5-' ) -and $.SID.EndsWith( '-500' ) }).Name
(Add the -ComputerName option to the gwmi call to do this on a server.)
The rest becomes:
$user = ([ADSI]"WinNT://$($env:COMPUTERNAME)/$adminName,User")
$user.SetPassword( 'xxx' )
$user.SetInfo()
(applying the appropriate computer name as needed, of course.)

Resources