Sometimes it can be useful to retrieve the number of messages in an MSMQ queue, for example for monitoring. However, it’s not immediately apparent how to do it if you google it, so here are my thoughts on the subject.
Other blog posts suggest iterating over messages (e.g. Counting Messages in an MSMQ MessageQueue from C#) or doing it using WMI. WMI is the best alternative in my opinion and if you want a quick way of doing it then PowerShell is the easiest:
$queues = Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue $queues | ft -property Name,MessagesInQueue
The result will be something similar to this:
Name MessagesInQueue ---- --------------- active714\private$\notify_queue$ 0 active714\private$\deltagarloggservice\deltagarloggservi... 0 active714\private$\order_queue$ 0 active714\private$\admin_queue$ 0 Computer Queues 27
This can also be done on remote machines:
$host = ... $cred = get-credential $queues = Get-WmiObject Win32_PerfFormattedData_msmq_MSMQQueue -computer $host -credential $cred $queues | ft -property Name,MessagesInQueue
The Get-Credential Cmdlet will display a login dialog which is fine in interactive sessions but if you need to set the credentials in a non-interactive script, then the tip in this blog post might help: PowerShell – How to create a PSCredential object.
Retrieving message counts from code takes a little more coding but here’s an example in C# that searches for a given queue and returns its message count:
private static int GetMsmqMessageCount(string queuePath, string machine, string username, string password) { var options = new ConnectionOptions {Username = username, Password = password}; var path = string.Format(@"\\{0}\root\CIMv2", machine); var scope = new ManagementScope(path, options); scope.Connect(); string queryString = String.Format("SELECT * FROM Win32_PerfFormattedData_msmq_MSMQQueue WHERE Name = '{0}'", queuePath); var query = new ObjectQuery(queryString); var searcher = new ManagementObjectSearcher(scope, query); IEnumerable<int> messageCountEnumerable = from ManagementObject queue in searcher.Get() select (int) (UInt64) queue.GetPropertyValue("MessagesInQueue"); return messageCountEnumerable.First(); }
This code also uses WMI but this time we do a query rather than enumerate all queues.
The above snippets has worked well for us so I felt it would be useful to post them here. Please leave a comment if you have issues with them or suggestions for improvement!
/Emil