Количество сообщений в MSMQ через Powershell - PullRequest
9 голосов
/ 18 февраля 2010

Я бы хотел указать путь к очереди и узнать количество сообщений по нему.Любой совет, как это можно сделать?

Ответы [ 10 ]

8 голосов
/ 13 июня 2011

Будет выведен список всех очередей на компьютере и количество сообщений:

gwmi -class Win32_PerfRawData_MSMQ_MSMQQueue -computerName $computerName |
    ft -prop Name, MessagesInQueue
4 голосов
/ 15 января 2014

PowerShell под Windows Server 2012/2012 R2 и Windows 8 / 8.1 имеет несколько встроенных командлетов, которые можно использовать при установке Server Core Queue (MSMQ) Server Core .

# Get all message queues
Get-MsmqQueue;

# Get all the private message queues.
# Display only the QueueName and MessageCount for each queue.
Get-MsmqQueue -QueueType Private | Format-Table -Property QueueName,MessageCount;

Существует ряд других командлетов, которые можно использовать для управления очередью и создания сообщений. т.е.

  • New-MsmqQueue
  • Remove-MsmqQueue
  • Send-MsmqQueue
  • Receive-MsmqQueue
  • Get-MsmqQueueManager

Полный список справки по командлетам MSMQ см. Командлеты MSMQ в Windows PowerShell или Get-Command -Module MSMQ, если у вас уже установлена ​​эта функция.

4 голосов
/ 18 февраля 2010

Итак, я увидел это: Что я могу сделать с C # и Powershell? и пошел сюда: http://jopinblog.wordpress.com/2008/03/12/counting-messages-in-an-msmq-messagequeue-from-c/

И сделал это

# Add the .NET assembly MSMQ to the environment.
[Reflection.Assembly]::LoadWithPartialName("System.Messaging")

# Create a new QueueSizer .NET class help to warp MSMQ calls.
$qsource = @"
public class QueueSizer
    {
        public static System.Messaging.Message PeekWithoutTimeout(System.Messaging.MessageQueue q, System.Messaging.Cursor cursor, System.Messaging.PeekAction action)
        {
            System.Messaging.Message ret = null;
            try
            {
                // Peek at the queue, but timeout in one clock tick.
                ret = q.Peek(new System.TimeSpan(1), cursor, action);
            }
            catch (System.Messaging.MessageQueueException mqe)
            {
                // Trap MSMQ exceptions but only ones relating to timeout. Bubble up any other MSMQ exceptions.
                if (!mqe.Message.ToLower().Contains("timeout"))
                {
                    throw;
                }
            }
            return ret;
        }

        // Main message counting method.
        public static int GetMessageCount(string queuepath)
        {
            // Get a specific MSMQ queue by name.
            System.Messaging.MessageQueue q = new System.Messaging.MessageQueue(queuepath);

            int count = 0;

            // Create a cursor to store the current position in the queue.
            System.Messaging.Cursor cursor = q.CreateCursor();

            // Have quick peak at the queue.
            System.Messaging.Message m = PeekWithoutTimeout(q, cursor, System.Messaging.PeekAction.Current);

            if (m != null)
            {
                count = 1;

                // Keep on iterating through the queue and keep count of the number of messages that are found.
                while ((m = PeekWithoutTimeout(q, cursor, System.Messaging.PeekAction.Next)) != null)
                {
                    count++;
                }
            }

            // Return the tally.
            return count;
        }
    }
"@

# Add the new QueueSizer class helper to the environment.
Add-Type -TypeDefinition $qsource -ReferencedAssemblies C:\Windows\assembly\GAC_MSIL\System.Messaging\2.0.0.0__b03f5f7f11d50a3a\System.Messaging.dll

# Call the helper and get the message count.
[QueueSizer]::GetMessageCount('mymachine\private$\myqueue');

И это сработало.

2 голосов
/ 22 июля 2014

, следуя указаниям по этой ссылке , вы можете использовать

$queues = Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue
$queues | ft -property Name,MessagesInQueue

для получения размера локальных очередей или

$host = ...
$cred = get-credential
$queues = Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue -computer $host -credential $cred
$queues | ft -property Name,MessagesInQueue

для удаленных очередей.

2 голосов
/ 18 марта 2010

Решение, предоставленное Ирвином, меньше, чем идея.

Вы можете сделать .GetAllMessages вызов, чтобы сделать это за одну проверку вместо цикла foreach.

$QueueName = "MycomputerName\MyQueueName" 
$QueuesFromDotNet =  new-object System.Messaging.MessageQueue $QueueName


If($QueuesFromDotNet.GetAllMessages().Length -gt $Curr)
{
    //Do Something
}

.Length дает вам количество сообщений в данной очереди.

1 голос
/ 31 января 2017

Используйте это для вашего блока c #, чтобы получить количество.Он использует счетчик производительности для запроса один раз:

public static int GetMessageCount(string machineName, string queuepath)
    {
        var queueCounter = new PerformanceCounter(
            "MSMQ Queue",
            "Messages in Queue",
            string.Format("{0}\\{1}", machineName, queuepath),
            machineName);

        return (int)queueCounter.NextValue();
    }

Это более эффективно, чем повторный просмотр, поскольку работа в основном выполняется на удаленной машине, а также более эффективна, чем GetAllMessages, поскольку при этом возвращается дополнительное сообщениеданные, а затем подсчитывает элементы - ужасная производительность при любой реальной нагрузке.

1 голос
/ 18 февраля 2010

В Расширения сообщества PowerShell есть набор командлетов управления MSMQ. Попробуйте и посмотрите, поможет ли какой-либо из них (вероятно, Get-MSMQueue):

Clear-MSMQueue
Get-MSMQueue
New-MSMQueue
Receive-MSMQueue
Send-MSMQueue
Test-MSMQueue

Примечание: попробуйте захватить дистрибутив на основе модуля бета 2.0 - просто не забудьте "разблокировать" zip перед разархивированием.

0 голосов
/ 20 декабря 2015
winrm s winrm/config/client '@{TrustedHosts="yourIp"}'
$securePassword = ConvertTo-SecureString "YourPassword" -AsPlainText -force
$credential = New-Object System.Management.Automation.PsCredential("Domain\Usernama",$securePassword)  
$session = New-PSSession YourIP -credential $credential
$command = {Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue | ft -property Name,MessagesinJournalQueue,MessagesInQueue | out-String} 
Invoke-Command -session $session -scriptblock $command

enter image description here

0 голосов
/ 15 января 2015

Я искал хороший ответ на этот вопрос, и в то время как ответ Ирвина поставил меня в нужное русло, я искал некоторый код, который был бы немного более мощным. Основная причина для этого - иметь дело с изменениями, поскольку вы не можете 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 $_
        }
    }

Его можно оптимизировать так, чтобы первая функция возвращала очереди вместо имен очередей, но мне нужны были оба для разных сценариев.

0 голосов
/ 13 ноября 2014

Попробуйте один из этих ...

function GetMessageCount2($queuename)
{
    $queuename = $env:computername + "\" + $queuename
    return (Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue | Where-Object -filterscript {$_.Name -eq $queuename}).MessagesinQueue 
}

function GetMessageCount3($queuename)
{
    return (Get-MsmqQueue | Where-Object -FilterScript {$_.QueueName -eq $queuename}).MessageCount
}
...