Unable to read uninstall keys for x64 registry, vbscript - windows

I was trying to read the Uninstall Keys (DisplayName, Display Version, Vendor ..) from both 32 and 64 Bit installation keys. I have below code but it is always giving only 32 bit keys info. As I wrote the below code it is giving the entries from 32 bit twice :(
' Constants (taken from WinReg.h)
'
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
' Chose computer name, registry tree and key path
'
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Add
ObjExcel.Cells (1,1) = "Application Name"
ObjExcel.Cells (1,4) = "Application Vendor"
ObjExcel.Cells (1,2) = "Application Version"
ObjExcel.Cells (1,3) = "DRM Build"
strComputer = InputBox("Enter the Machine name. To run on the current machine, press ENTER", "Machine Name", "")
If strComputer = "" Then
strComputer = "."
End If
Msgbox "Script is Running and may take couple of minutes to complete. Click on OK to continue",0, "Information"
hDefKey = HKEY_LOCAL_MACHINE
' Connect to registry provider on target machine with current user
Set oReg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
'{impersonationLevel=impersonate}!
' Enum the subkeys of the key path we've chosen
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
row = 2
getRegistryEntries hDefKey, strKeyPath, ObjExcel, oReg, row
strKeyPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
getRegistryEntries hDefKey, strKeyPath, ObjExcel, oReg, row
fileName = Year(now) & month(now) & day(now) & hour(now) & minute(now) & second(now)
ObjExcel.ActiveWorkbook.SaveAs "C:\" & fileName & ".xlsx"
ObjExcel.Quit
Set ObjExcel = Nothing
msgbox "Work Done, file saved in C Drive with the name: " & fileName
Function getRegistryEntries(hDefKey, strKeyPath, byRef objExcel, byRef oReg, byRef row)
oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
Set objShell = CreateObject("WScript.Shell")
For Each strSubkey In arrSubKeys
' Show the subkey
'
furtherKeys = False
strDisName = "HKEY_LOCAL_MACHINE\" & strKeyPath & "\" & strSubkey & "\DisplayName"
On Error Resume Next
present = False
disName = objShell.RegRead(strDisName)
If disName <> "" Then
present = True
End If
disVersionPresent = false
disVer = ""
If present = true Then
strDisVer = "HKEY_LOCAL_MACHINE\" & strKeyPath & "\" & strSubkey & "\DisplayVersion"
strDisVendor = "HKEY_LOCAL_MACHINE\" & strKeyPath & "\" & strSubkey & "\Publisher"
strDRMBuild = "HKEY_LOCAL_MACHINE\" & strKeyPath & "\" & strSubkey & "\DRMBUILD"
disVer = objShell.RegRead(strDisVer)
If err.number = 0 Then
disVersionPresent = True
End If
If disVersionPresent Then
ObjExcel.Cells (row,1) = disName
ObjExcel.Cells (row,2) = "'" & disVer
furtherKeys = True
disVendor = objShell.RegRead(strDisVendor)
If err.number = 0 Then
ObjExcel.Cells (row,4) = disVendor
End If
DRMBuild = objShell.RegRead(strDRMBuild)
If err.number = 0 Then
ObjExcel.Cells (row,3) = "'" & DRMBuild
End If
End If
End If
If furtherKeys Then
row = row + 1
End If
Next
End Function

Related

Read Windows Registry value into array

I have to read Windows Registry value into array in VBA. Value has type REG_MULTI_SZ.
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Control\Lsa\Authentication Packages"
strValueName = "Sources"
Return = objReg.GetMultiStringValue(HKEY_LOCAL_MACHINE, strKeyPath, _
strValueName, arrValues)
If (Return = 0) And (Err.Number = 0) Then
'Treat the multistring value as a collection of strings
'separated by spaces and output
For Each strValue In arrValues
WScript.Echo strValue
Next
Else
WScript.Echo "GetMultiStringValue failed. Error = " & Err.Number
End If
It gives an error with number 0 and no description. Any clue?
According to your screenshot your key is "Authentication Packages", not "Sources".
Change this:
strKeyPath = "SYSTEM\CurrentControlSet\Control\Lsa\Authentication Packages"
strValueName = "Sources"
into this:
strKeyPath = "SYSTEM\CurrentControlSet\Control\Lsa"
strValueName = "Authentication Packages"
It was a simple error. The working code is here.
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\"& strComputer & "\root\default:StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Control\Lsa"
strValueName = "Authentication Packages"
Return = objReg.GetMultiStringValue(HKEY_LOCAL_MACHINE,strKeyPath, strValueName,arrValues)
WScript.Echo "GetMultiStringValue. Return = " & Return
If (Return = 0) And (Err.Number = 0) Then
' Treat the multistring value as a collection of strings
' separated by spaces and output
For Each strValue In arrValues
WScript.Echo strValue
Next
Else
Wscript.Echo "GetMultiStringValue failed. Error = " & Err.Number
End If

signature auto reply for plain text emails

im currently using a VBS to set HTML newmail/reply signatures. this is the script.
I want to set the txtreply.txt as default reply on txt emails. atm im not even able to choose the file from outlook.
Option Explicit
On Error Resume Next
Dim qQuery, objSysInfo, objuser, strComputer, objWMIService, colProcessList, objProcess
Dim FullName, EMail, Title, PhoneNumber, MobileNumber, FaxNumber, OfficeLocation, Department, Firstname, Lastname, HeadNumber
Dim web_address, web_address_pl, FolderLocation, HTMFileString,HTMFileString2,HTMFileString3 StreetAddress, Town, State, Company, gptw_link, gptw_img
Dim ZipCode, PostOfficeBox, UserDataPath
Dim linkedin_link, linkedin_img
' Closing outlook
'==========================================================
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = 'OUTLOOK.EXE'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
WScript.Sleep 1000
' Read LDAP(Active Directory)
'==========================================================
Set objSysInfo = CreateObject("ADSystemInfo")
'objSysInfo.RefreshSchemaCache
qQuery = "LDAP://" & objSysInfo.Username
Set objuser = GetObject(qQuery)
FullName = objuser.displayname
Firstname = objuser.Firstname
Lastname = objuser.Lastname
EMail = objuser.mail
Company = objuser.Company
Title = objuser.title
HeadNumber = ""
PhoneNumber = objuser.TelephoneMobile
FaxNumber = objuser.FaxNumber
OfficeLocation = objuser.physicalDeliveryOfficeName
StreetAddress = objuser.streetaddress
PostofficeBox = objuser.postofficebox
Department = objUser.Department
ZipCode = objuser.postalcode
Town = objuser.l
MobileNumber = objuser.TelephoneMobile
Dim objShell, RegKey, RegKeyParm
Set objShell = CreateObject("WScript.Shell")
RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Common\General"
RegKey = RegKey & "\Signatures"
objShell.RegWrite RegKey , "Signatures"
UserDataPath = ObjShell.ExpandEnvironmentStrings("%appdata%")
FolderLocation = UserDataPath &"\Microsoft\Signatures\"
HTMFileString = FolderLocation & "Newmail.htm"
HTMFileString2 = FolderLocation & "Reply.htm"
HTMFileString3 = FolderLocation & "txtreply.txt."
' Ingen rettigheder for brugeren i at ændre signaturen.
'==========================================================
' Outlook 2010
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Common\MailSettings\NewSignature" , "Newmail"
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Common\MailSettings\ReplySignature" , "Reply"
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Outlook\Options\Mail\EnableLogging" , "0", "REG_DWORD"
' Outlook 2013
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common\MailSettings\NewSignature" , "Hartmanns"
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Common\MailSettings\ReplySignature" , "Hartmanns_Reply"
objShell.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0 \Outlook\Options\Mail\EnableLogging" , "0", "REG_DWORD"
' KOntroller om signatur biblioteket eksistere, opret hvis ikke
'==========================================================
Dim objFS1
Set objFS1 = CreateObject("Scripting.FileSystemObject")
If (objFS1.FolderExists(FolderLocation)) Then
Else
Call objFS1.CreateFolder(FolderLocation)
End if
' Opret signatur filen
'==========================================================
Dim objFSO
Dim objFile,objFile2,objFile3,afile
Dim aQuote, aColon
Dim objCitatFile, strText, arrCitat, x
aQuote = chr(34)
aColon = chr(58)
' Opbyg HTML fil struktur
'==========================================================
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Slet andre signatur filer
' Disse filer er automatisk oprettet af Outlook 2003, 2007 & 2010
'==========================================================
Set AFile = objFSO.GetFile(Folderlocation&"Newmail.rtf")
'aFile.Delete
Set AFile = objFSO.GetFile(Folderlocation&"Newmail.txt")
'aFile.Delete
Set objFile = objFSO.CreateTextFile(HTMFileString,True)
objFile.Close
Set objFile = objFSO.OpenTextFile(HTMFileString, 2)
objfile.write "<!DOCTYPE HTML PUBLIC " & aQuote & "-//W3C//DTD HTML 4.0 Transitional//EN" & aQuote & ">" & vbCrLf
objfile.write "<HTML><HEAD><TITLE>"
the new mail content
objfile.write "</body></HTML>" & vbCrLf
objfile.Close
' Skriv besvar signatur
' =========================================================
Set AFile = objFSO.GetFile(Folderlocation&"Reply.rtf")
aFile.Delete
Set AFile = objFSO.GetFile(Folderlocation&"Reply.txt")
aFile.Delete
Set objFile2 = objFSO.CreateTextFile(HTMFileString2,True)
objFile2.Close
Set objFile2 = objFSO.OpenTextFile(HTMFileString2, 2)
objfile2.write "<!DOCTYPE HTML PUBLIC " & aQuote & "-//W3C//DTD HTML 4.0 Transitional//EN" & aQuote & ">" & vbCrLf
objfile2.write "<HTML>
the reply email
objfile2.write "</body></HTML>" & vbCrLf
objfile2.close
' Skriv Plain tekst besvar signatur
' =========================================================
Set AFile = objFSO.GetFile(Folderlocation&"txtreply.rtf")
'aFile.Delete
Set AFile = objFSO.GetFile(Folderlocation&"txtreply.htm")
'aFile.Delete
Set objFile3 = objFSO.CreateTextFile(HTMFileString3,True)
objFile3.Close
Set objFile3 = objFSO.OpenTextFile(HTMFileString3, 2)
objfile3.write "<font size=3></font><br /><br />"
objfile3.write "<font size=3><b></font></b><br>"
objfile3.write "<font size=3><b></b><br /></font>"
objfile3.write "<font size=3></font><br /><br /></font>"
objfile3.write "<font size=3>Please consider the environment before printing this email or its attachments</font>"
objfile3.close
' Læs outlook profilen og sæt signaturen som default
' =========================================================
Call SetDefaultSignature("newmail","")
Call SetDefaultReplyForwardSignature("Reply","")
Sub SetDefaultSignature(strSigName, strProfile)
Dim objreg, strKeyPath, myArray, arrProfileKeys, subkey, strsubkeypath
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
If Not IsOutlookRunning Then
Set objreg = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows NT\" & _
"CurrentVersion\Windows " & _
"Messaging Subsystem\Profiles\"
' Find profil navn, hvis ikke det er defineret
If strProfile = "" Then
objreg.GetStringValue HKEY_CURRENT_USER, _
strKeyPath, "DefaultProfile", strProfile
End If
' Byg array fra signatur navne
myArray = StringToByteArray(strSigName, True)
strKeyPath = strKeyPath & strProfile & _
"\9375CFF0413111d3B88A00104B2A6676"
objreg.EnumKey HKEY_CURRENT_USER, strKeyPath, _
arrProfileKeys
For Each subkey In arrProfileKeys
strsubkeypath = strKeyPath & "\" & subkey
objreg.SetBinaryValue HKEY_CURRENT_USER, _
strsubkeypath, "New Signature", myArray
Next
'Else
' strMsg = "Please shut down Outlook before " & _
' "running this script."
' MsgBox strMsg, vbExclamation, "SetDefaultSignature"
End If
End Sub
'Reply_Forward
Sub SetDefaultReplyForwardSignature(strSigName, strProfile)
Dim objreg, strKeyPath, myArray, arrProfileKeys, subkey, strsubkeypath
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
If Not IsOutlookRunning Then
Set objreg = GetObject("winmgmts:" & _
"{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows NT\" & _
"CurrentVersion\Windows " & _
"Messaging Subsystem\Profiles\"
' Find profil navn, hvis ikke det er defineret
If strProfile = "" Then
objreg.GetStringValue HKEY_CURRENT_USER, _
strKeyPath, "DefaultProfile", strProfile
End If
' Byg array fra signatur navne
myArray = StringToByteArray(strSigName, True)
strKeyPath = strKeyPath & strProfile & _
"\9375CFF0413111d3B88A00104B2A6676"
objreg.EnumKey HKEY_CURRENT_USER, strKeyPath, _
arrProfileKeys
For Each subkey In arrProfileKeys
strsubkeypath = strKeyPath & "\" & subkey
objreg.SetBinaryValue HKEY_CURRENT_USER, _
strsubkeypath, "Reply-Forward Signature", myArray
Next
'Else
'strMsg = "Please shut down Outlook before " & _
' "running this script."
'MsgBox strMsg, vbExclamation, "SetDefaultSignature"
End If
End Sub
Function IsOutlookRunning()
Dim strQuery, colProcesses
strComputer = "."
strQuery = "Select * from Win32_Process " & _
"Where Name = 'Outlook.exe'"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery(strQuery)
For Each objProcess In colProcesses
If UCase(objProcess.Name) = "OUTLOOK.EXE" Then
IsOutlookRunning = True
Else
IsOutlookRunning = False
End If
Next
End Function
Public Function StringToByteArray _
(Data, NeedNullTerminator)
Dim strAll, intLen, i
strAll = StringToHex4(Data)
If NeedNullTerminator Then
strAll = strAll & "0000"
End If
intLen = Len(strAll) \ 2
ReDim arr(intLen - 1)
For i = 1 To Len(strAll) \ 2
arr(i - 1) = CByte _
("&H" & Mid(strAll, (2 * i) - 1, 2))
Next
StringToByteArray = arr
End Function
Public Function StringToHex4(Data)
Dim strAll, strChar, strTemp, i
For i = 1 To Len(Data)
' Konverter hver karakter (4) til hex ?#!" :)
strChar = Mid(Data, i, 1)
strTemp = Right("00" & Hex(AscW(strChar)), 4)
strAll = strAll & Right(strTemp, 2) & Left(strTemp, 2)
Next
StringToHex4 = strAll
End Function
if i create a txt file in the \Microsoft\Signatures folder it shows in outlook but im not able to create the file using the script. problem is that i need to create the .txt signature on 100 users.

Teamviewer VBScript Pinging Computers

I am looking for a way to have my current VBScript (it is very big and I don't know if there is a way to pair it down) that currently creates a list of all computers in active directory and outputs it to a file. Once that is completed the rest of my script then calls that text file and creates another one with all the computer names and date/time/ and what the teamviewer ID is by means of either Windows 7 reg key or Windows XP. The issue I am running into is that if a computer doesn't exist in the domain anymore the script places the previous value into the computer that doesn't exist which is creating duplicates.
I would love to find a way to edit my script and ping each of the computers in the original text file and remove the computers out of it that are not online. I will attach my script. Let me know if you have any questions.
' Declare the constants
Dim oFSO
Const HKLM = &H80000002 ' HKEY_LOCAL_MACHINE
'Const REG_SZ = 1 ' String value in registry (Not DWORD)
Const ForReading = 1
Const ForWriting = 2
' Set File objects...
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objDictionary2 = CreateObject("Scripting.Dictionary")
' Set string variables
strDomain = "my domain" ' Your Domain
strPCsFile = "DomainPCs.txt"
strPath = "C:\logs\" ' Create this folder
strWorkstationID = "C:\logs\WorkstationID.txt"
If objFSO.FolderExists(strPath) Then
Wscript.Echo "This program will collect Workstation ID on remote compter(s)"
Else
Wscript.Echo "This program will collect Workstation ID on remote compter(s)"
oFSO.CreateFolder strPath
End If
' Get list of domain PCs - Using above variables.
strMbox = MsgBox("Would you like info for entire domain: rvdocs.local?",3,"Hostname")
'an answer of yes will return a value of 6, causing script to collect domain PC info
If strMbox = 6 Then
Set objPCTXTFile = objFSO.OpenTextFile(strPath & strPCsFile, ForWriting, True)
Set objDomain = GetObject("WinNT://" & strDomain) ' Note LDAP does not work
objDomain.Filter = Array("Computer")
For Each pcObject In objDomain
objPCTXTFile.WriteLine pcObject.Name
Next
objPCTXTFile.close
Else
'an answer of no will prompt user to input name of computer to scan and create PC file
strHost = InputBox("Enter the computer you wish to get Workstation ID","Hostname"," ")
Set strFile = objfso.CreateTextFile(strPath & strPCsFile, True)
strFile.WriteLine(strHost)
strFile.Close
End If
' Read list of computers from strPCsFile into objDictionary
Set readPCFile = objFSO.OpenTextFile(strPath & strPCsFile, ForReading)
i = 0
Do Until readPCFile.AtEndOfStream
strNextLine = readPCFile.Readline
objDictionary.Add i, strNextLine
i = i + 1
Loop
readPCFile.Close
' Build up the filename found in the strPath
strFileName = "Workstation ID_" _
& year(date()) & right("0" & month(date()),2) _
& right("0" & day(date()),2) &".txt"
' Write each PC's software info file...
Set objTextFile2 = objFSO.OpenTextFile(strPath & strFileName, ForWriting, True)
For each DomainPC in objDictionary
strComputer = objDictionary.Item(DomainPC)
On error resume next
' WMI connection to the operating system note StdRegProv
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
' These paths are used in the filenames you see in the strPath
pcName = "SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\"
pcNameValueName = "ComputerName"
objReg.GetStringValue HKLM,pcName,pcNameValueName,pcValue
strKeyPath = "SOFTWARE\Wow6432Node\TeamViewer\Version5.1\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath, strValueName, strValue
If IsNull(strValue) Then
strKeyPath = "SOFTWARE\TeamViewer\Version5.1\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath,strValueName,strValue
End If
If IsNull(strValue) Then
strValue = " No Teamviewer ID"
End If
Set objReg = Nothing
Set ObjFileSystem = Nothing
objTextFile2.WriteLine(vbCRLF & "==============================" & vbCRLF & _
"Current Workstation ID: " & UCASE(strComputer) & vbCRLF & Time & vbCRLF & Date _
& vbCRLF & "Teamviewer ID:" & "" & strValue & vbCRLF & "----------------------------------------" & vbCRLF)
'GetWorkstationID()
Next
WScript.echo "Finished Scanning Network check : " & strPath
objFSO.DeleteFile(strPath & strPCsFile)
wscript.Quit
The cause of the issue is that objReg retains its value from the previous iteration when
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
fails due to a non-reachable computer (which is masked by On Error Resume Next).
One way to deal with the issue is to set objReg to Nothing before trying to connect to the remote host and check if the variable still is Nothing afterwards:
On Error Resume Next
Set objReg = Nothing
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
If Not objReg Is Nothing Then
'check for TeamViewer ID
Else
'remote host unavailable
End If
A more elegant solution to the problem (one that doesn't require the infamous On Error Resume Next) is to ping the remote computer before trying to connect to it:
Set wmi = GetObject("winmgmts://./root/cimv2")
qry = "SELECT * FROM Win32_PingStatus WHERE Address='" & strComputer & "'"
For Each response In wmi.ExecQuery(qry)
If IsObject(response) Then
hostAvailable = (response.StatusCode = 0)
Else
hostAvailable = False
End If
Next
If hostAvailable Then
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
'check for TeamViewer ID
Else
'remote host unavailable
End If
Here is what I came up with. I had to add the "On Error Resume Next" otherwise it would bring up an error box. Here is the code with the modified piece:
' Declare the constants
Dim oFSO
Const HKLM = &H80000002 ' HKEY_LOCAL_MACHINE
'Const REG_SZ = 1 ' String value in registry (Not DWORD)
Const ForReading = 1
Const ForWriting = 2
' Set File objects...
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objDictionary2 = CreateObject("Scripting.Dictionary")
' Set string variables
strDomain = "mydomain" ' Your Domain
strPCsFile = "DomainPCs.txt"
strPath = "C:\logs\" ' Create this folder
strWorkstationID = "C:\logs\WorkstationID.txt"
If objFSO.FolderExists(strPath) Then
Wscript.Echo "This program will collect Workstation ID on remote compter(s)"
Else
Wscript.Echo "This program will collect Workstation ID on remote compter(s)"
oFSO.CreateFolder strPath
End If
' Get list of domain PCs - Using above variables.
strMbox = MsgBox("Would you like info for entire domain: rvdocs.local?",3,"Hostname")
'an answer of yes will return a value of 6, causing script to collect domain PC info
If strMbox = 6 Then
Set objPCTXTFile = objFSO.OpenTextFile(strPath & strPCsFile, ForWriting, True)
Set objDomain = GetObject("WinNT://" & strDomain) ' Note LDAP does not work
objDomain.Filter = Array("Computer")
For Each pcObject In objDomain
objPCTXTFile.WriteLine pcObject.Name
Next
objPCTXTFile.close
Else
'an answer of no will prompt user to input name of computer to scan and create PC file
strHost = InputBox("Enter the computer you wish to get Workstation ID","Hostname"," ")
Set strFile = objfso.CreateTextFile(strPath & strPCsFile, True)
strFile.WriteLine(strHost)
strFile.Close
End If
' Read list of computers from strPCsFile into objDictionary
Set readPCFile = objFSO.OpenTextFile(strPath & strPCsFile, ForReading)
i = 0
Do Until readPCFile.AtEndOfStream
strNextLine = readPCFile.Readline
objDictionary.Add i, strNextLine
i = i + 1
Loop
readPCFile.Close
' Build up the filename found in the strPath
strFileName = "Workstation ID_" _
& year(date()) & right("0" & month(date()),2) _
& right("0" & day(date()),2) & ".txt"
' Write each PC's software info file...
Set objTextFile2 = objFSO.OpenTextFile(strPath & strFileName, ForWriting, True)
For each DomainPC in objDictionary
strComputer = objDictionary.Item(DomainPC)
Set wmi = GetObject("winmgmts://./root/cimv2")
qry = "SELECT * FROM Win32_PingStatus WHERE Address='" & strComputer & "'"
For Each response In wmi.ExecQuery(qry)
If IsObject(response) Then
hostAvailable = (response.StatusCode = 0)
Else
hostAvailable = False
End If
Next
On error resume Next
If hostAvailable Then
'check for TeamViewer ID
' WMI connection to the operating system note StdRegProv
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
' These paths are used in the filenames you see in the strPath
pcName = "SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName\"
pcNameValueName = "ComputerName"
objReg.GetStringValue HKLM,pcName,pcNameValueName,pcValue
strKeyPath = "SOFTWARE\Wow6432Node\TeamViewer\Version5.1\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath, strValueName, strValue
If IsNull(strValue) Then
strKeyPath = "SOFTWARE\Wow6432Node\TeamViewer\Version5\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath,strValueName,strValue
End If
If IsNull(strValue) Then
strKeyPath = "SOFTWARE\TeamViewer\Version5.1\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath,strValueName,strValue
End If
If IsNull(strValue) Then
strKeyPath = "SOFTWARE\TeamViewer\Version5\"
strValueName = "ClientID"
objReg.GetDWORDValue HKLM,strKeyPath,strValueName,strValue
End If
If IsNull(strValue) Then
strValue = " No Teamviewer ID"
End If
Set objReg = Nothing
Set ObjFileSystem = Nothing
objTextFile2.WriteLine(vbCRLF & "==============================" & vbCRLF & _
"Current Workstation ID: " & UCASE(strComputer) & vbCRLF & Time & vbCRLF & Date _
& vbCRLF & "Teamviewer ID:" & "" & strValue & vbCRLF _
& "----------------------------------------" & vbCRLF)
'GetWorkstationID()
strValue = NULL
Else
'remote host unavailable
End If
Next
WScript.echo "Finished Scanning Network check : " & strPath
'objFSO.DeleteFile(strWorkstationID)
objFSO.DeleteFile(strPath & strPCsFile)
wscript.Quit

Recursive search of HKU registry hive for a DWORD value

I need help with a VBScript that will recursively search the Windows HKU registry hive for a DWORD value. It would be helpful if the script could ignore the system accounts only looking in the S-1-5-21* keys. I MUST accomplish this using the HKU hive and not the HKCU hive because the program I plan to use to run the script runs in the context of system. No way around that.
Thank you.
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKU = &H80000003
strComputer = "."
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
'Read the HKEY_CURRENT_USER hive, registry path, and valuename to retrieve settings
strKeyPath = "Software\Policies\Microsoft\Windows\System\Power"
strValueName = "PromptPasswordOnResume"
oReg.GetDWORDValue HKCU,strKeyPath,strValueName,dwValue
'Return a failure exit code if entry does not exist
If IsNull(dwValue) Then
Wscript.Echo "The value is either Null or could not be found in the registry."
WScript.Quit 1
'Return a failure exit code if value does not equal STIG setting
ElseIf dwValue <> 1 Then
Wscript.Echo "This is a finding. ", strValueName,"=", dwValue
WScript.Quit 1
'Return a passing exit code if value matches STIG setting
ElseIf dwValue = 1 Then
Wscript.Echo "This is not a finding. "
WScript.Quit 0
End If
All this is what I ultimately came up with to resolve my issue.
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
'Set the local computer as the target
strComputer = "."
'set the objRegistry Object
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
'Enumerate All subkeys in HKEY_USERS
objRegistry.EnumKey HKEY_USERS, "", arrSubkeys
'Define variables
strKeyPath = "\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments"
strValueName = "HideZoneInfoOnProperties"
strSID = "S-1-5-21-\d*-\d*-\d*-\d{4,5}\\"
strValue = 1
f = True
For Each i in arrSubKeys
Set objRegExp = New RegExp
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = strSID
Set colMatches = objRegExp.Execute(i + strKeyPath)
For Each objMatch In colMatches
objRegistry.GetDWORDValue HKEY_USERS,i + strKeyPath,strValueName,dwValue
If IsNull(dwValue) Then
WScript.Echo "This is a finding, the key " & i + strKeyPath & "\" & strValueName & " does not exist."
f = False
ElseIf dwValue <> strValue Then
WScript.Echo "This is a finding, the " & i + strKeyPath & "\" & strValueName & ": " & dwValue & " does not equal REG_DWORD = " & strValue & "."
f = False
ElseIf dwValue = strValue Then
WScript.Echo "This is not a finding " & i + strKeyPath & "\" & strValueName & " = " & dwValue
End If
Next
Next
If f Then
WScript.Quit 0
Else
WScript.Quit 1
End If
You don't need recursion here. Simply iterate over the subkeys of HKEY_USERS and (try to) read the value. The return code of GetDWORDValue() will indicate whether or not the value could be read.
Const HKEY_USERS = &h80000003
subkey = "Software\Policies\Microsoft\Windows\System\Power"
name = "PromptPasswordOnResume"
computer = "."
Set reg = GetObject("winmgmts://" & computer & "/root/default:StdRegProv")
reg.EnumKey HKEY_USERS, "", sidList
For Each sid In sidList
key = sid & "\" & subkey
rc = reg.GetDWORDValue(HKEY_USERS, key, name, val)
If rc = 0 Then
If val = 1 Then
WScript.Echo "OK"
WScript.Quit 0
Else
WScript.Echo "Not OK"
WScript.Quit 1
End If
End If
Next
I am not sure if i got you right. If it is that you want to search in the HKU not in the HKCU, then the point is that an account in HKU is mapped to HKCU. Like in your case S-1-5-21* will be mapped to HKCU. You can check it by modifying an entry in HKCU and that will be reflected in HKU(S-1-5-21*) and vice-a-versa.

Searching the registry and i need the output of Path from list of servers using VBscript

Below Script is working fine ,it gets the path of the key i am searching . Please some one help me to find the way to read the list of servers from text file. im learning vbscript and tried some ways to read the text file it fails.
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "Server name"
const REG_SZ = 1
const REG_EXPAND_SZ = 2
const REG_BINARY = 3
const REG_DWORD = 4
const REG_MULTI_SZ = 7
strOriginalKeyPath = "SOFTWARE\VMware, Inc.\VMware Tools"
FindKeyValue(strOriginalKeyPath)
'-------------------------------------------------------------------------
Function FindKeyValue(strKeyPath)
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
errorCheck = oReg.EnumKey(HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys)
If (errorCheck=0 and IsArray(arrSubKeys)) then
For Each subkey In arrSubKeys
strNewKeyPath = strKeyPath & "\" & subkey
FindKeyValue(strNewKeyPath)
Next
End If
oReg.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, _
arrValueNames, arrValueTypes
If (errorCheck=0 and IsArray(arrValueNames)) then
For i=0 To UBound(arrValueNames)
'Wscript.Echo "Value Name: " & arrValueNames(i)
if arrValueNames(i) = "InstallPath" then
strValueName = arrValueNames(i)
oReg.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dwValue
wscript.echo strComputer & "\" & strkeyPath & vbNewLine
end if
Next
End if
end Function
Following is some code I use to read a list of machine names like:
MACHINE1
MACHINE2
MACHINE3
Into an array, which you can then loop through with a "For" statement.
pcList = readlist("C:\temp\testlist.txt")
'
' Reads in a list of PC names from a file and returns
' an array containing one PC name per member.
'
' Blank lines are ignored.
' Lines starting with ";" are treated as comments and
' are not added to the list.
'
'
function ReadList(listfile)
const forReading = 1
dim thelist()
redim thelist(1)
listLen = 0
set theFSO = createobject("Scripting.FileSystemObject")
set listFile = theFSo.openTextFile(listfile,forReading)
while not listFile.atendofstream
pcname = ltrim(rtrim(listFile.readline))
if len(pcname)>1 and left(pcname,1)<>";" then
if listlen = 0 then
thelist(0) = pcname
listlen = listlen+1
else
redim preserve thelist(listlen)
thelist(listlen) = pcname
listlen = listlen + 1
end if
end if
wend
listfile.close
set listfile = nothing
set thefso = nothing
ReadList = theList
end Function

Resources