searching arrays with vbs - vbscript

I'm trying to search through an array for a printer and if the printer exists display the name in the HTA. That bit works ok, but when no printer is found in the array all the installed printers on the device are displayed. is there a way to only show printers that are found
Set objFSO = CreateObject("Scripting.FileSystemObject")
arrPrinters = Split(objFSO.OpenTextFile("C:\Windows\DEW\denied-printers.txt" ,ForReading).ReadAll(), VbCrLf)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
For Each objPrinter in colInstalledPrinters
localprinter = objPrinter.Name
For Each strLine in arrPrinters
If inStr(localprinter,strLine) > 0 Then
strHTML = strHTML & "<tr><td>" & localprinter & "</td></tr>"
End If
Next
Next

try this
If inStr(localprinter,strLine) > 0 OR inStr(localprinter,strLine) = NULL Then
End If
the problem is if array is empty, strline is NULL and when you used it in inStr, it returns NULL instead of '0'. That is one possibility – tunmise fasipe 3 mins ago edit

Your main problem - i guess without knowing the contents of yoyr file - is that in instr(textToSearch, searchString) you switch the two parameters .
Anyway, here a version of your code i tested.
const ForReading = 1
strComputer = "."
set objFSO = createObject("Scripting.FileSystemObject")
printers = objFSO.OpenTextFile("denied-printers.txt" ,ForReading).ReadAll()
set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
for Each objPrinter in colInstalledPrinters
localprinter = objPrinter.Name
if instr(printers, localprinter) then
strHTML = strHTML & "<tr><td>" & localprinter & "</td></tr>"
end if
next
EDIT: here the stand alone vbscript version, save it to a .vbs file and run to test
on error resume next
const ForReading = 1
strComputer = "."
file = "denied-printers.txt"
set objFSO = createObject("Scripting.FileSystemObject")
set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
if err.number=0 then
printers = objFSO.OpenTextFile(file ,ForReading).ReadAll()
if err.number=0 then
set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
for Each objPrinter in colInstalledPrinters
localprinter = objPrinter.Name
if instr(printers, localprinter) then
wscript.echo localprinter & " found in " & file
end if
next
else
wscript.echo "file " & file & " not found, showing all printers"
for Each objPrinter in colInstalledPrinters
wscript.echo objPrinter.Name
next
end if
else
wscript.echo "Error" & err.description
end if

Related

Vbscript to find critical process

