Use Registry value to start a batch - windows

I'd like to check at fixed time intervals (days) if a specific registry key exceeds a certain value.
If yes, then run a batchfile.
Is this possible (maybe with RegScanner ?) / how ?
thx

This is from the sample code in Help on RegistryValueChangeEvent in WMI
Set wmiServices = GetObject("winmgmts:root/default")
Set wmiSink = WScript.CreateObject( _
"WbemScripting.SWbemSink", "SINK_")
wmiServices.ExecNotificationQueryAsync wmiSink, _
"SELECT * FROM RegistryValueChangeEvent " _
& "WHERE Hive='HKEY_LOCAL_MACHINE' AND " _
& "KeyPath='SOFTWARE\\Microsoft\\WBEM\\sCRIPTING' " _
& "AND ValueName='Default Namespace'"
WScript.Echo "Listening for Registry Value" _
& " Change Events..." & vbCrLf
While(True)
WScript.Sleep 1000
Wend
Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
WScript.Echo "Received Registry " _
& "Change Event" & vbCrLf & _
wmiObject.GetObjectText_()
End Sub

Related

Is there a way to organize WriteLine output into columns in a text file?

Is there any way to separate the WriteLine data output in a text file into columns (ex: Date | Location | Size)?
I've yet to see any information regarding this anywhere online, unsure if possible since the data being written isn't static. Would I need an entirely different function in order to have the script handle the formatting of the text file?
Option Explicit
Dim sDirectoryPath,Search_Days,r_nr,iDaysOld,CmdArg_Object,lastModDate
Dim oFSO,oFolder,oFileCollection,oFile,oTF,Inp, SubFolder,fullpath
Set CmdArg_Object = Wscript.Arguments
Select Case (CmdArg_Object.Count)
Case 3
sDirectoryPath = CmdArg_Object.item(0)
Search_Days = CmdArg_Object.item(1)
r_nr = CmdArg_Object.item(2)
Case Else
WScript.Echo "SearchFiles.vbs requires 3 parameters:" & _
vbCrLf & "1) Folder Path" & _
vbCrLf & "2) # Days to Search" & _
vbCrLf & "3) Recursive option (r/nr)"
WScript.Quit
End Select
Set oFSO = CreateObject("Scripting.FileSystemObject")
iDaysOld=Date+(-1*Search_Days)
Inp = InputBox("Please Enter Desired Location of Log File:")
If Inp= "" Then
Set oTF = oFSO.CreateTextFile("C:\output.txt")
Else
Set oTF = oFSO.CreateTextFile(oFSO.BuildPath(Inp, "output.txt"))
End If
Set oFolder = oFSO.GetFolder(sDirectoryPath)
Set oFileCollection = oFolder.Files
WScript.Echo Now & " - Beginning " & Search_Days & " day search of " & sDirectoryPath
If r_nr = "r" Then
oTF.WriteLine ("Search Parameters-") & _
vbCrLf & "DirectoryPath: " & sDirectoryPath & _
vbCrLf & "Older than: " & Search_Days &" Days " & _
vbCrLf & "Recursive/Non-Recursive: " & r_nr & _
vbCrLf & "------------------ "
TraverseFolders oFSO.GetFolder(sDirectoryPath)
Function TraverseFolders (FolderName)
For Each SubFolder In FolderName.SubFolders
For Each oFile In SubFolder.Files
lastModDate = oFile.DateLastModified
If (lastModDate <= iDaysOld) Then
oTF.WriteLine (oFile.DateLastModified) & " " & oFile.Path
End If
Next
TraverseFolders(Subfolder)
Next
End Function
Else
oTF.WriteLine ("Search Parameters:") & _
vbCrLf & "DirectoryPath: " & sDirectoryPath & _
vbCrLf & "Older than: " & Search_Days &" Days " & _
vbCrLf & "Recursive/Non-Recursive: " & r_nr & _
vbCrLf & "------------------------- "
For Each oFile In oFileCollection
lastModDate = oFile.DateLastModified
If (lastModDate <= iDaysOld) Then
oTF.WriteLine (oFile.DateLastModified) & " " & oFile.Path
End If
Next
End If
If Inp = "" Then
WScript.Echo "Now - Finished! Results Placed in: C:\output.txt"
Else
WScript.Echo "Now - Finished! Results Placed in: " & Inp
End If
You could use a delimiter-separated output format, e.g. like this:
Delim = vbTab
oTF.WriteLine "DateLastModified" & Delim & "Size" & Delim & "Path"
...
For Each oFile in oFileCollection
oTF.WriteLine oFile.DateLastModified & Delim & oFile.Size & Delim & oFile.Path
Next
Using tabs and a carefully chosen order of fields has the advantage that editors will display the content in (mostly) proper columns and you can import it as CSV in other programs.
If you're aiming for a fixed-width format you need to pad the data yourself e.g. with custom padding functions, e.g.
Function LPad(s, l)
n = 0
If l > Len(s) Then n = l - Len(s)
LPad = String(n, " ") & s
End Function
Using a StringBuilder object would also be an option, as described in this answer to another question.

