Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The number of messages on an MSMQ via Powershell

I'd like to provide a queuepath and get the number of messages thereupon. Any advice on how this could be done?

like image 933
Irwin Avatar asked Feb 18 '10 14:02

Irwin


5 Answers

This will list all queues on a machine and the number of messages:

gwmi -class Win32_PerfRawData_MSMQ_MSMQQueue -computerName $computerName |
    ft -prop Name, MessagesInQueue
like image 95
RobO Avatar answered Nov 13 '22 15:11

RobO


PowerShell under Windows Server 2012/2012 R2 and Windows 8/8.1 has a bunch built-in Cmdlets that can be used by installing the Microsoft Message Queue (MSMQ) Server Core feature.

# 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;

There is a number of other Cmdlets that can be used for queue management and message creation. i.e.

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

For the full list of MSMQ Cmdlet help see MSMQ Cmdlets in Windows PowerShell, or Get-Command -Module MSMQ if you already have the feature installed.

like image 22
Bernie White Avatar answered Nov 13 '22 16:11

Bernie White


I have been hunting high and low for information on accessing queues in a cluster.

For others trying to use powershell commands on clustered queues:

On one of the cluster nodes:

$env:computername = "MsmqHostName"
Get-MsmqQueue | Format-Table -Property QueueName,MessageCount

remote from the cluster:

Invoke-Command -ScriptBlock {$env:computername = "msmqHostName";Get-MsmqQueue | Format-Table -Property QueueName,MessageCount } -ComputerName ClusternNodeName
like image 31
housten Avatar answered Oct 22 '22 07:10

housten


So, I saw this: What can I do with C# and Powershell? and went here:http://jopinblog.wordpress.com/2008/03/12/counting-messages-in-an-msmq-messagequeue-from-c/

And made this

# 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');

And it worked.

like image 4
Irwin Avatar answered Nov 13 '22 15:11

Irwin


The solution provided by Irwin is less than idea.

There is a .GetAllMessages call you can make to have this done in one check, instead of a foreach loop.

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


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

The .Length gives you the number of messages in the given queue.

like image 2
Clarence Klopfstein Avatar answered Nov 13 '22 16:11

Clarence Klopfstein