Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

python - Installing all .msi files within a folder

I'm trying to write a powershell script that I am kicking off from a python script that will allow me to go through and install each .msi file that is contained within a certain folder.

This is what I have so far:

$msiFiles = Get-ChildItem -Path "***PATH TO FOLDER***" -Recurse -Include *.msi

foreach($file in $msiFiles)
{

    Write-Host "$file is being installed"
    Start-Process "msiexec.exe" -arg "/I $file /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait
    Write-Host "$file is finished being installed"


}

I want to install these msi's in silent mode so I don't see or need ant GUI interaction. When it goes to install the msi's I get a pop up from the installer with all the possible commands to use to install stuff, but it doesn't actually install it.

What is the proper command to install these in silent mode?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Generally, if invoking msiexec does nothing but show a dialog describing the command-line syntax, the implication is that there's a syntax problem.

The likely source of the syntax error is that the "..." string you're using as the -arg argument (full name: -Args or -ArgumentList) has $file embedded in it without embedded quoting:

That is, if the value of $file has embedded spaces, for instance (e.g., C:Msi Installersfoo.msi), the resulting msiexec command will be syntactically invalid, because the space-separated tokens of the path are each considered an argument.

Bill_Stewart's helpful answer shows you how to use embedded quoting around $file to solve this problem, by enclosing it in `" (` is PowerShell's escape character).

If you were to stick with passing the arguments as a single string, you would use:

Start-Process msiexec.exe -Args "/I `"$file`" /qb ADDLOCAL=ALL ALLUSERS=TRUE" -Wait

Arguably, however, it's cleaner not to pass a single, command-line-like string as the only argument, but to instead pass the arguments as elements of an array, which is indeed what -ArgumentList / -Args was designed to accept (its parameter type is [string[]]):

Start-Process msiexec.exe -Args /I, `"$file`", /qb, ADDLOCAL=ALL, ALLUSERS=TRUE -Wait

Note how $file is still passed with embedded quoting, which is unfortunately required due to a bug in Start-Process (as of Windows PowerShell v5.1 / PowerShell Core v7.1); it looks like this bug will not get fixed, however, but the linked GitHub report suggests introducing a new
-ArgumentArray parameter with the correct behavior.


You may alternatively build up the array of arguments in advance; note how this is done in expression mode (with syntax more like regular programming languages), so the array elements all require quoting; also note how I'm using single quotes to define literal arguments:

# Create the array of arguments to pass to msiexec
$msiArgs = 
  '/I',
  "`"$file`"",      #`# !! enclosing in `"...`" is needed due to the bug mentioned above
  '/qb',
  '/ADDLOCAL=ALL',
  'ALLUSERS=TRUE'

Start-Process msiexec.exe -Args $msiArgs -Wait      

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...