Reputation: 11
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?
Upvotes: 1
Views: 5516
Reputation: 24545
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.)
Upvotes: 2
Reputation: 437688
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.
Upvotes: 1