Solved

write a PS script to run exe remotely.

Posted on 2014-04-17
40
1,451 Views
Last Modified: 2014-05-03
I need to write a PS script to run an installation executable/msi again 20 remote domain servers.  

Can someone advise?

Thanks.
0
Comment
Question by:nav2567
  • 14
  • 13
  • 8
  • +1
40 Comments
 

Author Comment

by:nav2567
ID: 40007776
I am checking this link http://gallery.technet.microsoft.com/scriptcenter/56962f03-0243-4c83-8cdd-88c37898ccc4

Do I just copy the whole function and save it to a .PS1 and run it?
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 40007804
You could copy the aforementioned function and run it for each serve. Since the function accepts the computer names in the pipeline you could do this:

"comp1", "comp2", "comp3" |  Run-RemoteCMD
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 40007810
You'll need to put the msi on a shared resource that will be assessable to all the computers. The first time you call the function it will prompt you for the command. You'd type in the fully qualified name of the msi file.
0
 

Author Comment

by:nav2567
ID: 40007821
Steve,

Can you explain again?  I save this function to a remote.ps1 file.  I have another servers.txt file with a list of server.  

How do I use them together?  I tried to just run the remote.ps1 but nothing happens.
0
 
LVL 28

Expert Comment

by:becraig
ID: 40007825
why not use psexec which would work easier :

 Use your list of servers:

for /f %A in (serverlist.txt) do copy <msifile.msi> \\%A\c$\Temp  & psexec \\%A c:\temp\msifile.msi 

Open in new window


You can add flags as needed.,
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 40007834
Here's how you could do it in a ps1 file name Install.ps1 using a file name server.txt that resides in the current directory. You could fully qualify the file name if you'd like:

# ============================================================================================== 
#   
# Script Name : Run Remote cmd.exe Commands 
#  
# AUTHOR: Mohamed Garrana  
# DATE  : 4/12/2010 
#  
# COMMENT:  
# this script invokes whatever command you can use in cmd.exe on one or more computers 
#you input the command name as a screen input when you run the script 
#you can use all cmd.exe command like [del,ipconfig /flushdns,ipconfig /registerdns,gpupdate /force ,notepad.exe,defrag c:, ... 
#..wuauclt /detectnow,powercfg,net start ,net stop,copy,arp,wscript.exe ....] 
#if you can do it from cmd.exe you can do it here on multiple computers at the same time 
# ============================================================================================== 
 
 
function Run-RemoteCMD { 
 
    param( 
    [Parameter(Mandatory=$true,valuefrompipeline=$true)] 
    [string]$compname) 
    begin { 
        $command = Read-Host " Enter command to run" 
        [string]$cmd = "CMD.EXE /C " +$command 
                        } 
    process { 
        $newproc = Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ($cmd) -ComputerName $compname 
        if ($newproc.ReturnValue -eq 0 ) 
                { Write-Output " Command $($command) invoked Sucessfully on $($compname)" } 
                # if command is sucessfully invoked it doesn't mean that it did what its supposed to do 
                #it means that the command only sucessfully ran on the cmd.exe of the server 
                #syntax errors can occur due to user input  
     
     
     
     
    } 
    End{Write-Output "Script ...END"} 
                 } 
     
 
#---------------- 
#you can use this script to run any command that can be run on CMD.EXE 
#the following is only to give you an idea how can you use it 
#----------------- 
#for copying files from many remote computers to a single 
# get-content c:\servers.txt | Run-Remotecommand 
#Enter command to run: copy c:\log\log.txt d:\ 
#you only input "copy c:\log\log.txt d:\" 
#--------------------------------------- 
#for forcing group policy update on multiple computers 
# get-content c:\servers.txt | Run-Remotecommand 
#Enter command to run: gpupdate /force 
#-------------------------------------- 
#for stopping the Bits service on multiple computers 
# get-content c:\servers.txt | Run-Remotecommand 
#Enter command to run: Net stop bits 
#--------- 
#you can always run it against a single server using  
#Run-RemoteCommand server1 
#Enter command to run: enter whatever you'd normally enter in cmd.exe shell 

# Here's the code you'd write to perform the installations:
Get-Content "servers.txt" | Run-RemoteCMD 

Open in new window

0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40008685
steveGTR

invoke command require Ps remoting enabled...........by default only 2012 server is enabled

