Install MSI on remote computer using Powershell - powershell

I am trying to write a Powershell script which will deploy software on a collection of WS2016 servers. I am a local administrator on all these servers. Here's what I have so far:
$Cred = Get-Credential
$Computer = 'myserver.contoso.com'
$SplunkMSI = '\\mylocalbox\C$\Splunk.msi'
$InstallDir = 'C:\Apps\Splunk\'
$sb = {
param($installer, $dir)
Start-Process -FilePath 'c:\windows\system32\msiexec.exe' -ArgumentList "$installer INSTALLDIR=$dir AGREETOLICENSE=Yes /qn /norestart /L*v C:\temp\splunkInstall.log" -Wait -NoNewWindow
}
Write-Host "Deploying Splunk to host $Computer"
Invoke-Command -Computer $Computer -Credential $Cred -ScriptBlock $sb -ArgumentList $SplunkMSI, $InstallDir -ErrorAction Stop
When I run this script, I get prompted for credentials, and then I see the output of the Write-Host, but then... nothing. I have to manually terminate the script.
I logged onto the remote host, but see no evidence that the MSI was executed or failed to execute.
Anyone see a smoking gun?

ya, it looks like it's looking for $installer and $dir in the script block but they're not specified

Related

Invoke-Command executes on remote machine without having an effect

I'm trying to run a command on a VM using Invoke-Command. The command should stop a program that processes jobs after it finishes its current job. It works if I run it in the terminal using RDC.
& 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' /stop
But if I run it from a different machine using Invoke-Command nothing seems to happen.
$session = New-PSSession -ComputerName 'hostname' -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock {
& 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' /stop
}
However Process Monitor shows the command come in for both cases, but the program is still running.
I have also tried using Start-Process with the same result, i.e. it works in the terminal on the VM but not using Invoke-Command.
Start-Process -FilePath 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe' -ArgumentList '/stop'
I've been stuck for many days and I've exhausted my googlable knowledge for this problem.
Are you sure that file exists on the remote computer?
For simplicity, I rewrote your command to a known executable that is always there in Windows and returns unique info for any given computer.
C:\> & 'C:\Windows\system32\HOSTNAME.EXE'
server1
C:\> icm {& 'C:\Windows\system32\HOSTNAME.EXE'}
server1
C:\> icm {& 'C:\Windows\system32\HOSTNAME.EXE'} -ComputerName server2
server2
Here's your script with some error handling.
$session = New-PSSession -ComputerName 'hostname' -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock {
$exe = 'C:\Program Files\Autodesk\Vault Client 2021\Explorer\JobProcessor.exe'
$ok = Test-Path $exe
if ($ok) {& $exe /stop} else {
Write-Warning "EXE not present on $($env:COMPUTERNAME)!"
}
}
Learn how to add error handling and you'll be well on your way to solving your problems faster and getting more stuff done.

powershell execute start-process on remote machine

IDE: PowerShell ISE
I have a script which installs the chrome to a remote machine
#Script : Test01.ps1
Start-Process D:\Chrome\Chrome.exe -wait -verb runas
write-host "Chrome is installed"
and I am executing the above script using :
Invoke-Command -ComputerName MySystem18 -FilePath D:\Test01.ps1 -ArgumentList Process
The above script is working on local system (MySystem03) and remote machine (MySystem18).
But when I am executing this in MySystem18 it is not showing up the acknowledgement or cursor after the installation of chrome, even after successful installation of chrome on MySystem18.
Can you tell me how to fix it.
D:\Chrome\Chrome.exe is a path on your remote computer ? If not, try to share a dir with Chrome.exe named yourdirshared on your mysystem03 and replace by \\mysystem03\yourdirshared\Chrome.exe into your ps1
if always doesnt work, you can try to remove -wait my be...
if always doesnt work, are you try to specify credentil parameter?
$Username = 'username'
$Password = 'yourpassword
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Invoke-Command -ComputerName "MySystem18" -Credential $Cred -ScriptBlock {Start-Process D:\Chrome\Chrome.exe -wait -verb runas; write-host "Chrome is installed" }

