understanding the For Each Loop - loops

I'm new to scripting and programming.
In the following and similar scripts, I noticed that there exists a 'objOperatingSystem'
that is referred to in the 'For Each' loop.
I understand that 'colSettings' is a variable that contains the WMI collection, but where does the 'objOperatingSystem' come from ?
Pls help. Thanks!!!
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colSettings
Wscript.Echo "Available Physical Memory: " & _
objOperatingSystem.FreePhysicalMemory
Next

objOperatingSystem is a variable. For Each declared it. Basically, for every item in colSettings a variable named objOperatingSystem will be set to the current item, and the body of the for loop executed.

It's vb script. And it's looking into the operating system object thru WMI to see available memory. it's part on the winmgmts (windows management) object. Use a neat tool called WMI creator and surf all the cool wmi's on your computer. It's is just a variable created to hold the object it's looking for in WMI and then iterates thru it "for each" time.

Related

How do I make this vbs script accept parameters when launching a file in the background?

I have the following in a VBS file called "Launch.vbs":
CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False
I can call this from a batch file like this:
wscript.exe "Launch.vbs" "ProgramIWantToStartInBackground.exe"
However, this does not allow me to pass parameters to it, for example:
wscript.exe "Launch.vbs" "ProgramIWantToStartInBackground.exe" "Parameter"
wscript.exe "Launch.vbs" "ProgramIWantToStartInBackground.exe" Parameter
In both of the above examples, the program does launch in the background, but does not receive any parameters given.
How can I modify the vbscript code to allow a parameter?
There are lots of ways of tackling this problem, but it boils down to understanding how programs run from the command prompt.
This line in launch.vbs is going to wrap any command passed in double-quotes which is fine for just the executable but causes issues when parameters are passed, as only the executable path should be wrapped in double-quotes to avoid issues with any spaces that might be in the path.
CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False
Instead, you have two options.
Pass two arguments into launch.vbs and only wrap the first one in double quotes.
CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """ " &
WScript.Arguments(1), 0, False
Exeute using;
wscript.exe "Launch.vbs" "ProgramIWantToStartInBackground.exe" Parameter
Executes as;
"ProgramIWantToStartInBackground" Parameter
Remove the wrapping and apply to the argument passed in.
CreateObject("Wscript.Shell").Run WScript.Arguments(0), 0, False
Execute using;
wscript.exe "Launch.vbs" ""ProgramIWantToStartInBackground.exe" Parameter"
Executes as;
"ProgramIWantToStartInBackground" Parameter
Here is another version that processes all the possible arguments.
Dim strRun
strRun = ""
For Each strArg in WScript.Arguments
strRun = strRun & """" & strArg & """ "
Next
CreateObject("Wscript.Shell").Run strRun, 0, False
Excute it as wscript.exe Launch.vbs ProgramIWantToStartInBackground.exe Parameter1 Parameter 2 ... ParameterN.
If there is space in the parameters or path, wrap that with "" as usual.

Copy New Access client to users

