Answered by:
Installing .exe/.msi programs on remote workstations in a PS script
Question
-
I am trying to develop a simple powershell script that will allow me to install various .exe and .msi files on remote workstations in a 2008R2 / Windows 7 environment. I have always used SysInternals PSexec to accomplish this, but I am trying to replace psexec entirely to powershell. I have started a basic script but need some help. My script is (so far) as follows:
-----------------------------------------------
#Variables
$computername = Get-Content C:\PSdeploy\list.txt
$sourcefile = "\\Servershare\7u25\jre-7u25-windows-x64.exe"
$destinationFolder = "\\$computername\C$\Temp"
#This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it.
if (!(Test-Path -path $destinationFolder)) {New-Item $destinationFolder -Type Directory}
Copy-Item -Path $sourcefile -Destination $destinationFolder
#This section will install the software
foreach ($computer in $computername)
{Invoke-Command -ComputerName $computername -ScriptBlock {Start-Process c:\temp\jre-7u25-windows-x64.exe}}-----------------------------------------------
Now, my problem is that the invoke-command is not doing anything. The script copies the file to C:\temp on the destination computer, but hangs when it gets to the next section. However, it does not complete and no errors come up in PS. If I run the invoke-command -scriptblock {start-process C:\temp\jre-7u25-windows-x64.exe} on the local workstation the java installer comes up.
Of course I want this to be a silent install, but I will work with the switches (I believe just add the -argumentlist -s) when I can get the installer to at least execute. I would also like to be notified somehow of success of failure. PSexec tells me a process ID, so I can open task manager on the remote computer and see the progress, is there a way to do this in PS as well?
I have looked around online for a script that accomplishes this but so far nothing I found has worked. There were a couple PS scripts I found that did work, but in the end they called upon psexec to execute the installer, which I am trying to avoid.
Any and all help is greatly appreciated, thank you!
Answers
-
Ah I see now, $destinationFolde was set using $computername, not computer, try changing the script to be:
#Variables $computername = Get-Content C:\PSdeploy\list.txt $sourcefile = "\\Servershare\7u25\jre-7u25-windows-x64.exe" #This section will install the software foreach ($computer in $computername) { $destinationFolder = "\\$computer\C$\Temp" #This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it. if (!(Test-Path -path $destinationFolder)) { New-Item $destinationFolder -Type Directory } Copy-Item -Path $sourcefile -Destination $destinationFolder Invoke-Command -ComputerName $computer -ScriptBlock {Start-Process 'c:\temp\jre-7u25-windows-x64.exe'} }
I modified the original code that you posted, so if you made any further changes, you will need to make those changes to this script
If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
Don't Retire Technet
- Edited by clayman2 Monday, August 26, 2013 5:12 PM edit script
- Marked as answer by commdudeaf Tuesday, August 27, 2013 1:18 PM
All replies
-
I think the issue may be that, the exe is running but seeing you are doing it remotely, and there is no silent install switch, it is just sitting there waiting for a response.
I would run it on the local machine and then look at your processes to see the name of the process, then after you run Invoke-Command, you can run
Get-Process -Name <ProcessName> -ComputerName <RemoteComputer>
To see if it is actually running
If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
Don't Retire Technet- Edited by clayman2 Monday, August 26, 2013 1:26 PM format
-
Thanks for the input. I also tried running the script with the
-ArgumentList /S
parameter after the jre-7u25-windows-x64.exe and still have the same result - failure. I am running the script through ISE, and the status on the bottom indicates the script is "running" but never completes, I have to "stop" the script. This makes me feel like it may be a permissions issue.
On the remote workstation I have task manager open, looking at the processes (from all users) before and after I start the script. The number of processes does not increase. If I run the invoke-command on the local workstation - the java installer starts and a new process is created by the name of "jre-7u25-windows-x64.exe".
- Edited by commdudeaf Monday, August 26, 2013 1:54 PM
-
Alright I'm making some progress. I added the following after jre-7u25-windows-x64.exe
-ArgumentList /s -Verb runas -Wait
After this modification to the script, I was able to successfully install java on the desintations workstation. Only on one workstation though. The list.txt file is where I would like to list the workstations needing the program installed. When I only had one workstation (Win7Test1) listed in the text file, the script successfully installed java on the workstation. The script ran and completed after adding the abovecommands.
However, after adding a second test workstation to the list.txt file, I get the following errors:
(It's seeing all of the workstations listed in the text file, as one network path)
New-Item : The network path was not found. At line:11 char:53 + if (!(Test-Path -path $destinationFolder)) {New-Item <<<< $destinationFolder -Type Directory} + CategoryInfo : WriteError: (\\Win7Test1 Win7Test2\C$\Temp:String) [New-Item], IOException + FullyQualifiedErrorId : CreateDirectoryIOError,Microsoft.PowerShell.Commands.NewItemCommand Copy-Item : The network path was not found. At line:12 char:10 + Copy-Item <<<< -Path $sourcefile -Destination $destinationFolder + CategoryInfo : NotSpecified: (:) [Copy-Item], IOException + FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand This command cannot be executed due to the error: The system cannot find the file specified. + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand This command cannot be executed due to the error: The system cannot find the file specified. + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
- Edited by commdudeaf Monday, August 26, 2013 2:57 PM
-
Your text file needs to be formatted, so that each computer name is on a line by itself so for instance:
computer1
Get-Content looks at each line, so if both machines are on the same line, then that line would be considered as one entry.
computer2
If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
Don't Retire Technet- Edited by clayman2 Monday, August 26, 2013 4:20 PM edit
-
-
Ah I see now, $destinationFolde was set using $computername, not computer, try changing the script to be:
#Variables $computername = Get-Content C:\PSdeploy\list.txt $sourcefile = "\\Servershare\7u25\jre-7u25-windows-x64.exe" #This section will install the software foreach ($computer in $computername) { $destinationFolder = "\\$computer\C$\Temp" #This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it. if (!(Test-Path -path $destinationFolder)) { New-Item $destinationFolder -Type Directory } Copy-Item -Path $sourcefile -Destination $destinationFolder Invoke-Command -ComputerName $computer -ScriptBlock {Start-Process 'c:\temp\jre-7u25-windows-x64.exe'} }
I modified the original code that you posted, so if you made any further changes, you will need to make those changes to this script
If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
Don't Retire Technet
- Edited by clayman2 Monday, August 26, 2013 5:12 PM edit script
- Marked as answer by commdudeaf Tuesday, August 27, 2013 1:18 PM
-
@clayman2, thanks for the help. The changes you made cause the script to hang. Here's what happens when I run the script with your modifications;
the "list.txt" file contains two computers, lets say computer1 and computer2. When I run the script, if there is no temp folder on either computer the script creates the C:Temp folder and copies the file from the fileshare to C:\Temp on computer1, and then hangs. The script does not start the process nor does it move on to copy the file to computer2. If the Temp older is already in place and the java file is in the folder, the script still hangs. It doesn't error out or stop, just keeps running without ever starting the process or moving on to the next computer in the text file.
After looking over the code, it looks like I do not even need the line:
foreach ($computer in $computername)
since $computer is not defined anywhere. I have removed this line, and the script works properly (again) with only one computer defined in "list.txt" but when I add a second computer in to the text file, I get the same error as before.
So, there is an error with my code while atempting to copy the file from the source fileshare to the destination computer (or create a new folder "C:\Temp" if it does not already exist). To my understanding, the line
$computername = Get-Content C:\SysinternalsSuite\list.txt
should pull all computers from the list.txt file, and run the following script against each of them, individually. The problem is that the script is trying to run against all of them at once. This is where I am getting stuck.
The script is trying to use "\\Win7Test1 Win7Test2\C:\Temp" instead of running the command twice as "\\Win7Test1\C:\Temp" and "\\Win7Test2\C:\Temp".
New-Item : The network path was not found. At line:13 char:53 + if (!(Test-Path -path $destinationFolder)) {New-Item <<<< $destinationFolder -Type Directory} + CategoryInfo : WriteError: (\\Win7Test1 Win7Test2 \C$\Temp:String) [New-Item], IOException + FullyQualifiedErrorId : CreateDirectoryIOError,Microsoft.PowerShell.Commands.NewItemCommand
- Edited by commdudeaf Monday, August 26, 2013 6:09 PM
-
$computer isnt defined until the ForEach loop, that is where it is defined.
Get-Content <Path to File> will return an array, with each element consisting of a line in the document, therefore you need to loop through, unless a paramater accepts an array.
It seems that everything is working, up to the point of the Invoke-Command. I am not that familar with this command as I have never had a need to use it, plus my environment isnt set up for it.
So for testing, comment out the Invoke-Command, to verify that everyting is working as expected and the script completes, once that is verified, we now know it is something with Invoke-Command
If you find that my post has answered your question, please mark it as the answer. If you find my post to be helpful in anyway, please click vote as helpful.
Don't Retire Technet- Proposed as answer by mmolloy777 Wednesday, November 20, 2013 6:22 PM
- Unproposed as answer by mmolloy777 Wednesday, November 20, 2013 6:22 PM
-
#Variables $computername = Get-Content 'M:\Applications\Powershell\comp list\Test.txt' $sourcefile = "\\Server\Apps\LanSchool 7.7\Windows\Student.msi" #This section will install the software foreach ($computer in $computername) { $destinationFolder = "\\$computer\C$\download\LanSchool" #This section will copy the $sourcefile to the $destinationfolder. If the Folder does not exist it will create it. if (!(Test-Path -path $destinationFolder)) { New-Item $destinationFolder -Type Directory } Copy-Item -Path $sourcefile -Destination $destinationFolder Invoke-Command -ComputerName $computer -ScriptBlock { & cmd /c "msiexec.exe /i c:\download\LanSchool\Student.msi" /qn ADVANCED_OPTIONS=1 CHANNEL=142} }I found this thread and was able to modify the script so it will install an .MSI - I've tested this and it works great! Hopefully it can help some others as well :)- Edited by mmolloy777 Wednesday, November 20, 2013 6:29 PM
-
hey clayman2, I've tried your code but on my side it returns
[l4d408] Connecting to remote server failed with the following error message : WinRM cannot process the request. The following error occured while using Kerberos authentication: A specified logon session does not exist. It may already have been terminated.
I'm still new to PS and if anyone is kind enough to point me where to look at I'll be very grateful.
-
Hi,
Have you configured remoting? That's required for the Invoke-Command cmdlet to work.
http://technet.microsoft.com/en-us/magazine/ff700227.aspx
Don't retire TechNet! - (Maybe there's still a chance for hope, over 12,420+ strong and growing)