如何使用 PowerShell 从 MSMQ 消息队列中删除特定消息
How to use PowerShell to delete specific messages from an MSMQ message queue
我正在尝试使用 PowerShell 从 MSMQ 消息队列中删除特定消息。我知道 PowerShell 4+ 中引入了几个用于管理 MSMQ 队列和消息的新 cmdlet,但据我所知,这些仍然无法帮助我实现删除特定消息的目标。
我想要实现的是一个连接到指定队列的简单脚本,然后遍历该队列中的每条消息,在消息正文中查找指定的搜索字符串,然后 将任何匹配的消息移动 到同一服务器上的另一个队列。我有这个非常适合搜索消息,并且可以使用 Send 方法复制任何匹配项:
$source = new-object System.Messaging.MessageQueue($sourcequeuename)
$destination = new-object System.Messaging.MessageQueue($destinationqueuename)
$msgs = $source.GetAllMessages()
foreach ( $msg in $msgs )
{
#Extra logic here - check message body for search string etc...
$destination.Send($msg)
}
但是 - 一旦复制,我从源队列中删除原始消息的唯一选择似乎是清除 整个 源队列,这也将删除所有其他消息,我不想这样做!
$source.Purge()
我以为我正在使用新的 (PowerShell 4+) 'Move-MsmqMessage' cmdlet...
Move-MsmqMessage -DestinationQueue $d -InputObject $q -Message $msg
但我正在努力让它工作 - 我不清楚我是否可以将特定的消息对象传递给它来移动。谁能给我一个使用 PowerShell(任何版本)循环遍历队列中的消息并使用此 Move-MsmqMessage cmdlet 移动特定消息的工作示例?
未测试,但您应该可以使用 ReceiveById 功能删除消息:
foreach ( $msg in $msgs )
{
#Extra logic here - check message body for search string etc...
$source.ReceiveById($msg.Id, [timespan]::FromMinutes(1))
}
问题和答案不包含使用的完整脚本。这是我用来从队列中删除单个消息的完整脚本,一旦我知道了消息的 ID。
[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$queuePath = "FormatName:DIRECT=OS:MachineName\private$\NameOfQueue"
$queue = New-Object System.Messaging.MessageQueue $queuePath
$poisonMessageId = "d53df8ba-3b6a-418b-ab27-198655534253996"
$queue.ReceiveById($poisonMessageId)
顺便说一句,找到消息 ID 很容易,顺便说一句。
前往以下位置查找消息:
计算机管理 -> 服务和应用程序 -> 消息队列 -> 专用队列。
打开包含您要删除的邮件的私人队列
Select 'Properties' 并且在 'General' 选项卡中是消息 ID。
Jay Dubya 的脚本扩展版本,按模式删除
$StringToFind = "AMS1-COMET5"
$QueueName = "AMS1-COMET5"
[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$queuePath = "FormatName:DIRECT=OS:"+ [System.Net.Dns]::GetHostName() + "\private$\" + $QueueName
$queue = New-Object System.Messaging.MessageQueue $queuePath
$SrcQueue = Get-MsmqQueue($QueueName)
$Messages = $SrcQueue | Receive-MsmqQueue -Peek -Count 10000000
$Messages |foreach {
if ($_.Label -match $StringToFind) {
$_.Label
$queue.ReceiveById($_.Id)
}
}
我正在尝试使用 PowerShell 从 MSMQ 消息队列中删除特定消息。我知道 PowerShell 4+ 中引入了几个用于管理 MSMQ 队列和消息的新 cmdlet,但据我所知,这些仍然无法帮助我实现删除特定消息的目标。
我想要实现的是一个连接到指定队列的简单脚本,然后遍历该队列中的每条消息,在消息正文中查找指定的搜索字符串,然后 将任何匹配的消息移动 到同一服务器上的另一个队列。我有这个非常适合搜索消息,并且可以使用 Send 方法复制任何匹配项:
$source = new-object System.Messaging.MessageQueue($sourcequeuename)
$destination = new-object System.Messaging.MessageQueue($destinationqueuename)
$msgs = $source.GetAllMessages()
foreach ( $msg in $msgs )
{
#Extra logic here - check message body for search string etc...
$destination.Send($msg)
}
但是 - 一旦复制,我从源队列中删除原始消息的唯一选择似乎是清除 整个 源队列,这也将删除所有其他消息,我不想这样做!
$source.Purge()
我以为我正在使用新的 (PowerShell 4+) 'Move-MsmqMessage' cmdlet...
Move-MsmqMessage -DestinationQueue $d -InputObject $q -Message $msg
但我正在努力让它工作 - 我不清楚我是否可以将特定的消息对象传递给它来移动。谁能给我一个使用 PowerShell(任何版本)循环遍历队列中的消息并使用此 Move-MsmqMessage cmdlet 移动特定消息的工作示例?
未测试,但您应该可以使用 ReceiveById 功能删除消息:
foreach ( $msg in $msgs )
{
#Extra logic here - check message body for search string etc...
$source.ReceiveById($msg.Id, [timespan]::FromMinutes(1))
}
问题和答案不包含使用的完整脚本。这是我用来从队列中删除单个消息的完整脚本,一旦我知道了消息的 ID。
[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$queuePath = "FormatName:DIRECT=OS:MachineName\private$\NameOfQueue"
$queue = New-Object System.Messaging.MessageQueue $queuePath
$poisonMessageId = "d53df8ba-3b6a-418b-ab27-198655534253996"
$queue.ReceiveById($poisonMessageId)
顺便说一句,找到消息 ID 很容易,顺便说一句。
前往以下位置查找消息:
计算机管理 -> 服务和应用程序 -> 消息队列 -> 专用队列。
打开包含您要删除的邮件的私人队列
Select 'Properties' 并且在 'General' 选项卡中是消息 ID。
Jay Dubya 的脚本扩展版本,按模式删除
$StringToFind = "AMS1-COMET5"
$QueueName = "AMS1-COMET5"
[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$queuePath = "FormatName:DIRECT=OS:"+ [System.Net.Dns]::GetHostName() + "\private$\" + $QueueName
$queue = New-Object System.Messaging.MessageQueue $queuePath
$SrcQueue = Get-MsmqQueue($QueueName)
$Messages = $SrcQueue | Receive-MsmqQueue -Peek -Count 10000000
$Messages |foreach {
if ($_.Label -match $StringToFind) {
$_.Label
$queue.ReceiveById($_.Id)
}
}