[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now


powershell run batch file on multiple computers

Posted on 2013-01-03
Medium Priority
Last Modified: 2013-01-16
In enterprise, many still use batch files instead of PS so I have to find a way to continue to use batch files for now.
We currently use PSEXEC but it is being shelved for security reasons.

Issue:  I need to run a batch file on 15 servers.  The batch file is local.
I would like to use powershell.
Is this possible?
The only way I can figure out how to do this is  using Invoke-Command
1. copy the .bat file to a tmp folder on the target server
2.  run the bat file
3. remove it.

Is there a way to run a local batch file on a remote server using powershell?

Question by:greetrufus
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
  • +1
LVL 12

Expert Comment

by:Gary Dewrell
ID: 38740108
We place all of our batchiles/PS scripts on a network share that all servers by default have a mapped drive to. That way it appears as they on the local server.
LVL 12

Expert Comment

by:Gary Dewrell
ID: 38740116
I have not tried it but maybe you could do something like:

Use invoke command to map a drive from the remote server to your local server/pc.
Then invoke that batch file from the mapped drive.
LVL 29

Expert Comment

ID: 38740132
You can do two things I know of:

1. Use net use and specify the username and password as a part of your invoke-command script

2. Pass in the path as a variable in your argument list and map it then call from that drive.
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

LVL 71

Expert Comment

ID: 38740587
One way is to paste the content of the batch file, and redirect it to invoke-command:
get-content c:\Batch.cmd | invoke-command -computer $PC -script { cmd.exe /D /Q } | out-null

Open in new window


Author Comment

ID: 38741642
Qlemo, I think I have the idea your going at.
Let me tell you my test setup.

c:\scripts\Test.bat for testing which contains:
         @echo TEST IPCONFIG

get-content C:\Scripts\test.bat | invoke-command -computer SERVER01 -script { cmd.exe /D /Q } | out-null

Open in new window

So i should get back ipconfig info as a result, correct?

Script runs with no errors but nothing returns.
LVL 29

Expert Comment

ID: 38741651
Is there any logic built into your batch file besides the ipconfig command  ?

Author Comment

ID: 38741740
Yes.  I was using the above for testing.
I am building a scripting app that can run PS and batch on multiple remote servers.
So I am sure there will be some advanced cmd scipting at some point.

At this point, it is more proof of concept on the best way to use PS to do this.
We have been using PSEEXEC but am being forced to remove it.

Author Comment

ID: 38741951
So I got this to work based off Qlemo's approach and it works for simple batch.
I have not tested any advanced files yet.
The key was using the /c && to seperate the commands sent to cmd.exe
Here is what worked:

#Read the content of the batch file.  && is the command line separator for strings in cmd.exe
$Getbatch = (get-content C:\Scripts\test.bat) -join "&&" 

#Pass the content to Invoke-command
Invoke-Command -computername SERVER01 {PARAM($myArg) cmd.exe /c "$myArg"} -ArgumentList "$Getbatch"

Open in new window

Hope that helps someone else.  If i have different findings for more advanced batches, i'll post an update.

Thanks everyone!!!

Author Comment

ID: 38746393
I've requested that this question be closed as follows:

Accepted answer: 0 points for greetrufus's comment #a38741951
Assisted answer: 500 points for Qlemo's comment #a38740587

for the following reason:

Qlemo's logic led to my conclusion.  Great job!!!!!
LVL 71

Expert Comment

ID: 38742149
I've redirected the output of the "batch" to the NULL device with    | out-null  , as I thought you were not interested in any output.

&& is not the command separator. It is the "if success then execute" operator, that is the prior command has to execute without any "error". It is convenient to use in combination with "conditional" commands like
  echo 1| find "2" >nul && echo Yes || echo No
   echo 2| find "2" >nul && echo Yes || echo No

You should not have to use any special command separator (and then not use /C), or provide the single ampersand   &   as separator.

Author Comment

ID: 38744817
After some research I see what you are saying.
using /C and && would alow me to execute multiple cmd commands but will not handle batch scripting.
I went back to your original post and instead of a commands in the batch file, i substituted a For Each statement:
     for /L %%I in (1,1,3) do echo loop %%I
I also removed the Out-Null to see what the return was.
When i run the PS script, the return is the string?

How is the piped content getting feed to the -scriptbock?

Moderator, can this question be reopened? or should I start another?
Sorry for the hassle!!!
LVL 71

Expert Comment

ID: 38746394
To stop the process of closing this question, just post a comment and press Object instead of Submit. I have done that now, so the question stays open.
LVL 71

Accepted Solution

Qlemo earned 2000 total points
ID: 38746703
I'm not clear about what you tried. Executing
"for /L %I in (1,1,3) do echo loop %I" | invoke-command -script { cmd.exe /D /Q }

Open in new window

will output the values 1 to 3 as expected. Remember that with this method we won't execute a batch, but more perform interactive commands outside of any batch. Hence FOR vars may have only one preceeding percent sign.

It is not the best of all methods, as certain restrictions apply, and the output contains the cmd banner and prompt strings. Running the script locally or from a network share is still the better way (usually). But if we want to do something similar to what you started with:
$bat = @"
@echo off
for /L %%I in (1,1,3) do echo loop %%I

invoke-command -script {
   $f = "$env:temp\a.cmd"
   out-file -encoding ASCII -InputObject $bat $f
   cmd /D /Q /C $f
   remove-item $f

Open in new window

This creates the .cmd file locally, executes and then removes it.

Featured Post

Q2 2017 - Latest Malware & Internet Attacks

WatchGuard’s Threat Lab is a group of dedicated threat researchers committed to helping you stay ahead of the bad guys by providing in-depth analysis of the top security threats to your network.  Check out our latest Quarterly Internet Security Report!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows 10 came with  a lot of built in applications, Some organisations leave them there, some will control them using GPO's. This Article is useful for those who do not want to have any applications in their image (example:me).
There are times when we need to generate a report on the inbox rules, where users have set up forwarding externally in their mailbox. In this article, I will be sharing a script I wrote to generate the report in CSV format.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question