Я искал хороший ответ на этот вопрос, и в то время как ответ Ирвина поставил меня в нужное русло, я искал некоторый код, который был бы немного более мощным. Основная причина для этого - иметь дело с изменениями, поскольку вы не можете Add-Type
несколько раз из-за типа, загружаемого во время выполнения .Net, и не могут быть выгружены без закрытия вашего экземпляра powershell.
Итак, я взял его ответ и придумал:
# Add the .NET assembly MSMQ to the environment.
[Reflection.Assembly]::LoadWithPartialName("System.Messaging") | out-Null
function Get-QueueNames([Parameter(Mandatory=$true)][String]$machineName, [String]$servicePrefix)
{
[System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($machineName) |
ForEach-Object { $_.Path } |
Where-Object { $_ -like "*$($servicePrefix).*" }
}
function Get-MessageCount([parameter(Mandatory=$true)][String]$queueName)
{
function HasMessage
{
param
(
[System.Messaging.MessageQueue]$queue,
[System.Messaging.Cursor]$cursor,
[System.Messaging.PeekAction]$action
)
$hasMessage = $false
try
{
$timeout = New-Object System.TimeSpan -ArgumentList 1
$message = $queue.Peek($timeout, $cursor, $action)
if ($message -ne $null)
{
$hasMessage = $true
}
}
catch [System.Messaging.MessageQueueException]
{
# Only trap timeout related exceptions
if ($_.Exception.Message -notmatch "timeout")
{
throw
}
}
$hasMessage
}
$count = 0
$queue = New-Object System.Messaging.MessageQueue -ArgumentList $queueName
$cursor = $queue.CreateCursor()
$action = [System.Messaging.PeekAction]::Current
$hasMessage = HasMessage $queue $cursor $action
while ($hasMessage)
{
$count++
$action = [System.Messaging.PeekAction]::Next
$hasMessage = HasMessage $queue $cursor $action
}
$count
}
$machineName = "."
$prefix = "something"
Get-QueueNames $machineName $prefix |
ForEach-Object {
New-Object PSObject -Property @{
QueueName = $_
MessageCount = Get-MessageCount $_
}
}
Его можно оптимизировать так, чтобы первая функция возвращала очереди вместо имен очередей, но мне нужны были оба для разных сценариев.