VBSCRIPT MsgBox VbYesNo countdown

Tried searching for the answer, all were too simple, or didn't match what I need. I have a message box, and I have it displaying information correctly. I have a Yes and No button. I want a timer, so when the timer runs out, it continues. If someone hits yes, it continues down the code, if they hit no, then it returns the user elsewhere. This is what I have, please help.
akey = MsgBox ("Image OS = " & ImageType & vbcrlf & _
"ComputerName = " & ComputerName & vbcrlf & _
"TimeZone = " & TZone & vbcrlf & _
"Ghost Server = " & Server & vbcrlf & _
"Broadcast Method = " & BMethod & vbcrlf & _
"Ghost Session = " & GhostSession _
, vbyesno + vbquestion,VN & " Please Confirm")
You can use Popup instead of Msgbox...
http://ss64.com/vb/popup.html
Set objShell = CreateObject("WScript.Shell")
X = objShell.Popup("You have 3 Seconds to answer", 3, "Test", vbYesNo)
Select Case X
Case vbYes
Msgbox "You pressed YES"
Case vbNo
Msgbox "You pressed NO"
Case Else
MsgBox "You pressed NOTHING"
End Select
Otherwise, you can try to manipulate an HTA or Internet Explorer window to do something similar.

Getting Script Name from wscript.exe Process

