CMD powershell 命令不允许管道
CMD powershell command not allowing pipe
我试图让 SQL 使用 xp_cmdshell 执行一些 powershell 命令,这一直有效,但是我 运行 遇到了一个不寻常的问题。当我尝试使用管道时,它无法识别管道后的命令。我从标准 cmd 行尝试了此操作,可以确认会发生同样的问题。这是我正在使用的命令:
powershell.exe -command get-eventlog -Newest 10 -LogName Application -Before "2018-04-18T22:02:23" -After "2018-04-17T22:02:23" -computername dk01sv1115 | Select Message
当我在最后使用命令而不使用 | Select Message
时,它可以正常工作。问题是我没有收到完整的事件消息,我尝试使用 Select 和 Format 函数来尝试获取完整的详细信息,但管道似乎是问题所在。如果您在启动 powershell 后 运行 使用相同的命令(IE 运行 powershell.exe 然后 运行 命令)它可以正常工作,但是当您使用 SQL 到 运行 powershell.exe 作为 SQL 中的单独一行,它 运行 无限期地存在。示例 SQL:
Declare @command nvarchar(1000),@computername nvarchar(1000)
Set @computername = 'test'
Set @command = 'powershell.exe
get-eventlog -Newest 10 -LogName Application -Before "' + REPLACE(Convert(VARCHAR(255),GETDATE(),120),' ','T') +'" -After "' + REPLACE(Convert(varchar(255),DateAdd(dd,-1,GETDATE()),120),' ','T') + '" -computername ' + @computername + '
exit'
exec xp_cmdshell @command
| Select Message
部分由 cmd.exe
解释,而不是 PowerShell,因为管道符号 (|
) 在 cmd.exe
中也很特殊(大致相同意义),而你还没有将它包含在 "..."
.
中
从 cmd.exe
调用 PowerShell 的最佳方法是 将整个 PowerShell 命令作为单个双引号字符串("..."
) 到 -Command
参数:
powershell.exe -command "get-eventlog -Newest 10 -LogName Application -Before 2018-04-18T22:02:23 -After 2018-04-17T22:02:23 -computername dk01sv1115 | Select Message"
关于嵌入式引用的提示:
要引用 文字 ,您可以在整个 "..."
字符串中使用 '...'
。
- 请注意,原始命令中引用的值实际上不需要引用(例如,
"2018-04-18T22:02:23"
),因此我在我的重新表述中使用了它们 未引用 .
如果您需要嵌入 "
个字符,请使用 \"
(原文如此 - 尽管 PowerShell- 内部 它是 `
作为转义字符)。
如果您使用 "PowerShell -command" 形式,则将复杂命令放在引号或花括号中。
更新:
通过 Invoke-SQLCommand 添加 ^ 转义字符:
Invoke-Sqlcmd -ServerInstance ECS-DCTS05 -Database Test -Query "xp_cmdshell 'powershell -command dir c:\ ^| format-list'"
这适用于从 cmd.exe 开始的各个地方:
powershell -noprofile -command "get-childitem | format-list" # quoted
这不使用格式列表:
powershell -noprofile -command get-childitem | format-list # no quotes/braces
添加:
实际上,以下命令在我的 Win7 PowerShell 5.1 机器上都按预期工作:
开始搜索或WinKey+运行:
cmd /k powershell -noprofile -command "get-childitem | format-table"
或从打开的 cmd 提示符:
powershell -noprofile -command "get-childitem | format-list"
powershell -noprofile -command "get-childitem | format-table"
在每种情况下,格式命令字都符合预期。
如果您在引用时遇到问题,那么引号外的 CMD 转义符是 ^,因此有时在管道前加上 ^ 将有助于 Cmd.exe(例如,在 cmd.exe 中用于 /f 。 ..in ("command here with ^| pipe") do ... 语句。
也是:
powershell -noprofile -command "get-childitem | ForEach-Object FullName"
这证明 PowerShell 是 运行 管道的第二个元素。
已编辑:这也有效,但作为仅在 PowerShell 中提及的评论,因为 CMD 不理解大括号:
powershell -noprofile -command { get-childitem | format-list } # curly braces added
我试图让 SQL 使用 xp_cmdshell 执行一些 powershell 命令,这一直有效,但是我 运行 遇到了一个不寻常的问题。当我尝试使用管道时,它无法识别管道后的命令。我从标准 cmd 行尝试了此操作,可以确认会发生同样的问题。这是我正在使用的命令:
powershell.exe -command get-eventlog -Newest 10 -LogName Application -Before "2018-04-18T22:02:23" -After "2018-04-17T22:02:23" -computername dk01sv1115 | Select Message
当我在最后使用命令而不使用 | Select Message
时,它可以正常工作。问题是我没有收到完整的事件消息,我尝试使用 Select 和 Format 函数来尝试获取完整的详细信息,但管道似乎是问题所在。如果您在启动 powershell 后 运行 使用相同的命令(IE 运行 powershell.exe 然后 运行 命令)它可以正常工作,但是当您使用 SQL 到 运行 powershell.exe 作为 SQL 中的单独一行,它 运行 无限期地存在。示例 SQL:
Declare @command nvarchar(1000),@computername nvarchar(1000)
Set @computername = 'test'
Set @command = 'powershell.exe
get-eventlog -Newest 10 -LogName Application -Before "' + REPLACE(Convert(VARCHAR(255),GETDATE(),120),' ','T') +'" -After "' + REPLACE(Convert(varchar(255),DateAdd(dd,-1,GETDATE()),120),' ','T') + '" -computername ' + @computername + '
exit'
exec xp_cmdshell @command
| Select Message
部分由 cmd.exe
解释,而不是 PowerShell,因为管道符号 (|
) 在 cmd.exe
中也很特殊(大致相同意义),而你还没有将它包含在 "..."
.
从 cmd.exe
调用 PowerShell 的最佳方法是 将整个 PowerShell 命令作为单个双引号字符串("..."
) 到 -Command
参数:
powershell.exe -command "get-eventlog -Newest 10 -LogName Application -Before 2018-04-18T22:02:23 -After 2018-04-17T22:02:23 -computername dk01sv1115 | Select Message"
关于嵌入式引用的提示:
要引用 文字 ,您可以在整个
"..."
字符串中使用'...'
。- 请注意,原始命令中引用的值实际上不需要引用(例如,
"2018-04-18T22:02:23"
),因此我在我的重新表述中使用了它们 未引用 .
- 请注意,原始命令中引用的值实际上不需要引用(例如,
如果您需要嵌入
"
个字符,请使用\"
(原文如此 - 尽管 PowerShell- 内部 它是`
作为转义字符)。
如果您使用 "PowerShell -command" 形式,则将复杂命令放在引号或花括号中。
更新: 通过 Invoke-SQLCommand 添加 ^ 转义字符:
Invoke-Sqlcmd -ServerInstance ECS-DCTS05 -Database Test -Query "xp_cmdshell 'powershell -command dir c:\ ^| format-list'"
这适用于从 cmd.exe 开始的各个地方:
powershell -noprofile -command "get-childitem | format-list" # quoted
这不使用格式列表:
powershell -noprofile -command get-childitem | format-list # no quotes/braces
添加: 实际上,以下命令在我的 Win7 PowerShell 5.1 机器上都按预期工作:
开始搜索或WinKey+运行: cmd /k powershell -noprofile -command "get-childitem | format-table"
或从打开的 cmd 提示符: powershell -noprofile -command "get-childitem | format-list" powershell -noprofile -command "get-childitem | format-table"
在每种情况下,格式命令字都符合预期。
如果您在引用时遇到问题,那么引号外的 CMD 转义符是 ^,因此有时在管道前加上 ^ 将有助于 Cmd.exe(例如,在 cmd.exe 中用于 /f 。 ..in ("command here with ^| pipe") do ... 语句。
也是: powershell -noprofile -command "get-childitem | ForEach-Object FullName"
这证明 PowerShell 是 运行 管道的第二个元素。
已编辑:这也有效,但作为仅在 PowerShell 中提及的评论,因为 CMD 不理解大括号:
powershell -noprofile -command { get-childitem | format-list } # curly braces added