【问题标题】:How to escape unknown string and pass it to native command如何转义未知字符串并将其传递给本机命令
【发布时间】:2019-11-26 17:30:52
【问题描述】:

考虑以下示例(忽略安全隐患):

$pass = (Read-Host)
&net user testuser $pass /add

现在如果有人输入如下内容:

a1'"\'"\'"\

这行不通。我收到错误消息说这样的用户不存在。

我尝试使用[Regex]::Escape(),但它不起作用。我尝试将$pass 放在双引号中,但它不起作用。我尝试像这样使用Start-Process

Start-Process -Wait net -ArgumentList @("user", "testuser", $pass, "/add")

但它不起作用。我尝试运行net 命令而不使用前导&,但它不起作用。

我读过大约。 StackOverflow 上的 30 个问题在询问“powershell 转义命令参数”(显示的 197 个)后显示,但没有什么比我需要的更接近。也许我错过了什么,但 197 个问题很多

编辑:

好的,所以我找到了这个:

https://github.com/PowerShell/PowerShell/issues/1995

如果不编写自定义函数并知道调用的是本机二进制文件还是 cmdlet 或其他东西,似乎几乎不可能做到正确。从来没有比说“我什至没有”更合适的时刻了。

编辑 2: 关于这种情况(用户创建和正确引用密码)Ansgar Wiechers 提供的链接显示了另一种创建本地用户帐户的方法,非常感谢。这并不意味着引用问题就消失了,只是意味着需要这样引用的情况少了一种。

【问题讨论】:

  • 这是X-Y problem的经典案例。与其尝试转义用于net user 的任意密码,不如研究如何在 PowerShell 中正确创建本地用户帐户。 net user 是一种方法,但还有其他方法更适合处理任意密码字符串。 Related.
  • @AnsgarWiechers:虽然学习 PowerShell 原生的做事方式总是有益的——因为它们通常提供描述性、标准化的语法和更强大的功能——但 PowerShell 对外部参数的错误引用没有任何借口程序:调用外部可执行文件——在这种情况下是net.exe——是shell的核心任务之一,鉴于PowerShell [Core]是跨平台的,考虑到类Unix平台(不像Windows),这一点尤其重要拥有大量强大且高性能的实用程序(外部可执行文件)。
  • @AnsgarWiechers 引用:“考虑以下示例(忽略安全隐患):”。此外,如果不安装特性和/或功能,我找不到任何其他方法来创建用户。例如“New-LocalUser”在 Windows Server 2014 上不起作用,我必须支持它。就这样。
  • @AnsgarWiechers 您链接到的问题将net user 列为投票最多的答案。 New-LocalUser 是 PS 5.1,我充其量是 4.0,3.5 作为基线。提到的模块Carbon 必须单独安装,我不能这样做。所以看来这不是X-Y problem的经典案例,我正在尝试做X,但除了做Y没有办法。
  • @mklement0 我的目的不是为引用地狱找借口。但是,我一直在想“使用有效的方法”。如果有其他(可行的)方法可以实现特定目标:不要浪费时间解决一种特定方法的局限性。

标签: powershell cmd escaping quoting


【解决方案1】:

注意:鉴于下面详述的引用所面临的挑战,请考虑 solving this problem differently,它最终可能会提供更大的灵活性和更好的安全性。
但是,了解 PowerShell 的一般引用挑战很重要,尤其是因为可能并不总是有替代调用外部程序的方法。


虽然没有必要,但不幸的现实是 PowerShell 需要手动转义嵌入式 " 字符。就像\" 向外部程序传递参数时一样,这是this GitHub issue 中总结的一个长期存在的问题。

# Sample password
$pass = @'
a1'"\'"\'"\
'@

#"# Escape all embedded " chars. as \"
net user testuser ($pass -replace '"', '\"') /add

至于你尝试了什么

我尝试使用[Regex]::Escape()

您正在尝试传递存储在变量逐字中的密码,因此正则表达式在这里不起作用。

我尝试将 $pass 放在双引号中

这没有任何效果,因为$pass 是以字符串变量开头(字符串是Read-Host 返回的内容)。

我尝试使用Start-Process

Start-Process 绝不是用于同步调用控制台应用程序的正确工具 - 请参阅https://stackoverflow.com/a/51334633/45375

此外,Start-Process 有自己的报价挑战 - 请参阅 this GitHub issue

【讨论】:

  • 我尝试的是我绝望的尝试。实际上,我只对Start-Process 抱有任何希望,并认为可能由于Powershell 的特性,其他方法会起作用。至于您链接的问题,这与我添加的问题相似,基本上意味着由于Windows的参数是如何解析的以及开发人员需要保持向后兼容性,所以没有办法做到这一点对我>。我不知道他们为什么不提供任何内置(或任何其他似乎)模块来启动外部工具 - 如果您问我,执行外部程序基本上就是 shell 的用途。
猜你喜欢
  • 2021-08-30
  • 2019-06-04
  • 1970-01-01
  • 1970-01-01
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多