I am using this code:
Dim name
name = CreateObject("WScript.Shell").ExpandEnvironmentStrings("%computername%")
Set wmi = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& name & "\root\cimv2")
For Each hwnd In wmi.InstancesOf("Win32_Process")
If hwnd.Name = "wscript.exe" Then
'get name and possibly location of currently running script
End If
Next
I am successfully listing all processes and picking out the wscript.exe. However, I have searched and have found no way to find the name of the script running in wscript.exe, ie. is it myscript.vbs or jscript.js or anything. Bonus if there is a way to find the whole path of the script.
EDIT:
With more searching, I found a solution. In the above script, the hwnd variable stores the handle for the wscript.exe process. There is a property for handles: hwnd.CommandLine. It shows how to call it from the command line, so it would be something like:
"C:\Windows\System32\wscript.exe" "C:\path\to\script.vbs"
So I can parse the hwnd.CommandLine string to find the path and name of all running scripts.
You have ScriptName and ScriptFullName properties.
' in VBScript
WScript.Echo WScript.ScriptName
WScript.Echo WScript.ScriptFullName
// in JScript
WScript.Echo(WScript.ScriptName);
WScript.Echo(WScript.ScriptFullName);
[EDIT] Here you go (use .CommandLine property):
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& "." & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery( _
"Select * from Win32_Process " _
& "Where Name = 'WScript.exe'", , 48)
Dim strReport
For Each objProcess in colProcesses
' skip current script, and display the rest
If InStr (objProcess.CommandLine, WScript.ScriptName) = 0 Then
strReport = strReport & vbNewLine & vbNewLine & _
"ProcessId: " & objProcess.ProcessId & vbNewLine & _
"ParentProcessId: " & objProcess.ParentProcessId & _
vbNewLine & "CommandLine: " & objProcess.CommandLine & _
vbNewLine & "Caption: " & objProcess.Caption & _
vbNewLine & "ExecutablePath: " & objProcess.ExecutablePath
End If
Next
WScript.Echo strReport
myProcess="wscript.exe"
Set Processes = GetObject("winmgmts:").InstancesOf("Win32_Process")
For Each Process In Processes
If StrComp(Process.Name, myProcess, vbTextCompare) = 0 Then 'check if process exist
CmdLine=process.commandline
End If
Next
myArr=split(CmdLine,"\")
mySN=replace(myArr(ubound(myArr)),"""","")
Wscript.Echo "Full Pth: " & Cmdline &vbcrlf&"Script Name: "& mySN

Print binary data WScript

I am using the last example on this page in WMI to print out some Windows System Log information:
http://msdn.microsoft.com/en-us/library/aa394593(VS.85).aspx
I would also like to print out the binary data as well, but I am not sure how to do that in WScript. Here is my modified code:
' test.vbs
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery _
("Select * from Win32_NTLogEvent " _
& "Where Logfile = 'System' and SourceName = 'MySource'")
For Each objEvent in colLoggedEvents
Wscript.Echo "Category: " & objEvent.Category & VBNewLine _
& "Event Code: " & objEvent.EventCode & VBNewLine _
& "Message: " & objEvent.Message & VBNewLine _
& "Time Written: " & objEvent.TimeWritten & VBNewLine _
& "Event Type: " & objEvent.Type & VBNewLine _
& "Binary Data: " & objEvent.Data
Next
I get this error message from Windows Script Host when running test.vbs:
Error: Type mismatch, Code: 800A000D, Source: Microsoft VBScript runtime error
Any idea how to print the data out as a hex character string?
.Data is an array of integer values (little endian encoded wide characters from the looks of it). You'd need to ChrW() each pair of numbers and concatenate them to a string before you could print the data. A function like this might work:
Function ToStr(arr)
ToStr = ""
For i = 0 To UBound(arr) Step 2
ToStr = ToStr & ChrW(arr(i) + arr(i+1)*256)
Next
End Function

Basic VBS help - optimizing VBS script

I found this simple script that outputs the logical disk sizes.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For Each objDisk in colDisks
Wscript.Echo "DeviceID: " & objDisk.DeviceID & " with a Disk Size: " & objDisk.Size
Next
My VBS skills are very poor and I need help:
I would like to get a single size number of ONLY the C and D partitions added together
if the size (from step1) is not equal to 500-GB (between 450,000,000,000 and 550,000,000,000) I need the computer to prompt a warning and "press any key" to continue
I don't want a pop-up window since this is going to run from the prompt of WinPE, is it possible to get the output in the prompt window?
I'm asking a lot so thank you in advance if you can help
You will need to start your script using cscript.
The code for this comes from http://ask.metafilter.com/79481/vbscript-printing-to-command-line
This allows the echos to go to the command line instead of a Message box.
CheckStartMode
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For Each objDisk in colDisks
If(objDisk.DeviceID="C:" or objDisk.DeviceID="D:") then
Wscript.Echo "DeviceID: " & objDisk.DeviceID & " with a Disk Size: " & objDisk.Size
TotalSize = CCur(TotalSize) + CCur(objDisk.Size)
End if
Next
If(TotalSize <450000000000 or TotalSize >550000000000) then
Wscript.Echo "Disk size of " & TotalSize & " is out of range."
Wscript.Echo "Press enter to contine."
z = WScript.StdIn.Read(1)
End if
Wscript.Echo "Complete, Press enter to end."
z = WScript.StdIn.Read(1)
Sub CheckStartMode
' Returns the running executable as upper case from the last \ symbol
strStartExe = UCase( Mid( wscript.fullname, instrRev(wscript.fullname, "\") + 1 ) )
If Not strStartExe = "CSCRIPT.EXE" Then
' This wasn't launched with cscript.exe, so relaunch using cscript.exe explicitly!
' wscript.scriptfullname is the full path to the actual script
set oSh = CreateObject("wscript.shell")
oSh.Run "cscript.exe """ & wscript.scriptfullname & """"
wscript.quit
End If
End Sub

Resources