Invoke mage using Powershell 2.0 and invoke operator (i.e. &)
Asked Answered
S

2

6

I would like to use Powershell 2.0 to script the creation of an application manifest using Microsoft's Manifest Generation and Editing tool (mage). Specifically, I would like to be able to pass dynamically specified parameter values to the mage command (e.g. read from xml or some other source).

Although I can accomplish this using invoke-expression, I would prefer to avoid it is regarded as a less secure option (i.e. vulnerable to "powershell injection attacks").

Here is what I know.

This succeeds with the message "application.exe.manifest successfully created":

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -New Application

This does not succeed with the message "The first argument must be one of the following: -New, -Update, -Sign" (which is a mage, not powershell, error message):

$params = "-New Application"

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

How can I pass the $params value to the mage command so it is successfully interpreted by mage?

Separatrix answered 24/11, 2010 at 19:56 Comment(1)
Really "PowerShell injection attacks," come on. What kind of PowerShell administration scripts are you writing that would be executed by anyone other an admin.Scrapple
S
6

It is easy with $params defined as an array, one parameter per array item:

# define $params as an array
$params = "-New", "Application"

# and pass this array in, just as you tried before
& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

Ditto with $params dynamically built in a few steps:

$params = @()
...
$params += '-New'
...
$params += 'Application'
...
& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" $params

This way is often overlooked but it is very handy, it allows easy dynamic composition of complex command lines for native applications.

P.S. And we do not have to care of spaces in parameter values, we use values in the parameter array as they are, no extra " needed.

Steric answered 25/11, 2010 at 3:19 Comment(0)
A
3

Start-Process

There are more ways how to do that. First is via Start-Process:

$p = '-h 3 google.com'
start-process tracert -arg $p

New window pops up. If you would like to run the process inside the console, just run it with -NoNewWindow

$p = '-h 3 google.com'
start-process tracert -arg $p -nonew

$params = "-New Application"
start-process "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -arg $params -nonew

Invoke-Expression

Invoke-Expression could help as well. But it is tricky, because you have spaces in path to your executable. This works, because there is no space in the path:

$p = '-h 3 google.com'
invoke-expression "tracert $p"

But if there is a space, you need to use & inside:

$params = "-New Application"
Invoke-Expression "& ""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"" $params"

Note that "& ""C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe"" $params" is expanded to this:

& "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\mage.exe" -New Application

which is what you wanted. But if there is again a space in one of the parameters, then again.. you need to quote it:

$file1 = 'c:\test path\file1.txt'
$file2 = 'c:\test path\file2.txt'
$params = """$file1"" ""$file2"""
Invoke-Expression "& someexecutable $params"

The parsing is quite tricky :|

Alimony answered 24/11, 2010 at 21:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.