Learn about Windows PowerShell
Hey, Scripting Guy! How can I hide the command window when executing a command like net localgroup Administrators?-- AA
Hey, AA. You know, before we begin we’d like to take a few minutes to recognize all those faithful readers who read the Hey, Scripting Guy! column each and every day. Hey, June; how’s it going?
No, that’s pretty much it. Maybe we should have said we wanted to recognize our faithful reader.
Hmmm, that’s an interesting idea: if we actually answered the questions instead of rambling on and on maybe we would have more than just one faithful reader. What the heck; we’re willing to try anything:
Set objShell = CreateObject("Wscript.Shell")
strCommand = "net localgroup Administrators"
Set objExec = objShell.Exec(strCommand)
Do Until objExec.Status
To begin with, AA, we’re assuming that you’ve been using the Windows Script Host Run method in order to run net localgroup Administrators. And, yes, that will cause a command window to open up on screen. (Even worse, if you don’t include the proper parameters that window will open and then close before you ever have a chance to read the information that net localgroup Administrators returns.) What you want to do is run your command-line utility without a second command window opening up and then have the information returned from net localgroup Administrators displayed in the original command window. In other words, you’d like your entire session to look something like this:
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
Alias name Administrators
Comment Administrators have complete and unrestricted access to the computer/domain
FABRIKAM\InfoSec Secure Environment
The command completed successfully.
Can we do that? You bet we can, as long as we use the Exec method rather than the Run method. When you run a command-line tool from Exec the script will not open up a second command window. Instead, the script runs in an invisible window, and the data returned by the tool gets stored in the StdOut property. All we have to do is read in the value of StdOut and we’ll have complete access to the returned data.
Which is exactly what we do in our script. We start out by creating an instance of the Wscript.Shell object, then assign the name of our command-line command (net localgroup Administrators) to a variable named strCommand. After doing that tiny bit of setup we can run the command using this single line of code:
Set objExec = objShell.Exec(strCommand)
As you can see, we call the Exec method, passing it the variable strCommand. At the same time we create an object reference named objExec. That’s required because the Exec method actually creates an instance of an object: the WshScriptExec object.
No, that’s not a bad thing; that’s a good thing. Because Exec creates an object we can then work with the properties of that object, properties like StdOut and Status. And that’s the key to creating this script. For example, take a look at the next block of code in our script:
Do Until objExec.Status
What we’re doing here is waiting until the Status property of the WshScriptExec object is true. If Status is false (that is, equal to 0) that means that Exec is still running the command; in other words, net localgroup Administrators hasn’t finished doing whatever it is that net localgroup Administrators does. (We’re just kidding: it lists the members of the local Administrators group.) If Status is false we pause the script for 250 milliseconds (Wscript.Sleep 250), then loop around and check the value of the Status property again. This continues until Status is no longer equal to 0, which can mean only one thing: our command is finished.
As we noted earlier, when Exec runs a command-line utility that utility runs in a hidden window; in addition, any information returned by that utility is stored in Exec’s StdOut property. Logically enough, that means we can report back the results of running net localgroup Administrators simply by doing this:
So what are we doing here? We’re just using the ReadAll() method to read the value of StdOut, a value we then echo back to the screen. The net result? Although we don’t see any command windows or any other signs of activity, net localgroup Administrators runs in the background; when it’s done processing, the list of group members is displayed in the command window. Simple and elegant.
We hope that answers your question, AA. Oh: and see you tomorrow, June!
This is interesting, I'm a beginner and have no clue what you are talking about. Please explain this as to how i can hide my cmd window when I first logon. Such as where do I put the script so that it starts up and where do I place my .cmd file and so on...
I am interested in a variant of this script.
I am currently doing this, in a excel vba. Even with Exec, it opens a command window.
I can't seem to be hiding it.
Any clue is welcome
When I invoke a command using Exec(), I get a console window that appears for a split-second, then disappears.
Windows 7, WSH 5.8, JScript Version 5.8.16732 .
Has this behavior changed since this blog post was written? Is there a way to suppress the console window?
I just tried this on Win XP, SP3 and found that it did pop up a window.
There is no way to hide the window using Exec. You can with the Run method, but you have no access to StdIN/Out/Err.
When you use the Exec method there is a cmd window popped up until it completes executing all the commands.
I am running a batch file using exec method and the window is getting popped, how can i make this window invisible.
Set objExecObject = oShell.Exec("Script.bat")
This is just wrong. The converse is actually true. .Exec CANNOT hide the shell window, while .Run can. Can this be amended please?
@carl did you actually try the code to see that it really does work as stated. You are thinking about another kind of hiding. Exec does not produce a new window.
Actually create the script and run it. You will see what the article is talking about.
I've created this in an HTA (but using JScript), and no matter how I try, WScript.Shell.Exec will always show a command window (in Windows 7) for a fraction of a second, while I can easily hide it with WScript.Shell.Run. But, as others have stated, Run does not allow access to StdOut. The only somewhat viable solution is to have the script echo to a file and read that file, but you still won't know exactly when the file is actually "done". That is, you won't know if the process you triggered has concluded writing to the file. This is especially problematic for processes that take variable lengths of time to complete (like ping or tracert).
For those who find it still opens a window, remember you must launch the application with the 'cscript ' syntax. If you leave off the 'cscript' bit, it will open a window briefly.
Unfortunately, this almost renders the whole thing rather useless, as if you attempt to script this into some sort of single command, you then need to hide the batch file window that launches this, so you are back at step one. You'd think creating a shortcut
to 'cscript ' would solve the issue, but this also opens a window briefly (although you can minimize it, so it just flashes in the taskbar briefly). The best solution is creating ANOTHER .vbs file that launches the file using cscript, and using the .Run parameter
instead of .Exec (.Run can run hidden). For example, your 'RunHidden.vbs' should look a bit like this:
Set objShell = CreateObject("wscript.Shell")
objShell.Run "cscript.exe //NOLOGO c:\temp\test.vbs",0,true
This works for me, finally no window or even an icon in taskbar shows as it executes.