0

I am trying to start an installation via msiexec. The following parameters are available and if I use this on that way, the installation will be correct. This is the example from the vendor:

msiexec.exe /i ApexOne.msi MyServer="win2016-x64:8080|4343" MyDomain="Workgroup\Subdomain" /Lv+ "c:\temp\MSI.log"

This is my code:

Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList @('/i ".\agent.msi" MyServer="servername:8080|4344" MyDomain="999-Test"') -wait

But for automation I have to use the variable $domain to generate the correct domain. I tried different codes, but nothing helped:

This is the code for my variable $domain $domain='999-Test'

Example: Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList @('/i ".\agent.msi" MyServer="servername:8080|4344" MyDomain=**"$domain"'**) -wait

I tried that also, but I don't know how to fix this failure. I think the interpration of the variable is false, but I can not fix it.

-ArgumentList @('/i ".\agent.msi"','MyServer="servername:8080|4344"','MyDomain='$domain'')

Maybe someone can help me to fix this error?

Xiffus
  • 1
  • 1
  • 1
  • Single quotes treat the string as a literal string without doing interpolation (variable and expression substitution). You'll need to replace the outer ```'``` with ```"``` - so ```"MyDomain='$domain'"```. Note that you'd also need to escape any double-quotes *inside* your string with a backtick if there were any (e.g. ```"MyDomain=`"$domain`""```). – mclayton Jun 29 '21 at 13:39
  • I used this one, but it does not work: ```@('/i ".\agent.msi" MyServer="servername:8080|4344" MyDomain=`"$domain`"') -wait``` – Xiffus Jun 29 '21 at 14:21
  • With this one the install does not begin, there are missing the terminator ```'```. I: So I tried this one: ``Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList @('/i ".\agent_vorlage.msi" MyServer="av01.badencloud.de:8080|4344" "MyDomain=`"$domain`""') -wait``` – Xiffus Jun 29 '21 at 14:25
  • 1
    You're mixing and mis-matching single and double quotes a little bit - that won't work. Try ```-ArgumentList @("/i `".\agent_vorlage.msi`" MyServer=`"av01.badencloud.de:8080|4344`" MyDomain=`"$domain`"")```. The whole string is surrounded by double-quotes ```"``` and the quotes *inside* are escaped with ```backtick double-quote``` - i.e. `" – mclayton Jun 29 '21 at 14:55
  • Just skim reading today, [maybe have a look here](https://stackoverflow.com/a/51460517/129130). – Stein Åsmul Jun 29 '21 at 15:36

2 Answers2

1

The msiexec.exe program seems to have some peculiarities in its command-line parser. I recommend an approach like the following:

$msiFileName = ".\agent.msi"
$myServer = "servername:8080|4344"
$myDomain = "999-Test"
$argumentList = @(
  '/i'
  '"{0}"' -f $msiFileName
  'MyServer="{0}"' -f $myServer
  'MyDomain="{0}"' -f $myDomain
)
$startArgs = @{
  "FilePath" = "msiexec.exe"
  "ArgumentList" = $argumentList
  "Wait" = $true
}
Start-Process @startArgs

This example creates an array of string arguments for the -ArgumentList parameter using single quotes (') and string formatting (-f). In the above example, each element in the $argumentList array is a separate string and contains the following elements:

/i
".\agent.msi"
MyServer="servername:8080|4344"
MyDomain="999-Test"

(Note that in the content of the array we are preserving the " characters.)

Next, we create a hashtable for the Start-Process cmdlet and call it using the @ operator. (Creating a hashtable for a cmdlet's parameters is known as splatting and is a convenient way to build a large number of parameters for a cmdlet in a more readable and maintainable way.)

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
1
  • Due to a long-standing bug in Start-Process, it is actually preferable to always pass all arguments for the target process encoded in a single string passed to -ArgumentList (-Args), rather than individually, as elements of an array - see this answer.

  • Doing so requires two things:

    • To incorporate variable values, you must use an expandable string, i.e. a double-quoted string, "...".

    • Any embedded quoting inside this overall "..." string must itself use double-quoting only, as CLIs on Windows generally only understand " (double quotes) and not also ' (single quotes) to have syntactic function. To embed " characters in a "..." string, escape them as `" (or as ""; inside a '...' string, you needn't escape them at all).

While this is somewhat cumbersome, it does have the advantage of allowing you to directly control the exact command line that the target process will see - and that enables you satisfy msiexec's picky syntax requirements where PROP="value with spaces" must be passed exactly with this value-only double-quoting (whereas PowerShell - justifiably - turns this argument into "PROP=value with spaces" behind the scenes, when it - of necessity - re-quotes arguments to synthesize the actual command line to use).

Therefore, use the following (using positional argument binding to -FilePath and -ArgumentList, respectively):

Start-Process -Wait $env:systemroot\system32\msiexec.exe "/i .\agent.msi MyServer=`"servername:8080|4344`" MyDomain=`"999-Test`""

Note: Strictly speaking, you do not need the embedded `"...`" quoting in your case, given that your property values have no embedded spaces.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Thanks for these Powershell hints on msiexec.exe issues. I added a couple of your answers to my [experimental deployment information grid](https://installdude.com/jumpgate.php) - so I can find them easily. – Stein Åsmul Jun 29 '21 at 23:00
  • I'm glad to hear it, @SteinÅsmul - looks like a handy collection of information. – mklement0 Jun 29 '21 at 23:15
  • 1
    It is still quite experimental, but it helps quite a bit now and then - especially when you are on a machine without all your other tools available. – Stein Åsmul Jun 29 '21 at 23:21