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.
Related
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
I use the following example to install some software on a remote computer
I would like to get the exit code back from the MSI so I can determine if successful or if not what the error was
I assumed $result would contain the information I need but I am obviously missing something
Ideas please?
$Result = Invoke-Command -computername MYREMOTEPC -ScriptBlock { Start-Process "msiexec" -ArgumentList "/i C:\tmp\MYSOFTWARE.msi /quiet /norestart" -Wait -Passthru }
Enclose the Start-Process -Passthru command in (...).ExitCode:
$Result = Invoke-Command -computername MYREMOTEPC -ScriptBlock {
(
Start-Process "msiexec" -ArgumentList "/i C:\tmp\MYSOFTWARE.msi /quiet /norestart" -Wait -PassThru
).ExitCode
}
-PassThru instructs Start-Process to output a System.Diagnostics.Process instance representing the launched process, and given that -Wait is also used, its .ExitCode property can be accessed right away.
As a precursor to running an installation file on several remote servers, I need to update the Powershell setting MaxMemoryPerShellMB. This requires running a PS session as Administrator on the remote server. I have been trying to run Invoke-Command which then runs a ScriptBlock consisting of a Start-Process command which includes the -Verb RunAs parameter. Nothing seems to work, however.
I have tried with various quoting schemes, single, double, triple, but nothing seems to work.
I've tried running the Start-Process from an Enter-PSSession, with the same results.
Following is the code I'm testing now:
$creds = Get-Credential -Username 'DOMAIN\userID' -Message "Enter Username and Password to access the remote servers."
$ScriptBlock = {
Start-Process -FilePath Powershell.exe -ArgumentList """Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024""" -Verb RunAs -Wait
}
Invoke-Command -ComputerName testsvr01 -Credential $creds -ScriptBlock $ScriptBlock
I should be able to RDP to the remote server and run Get-Item WSMan:\localhost\Shell and have it show the updated value, but the value isn't changed.
When running the code it pauses for a second when the Invoke-Command runs, but other than that, there is no feedback in Powershell.
On the remote server I see the following two Kerberos errors in the System Event log.
0x19 KDC_ERR_PREAUTH_REQUIRED,
0xd KDC_ERR_BADOPTION
Any help is greatly appreciated.
> powershell.exe -?
...
EXAMPLES
...
PowerShell -Command "& {Get-EventLog -LogName security}"
-Command
...
To write a string that runs a Windows PowerShell command, use the format:
"& {<command>}"
where the quotation marks indicate a string and the invoke operator (&)
causes the command to be executed.
So you could try to call Set-Item in the following way:
$ScriptBlock = {
Start-Process -FilePath Powershell.exe -ArgumentList "-Command"," &{ Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 1024 }" -Verb RunAs -Wait -PassThru
}
$process = Invoke-Command -ComputerName testsvr01 -Credential $creds -ScriptBlock $ScriptBlock
$process.ExitCode
I'm also returning a process object via -PassThru on which you might check the `ExitCode``
Hope that helps
I am trying to install google chrome on a remote server but when I run my script, no error is returned and yet the MSI does not install the software automatically. This script can work locally but not remotely.
Here is the script:
$msi = "MSI path"
Invoke-Command -ComputerName RemoteServer -ScriptBlock {param($msi) Start-Process msiexec.exe -Wait -ArgumentList "/I (MSI Path) /qn /passive"} -ArgumentList $msi
Any help or feedback is appreciated.
I'm not sure, but I think your problem is that you're using the $msi as local and as remote variable. Tow options:
For readonly variables you use the "Using" keyword
See about_remote_variables about details. If you only need to read the value from a variable you can the following:
$msi = "MSI path"
Invoke-Command -ComputerName RemoteServer -ScriptBlock { Start-Process msiexec.exe -Wait -ArgumentList "/I $Using:msi /qn /passive"}
Here you don't need the ArgumentList-parameter of Invoke-Command.
Add a _remote suffix to remote variables
This is only a style I'm using in my scripts to distinguish about local and remote variables.
$msi = "MSI path"
Invoke-Command -ComputerName RemoteServer -ScriptBlock {param($msi_remote) Start-Process msiexec.exe -Wait -ArgumentList "/I $msi_remote /qn /passive"} -ArgumentList $msi
Hope that helps.
Couldnt get my script to work as it is a permission problem on the remote server. It has since been resolved.
I've tried the following:
Start-Process powershell -ArgumentList "C:\Program Files\Prometheus.io\prometheus.exe" -WindowStyle hidden
Invoke-Command -ComputerName . -AsJob -ScriptBlock {
'C:\Program Files\Prometheus.io\prometheus.exe'
}
Start-Job -Name "prometheus" -ScriptBlock {Get-Process prometheus.io}
Start-Job {& .\prometheus.exe}
Sometimes it starts but terminates immediately after starting. If I start it manually it works correctly.
How can I keep my process alive in background?
EDIT :
It doesn't worked because i wasn't in the directory of my process that need a file which pathfile is not set.
Your syntax for Start-Process is wrong, you don't need to reference powershell, just launch your program with the WindowStyle param set
Start-Process "C:\Program Files\Prometheus.io\prometheus.exe" -WindowStyle Hidden
The WorkingDirectory param can also be used to start the program in a specific directory
Start-Process "C:\Program Files\Prometheus.io\prometheus.exe" -WorkingDirectory "C:\Program Files\Prometheus.io" -WindowStyle Hidden