PowerShell Invoke-Command remotely using a share

I am trying to install software (.exe) with PowerShell remotely on another computer. I have now:
Invoke-Command -Authentication Credssp -Credential $cred -ComputerName "TargetComputer01" -ScriptBlock {Start-Process -FilePath $args[0] -ArgumentList ('/log "{0}" /quiet /norestart' -f $args[1]) -Wait -PassThru -Verb RunAs} -ArgumentList #($Installer, $LogPath)
This does not work, no errors, no log file, no installed software. So I have no idea why it is not working. I use Credssp because the installer is located on a share. When I place the installer somewhere on the TargetComputer01, it is working with a session, see:
Invoke-Command -Session $session -ScriptBlock {Start-Process -FilePath $args[0] -ArgumentList ('/log "{0}" /quiet /norestart' -f $args[1]) -Wait -PassThru -Verb RunAs} -ArgumentList #($Installer, $LogPath)
Any idea why the first command with Credssp is not working??
Yes I also have enabled Credssp with those commands. It seems that my script does run succesfully on TargetComputer01 (Windows Server 2012) but did not run succesfully on TargetComputer02 (Windows Server 2008 R2). The PowerShell versions are the same, and all other configuration is also the same (e.g. firewall settings).
I found however a way to get it working with a PSSession, see the following code:
$cred = Get-Credential -UserName "domain\username" -Message "Enter your credentials"
$session = New-PSSession -ComputerName "TargetComputer02" -Credential $cred -Authentication Credssp
Invoke-Command -Session $session -ScriptBlock {
param
(
$Installer, $LogPath
)
Start-Process -FilePath $Installer -ArgumentList ('/log "{0}" /quiet /norestart' -f $LogPath) -Wait -PassThru -Verb RunAs
} -ArgumentList #($Installer, $LogPath)
I am not sure why the other Invoke-Command without the session but with Credssp does not work on Windows Server 2008 R2, but the above code works on both Operating Systems! :)
Have you actually enabled CredSSP on the two computers? See the Enable-WSManCredSSP command.
On the client computer, or the computer you're running the script on, you need to set it to delegate credentials to the target computer:
Enable-WSManCredSSP -role Client -DelegateComputer "TargetComputer01"
You should verify this was set up properly by going into gpedit.msc -> Computer Configuration -> System -> Credentials Delegation. “Delegating fresh credentials” should now be enabled, and when you open up the details for it, TargetComputer01 should show up like “WSMAN/TargetComputer01”
And now on the receiving computer:
Enable-WSManCredSSP -role Server
Also make sure you run Enable-PSRemoting on TargetComputer01.
Let me know if this works for you!

Powershell Start-Process msiexec on a remote machine not working