if PS remoting is already turned on.

it will work this way.

example:
$Servers = get-content c:\servers.txt 
foreach ($Server in $Servers)
{
Invoke-command -computerName $Server {your script or any installation msi that the computer can get}
}

Open in new window

0
 

Author Comment

by:nav2567
ID: 40009356
Justin, you script does not work.

Steve, your script works but it does not work if I put more than one servers in servers.txt
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009362
I know you wanna try using a powershell solution but for my money I usually find psexec works much better in this instance:

for /f %A in (serverlist.txt) do copy <msifile.msi> \\%A\c$\Temp  & psexec \\%A  cmd /c c:\temp\msifile.msi  <msi flags>

Open in new window

0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40009368
what is the error of my script?

and do you have PS remoting turned on?
0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40009371
becraig - I believe the Author is asking for POWERSHELL
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009382
ahh in that case :


gc serverlist.txt | % {
copy c:\temp\msifile.msi \\$_\c$\temp
invoke-command -computername $_ -scriptblock { cmd /c c:\temp\msifile.msi}
}

Open in new window

0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 40009397
What is displayed when you do the following:

Get-Content "servers.txt"

Of course the "servers.txt" will be the fully qualified path to the servers.

When you say it doesn't work if you put in more than one server. What does that mean exactly? Does it generate an error? You do realized that it will only prompt you once for the command.

What is the output?
0
 

Author Comment

by:nav2567
ID: 40009406
thanks.

what is the reason of adding copy c:\temp\msifile.msi \\$_\c$\temp in the script?

Can I just use this?

