- FREE: File Permissions Check – Compare folder and file permissions - Fri, Feb 20 2015
- FREE: ABC-Deploy – Software deployment and inventory - Wed, Apr 16 2014
- FREE: AD Permissions Reporter – View Active Directory permissions - Fri, Feb 7 2014
This post was sponsored by Smart-X Software Solutions.
If you manage a Terminal Server Farm, a Citrix farm or any bunch of uniform machines, whether physical or virtual, you probably have a set of management scripts that help you get your work done with a minimum effort.
Often the need arises to perform some maintenance tasks on several remote machines, and you face a common sysadmin’s dilemma – do I just log into all these machines one by one (may be good enough if you only have a few machines to handle) or should I find some way to group these multiple remote tasks into one local task?
Method 1: Use Sysinternals' PSExec
The most common way to invoke commands remotely is by using PSExec. This is a classic command line tool by SysInternals, that can easily invoke a command on a remote computer/s and redirect the output to your local command shell.
You will need to download PSExec to your computer.
The next step would be to prepare a simple TXT file with the names of the computers on which you want to run the command, one name per line.
In this example, we will use a plain text file named 'CompList.txt' which looks like this:
Complist.txt
Tssrv01
Tssrv02
Tssrv03
Tssrv04
Tssrv05
Tssrv06
Tssrv07
Tssrv09
Tssrv10
In this scenario we’ll run the following short script, which cleans the Windows spooler directory and restarts the Print Spooler service, which helps overcome some common printing issues:
CleanSpool.bat
net stop spooler /y
del %windir%\system32\spool\PRINTERS\*.* /f /q
net start spooler
net start cpsvc
Now, assuming the commands above are saved to a batch file named 'CleanSpool.bat' which is located in C:\temp directory, enter the following command on your computer:
Psexec -c -f @c:\temp\complist.txt c:\temp\cleanspool.bat
This is a sample output of the command:
C:\Windows\system32>net stop spooler /y The Print Spooler service is stopping. The Print Spooler service was stopped successfully. C:\Windows\system32>del C:\Windows\system32\spool\PRINTERS\*.* /f /q C:\Windows\system32>net start spooler The Print Spooler service is starting. The Print Spooler service was started successfully. C:\Windows\system32>net start cpsvc C:\WINDOWS\system32>net stop spooler /y The following services are dependent on the Print Spooler service. Stopping the Print Spooler service will also stop these services. Citrix Print Manager Service The Citrix Print Manager Service service is stopping.. The Citrix Print Manager Service service was stopped successfully. The Print Spooler service is stopping. The Print Spooler service was stopped successfully. C:\WINDOWS\system32>del C:\WINDOWS\system32\spool\PRINTERS\*.* /f /q C:\WINDOWS\system32>net start spooler The Print Spooler service is starting. The Print Spooler service was started successfully. C:\WINDOWS\system32>net start cpsvc The Citrix Print Manager Service service is starting. The Citrix Print Manager Service service was started successfully.
As you can see, it's fairly easy to run the command, but analyzing the output can be a pain. While your script may run successfully on some computers, you might want to spot those machines on which the service could not be restarted, or on which the script could not terminate successfully for any other reason. Especially if the command you're running produces several output lines, it may take a while to spot these errors as the output is spilled continuously on your command prompt.
Another thing that might prove time consuming, is preparing the list of servers. Assuming your servers are named CTXSRV150 to CTXSRV274 (with several skips), you would have to create a script that creates the list, rather than manually copying and pasting it over and over. On the other hand, if your computer names follow a continuous numeric pattern, you might prefer to leverage the good old FOR command like this:
For /l %i in (150,1,274) do psexec \\CTXSRV%i c:\temp\cleanspool.bat
This way, your command will be executed one-by-one on all servers within the above numeric range. (Tip: if you want to use the FOR statement within a batch file, use %% instead of %).
Method 2: Use WMI to run remote commands
As you probably know, Microsoft has integrated WMI (Windows Management Infrastructure) on all of its operating systems. In few words, WMI is a framework that allows you to retrieve management data and invoke functions, while abstracting the API level.
Creating a script which uses WMI is a bit more difficult, but once your script is ready, you can re-use it over and over with minor changes. The major advantage in using a WMI script is that your flexibility is almost infinite. You can analyze the output within the script, notify upon failures and even run corrective actions.
The disadvantages, however, is that you have to work hard for each change, test it thoroughly and only then run it on your production environment.
Here is a little script I made for generic execution of remote commands:
option explicit on error resume next dim sOriginalCompPrefix 'The prefix of the computers' names dim sCompPrefix 'The calulated computers' names prefix dim iStart 'Start from number dim iEnd 'End at dim i 'Used as enumerator dim objWMIService 'Used to contain the WMI object dim oError ' Used to contain the WMI return object dim sCommandLine 'Used to hold the process name that should be invoked dim iProcessID 'Used to contain the PID of the executable that was invoked on the remote computer dim sComputersToSkip iStart = 1 iEnd = 8 sOriginalCompPrefix = "DevTS" sComputersToSkip = "TSSRV011;TSSRV012;TSSRV087;TSSRV130" if wscript.arguments.count = 0 then wscript.echo "Please specify the name of the process you wish to run as a command line argument" wscript.quit end if for i = 0 to wscript.arguments.count -1 sCommandLine = scommandLine & wscript.arguments(i) & " " next scommandline = left(scommandline,len(scommandline)-1) wscript.echo "Executing '" & sCommandLine & "' on remote computers..." & vbcrlf for i = iStart to iEnd if i<10 then sCompPrefix = sOriginalCompPrefix & "00" 'Adds two leading zeros to the prefix elseif i<100 then sCompPrefix = sOriginalCompPrefix & "0" 'Adds a leading zero to the prefix else sCompPrefix = sOriginalCompPrefix end if if instr(1,sComputersToSkip,sCompPrefix & i,1) =0 then wscript.echo "Running '" & sCommandLine & "' on " & sCompPrefix & i & "..." err.clear Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sCompPrefix & i & "\root\cimv2:Win32_Process") if err.number <> 0 then Wscript.Echo "'" & sCommandLine & " failed to start on " & sCompPrefix & i & " with the following error:" & vbcrlf & err.description & vbcrlf else oError = objWMIService.Create(sCommandLine, null, null, iProcessID) If oError = 0 Then Wscript.Echo "'" & sCommandLine & " succesfully executed on " & sCompPrefix & i & " with PID " & iProcessID & vbcrlf Else Wscript.Echo "'" & sCommandLine & " failed to start on " & sCompPrefix & i & " with the following error:" & crlf & oError End If end if end if Next
The money time of this script is in the following line:
oError = objWMIService.Create(sCommandLine, null, null, iProcessID)
It tells the remote WMI namespace (initialized using the Set objWMIService statement) to execute the process.
I saved the best (and my favorite) for last:
Method 3: Use ControlUp to run remote commands
If writing a script is not for you, or if you're simply short of time and you want to get things done as quickly as possible, you should really give ControlUp (by Smart-X) a try. Not only that you don't have to write even a line of code, ControlUp analyzes the output for you and shows you exactly which servers need further attention.
After you download the product, the first step would be to select the remote computers on which you want to run the command. You can select the computers from a text file, from an IP subnet, or by selecting them from any Active Directory domain to which you have access, even those with no trusts with your own domain:
ControlUp – Select computers
Similar to PSExec, ControlUp launches a small service on each of the computers. This service will be automatically removed once you close the application.
After you added the computers, simply select them from the main grid, and select 'Run As' from the context menu.
Use ControlUp to run remote commands
On the 'Run As' screen, you can specify alternative credentials (If not specifying any credentials, the command will run under the system account of the remote computer)
Run As with ControlUp
Once you click OK, the requested program or script will be executed on all of the target machines you selected, in a way similar to PSExec, except for the fact that your commands will run in parallel, without keeping you waiting for each target to be completed before proceeding to the next one. You will also see a progress window, showing you a summary of the command’s success and failure outcomes on all your target machines:
ControlUp – Progress window
As you can see, some computers have encountered errors during the attempt to invoke the command. You can now fix the problem and use the 'Run Again' button to retry.
Another nice thing about ControlUp is that it's shipped with a set of tools that spare the need to write batch files, such as manipulating Windows Services, Registry, policy and Terminal Services sessions, but that’s a different story.
Conclusion
I made a small comparison chart that summarizes the differences between these three methods, which will hopefully help you select the most suitable solution for your purposes:
Three ways to run remote Windows commands
[1] Requires WMI + RPC connectivity for agent distribution. Once the agent is distributed, no RPC/WMI connectivity is required
[2] Up to 50 servers concurrently
Read the latest IT news and community updates!
Join our IT community and read articles without ads!
Do you want to write for 4sysops? We are looking for new authors.
My first thought for remoting was PowerShell …
PoweShell should be the first choice. All other options fade in comparison. I assume this is a “paid post” for ControlUp.
There are still many machines out there without PowerShell. Which method you use depends very much on your environment and your taste. I personally would always go for a GUI solution. And yes, this post was sponsored by Smart-X. It says so in the first line. 🙂
Be careful with PsExec. PsExec sends commands and credentials over the network in plain text. It will even work with password hashes.
PowerShell should absolutely be on this list. I realize it isn’t everywhere (yet) but it has to be offered as a solution here. It is a much better alternative to the WMI approach. I’m a big believer in the right tool for the job and certainly there will be situations where ControlUp makes sense. But any article that discusses remote management has to include PowerShell.
I would seriously consider WMIC as an option with powershell.
So to uninstall a application remotley it would be:
wmic /node:computertarget product where name=”Google Earth” call uninstall.
batch file example:
@echo off
cls
echo ——————————————————–
set /p target=Whats the name of the Target Machine:
echo Dumping list of install software from %target%
wmic /node:”%target%” product GET name | sort
echo ———————————————————————–
set /p software=Ok which software would you like to uninstall:
echo Ok, attemtpting to uninstall %software% from %target%
echo Please note if you get a —ReturnValue = 0;— string it has worked.
wmic /node:”%target%” product WHERE (name like “%software%”) call uninstall /nointeractive
echo ———————————————
echo Doing search patter to determine uninstallation success!
wmic /node:”%target%” product GET name | find /i “%software%”
echo Done…………………
pause
This is great article… this below link also contribute on the same topic
http://aikitsupport.com/how-to-run-commands-remotely-on-windows-server/
But all of these have requirement, either on the client (your computer) or on the server, on so you have to prepare in advance, which you probably haven’t since you ended up in this situation.
My favorite tool for this is scheduling the execution with AT.
AT is on EVERY windows computer and can schedule program execution on remote hosts like this:
AT \\remote-host 10:50 my-silent-installer.exe
Ofcourse you will have to wait for the execution for up to a whole minute, and you won’t get any output unless you pipe stdout to some file or something. But to me that is easy out weighted by the fact that I don’t have to install anything.
oError = objWMIService.Create(sCommandLine, null, null, iProcessID)
I’m getting error “Permission denied : GetObject” in above line.
http://stackoverflow.com/questions/21435173/vbscript-permission-denied-getobject
Please refer this post and help me out.
This is a tiring and frustrating topic. PSExec is great for arbitrary commands or running batch files that can be copied and run directly to a list of machines as indicated. But when the file that needs to be copied is a Powershell script, and .ps1 files are not associated on the remote machines with Powershell, trying to get PSExec to start a shell on a remote machine and then run powershell while feeding it the file name is an exercise in futility. Files not found, miscellaneous errors with identity and authentication, and syntax where escaping names for commands and files is concerned.
Powershell remoting isn’t any better. Turning it on remotely is one thing. But then getting credentials to it is something else altogether. Nothing but problems with it.
And in both instances, trying to get a Powershell script to actually output back to the client screen for things like checking for and installing updates on multiple machines is infuriating. Best I can ever do is run Start-Transcript and then pipe that to a file I can read after the fact. Trying to get that info to a client during runtime? Not so much. Don’t know what’s going wrong but I am growing really tired of the whole idea.
I recommend reading our series about PowerShell remoting (go to the end of the post in the previous link for a list of all posts in the series). Various ways exist to return output from the remote sessions.
@Keith
Did you try Powershell ISE?
I use it to run different commands or script on multiple servers at the same time.
Just use CTRL + SHIFT + R to open a powershell tab for every remote computer.
We’re in a somewhat restricted environment, so WMI is allowed but WinRM isn’t running on the remote machines. We have to make use of WMI but do it through PowerShell commandlets. It works well without the need to install any 3rd part tools (which can only be done after a long and laborious vetting and approval process).
My first thoughts was WinRM (in a workgroup environment):
Hi, I want to use psexec which you have mentioned on the toic “remote command lines”. as you have said, I must enter “Psexec -c -f @c:\temp\complist.txt c:\temp\cleanspool.bat” command at the end. I receive the below message:
“the specified application is not on the path”. why does it haen?
maybe it is better to say my problem. I have an automation script file that I want to run it on 10 user accounts through the main user account. in fact I have one windows with 11 users. all of them have administrative options. imagine I am in the user1 account environment now I want to run all the scripts on all the other 10 users from here (from user1 account). does this psexec solve my problem? thank you for your help.
Read this: How to use PsExec on multiple remote computers.