执行“现实生活"Powershell中变量的命令行 [英] Execute "real life" command line from variable in Powershell

查看:39
本文介绍了执行“现实生活"Powershell中变量的命令行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,当我从注册表中读取一些卸载字符串时,例如 "C:\Program Files (x86)\Opera\Launcher.exe"/uninstall 我可以将其复制到 Powershell 命令行,以调用运算符作为前缀并执行它.

When I for example read some uninstall string from the registry like "C:\Program Files (x86)\Opera\Launcher.exe" /uninstall I can copy it to the Powershell command line, prefix it with the call operator and execute it.

& "C:\Program Files (x86)\Opera\Launcher.exe" /uninstall

但是

$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
& $var

不起作用.我当然可以说

does not work. Of course I can just say

cmd /c $var

但是如果没有额外的 cmd 进程,真的没有办法做到这一点吗?

But is there really no way to do this without an additional cmd process?

推荐答案

为了使用 &(如果命令名称/路径是 不带引号的文字),命令名称/路径必须与其参数分开传递.
在调用外部程序时,您可以将这些参数作为数组传递.

In order to use & (or direct invocation if the command name/path is an unquoted literal), the command name/path must be passed separately from its arguments.
When invoking an external program, you may pass these arguments as an array.

下面的解决方案利用 PowerShell 自己的 Write-Output cmdlet 结合安全的 Invoke-Expression[1] 调用以便将字符串解析为其组成参数.

The solution below leverages PowerShell's own Write-Output cmdlet in combination with a - safe - invocation of Invoke-Expression[1] in order to parse the string into its constituent arguments.

# Gets the arguments embedded in the specified string as an array of literal tokens 
# (applies no interpolation). 
# Note the assumption is that the input string contains no NUL characters 
# (characters whose code point is `0x0`) - which should be a safe assumption
# Example: 
#   get-EmbeddedArguments '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'
# yields array @( 'C:\Program Files (x86)\Opera\Launcher.exe', '/uninstall' )
function get-EmbeddedArguments ([string] $String) {
  (Invoke-Expression "Write-Output -- $($String -replace '\$', "`0")") -replace "`0", '$'            #"
}

# Input string.
$var = '"C:\Program Files (x86)\Opera\Launcher.exe" /uninstall'

# Extract the command name (program path) and arguments.
# Note the destructuring assignment that stores the return array's 1st element
# in $exe, and collects the remaining elements, if any, in $exeArgs.
$exe, $exeArgs = get-EmbeddedArguments $var

# Use & to invoke the command (name / program path) ($exe) and pass
# it all arguments as an array.
& $exe $exeArgs

<小时>

[1] 正如比尔指出的那样,Invoke-Expression通常应该避免,因为它会带来安全风险,并且通常有更安全、更强大的选项可用.然而,这里没有简单的替代方案,通过临时替换输入字符串中的所有$实例来避免安全风险,以防止意外的字符串插值.上>


[1] Invoke-Expression should generally be avoided, as Bill points out, because it presents a security risk and there are typically safer and more robust options available. Here, however, there is no simple alternative, and the security risk is avoided by temporarily replacing all $ instances in the input string so as to prevent unintended string interpolation.

这篇关于执行“现实生活"Powershell中变量的命令行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