gc c:\serverlist.txt | % {
invoke-command -computername $_ -scriptblock { cmd /c msiexec /I c:\temp\msifile.msi /qn
}

this is a quiet installation.
0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40009417
you can do just run the msi in a shared location within the script block

{ \\server\shared\msi.msi /qn}

{c:\windows\system32\msiexec.exe /i \\server\shared\msi.msi /qn}
0
 

Author Comment

by:nav2567
ID: 40009429
So,  is the below the final script?

gc c:\serverlist.txt | % {
invoke-command -computername $_ -scriptblock { cmd /c c:\windows\system32\msiexec.exe /i \\server\shared\msi.msi /qn
}
0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40009434
$Servers = Get-Content "c:\serverlist.txt" 
foreach ($Server in $Servers)
{
Invoke-Command -ComputerName $Server {c:\windows\system32\msiexec.exe /i "\\server\shared\msi.msi" /qn}
}

Open in new window


i don't know why you need cmd it............. powershell takes docs command as well.

invoke command means to run the {the script} on the remote machine....

you basically the same as running that command in the machine powershell console
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009440
I only added the copy command in the event the msi might have some restrictions against install from a remote path (I have seen that a lot).

Otherwise what you have and what Justin have (which are pretty much the same)
should work with no issue.
0
 
LVL 30

Expert Comment

by:SteveGTR
ID: 40009450
Since I have received no response to my questions, I'll be leaving the thread. Good luck :)
0
 

Author Comment

by:nav2567
ID: 40009476
failed with the following message:

[servera] Connecting to remote server failed with the following error message : The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If
the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig". For more information, see the about_Remote_Troubleshooting Help topic.
    + CategoryInfo          : OpenError: (:) [], PSRemotingTransportException
    + FullyQualifiedErrorId : PSSessionStateBroken
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40009480
PS remoting is not turned on on your servers.
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009486
This was why I was suggesting a psexec solution, in the even psremoting was not enabled on the computers you wanted to run this on.


You will need to enable winrm on the client computers, how many computers are we looking at  ?

Do you have control over setting group policy ?
0
 

Author Comment

by:nav2567
ID: 40009491
how do I turn that on?
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009501
you can run enable-psremoting -force on the computer you need to enable it on, but there are a lot of considerations.

That is why I asked the two questions:
How many computers
Can you define GPO
0
 

Author Comment

by:nav2567
ID: 40009984
I have a lot of computers.  

I do not have any luck in getting it to work on PS even enable-psremoting -force  is run on the target server.

I am looking at the PSExec command.  I have tried the following but it is not working.   Becraig, can you help again?

psexec \\server1 -i msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart
0
 
LVL 28

Expert Comment

by:becraig
ID: 40009989
psexec -u domain\user -p password \\server1 cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart


The above should work
0
 

Author Comment

by:nav2567
ID: 40010546
I am getting this message.  Do you know how to fix it?

T h e   s y s t e m   a d m i n i s t r a t o r   h a s   s e t   p o l i c i e
s   t o   p r e v e n t   t h i s   i n s t a l l a t i o n .
 cmd exited on server1 with error code 1625.
0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40010551
The installation requires elevated mode
0
 
LVL 14

Expert Comment

by:Justin Yeung
ID: 40010552
Or do you have any gpo prevent installation
0
 
LVL 28

Expert Comment

by:becraig
ID: 40011867
The MSI you want to install is not natively allowed:

My suspicion is:
 User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode      
ConsentPromptBehaviorAdmin      
Prompt for consent for non-Windows binaries


If UAC is enabled on the machines you are trying to install on, then this would be your issue you can probably work around it via Group Policy

See the link below for more details:
http://technet.microsoft.com/en-us/library/dd835564%28v=ws.10%29.aspx
0
 

Author Comment

by:nav2567
ID: 40011879
I do not have any GPO that prevents the installation.  

I have disabled UAC on the target server but I am still getting the 1625 error.  

I will do some research myself.  If you have other idea to try, please advise.

Thanks, everyone!
0
 
LVL 28

Expert Comment

by:becraig
ID: 40011881
Did you disable that "Specific value" ?

Check:
 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

EnableInstallerDetection


set to
0 = Disabled (default for enterprise)

Reboot before retrying the msi install.
0
 

Author Comment

by:nav2567
ID: 40011901
Nevermind.  I have finally got it to work.

One last question, I need to create a script to read a server.txt file that contains list of servers and run the install, and start the service.  I tried the following but it does not work.  Can someone please correct it?

for /f %%i in (servers.txt) do
{
psexec -u domain\user -p password \\%%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart
sc \\%%i start wintech
}
0
 
LVL 28

Expert Comment

by:becraig
ID: 40011902
What is the specific problem you are having when you run it  ?
0
 
LVL 28

Expert Comment

by:becraig
ID: 40011907
If you save as .bat or .cmd file:
for /f %%i in (servers.txt) do psexec -u domain\user -p password \\%%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart & sc \\%%i start wintech


If running directly from the command line:
for /f %i in (servers.txt) do psexec -u domain\user -p password \\%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart & sc \\%i start wintech

No curly braces :)
0
 

Author Comment

by:nav2567
ID: 40025741
So far, the following works - Thanks becraig.

for /f %%i in (servers.txt) do psexec -u domain\user -p password \\%%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart & sc \\%%i start wintech

for /f %%i in (servers.txt) do sc \\%%i start wtech_agent

There are some server which shows errors during installation.  Can you help me make the bat better so it display which server(s) has issue?

Thanks again.
0
 
LVL 28

Expert Comment

by:becraig
ID: 40025987
Something like this should work, my batch is really rusty PS wiped all that knowledge away :)

for /f %%i in (servers.txt) do (
psexec -u domain\user -p password \\%%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart 
IF '%ERRORLEVEL%'=='0' (
  echo installed on %%1 
) else (
  echo %%i failed !!
)
sc \\%%i start wintech
)

Open in new window

0
 

Author Comment

by:nav2567
ID: 40038766
Thanks, becraig.

Can you make you the code to display only the following:

server1 install/server1 failed
0
 
LVL 28

Accepted Solution

by:
becraig earned 500 total points
ID: 40038794
@echo off
for /f %%i in (serverlist.txt) do (
psexec -u cme\v-craigw -p 2014N#WCh!n@Cr#d$ \\%%i cmd /c msiexec.exe /i "\\server2\share\wintech-windows-2.1.1-0.x64.msi" /quiet /norestart 
IF '%ERRORLEVEL%'=='0' (
  echo %%i Installed !!
) else (
  echo %%i failed !!
)
sc \\%%i start wintech
)
                  

Open in new window

0
 

Author Closing Comment

by:nav2567
ID: 40039258
Thanks, everyone.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Why would I want to create a function for tracking messages? I am glad you asked. As with most monotonous/routine tasks, human error tends to creep in after doing the same task over and over again. By creating a function, you load the function once…
Utilizing an array to gracefully append to a list of EmailAddresses
This video discusses moving either the default database or any database to a new volume.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

757 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now