如何用PowerShell过滤MSMQ日记队列中含A15C05U01_SAPProduced的消息
筛选MSMQ日记队列中包含指定内容的消息
你的核心问题是之前的筛选逻辑完全错误——$utf8是UTF8Encoding实例,根本没有MessageName属性,而且消息的业务字段都在XML格式的消息体里,必须先读取消息体内容再做判断。
下面提供两种可行的筛选方案:
方案1:直接匹配消息体文本(简单快速)
如果只需要判断消息体中是否包含目标字符串,不需要精准定位XML节点,可以用这种方法:
[Reflection.Assembly]::LoadWithPartialName("System.Messaging") $queueName = '.\Private$\wwprodmsgqueue1.0\Journal$'; $queue = New-Object System.Messaging.MessageQueue $queueName; $utf8 = New-Object System.Text.UTF8Encoding; $msgs = $queue.GetAllMessages(); # 筛选包含"A15C05U01_SAPProduced"的消息 $filteredMsgs = $msgs | Where-Object { $bodyContent = $utf8.GetString($_.BodyStream.ToArray()) $bodyContent -match 'A15C05U01_SAPProduced' } # 输出筛选结果 $filteredMsgs | ForEach-Object { Write-Host "消息ID: $($_.Id)" Write-Host "消息内容:`n$($utf8.GetString($_.BodyStream.ToArray()))`n" }
方案2:解析XML精准筛选(更严谨)
如果需要精准匹配XML结构中的指定节点值(比如MessageData下的第一个<string>节点),可以解析XML后再筛选:
[Reflection.Assembly]::LoadWithPartialName("System.Messaging") $queueName = '.\Private$\wwprodmsgqueue1.0\Journal$'; $queue = New-Object System.Messaging.MessageQueue $queueName; $utf8 = New-Object System.Text.UTF8Encoding; $msgs = $queue.GetAllMessages(); $filteredMsgs = $msgs | Where-Object { try { $bodyContent = $utf8.GetString($_.BodyStream.ToArray()) $xmlDoc = [xml]$bodyContent # 定位到MessageData下的第一个string节点,判断值是否匹配 $xmlDoc.SelectSingleNode('//MessageData/string[1]').InnerText -eq 'A15C05U01_SAPProduced' } catch { # 跳过非XML格式或结构不匹配的消息 $false } } # 输出结果 $filteredMsgs | ForEach-Object { Write-Host "消息ID: $($_.Id)" Write-Host "消息内容:`n$($utf8.GetString($_.BodyStream.ToArray()))`n" }
错误原因说明
你之前写的Where-Object {$utf8.MessageName -like "Produce Material"}有两个关键错误:
$utf8是编码处理对象,不是消息内容载体,不存在MessageName属性;MessageName是消息体XML中的节点,不是MSMQ消息对象($msg)的固有属性,必须先读取BodyStream解析内容后才能访问。
内容的提问来源于stack exchange,提问作者pemla
相关产品推荐
相关产品推荐

