CMD powershell 命令不允许管道

Jeb*_*buz 2 sql-server powershell cmd command-line-interface xp-cmdshell

我试图让 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
Run Code Online (Sandbox Code Playgroud)

当我使用命令而不使用| Select Message最后时,它可以正常工作。问题是我没有得到完整的事件消息,我尝试使用 Select 和 Format 函数尝试获取完整的详细信息,但管道似乎是问题所在。如果您在启动 powershell 后运行相同的命令(即运行 powershell.exe 然后运行该命令),它可以正常工作,但是当您使用 SQL 作为 SQL 中的单独行运行 powershell.exe 时,它​​会无限期地运行。示例 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 
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 5

| Select Message部分由 解释cmd.exe,而不是 PowerShell,因为管道符号 ( |) 也是特殊的cmd.exe(具有大致相同的含义),并且您没有将其包含在"...".

调用 PowerShellcmd.exe的最佳方法是将整个 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"
Run Code Online (Sandbox Code Playgroud)

关于嵌入引用的提示:

  • 要引用文字,您可以'...'在整个"..."字符串中使用。

    • 请注意,在您的原始命令中引用的值实际上并不需要引用(例如,"2018-04-18T22:02:23"),因此我在重新制定时使用了未引用的值
  • 如果您需要嵌入"字符,请使用\"(sic - 即使是 PowerShell - 在内部`用作转义字符)。