msiexec with -Wait installation continuously failing - powershell

There is my script:
try {
Start-Process "C:\tmp\_deployment\AcroRdrDC1900820071_hu_HU.exe" -argumentlist '/sALL /EULA_ACCEPT=YES /qn"' -PassThru -Wait
} catch {
Write-Host "mypatch.exe returned the following error $_"
Throw "Aborted mypatch.exe returned $_"
}
try {
Start-Process "C:\tmp\_deployment\Office 2016 Prof Plus 64bit HUN\setup.exe" -Verb runAs -PassThru -Wait
} catch {
Write-Host "mypatch.exe returned the following error $_"
Throw "Aborted mypatch.exe returned $_"
}
try {
Start-Process "C:\tmp\_deployment\jre-8u181-windows-x64.exe" -ArgumentList '/s INSTALL_SILENT=1 STATIC=0 AUTO_UPDATE=0 WEB_JAVA=1 WEB_JAVA_SECURITY_LEVEL=H WEB_ANALYTICS=0 EULA=0 REBOOT=0 NOSTARTMENU=0 SPONSORS=0' -PassThru -Wait
} catch {
Write-Host "mypatch.exe returned the following error $_"
Throw "Aborted mypatch.exe returned $_"
}
Start-Process msiexec.exe -PassThru -Wait -ArgumentList '/I C:\tmp\_deployment\7z1805-x64.msi /passive'
Start-Process msiexec.exe -PassThru -Wait -ArgumentList '/I C:\tmp\_deployment\tightvnc-2.8.11-gpl-setup-64bit.msi /quiet /norestart'
Everything is fine until the 7zip installation is complete. When it's done the next process - tightvnc - not installing to the computer.Everything is fine until the 7zip installation finishes. When the next process - tightvnc - starts, the installation will exit immediately and tightvnc not available on the machine.
I tried to change the last lines with this:
msiexec.exe /I C:\tmp\_deployment\tightvnc-2.8.11-gpl-setup-64bit.msi /quiet /norestart -Wait
But nothing.
If I run the the last lines alone, tightnc install will be successful.
I think the -Wait parameters not working. Any idea how can I solve this?
If anyone knows how to simplify this script, I would appreciate it!
Thanks for the help.

Related

Powershell: Call function during Start-Process