I wrote a vbscript to find the critical process details from server.I have few process name if that process exists then the script should give the mentioned output.But the problem here is even though if the process exist or not exist the script give same output as "CriticalProcesses=NA". Can anyone help to fix this ? Any help is much appreciated
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
'WScript.Echo "Caption: " & objItem.Caption
Dim process
Process = objItem.Caption
Next
If inStr(process, "SQLserver") Or inStr(process, "mysql") then
wscript.echo "CriticalProcesses=Database"
else if inStr(process, "java") Or inStr(process, "weblogic") Then
wscript.echo "CriticalProcesses=wls"
else
wscript.echo "CriticalProcesses=NA"
End if
End if
The problem here is that you are iterating through your processes in a for loop and then you test the process name outside of the loop. So your If instr(process.. bit only checks the last process found from your for loop.
To fix, stick the if test inside your loop, so it can test each process it finds.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
'WScript.Echo "Caption: " & objItem.Caption
Dim process
Process = objItem.Caption
If inStr(process, "SQLserver") Or inStr(process, "mysql") Then
wscript.echo "CriticalProcesses=Database"
ElseIF inStr(process, "java") Or inStr(process, "weblogic") Then
wscript.echo "CriticalProcesses=wls"
Else
'wscript.echo "CriticalProcesses=NA"
End If
Next
I've also changed your Else If to an ElseIf and removed the unnecessary second End If.
Lastly, I commented out that echo in your Else since you probably don't want the script to Echo NA over and over and over again. At least... I wasn't to hip on pressing Enter 200 times.
To capture whether a wls or database type process is running and then only echo once at the end, you can capture the true/false for each type in a boolean variable, then test after the for loop:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
Dim hasDBProcess
Dim hasWLSProcess
hasDBProcess = False
hasWLSProcess = False
For Each objItem In colItems
'WScript.Echo "Caption: " & objItem.Caption
Dim process
Process = objItem.Caption
If inStr(process, "SQLserver") Or inStr(process, "mysql") Then
hasDBProcess = True
ElseIF inStr(process, "java") Or inStr(process, "weblogic") Then
hasWLSProcess = True
End If
Next
If hasDBProcess Then
wscript.echo "CriticalProcess=Database"
ElseIf hasWLSProcess Then
wscript.echo "CriticalProcess=wls"
Else
wscript.echo "CriticalProcess=NA"
End if

Getting Volume Serial Number Of Script Location

here is a vbscript which shows all drives' volume serial numbers. But I need to customize to return only the volume serial number of the drive which the script is running from.
How to do it?
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
str = ""
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk")
For Each objItem In colItems
str = str & objItem.Name & " SerialNumber: " & objItem.VolumeSerialNumber & vbCrlf & vbCrlf
Next
MsgBox str
This should do what you need:
' Get the drive designator...
With CreateObject("Scripting.FileSystemObject")
strDrive = .GetDriveName(WScript.ScriptFullName)
End With
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceId='" & strDrive & "'")
' There should only be one item in the collection...
For Each objItem In colItems
MsgBox objItem.Name & " SerialNumber: " & objItem.VolumeSerialNumber
Next

AD Query “the remote server does not exist or is unavailable”

What a great idea. I redid the script with your suggestion. It however has another problem. The new script only returns the last computer in the computer OU. How do you correctly pass each instance from the Dictionary to the If statement?
dim strComputer, objFileToWrite, objWMIService
If Reachable(QueryAD) Then
Set objFileToWrite = CreateObject("Scripting.FileSystemObject").OpenTextFile("\\cheeng.net\winc\IT\NuanceKey.txt",8,true)
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & QueryAD & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
objFileToWrite.Write VBNewLine & "User Name = " & objComputer.UserName _
& VBNewLine & "Computer Name = " & objComputer.Name
Next
WScript.Echo QueryAD & " Computer is Reachable!"
Else
WScript.Echo QueryAD & "Computer is Unreachable!"
End If
Function QueryAD
Dim objDictionary, strItem, colItems, i, s
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objOU = GetObject("LDAP://OU=Computers,OU=WINC,DC=cheeng,DC=net")
objOU.Filter = Array("Computer")
For Each objComputer in objOU ' Add Workstations to Dictionary
objDictionary.Add a, objComputer.CN
a = a + 1
colItems = objDictionary.Items ' Get the workstations.
for i = 0 to objDictionary.count -1 ' Iterate the array.
s = colItems(i) ' Create return string.
next
QueryAD = s
Next
End Function
Function Reachable(strComputer) 'Test Connectivty to computer
Dim wmiQuery, objWMIService, objStatus
' Define the WMI query
wmiQuery = "Select * From Win32_PingStatus Where Address = '" & strComputer & "'"
' Run the WMI query
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2").ExecQuery(wmiQuery)
' Translate the query results to either True or False
For Each objStatus in objWMIService
If IsNull(objStatus.StatusCode) Or objStatus.Statuscode<>0 Then
Reachable = False 'if computer is unreachable, return false
Else
Reachable = True 'if computer is reachable, return true
End If
Next
Set objWMIService = Nothing
End Function
Before you connect to the remote computer, you need to ping it to see if it's online. Here's a function that does that.
Function Reachable(strComputer) 'Test Connectivty to computer
Dim wmiQuery, objWMIService, objPing, objStatus
wmiQuery = "Select * From Win32_PingStatus Where Address = '" & strComputer & "'"
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set objPing = objWMIService.ExecQuery(wmiQuery)
For Each objStatus in objPing
If IsNull(objStatus.StatusCode) Or objStatus.Statuscode<>0 Then
Reachable = False 'if computer is unreachable, return false
Else
Reachable = True 'if computer is reachable, return true
End If
Next
End Function
Then to use this function you can do a
If Reachable("computername") Then
Set objWMIService = GetObject...etc
Edit:
You'll want to add the reachable function inside your For loop and send one computer at a time to the function.
You also might want to query AD for only computers that are active. For example:
Set objFileToWrite = CreateObject("Scripting.FileSystemObject").OpenTextFile("\\cheeng.net\winc\IT\NuanceKey.txt",8,true)
arrComps = QueryAD
For Each strComputer in arrComps
If Reachable(strComputer) Then
Wscript.Echo strComputer & " Computer is Reachable!"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
objFileToWrite.Write VBNewLine & "User Name = " & objComputer.UserName _
& VBNewLine & "Computer Name = " & objComputer.Name
'You could also use strComputer here instead of objComputer.Name
Else 'If not reachable
Wscript.Echo strComputer & " Computer is Unreachable!"
End If 'End Reachable If
Next 'Loop to next computer
Function QueryAD
Const ADS_SCOPE_SUBTREE = 2
Dim objDictionary, colItems, strComputer
Set objDictionary = CreateObject("Scripting.Dictionary")
Set objRootDSE = GetObject("LDAP://RootDSE")
strDomain = objRootDSE.Get("DefaultNamingContext")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = _
"Select Name from 'LDAP://" & strDomain & "' " _
& "Where objectClass='computer' and userAccountControl <> 4098 and userAccountControl <> 4130"
'This will get all computers except disabled computers from AD
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
strComputer = objRecordSet.Fields("Name").Value
objDictionary.Add strComputer,strComputer
objRecordSet.MoveNext
Loop
objRecordSet.Close
QueryAD = objDictionary.Items
End Function
Function Reachable(strComputer) 'Test Connectivty to computer
'keep the same as you had it
End Function

VBscript to get info from pc

Hello I´m writing this script where i need Serial number, IP address, login user, produkt key from office, autoroute to a text file. I have begun to write a script but having some issues. Not a done script but im kinda stuck to here.
Here´s the script:
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
arrComputers = Array("localhost")
For Each strComputer In arrComputers
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService1.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService2.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly)
Set objWMIService = GetObject( "winmgmts:\\" & strCoputer & ".\root\CIMV2" )
Set colItems = objWMIService.ExecQuery( "SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL", _ wbemFlagReturnImmediately + wbemFlagForwardOnly)
next
For Each objItem In colItems2
Dim fso, tf
Set fso = CreateObject("Scripting.FileSystemObject")
Set tf = fso.CreateTextFile ("c:\" & objItem.UserName & ".txt", True)
tf.Write "Username: " & objItem.UserName
tf.WriteBlankLines(1)
tf.Write "Hostname: " & objItem.Name
tf.WriteBlankLines(1)
tf.Write "Domain: " & objItem.Domain
tf.WriteBlankLines(2)
next
For Each objItem In colItems1
tf.Write "Serial: " & objItem.IdentifyingNumber
tf.WriteBlankLines(1)
tf.Write "Model: " & objItem.Name
tf.WriteBlankLines(2)
tf.Write "Vendor: " & objItem.Vendor
tf.WriteBlankLines(1)
tf.Write "Version: " & objItem.Version
tf.WriteBlankLines(2)
Next
For Each objItem In colItems3
tf.Write "IP Address: " & objItem.IPAddress
tf.WriteBlankLines(1)
tf.Close
next
Microsoft has created a free tool called Scriptomatic which automatically creates vbscript code for such kind of task. You can download scriptomatic from the below location.
http://www.microsoft.com/en-in/download/details.aspx?id=12028

Obtaining process that launched (for instance) iexplore with VBScript/JScript

Is there a way to (ideally with a scripting language like VBScript / JScript) get details of a process that spawned a different program i.e., In the case when Computrace LoJack launches iexplore, to handle communications with the internet?
You can use WMI to check the ParentProcessId for the process you are interested in. In the case of "normal" user mode applications, the parent process should be explorer.exe.
strProcess = "iexplore.exe"
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = '" & strProcess & "'")
For Each objProcess in colProcesses
WScript.Echo objProcess.ParentProcessId
Next
In the case of Internet Explorer, make sure you check for the ID of IE as well since it will spawn multiple instances of itself. Try something like this:
strProcess = "iexplore.exe"
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = 'explorer.exe' OR name = 'iexplore.exe'")
i = 0
arrIds = Array()
For Each objProcess in colProcesses
ReDim Preserve arrIds(i)
arrIds(i) = objProcess.ProcessId
i = i + 1
Next
Set colProcesses = objWMIService.ExecQuery("Select * from Win32_Process " _
& " Where name = '" & strProcess & "'")
For Each objProcess in colProcesses
intParentID = objProcess.ParentProcessId
blnIsFound = False
For Each intID in arrIds
If intID = intParentID Then
blnIsFound = True
Exit For
End If
Next
If blnIsFound = False Then
WScript.Echo "Process " & objProcess.ProcessId & " spawned by process " & objProcess.ParentProcessId
End If
Next

Resources