For some reason Start-Process msiexec won't work when run through invoke command on a remote machine. I looked it up and while some people recommend using psiexec i have seen a lot of people using the plain old invoke-command to start msi installers on remote machines.
This is the code i am currently using:
$session = New-PSSession -computername $computerName -ea stop
$command = {
Param(
[Parameter()]
[string]$computerName,
[Parameter()]
[string]$domain,
[Parameter()]
[string]$user,
[Parameter()]
[string]$password,
[Parameter()]
[string]$installDir
)
$msiArgumentList = "/i C:\Installer.msi /l c:\log.txt /quiet /qr /norestart IAGREE=Yes DOMAIN=$domain ACCOUNT=$user PASSWORD=$password PASSWORDCONFIRM=$password INSTALLDIR=$installDir"
Start-Process msiexec -ArgumentList $msiArgumentList -Wait
}
Invoke-Command -session $session -ScriptBlock $command -ArgumentList $computerName, $domain, $user, $password, $installDir
Remove-PSsession -session $session
I used the same method to install services remotely using intallutil and it worked. Scripting is enabled on target machine as well as remoting so by all accounts it should work. Both computers have the same credentials but i still tried adding credentials to both invoke-command and the pssession. I tested the code locally and the installation worked. Remotely it doesn't and no errors what so ever. i can see on the target machine in taskmanager that msiexec is started but nothing happens. I even tried disabling the firewall and still nothing. i tried the & operator to start msiexec and still nothing.
Not sure what else i could try.
Maybe you try another way, if you don't come forward?
Use Task scheduler, to start the command line e.g by creating and executing a task on the remote machine:
SchTasks /CREATE /XML mycommand.xml /TN "thiscommand"
SchTasks /RUN /TN "thiscommand"
This is for starting a task (like) on the local computer.
With parameter /S you can create tasks on remote computers as in:
SchTasks /S thatPC /CREATE /XML mycommand.xml /TN "thiscommand"
SchTasks /S thatPC /RUN /TN "thiscommand"
For details of parameters and for syntax of the .xml file defining the task you can look into the help.
You could try executing Start-Process with Passthru to see if an error is being returned:
(Start-Process -FilePath msiexec.exe -ArgumentList $msiArgumentList -Wait -Passthru).ExitCode
The other thing that may help is increasing your logging to /l*v
Update 1
Can you try the following, just to check remote commands for msi are working, it should result in 1619.
(Start-Process -FilePath msiexec.exe -ArgumentList "/i no.msi /quiet /qb!" -Wait -Passthru).ExitCode
It seems the problem was a combination of how the msi installer was build and the restrictions windows server has towards interactive processes. I ended up using psexec to bypass this problem.
The only solution that worked for me was to poll the process status. This can be run inside a scriptblock in a remote powershell session.
$res = Start-Process -FilePath $process -ArgumentList $arguments -Wait -PassThru
while ($res.HasExited -eq $false) {
Write-Host "Waiting for $process..."
Start-Sleep -s 1
}
$exitCode = $res.ExitCode
Using the answers above I ended up with
$session = New-PSSession -ComputerName $serverName -Credential $mycred
invoke-command -Session $session -ScriptBlock { param ($argxs) write-host $argxs; start-process msiexec.exe -ArgumentList $argxs } -ArgumentList "/i `"$pathToMsi`" /qn /L*V `"E:\package.log`""
The write-host is just there to verify the augments are correctly escaped but proved invaluable in debugging.

Executing an Exe file inside Invoke-Command causes Access Denied

Using Powershell, I'm trying to connect to a remote machine and install an exe file on that system. Unfortunately I'm getting an Access is denied error when running the file. What's truly odd about this error, is that other exe's located on the same path run fine, so I'm wondering if something more cryptic could be involved?
I'm currently using this command to connect to the remote machine, upon which I'm a local admin.
$InstallFile = "\\networkshare\folder\folder\setup.exe"
$InstallParameters = "SampleParameter1 = 5"
$Server = SERVERNAME.DOMAINNAME.COM
$cred = Get-Credential
invoke-command -Computername $Server -authentication credssp -credential $cred -ScriptBlock {
$CurrentProcess = Start-Process -FilePath $InstallFile -ArgumentList $InstallParameters -Wait -PassThru
$CurrentProcess | Wait-Process
}
I'm using CredSSP which seems to be working well since it fixed this issue for other files, but this one simply refuses. Any other thoughts? I ran into a similar issue with .NET 4 and was unable to resolve that install either.
I've noticed you are using Start-Process to run your executable. According to this:
http://technet.microsoft.com/en-us/library/dd347667.aspx
there's also -Credential parameter that can be passed to it. It very well might be the case that Start-Process is not executed by the user that called Invoke-Command. Try passing Credential to your Start-Process:
invoke-command -Computername $Server -authentication credssp -credential $cred -ScriptBlock {
$CurrentProcess = Start-Process -FilePath $InstallFile - Credential $cred -ArgumentList $InstallParameters -Wait -PassThru
$CurrentProcess | Wait-Process }