I have a function called RemoveSoftware:
function RemoveSoftware {
foreach ($utility in $toRemove) {
Try {
winget uninstall -e $utility
$wingetResult.Add("$node`n")
Start-Sleep -s 6
Wait-Process winget -Timeout 90 -ErrorAction SilentlyContinue
}
Catch {
Write-Host "Paket $utility konnte nicht deinstalliert werden. " -ForegroundColor red
}
}
}
This function is in a ps1 file. In the same file I want to start another powershell window which should start this function.
I tried this here:
Start-Process powershell.exe -Verb RunAs -ArgumentList "-command Start-Transcript C:\temp\winget-start.log -Append; & {$RemoveSoftware} | Out-Host" -WindowStyle Normal
But this don't work.
Also I tried several other things like Invoke-Expression and so on. Neither of it worked:(
Has someone a tipp for solving this problem?

Powershell Try/Catch or If/Else is not working for my script

I have the below powershell script which runs from my Jenkins:
$sqlpackage = Start-Process -FilePath sqlpackage.exe -ArgumentList '/Action:Publish','/SourceFile:"Database Services\bin\Release\Database Services.dacpac"',"/TargetConnectionString:""Data Source=${Env};Integrated Security=True;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;Initial catalog=${Target}""",'/p:BlockOnPossibleDataLoss=True' -wait -PassThru -Credential $Cred -RedirectStandardOutput sqlstdout.txt -RedirectStandardError sqlstderr.txt
$sqlpackage.WaitForExit()
$sqlpackage
I tried to use the below options for Try/Catch or If/Else, but so far nothing is working (it goes to the Else / Catch even thought the script passed successfully:
OPTION 1
$sqlpackage = Start-Process -FilePath sqlpackage.exe -ArgumentList '/Action:Publish','/SourceFile:"Database Services\bin\Release\Database Services.dacpac"',"/TargetConnectionString:""Data Source=${Env};Integrated Security=True;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;Initial catalog=${Target}""",'/p:BlockOnPossibleDataLoss=True' -wait -PassThru -Credential $Cred -RedirectStandardOutput sqlstdout.txt -RedirectStandardError sqlstderr.txt
$sqlpackage.WaitForExit()
$sqlpackage
if ($sqlpackage.LastExitCode -eq 0) {
Get-Content sqlstdout.txt
}
else {
echo "An error occurred $Error[0]"
Get-Content sqlstderr.txt
exit $sqlpackage.LastExitCode
}
OPTION 2
try
{
$sqlpackage = Start-Process -FilePath sqlpackage.exe -ArgumentList '/Action:Publish','/SourceFile:"Database Services\bin\Release\Database Services.dacpac"',"/TargetConnectionString:""Data Source=${Env};Integrated Security=True;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Connect Timeout=60;Encrypt=False;TrustServerCertificate=False;Initial catalog=${Target}""",'/p:BlockOnPossibleDataLoss=True' -wait -PassThru -Credential $Cred -RedirectStandardOutput sqlstdout.txt -RedirectStandardError sqlstderr.txt
$sqlpackage.WaitForExit()
$sqlpackage
}
catch{
echo "An error occurred $Error[0]"
Get-Content sqlstderr.txt
$LastExitCode = 1
exit $LastExitCode
}
Can you help me with the correct syntax? eventually the expected behavior is to show sqlstdout.txt in case it passed, and sqlstderr.txt in case it failed + fail the jenkins build.
For the OPTION 1, the property in the condition of the if block should be ExitCode, not LastExitCode.

Start-Command PowerShell v3.0, does nothing

I am trying to install software (executable) on several servers with various versions of PowerShell.
Normally below code works with no issue on PS4 and up. On PS3 it does not install anything, nor does it produce any errors on the remove server eventviewer. It treated as success by printing out "... -- installation succeeded" and exits. I've googled about and read that perhaps Start-Process is the culprit in PS3.
Begin {
$uncpath="\\remoteserveruncpath\" #"
$exe_parameter1 = "centralserver.com"
$creds = Get-Credential -Message "Password: " -Username "$($env:userdnsdomain)\$($env:username)"
}
Process {
$dnshostname = "server1","server2","server3"
ForEach ($server in $dnshostname) {
Invoke-Command -ComputerName $server -ScriptBlock {
param($server_int,$exe_parameter1_int,$uncpath_int,$creds_int)
(New-Object -ComObject WScript.Network).MapNetworkDrive('Z:',"$($uncpath_int)", $false, "$($creds_int.Username)", "$($creds_int.GetNetworkCredential().Password)")
$arguments = "/param_1=$exe_parameter1_int /param_2=$($server_int.ToLower()) /start-program=1 /S"
If((Start-Process "Z:\installer.exe" -ArgumentList $arguments -Wait -Verb RunAs).ExitCode -ne 0) {
Write-Host "$server_int -- installation succeeded"
} else {
Write-Error "$server_int -- installation failed"
}
} -ArgumentList $server,$exe_parameter1,$uncpath,$creds;
}
}
Any advice? Many thanks!
Without -PassThru, Start-Process produces no output, so accessing .ExitCode effectively returns $null, always.
And since $null -ne 0 is always $true, your code always indicates success.
In order to get the installer command's true exit code, you therefore need to use the following (note the addition of -PassThru):
if ((Start-Process -PassThru 'Z:\installer.exe' -ArgumentList $arguments -Wait -Verb RunAs).ExitCode -ne 0) { ... }

Powershell referencing current directory and subfolder

I use the following code to reference files in the current script directory
$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
Then I can call it like
try {
WriteLog("Installing...")
$installresult = (Start-Process msiexec.exe -ArgumentList "/i
$PSScriptRoot\InstallPrism6.msi /qn /norestart" -Wait -PassThru).ExitCode
WriteLog("Installation finished with return code: $installresult")
}
catch {
WriteLog($_.Exception.Message)
}
This works fine. However, if I want to reference a file in a subdirectory like so
try {
WriteLog("Installing...")
$installresult = (Start-Process msiexec.exe -ArgumentList "/i $PSScriptRoot
+ \test\InstallPrism6.msi /qn /norestart" -Wait -PassThru).ExitCode
WriteLog("Installation finished with return code: $installresult")
}
catch {
WriteLog($_.Exception.Message)
}
it fails with error code 1639.
If this doesn't work, how can I reference subdirectories when using $PSScriptRoot?
Note that the $PSScriptRoot variable is predefined on PowerShell 3.0 and newer, so you only need that variable if it's not already defined. I believe the proper syntax for what you want to do should look like the following:
if ( -not $PSScriptRoot ) {
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
try {
WriteLog "Installing..."
$installresult = (Start-Process msiexec.exe -ArgumentList "/i","`"$PSScriptRoot\test\InstallPrism6.msi`"","/qn","/norestart" -Wait -PassThru).ExitCode
WriteLog "Installation finished with return code: $installresult"
}
catch {
WriteLog $_.Exception.Message
}
-ArgumentList is technically an array, and I embedded the " in case the path contains any whitespace.
Try not leaving spaces in your path. When you are building a string using a variable, you don't need to concatenate. It's not about referencing subfolders.
try {
WriteLog("Installing...")
$installresult = (Start-Process msiexec.exe -ArgumentList "/i ${PSScriptRoot}\test\InstallPrism6.msi /qn /norestart" -Wait -PassThru).ExitCode
WriteLog("Installation finished with return code: $installresult")
}
catch {
WriteLog($_.Exception.Message)
}

Start-Process not running

I have been trying to re-write the following PowerShell code as I need it to wait until completion before carrying on so assumed Start-Process with -Wait would be sufficient however I can't seem to get it to actually run...
Original code which works, but won't wait until it's finished before carrying on with the script.
function ZipAndDeleteFile([string] $file, [string] $saveLocation)
{
$command = [string]::Format("`"{0}`" a -ep -df `"$saveLocation`" `"$file`"", $winrarPath);
iex "& $command";
}
My attempt at re-writing which isn't running as expected, does nothing so far...
function ZipAndDeleteFile([string] $file, [string] $saveLocation)
{
Start-Process -FilePath $winrarPath -ArgumentList "a -ep -df $saveLocation $file" -Wait
}
Fixed with the following... knew it was something silly.
Start-Process -FilePath $winrarPath -ArgumentList "a -ep -df `"$saveLocation`" `"$file`"" -Wait