During Installation process of a software using Start-Process "msiexec.exe" ... -wait, how to fix error and continue the installation process? - powershell

For the installation of the "Self-Hosted Integration runtime software, using PowerShell command
Start-Process "msiexec.exe" "/i $path /quiet /passive" -Wait, error comes up for "DIAHostService" not having "LocalSystem" access.
I have the code to change the login to the LocalSystem ("sc.exe config "ServiceName" obj="LocalSystem") But How can I do this during the Installation Process, how do I catch the error and do the required change and continue for the installation automatically?
Code:-
param([string]$path, [string]$authKey)
function Install-Gateway([string] $gwPath)
{
# uninstall any existing gateway
UnInstall-Gateway
Write-Host "Start Gateway installation"
Start-Process "msiexec.exe" "/i $path /quiet /passive" -Wait
Start-Sleep -Seconds 30
Write-Host "Succeed to install gateway"
}

Since I am in no position to replicate what you are doing, take this generic approach as an example.
param([string]$path, [string]$authKey)
function Install-Gateway([string] $gwPath)
{
Write-Warning -Message 'Starting Gateway uninstallation'
UnInstall-Gateway
Try
{
'Starting Gateway installation'
Start-Process -FilePath 'msiexec.exe' -ArgumentList "/i $path /quiet /passive" -Wait -ErrorAction Stop
Start-Sleep -Seconds 30
Write-Verbose -Message 'Gateway installation successful.' -Verbose
}
Catch
{
Write-Warning -Message 'AN error occurred'
$PSItem.Exception.Message
}
}
If you need to run this with a different user, then you need to add the RunAs as part of the Start-Process error logic. Yet using RunAs means starting a new Powershell instance. It will not run in the same process.
References
• PowerShell: Running Executables
Direct - Using the environment path or local folder
Invoke-Expression (IEX)
Invoke-Command (ICM)
Invoke-Item (II)
The Call Operator &
cmd /c - Using the old cmd shell
Start-Process (start/saps)
[Diagnostics.Process] Start()
WMI Win32_Process Create() Method
Stop-Parsing Symbol --%
see also:
'powershell start-process msiexec'
Powershell: Installing MSI files
'PowerShell start-process msiexec' try/catch
about_Try_Catch_Finally - PowerShell | Microsoft Docs
'PowerShell error preference'
Handling Errors the PowerShell Way | Scripting Blog
-ErrorAction and -ErrorVariable
You could also look at using PowerShell jobs for this use case.
start-process 'about PowerShell jobs'

Related

Powershell-Command to download a file with admin rights

I try do download a file via a powershell command. The command I use is simple:
Start-BitsTransfer -Source 'https://download.com/file.zip' -Destination 'E:\test\file.zip'
I can run the command in PS succesfully. But now I want to run it with elevated rights. So I gooogled and found this solution:
There it says the command should be:
Start-Process powershell.exe -Verb Runas -ArgumentList "-Command & {get-process}"
So I tried adjusting it for my use case:
Start-Process powershell.exe -Verb Runas -ArgumentList "-Command & {Start-BitsTransfer -Source 'https://download.com/file.zip' -Destination 'E:\test\file.zip'}"
But all is does is open a new PS-Window and closing it right after. Where is my mistake?
You can change to this
Start-Process powershell.exe -Verb Runas -ArgumentList "& {Start-BitsTransfer -Source 'https://download.com/file.zip' -Destination 'E:\test\file.zip'}"
Note the window will close after the execution completes. If you would like to see the output/errors (such as what would be shown in your non working example) just add another command to pause.
Start-Process powershell.exe -Verb Runas -ArgumentList "& {Start-BitsTransfer -Source 'https://download.com/file.zip' -Destination 'E:\test\file.zip';pause}"
& is used to invoke a command. It's useful for executing strings or scriptblocks. It runs in a child runspace.
& 'Get-Host'
& 'Write-Host' Hello -Fore Green
& {Write-Host Goodbye -Fore Cyan}
; is used to separate different commands on the same line.
& {$name = 'Doug';Write-Host Hello $name}
You can also use a period to invoke a scriptblock in the current runspace. In the previous command the $name variable would be empty in the callers scope where the following command would leave the variable defined.
& {$name = 'Doug';Write-Host Hello $name}
$name # empty as it all happens in the child scope
vs
. {$name = 'Doug';Write-Host Hello $name}
$name # populated because it's brought into the caller's scope

While installing msi using PowerShell command Start-Process, getting Exit-code 1603 error

We are tying to install an MSI file on Windows servers using the following script and are able to install the MSI file in a Windows server. The Following code IS working fine for some MSI files, but it's failing for others. getting exit-code as 1603. If we do clean installation it works fine, but while trying to reinstall, we are getting an exit-code:1603 error. All the configuration settings are same for all services.
As mentioned on the Microsoft web site, we verified that following conditions and none are applied to our case.
Windows Installer is attempting to install an app that is already installed on your PC.
The folder that you are trying to install the Windows
Installer package to is encrypted.
The drive that contains the folder that you are trying to install the Windows Installer package to is accessed as a substitute drive.
The SYSTEM account does not have Full Control permissions on the folder that you are trying to install the Windows Installer package to. You notice the error message because the Windows Installer service uses the SYSTEM account to install software.
Code:
:outer for($i=1; $i -le $attempts; $i++) {
$timeout = $null
$proc = Start-Process -filePath $InstallerPath -ArgumentList $InstallCommand -PassThru
$proc | Wait-Process -Timeout $SecondsToWait -ea 0 -ev timeout
If (($timeout) -or ($proc.ExitCode -ne 0)) {
$proc | kill
$error = "`tFailed To Run $($ProcessTitle)Operations: Exit-Code = $($proc.ExitCode)"
If(($i+1) -le $attempts) {
WriteLog -Message($error) -MainLoggingConfigs $MainLoggingConfigs
Start-Sleep -s $WaitTimePerAttempt
}
Else {
throw $error
}
}
Else {
break outer
}
If using an MSI, you'll want to use Start-Process msiexec.exe -wait -NoNewWindow instead of Wait-Process . If you are really worried about it running forever, consider using PowerShell jobs:
Start-Job -Name MyInstall -scriptBlock {
Start-Process msiexec.exe -NoNewWindow -ArgumentList $MSIArguments
}
Wait-Job -Name MyInstall
Then check the job Get-Job MyInstall for output, status messages, state, errors, and especially child jobs.
The error you get may be due to competing installation attempts if your Start-Process creates child processes that haven't ended. Try out using something like Kevin Marquette's solution to save off the verbose MSI logs as well:
$MSI = 'C:\path\to\msi.msi'
$DateStamp = get-date -Format yyyyMMddTHHmmss
$logFile = "$MSI-$DateStamp.log"
$MSIArguments = #(
"/i"
"`"$MSI`""
"/qn"
"/norestart"
"/L*v"
$logFile
)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow

ArgumentList for silent install .Net 4.7.2

Attempting to silently install .Net 4.7.2 on a remote machine using Invoke-Command but no matter what type of parameters I've tried I keep getting...
Invoke-Command : Parameter set cannot be resolved using the specified named parameters.
I've tried parameters like /q /quiet /passive and all that is provided keeps on getting the error.
Invoke-Command -ComputerName $problemChild -ScriptBlock { Start-Process "c:\windows\temp\dotNet472.exe" -ArgumentList '/q /norestart' -Wait -NoNewWindow -ErrorAction SilentlyContinue -ErrorVariable dotNetError -Verb RunAs }
Expecting to install .Net 4.7.2 silently with no reboot, just incase the user is still logged in.
Executing the command on a Win 7 with PS version 4 on a remote machine running Win 7 PS 2. I've confirmed that the parameters passed are the correct ones from MS article.
** Edit: Removing -NoNewWindow get's rid of the error but the installer doesn't run. While running the command below on the remote machine, get's the installer going and no issues are seen.
Start-Process "c:\windows\temp\dotNet472.exe" -ArgumentList '/q /norestart' -Wait -ErrorAction SilentlyContinue -ErrorVariable dotNetError -Verb RunAs

Powershell is returning exit code too quickly

I have a script to uninstall McAfee antivirus and the agent associated with it.
The issue i'm having is that the script provides an exit code too early and doesn't continue through. If I run the script multiple times I get the desired result, but as we're trying to push it out via PDQ remotely, we need it to run through the script and only provide an exit code at the end of the script.
I'm a powershell novice so there's probably a much better and easier way to write this script but any advice would be greatly appreciated.
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x {CE15D1B6-19B6-4D4D-8F43-CF5D2C3356FF} REMOVE=ALL REBOOT=R /q"; Write-Host "Uninstalling McAfee VirusScan Enterprise 8.8..."
$version = (Get-WmiObject -class Win32_OperatingSystem).Caption
Write-Host "Detected OS as $version"
if ($version -like '*Windows 7*')
{
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files (x86)\McAfee\Common Framework\frminst.exe" -ArgumentList "/forceuninstall"
}
elseif ($version -like '*Windows 10*')
{
Write-Host "Unmanaging McAfee Agent for Uninstall Process.."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\maconfig.exe" -ArgumentList "/provision /unmanaged";
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\x86\frminst.exe" -ArgumentList "/forceuninstall"
}
else
{
exit
}
Start-Process reports a return code as soon as it starts the process indicating whether it was successful or not. Either use -wait to force the script to wait until it finishes or capture the output and proceed based on what the returnvalue is. See the docs for Start-Process

Installing AppFabric 1.1 with PowerShell DSC results in modal dialog error

I'm trying to automate the installation of AppFabric 1.1 on a Windows 2012 R2 server using PowerShell DSC. This is actually part of me trying to automate the SharePoint Foundation install and configuration, but AppFabric 1.1 is a pre-requisite. Below is a snippit from my DSC config script:
Script InstallSharePointPreRequisites
{
GetScript = { Return "InstallSharePointPreRequisites" }
TestScript = {$false}
SetScript = {
Start-Process -FilePath 'c:\temp\SharePoint\pre\MicrosoftIdentityExtensions-64.msi' -ArgumentList '/qn' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\setup_msipc_x64.msi' -ArgumentList '/qn' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\sqlncli.msi' -ArgumentList '/qn' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\Synchronization.msi' -ArgumentList '/qn' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\WcfDataServices.exe' -ArgumentList '/quiet' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\appfabric\setup.exe' -ArgumentList '/i cacheclient","cachingService","CacheAdmin /gac /l c:\temp\appfabric.log' -Wait | Write-verbose
Start-Process -FilePath 'c:\temp\SharePoint\pre\AppFabric1.1-RTM-KB2671763-x64-ENU.exe' -ArgumentList '/quiet' -Wait | Write-verbose
}
DependsOn = "[File]GetSharePointFiles"
}
I know....the "TestScript = $false" is bad form, but I'm just trying to get the install to run at this point. :)
Anyway, when the DSC run get to the appfabric\setup.exe it's throwing the following exception:
"{"Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application."}"
When I run the Start-Process line from a normal PS prompt it installs fine and doesn't show a visible modal dialog box. I've also tried using the AppFabric setup EXE with similar switches with the same result. I'm sort of at a loss here. Has anyone else been able to install AppFabric 1.1 using PowerShell DSC? Or SharePoint Foundation 2013 for that matter? If so, how? I haven't been able to find good documentation on this scenario yet.
Thanks,
A
I solved this problem. First, there was a typo in my script. The app fabric setup line had CachAdmin rather than CacheAdmin (was missing the 'e' in cache). It took me some time and writing it a few more times to figure that out. After setting that, it is installing fine. Darn, old eyes and fat fingers... Thanks for looking. :)
A