批处理文件中的 Powershell:错误和命令未执行

Posted

技术标签:

【中文标题】批处理文件中的 Powershell:错误和命令未执行【英文标题】:Powershell in Batch file: Errors and Commands not executing 【发布时间】:2020-08-13 21:14:30 【问题描述】:

您可以在下面找到我将使用的两个示例文本文件的内容,example1.txtobf_example1.txt。后者在文件末尾包含example1.txt的字符串,但之前有一些混淆字符串。

example1.txt:

adasdkasdaksdasdkjlasdjasndjasd.

obf_example1.txt:

ŠxpÃÒ²Ø-Gêÿ ój"f>ïí   H€À(ø4$/+#6Ni9Pvü¶ |CF CÀ¾ý~ª-°à9ÉOÿ V[o¦.E…-Š  ƒ9Ú\žê*D´ß()^“£¹ìÅjXÑÍ¥â(¨µ×d'«P|I*èSººº&)Ø|̉ òÔ®¥Ô$LÁ:9ŠLá¶nZÒبNÙÀØŒ‹0õ´Sék›áÇÉîÆbËF§BЄƒöZKaÒR ²°ÅšDn?+¶()IªP›$ÇEv©¡k€[ßè¨×q-Ëk!µTóPA²—: A ?ÉEEEGÐJúÌ©ÒWµHB¡aäXû|ÓË BPÁwr„Ûi¥åܺÈQ÷ORàSb,Šv¢D ,Žb’(2 öb¢wtKzíĦ#ï¯u©²Ù  aîR隬ëÌTbà÷¥3ÄtSGì´R$)X   Šù
'¹¨D³ÞeOK3!·‹¦cäиNÅô:Na1žAÇ1ø8 &Fuôë %¸T¯_òMå†C"ý¤F   ™º„Iµºí4Ü¡ˆc!ì•+3 ‰‹M K@JÁ«8¢bsL†!Ù“à­šn·öMå•Œ&ýèvÀ¨?¦hùÊò(É@Žf~5‰‘qØçþƒ‰Å²ÓÖÊJU•âNWÁ«L¼Y”$G¢ßè&§ÖÉØŒS‘WàË„°SØW Ð¨´_è%‚Å¢ø.ãÃð”#X^þ*1þ‚q85¡lÒ‚Ò>‘¸ÿ £ôQôz#ø¤ÎõÚªï|Xö%;åÍËûGú+îUƒö³‰›p    U±Ò ðtÜGÜÿ  ð,åXÿ k8È I”ÿ “½¿Ð`¨u5=SÓqyFÈ É8ôã¨ð£è6’H@lÄI10‚Ö§ÑdµÖ?t¡]D†9Zj,¥EɺÜEq¤@,ìn—¢º‚´€bc·ú¨Lû£ÿ Ó×ÿÙ||adasdkasdaksdasdkjlasdjasndjasd.

当我在批处理文件中为example.txt 运行以下 powershell 命令时,它可以工作,并且我得到了 example.txt 的输出:

@echo off
for /f "delims=" %%a in ('powershell Get-Content .\example.txt') do set _output=%%a
echo %_output%

adasdkasdaksdasdkjlasdjasndjasd

到目前为止还不错。

但是,当我为 obf_example1.txt 运行上述 powershell 命令时,它不起作用并且我收到以下错误消息:

'¹¨D³ÃzeOK3!·â?¹Â¦cäÃ?Â?¸Â?NÃ.ô:Na1žAÃ╬1ø8 
The command "FuôëÂ" is either misspelled or could not be found.
The command "ýèvÃ?¨?¦hùÃSÂ?ò" is either misspelled or could not be found.

为什么?没关系我想:因为我只对example1.txtobf_example1.txt中的最后一个n字符感兴趣,所以我的想法是提取最后一个n字符并检查我是否可以看到@987654336的输出@ 然后。为了检查我的想法是否有效,我对example1.txt 运行以下命令以获取最后 4 个字符作为示例:

@echo off
for /f "delims=" %%a in ('powershell $a=Get-Content .\example.txt; $a.substring^(0,$a.length-4^)') do set _output=%%a
echo.%_output%

但它并没有向我显示任何东西。 %_output% 似乎是空的。如何解决?并且固定版本是否也适用于obf_example1.txt,以便我在那里得到输出而不是上述错误消息?

【问题讨论】:

您的数据中有与号和管道。当你回显输出时,变量值首先被扩展,然后命令被执行。它看到 & 和 |作为命令参数。 真的有必要从cmd调用powershell吗?我建议坚持一个或另一个。 @Thomas :我无法在纯批处理中获得obf_example1.txt 的最后一个n 字符,我在尝试使用type 命令或echo 时总是出错回显混淆的文件。这就是我与 powershell 混合并使用 Get-Content 之类的原因。如果你能帮我做这件事,我将不胜感激。 @Stephan:不,echo "%_output%" 不起作用。 【参考方案1】:

显然,您要查找的那段文字在|| 后面。