I use a very simple version control whereby I use the "tag" property on the Switchboard to record the version of the database.
On a linked "mastertable" I have a master record that shows the current version. If this is out of sync, then there is code in the switchboard to initiate a simple file copy of the new client version to the user's desktop.
I can't use any EXE type auto-installers to do this, so had to come up with an all Access solution, but having some issues with shell commands and timing that is causing the "auto" part of the installer to be inconsistent.
Below are my codes for the Client and my standalone "Installer" database (which only has one form that opens on startup and initiates the copy code). I use lookup tables for all file locations, but will use strings in my example.
Client.mdb:
strInstaller = "c:\Installer\Installer.mdb"
set obj = CreateObject("access.application") 'previously tried SHELL command
with obj
.visible = true
.userControl = true
.openCurrentDatabase (strInstaller)
end with
application.quit
Simple enough. So the above code just opens my Installer mdb which opens a form and executes the following on open.
Installer.mdb:
strFileName = "ClientDB"
strMaster = "D:\" & strFileName
strClient= dlookup("DBPath", "UserTbl", "LanID = '" & MyID & "'") & "\" & strFileName
if len(dir(strClient)) <> 0 then
kill strClient
end if
filecopy strMaster, strClient
The dlookup in the strClient simply looks up the path where the user opened up the instance of the client mdb. (I record this on every instance).
My issues is that I am not getting consistent results. Sometimes it will copy the file, and sometimes it won't. I've changed it to run from a button on the Installer Form, and it works every time, so I'm guessing it has something to do with timing.
I've tried putting a pause function before the kill command, and that seems to help if I set the pause to 3 or 4 seconds. I originally used Shell to open the Installer, but got rid of it as I heard that it was running concurrently with the installer.mdb code.
I'm thinking it's something obvious, but I've been staring at this for about an hour and can't figure it out. Ideally, I don't want the user to interact with this form using an "Install" button, but would like it to happen in the background. i.e. I want to set the .visible = false at some point.
Can anyone see an issue with this method, or suggest a better method to push out new copies of the client - and I can't use any EXE install programs.
You likely want to use the shell() command. You can use CreateObject, but that feature is NOT available in the runtime. (and worse, it will not work).
The simple trick is ONCE you shell out to the upgrade program, you want to QUIT the main program (since you can’t copy over it while it is running).
The code I use is thus:
strCurrentDir = CurrentProject.Path & "\"
' path to msaccess.exe is determined here
strShellProg = q & SysCmd(acSysCmdAccessDir) & "msaccess.exe" & q & " "
' path to current dir...assume upgrade program in same folder
strShellProg = strShellProg & q & strCurrentDir & "UpGrade.accDE" & q
If Shell(strShellProg, vbNormalFocus) > 0 Then
Application.Quit
Else
MsgBox "Un able to run upgrade", vbCritical, AppName
Application.Quit
End If
In above “q” is = """" (a single double quote).
So you shell out, and then immediate do a application.Quit. The upgrade program should have a “prompt” like “about to upgrade – ok”. That “prompt the user has to hit gives the main application time to quit. I also useally write out the locations to a text file in the above code - but the above steps to shell() is the main takeaway solution here.
As noted, you can use create object, but THEN if you quit the main application, then that variable holding the upgrade program will also go out of scope (or worse, the main application cannot shut down because it is “hosting” an automated copy of the upgrade application by CreateObject.
So you in practical terms don’t want to use createObject, since this means the main program is “hosting” or “holding” a copy of the upgrade program and the main program really can’t quit.

Run batch silently by hotkey (permissions issue?)

I am trying to control Spotify volume from inside a game without switching windows. To do this I did the following:
A. Found nircmd.exe from NirSoft that can control individual program volumes in Windows
B. Wrote a batch to execute the command
C. Wrote this .vbs script to hook into the batch silently:
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run chr(34) & "Spotify App Volume Up.bat" & Chr(34), 0
Set WshShell = Nothing
^
Using this .vbs snippet to accomplish silent run is really popular. This works when I click the .vbs myself. The problem I have is I need a way to execute this from another program. When I try to execute from any hotkey program or something like AutoHotKey it gives me this error:
ActiveX Component cannot create object 'WScript.Shell' Code: 800a01ad
I tried setting security of all involved files to everyone, full control. It did not help. It seems to me that Windows is trying to protect me by preventing scripts from initializing by other programs. Any suggestions? Otherwise does someone know how to execute this silently with another method?
EDIT:
AutoHotKey's run command will do this:
run "mybat.bat",, Hide
However, does anyone know how to get around this behavior with .vbs? I am curious.
I believe all your scripts, vbscript and your batch file can potentially be written natively in Ahk, but here's how I'd launch your vb script.
x:: ; press x
sc := ComObjCreate("ScriptControl")
sc.Language := "VBScript"
script =
(
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run chr(34) & "Spotify App Volume Up.bat" & Chr(34), 0
Set WshShell = Nothing
)
sc.ExecuteStatement(script)
return

Modifying a .reg file with returned variables from a VBScript

I am trying to: 1 Discover the user that is logged into the machine, add it to variable 1.
Then find out the SID in HKEY_USERS for this said user, add it to variable 2.
Once i have the SID, pipe it into a .reg file replacing the values that i have in it.
Code 1 finds the user. the result then goes into the code 2 replacing "Myusername" This finds the SID.
I then need to send this to a .reg file i made to replace certain registry paths.
Am i on the right track? Or way off? can anyone make these 2 peices of code work together?
Thanks guys. Any help is appreciated.
So far i have:
Code 1:
Set objNetwork = CreateObject("Wscript.Network")
Wscript.Echo "The current user is " & objNetwork.UserName
and
Code 2:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get _
("Win32_UserAccount.Name='Myusername',Domain='gnb'")
Wscript.Echo objAccount.SID

How to run a program on a specific remote computer

I have got this working line of code
I would like to run via VBScript a share program on a remote computer in a domain environment. The first part is ok where it is asking me to enter a computer name, but the problem is in the second part. I don't know how to run the program on the remote computer that I've entered in the first part.
computer = inputbox ("What computer do you wish to check? (Press Enter if this computer)","Computer")
set WMI = GetObject("WinMgmts://" & computer)
If computer="" then computer = "this computer"
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Run("""\\compname\Share\progr.exe""")
Set objShell = nothing
After running this script, it runs the program on my computer, not on the remote computer. I want to run the program on a specific computer that I have entered from keyboard.
From vbscript, the better way is using wmi. Please refer to this to get a complete information on how to get a connection to a remote computer via wmi and the problems you will face to do it.
Follow the information in microsoft page, and you will end with a objWMIService variable pointing to the WMI services of the remote machine. Then,
Set objProcess = objWMIService.Get("Win32_Process")
Dim strProcess
strProcess = "notepad.exe"
Dim lngReturn, intPID
lngReturn = objProcess.Create(strProcess, null, null, intPID)
If lngReturn = 0 Then
Wscript.Echo strProcess + " started. PID: " & intPID
Else
Wscript.Echo "Error: " & lngReturn
End If
use objWMIService (remember, its the remote machine) to get a reference to the processes collection (of the remote machine), and create a new process.

Resources