I'd like to provide a queuepath and get the number of messages thereupon. Any advice on how this could be done?
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
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.
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.
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With