使用 PowerShell,您可以轻松地使用

((Get-Content 'D:\Test\obf_example1.txt' -Raw) -split '\|\|')[-1]

返回

adasdkasdaksdasdkjlasdjasndjasd

这不是你想要的吗?

【讨论】:

很可能是的,但我需要将此命令包含在批处理文件中。尝试了for /f "delims=" %%a in ('powershell (Get-Content .\obf_example.txt -Raw) -split '\|\|')[1]') do set _output=%%a,然后用echo "%_output%" 输出它,它向我显示错误消息"-split" cannot be processed syntactically at this point. 你能帮我把你的命令包含在批处理文件格式中吗? 尝试给它一个绝对文件路径来读取。 PowerShell 的当前目录可能与 cmd 不同。但是,为什么要使用 cmd 来运行 PowerShell 而不是直接使用 PS 呢?如果必须,请在 cmd 中输入:powershell ((Get-Content 'D:\Test\obf_example1.txt' -Raw) -split '^\^|^\^|')[-1]。它将返回adasdkasdaksdasdkjlasdjasndjasd.您需要使用 ^ 以及拆分字符串中的反斜杠来转义管道字符。 我试过了,但它仍然显示-split" cannot be processed syntactically at this point。这就是我所做的:@echo off <new line> for /f "delims=" %%a in (powershell ((Get-Content '.\obf_example1.txt' -Raw) -split '^\^|^\^|')[-1]) do set _output=%%a <new line> echo.%_output%。如何解决这个问题?【参考方案2】:

以下内容可让我在|| 之后获得“明文”部分(来自您的示例):

for /f "delims=" %%a in (.\obf_example1.txt) do set "_output=%%a"
set _output
echo testing last 10: %_output:~-10%
set "_output=%_output:*||=%"
set _output
echo %_output%

(它可能不适用于文本文件的不同编码)

(考虑 Powershell - cmd 对行长有限制,很容易被淹没)

【讨论】:

感谢您的帮助,它成功了。是的,您是对的,obf_example1.txt 只是一个示例,它不适用于更大的示例。有没有机会处理一个更大的例子?我的问题的背景是我想批量提取 jpg 文件中的隐藏文本。隐藏文本通常位于 jpg 文件的末尾,比我在示例 obf_example1.txt 中提供的要大得多。 您无法克服行数限制,但如果您能够插入 CRLF(而不是 ||),它就是 new 行。然后我的第一行应该能够提取想要的字符串(“最后一行”),无论文件有多大。 感谢斯蒂芬的支持。我将|| 改为CRLF。我的批处理文件现在看起来像这样:@echo off, for /f "delims=" %%a in (.\image.jpg) do set "_output=%%a" echo %_output:~-3% --> 它打印出 ~-3。知道为什么它不显示最后 3 行吗? 当变量为空时,通常会发生这种情况。我上面的代码是否也会发生这种情况(无需修改或将其插入其他代码)? set _output 说什么?【参考方案3】:

如果您确实从显然不是文本文件的内容中获取文本字符,您可以尝试读取最后 4 个字节。 (我猜它是隐藏在二进制文件中的文本,可能是图形文件).

@For /F Delims^=^ EOL^= %%G In (
 '%__AppDir__%WindowsPowerShell\v1.0\powershell.exe  -NoP^
 "$f=[IO.File]::OpenRead('C:\Users\Ferit\Desktop\obf_example1.txt');"^
 "$f.Seek(-4,[System.IO.SeekOrigin]::End)|Out-Null;$buffer=new-object Byte[] 4;"^
 "$f.Read($buffer,0,4)|Out-Null;$f.Close();"^
 "[System.Text.Encoding]::UTF8.GetString($buffer)"')Do @Set "_output=%%G"
@Set _output 2>NUL&&Pause

不要忘记修改文本文件路径,(在线3,以及4 的三个实例,如果你想要更多或更少的字节。包含最后一行只是为了向您显示输出,(您显然会用自己的代码替换它)

【讨论】:

帮助了 - 非常感谢!我需要您帮助的最后一件事:如何将最后一个 n 字节放入批处理变量(没有字符串 _output)以便在我的批处理中进一步操作? 我已经解释过,包含最后一行只是为了向您显示输出,您可以在自己的代码中使用%_output%,无论您喜欢什么。现在,如果您愿意,可以使用 @If Defined _output Echo %_output%&Pause 作为最后一行的替换。

以上是关于批处理文件中的 Powershell:错误和命令未执行的主要内容,如果未能解决你的问题,请参考以下文章

带有 Git 命令错误处理的 Powershell - 在来自外部程序的非零退出代码时自动中止

尝试从批处理文件运行 PowerShell 命令时出现错误

如何从PowerShell /批处理文件中的网络路径运行命令

如何从批处理文件执行 PowerShell 命令?

我如何使用需要从命令提示符/批处理文件引用的参数调用PowerShell Start-Process命令?

powershell 使用多个命令或变量使用Try / Catch进行Powershell错误处理