2

I'm having trouble with a piece of code that I'm trying to get working in regards to executing an MSI application. I need to pass credentials that are stored in a variable and then pass those credentials through a "runas" to the MSI package so that it is installed with the escalated credentials I pass to the application.

Here is the section of code I am having trouble with.

if($filter -like "*.msi")
{
    Start-Process -FilePath "msiexec $FullFilePath" -Credential $adminCreds -ArgumentList "-noprofile -command &{Start-Process /i $FullFilePath /passive /norestart -verb runas}" -Wait -WorkingDirectory $path
    exit
}

My variables are as follows:

$filter = Get-ChildItem $path -Filter $($installer[$i]) -name
$FullFilePath = $path + "\" + $filter
$path = Split-Path $script:MyInvocation.MyCommand.Path

Thanks in advance!

Koobah84
  • 185
  • 2
  • 12
  • Thank you, but I am doing that if you look at my small code block. I think the way I'm passing the arguments; there is a syntax error that I'm unsure of because it just closes on me. I see a warning for a split second but can't make out what it says. – Koobah84 Jun 20 '18 at 18:13
  • I think you just need to take the `-verb runas` bit out of the script block: `Start-Process -FilePath "msiexec $FullFilePath" -Credential $adminCreds -ArgumentList "-noprofile -command &{Start-Process /i $FullFilePath /passive /norestart }" -WorkingDirectory $path -verb runas` – trebleCode Jun 20 '18 at 18:20
  • Unfortunately I'm getting the same thing. I got a bit more information. I ended up recording my screen while it flashed up with the warning message to see what it's saying, and here is what the message says: "Warning: This command cannot be executed due to the error: The system cannot find the file specified." I'm not sure why it's saying that because when I print the variables out right above the "start-process" everything is correct. The path prints to the path of the files and the filter prints the filename and extension and the FullFilePath prints the full file path. – Koobah84 Jun 20 '18 at 18:54
  • I'm convinced I'm not passing some variables in correctly, but I can't seem to figure out why. I believe it's the Start-Process -FilePath "msiexec $FullFilePath" – Koobah84 Jun 20 '18 at 18:56
  • This module for MSI files I've found to be very helpful. You might see if it has what you require: https://github.com/heaths/psmsi – Thom Schumacher Jun 20 '18 at 19:14
  • I appreciate it, but I'm not sure that will be an option because that would mean that I need to install this module on every machine that I execute my script on. I'm trying to make this as "hassle-free" as possible for our users. I'm not sure why this is as difficult as it is. It should be fairly trivial I would imagine. I appreciate all the help though! Thank you. Still trying to find a solution to this. – Koobah84 Jun 20 '18 at 19:34
  • 1
    `-FilePath` accepts an executable name / file path _only_, not also argument, so something like `"msiexec $FullFilePath"` cannot work. Even if you fixed that, you're passing arguments meant for _PowerShell_ via `-ArgumentList`, which `msiexec` wouldn't know how to interpret. – mklement0 Jun 21 '18 at 01:51
  • @mklement0 So is what you're saying; what I'm trying to do isn't possible? I tried just msiexec alone, but that just brought up the "msiexec properties" dialog for me., that's why I tried passing the file afterwards. If it is possible, could you please assist with this? Thanks in advance! – Koobah84 Jun 21 '18 at 14:40
  • If the need to run elevated _with specific credentials_ weren't in the picture, you'd probably want something like `Start-Process -Credential $adminCreds -FilePath msiexec -ArgumentList "/i \`"$FullFilePath\`" /passive /norestart" -WorkingDirectory $path`. You can only run elevated with the _current-user_ credentials (implicitly, with `-Verb RunAs`). If you use `-Credential` to run as a _different user_, you cannot also use `-Verb RunAs`. This scenario requires a tricky _nested_ `Start-Process` call - see https://stackoverflow.com/a/43281908/45375 – mklement0 Jun 21 '18 at 14:58
  • Thank you, I think that what I need to do, but I was still getting errors. I ended up working around my issue by going about it a different way. When I check if the file is a *.msi, I wrote a custom batch script that I will launch to execute the parameters for the MSI file. And I can still pass the credentials like I have it on the working start-process. for /f "tokens=1* delims=\" %%A in ( 'forfiles /s /m *.msi /c "cmd /c echo @relpath"' ) do for %%F in (^"%%B) do (set myapp=%%~F) ::Launch our installer start /w "" msiexec /i "%~dp0%myapp%" /passive /norestart – Koobah84 Jun 21 '18 at 16:13
  • @Koobah84: I encourage you to post that as an answer (and later self-accept) to benefit future readers, though I suggest also revising your question to make your original problem clearer. – mklement0 Jun 21 '18 at 20:29
  • @mklement0 yes, I will do that, I'm still revising my code a bit and adding on to it, but I will post it once I finish. What do you think would have been a better way for me to post my question to make it more clear? – Koobah84 Jun 21 '18 at 20:39
  • @Koobah84: I suggest focusing on just the part that fails, and describing _what_ you're trying to do separately from _how_ you're trying to do it. – mklement0 Jun 21 '18 at 20:41
  • 1
    @mklement0 I revised my question, hopefully it makes more sense now and I also posted the answer. Hope this helps someone. – Koobah84 Jun 22 '18 at 14:55
  • Thank you, I appreciate it. – mklement0 Jun 22 '18 at 15:05

1 Answers1

1

To get around my issue I created a code block that exports a temporary batch script to look for any msi application within the folder that the script is exectuted from. Once the script is ran, and application is installed the script deletes itself. I pass the credentials through the batch script instead of the MSI application directly, but this works properly for my needs. Here are the changes to my script.

$msiBatch = @"
@echo off
pushd "%~dp0"

::Get the MSI file name to install
for /f "tokens=1* delims=\" %%A in ( 'forfiles /s /m *.msi /c "cmd /c echo @relpath"' ) do for %%F in (^"%%B) do (set myapp=%%~F)

::Launch our installer
start /w "" msiexec /i "%~dp0%myapp%" /passive /norestart

::Self Delete
DEL "%~f0"
"@

Here is how it is ran:

if($filter -like "*.msi")
{
    $installPath = $path + "\msiInstaller.bat"
    $msiBatch | Out-File -Encoding Ascii -append $installPath
    $FullFilePath = $installPath

}

Start-Process -FilePath powershell.exe -Credential $adminCreds -NoNewWindow -ArgumentList "-noprofile -command &{Start-Process $FullFilePath -verb runas}" -Wait -WorkingDirectory $path        
break
Koobah84
  • 185
  • 2
  • 12