Use PowerShell to move MSMQ messages

Hi all

I want to write a script that will move all messages from one MSMQ to another. I know that PS v4 has some MSMQ cmds, but I need to be able to run the script on PS v2, so I can’t use them.

I’ve done some internet research and came up with this script:

$FromQueue = new-object System.Messaging.MessageQueue “.\private$\errors”
$DestinationQueue = new-object System.Messaging.MessageQueue “.\private$\messages”

do
{
$FromQueue.send($DestinationQueue.Receive())
}
while ($FromQueue.GetAllMessages().Length -ne 0)

I tested my script, and the messages disappear from the errors queue, but never appear in the messages queue. I tried replacing the do while loop with the following foreach loop, but the result was the same.

foreach ($message in $FromQueue) {$FromQueue.send($DestinationQueue.Receive()) }

I think my usage of the send and receive methods may be wrong. I’ve read through this [url]http://msdn.microsoft.com/en-us/library/System.Messaging.MessageQueue_methods(v=vs.110).aspx[/url], but .NET is at the limit of my knowledge. Can anyone offer any advice?

Nick

Hi Nick,

Please check if the destination queue has “Authenticated” enabled. If enabled you’ll need to tell the .NET object to authenticate like below:

$DestinationQueue = new-object System.Messaging.MessageQueue “.\private$\messages”
$DestinationQueue.Authenticate = $true

I hope that works for you.

Best,
Daniel

Hi Nick,

I’ve just realised another reason why it does not work. You’re getting all messages from the error queue but you’re trying send to the error queue ($FromQueue) again instead of the messages queue ($DestinationQueue).

Please check if below works for you (not tested).

foreach ($Message in $FromQueue.GetAllMessages())
{
  $DestinationQueue.Send($Message)
}

Regards,
Daniel

Hi Daniel,

Thanks for your input. I checked the queue and authenticated is not enabled. I also ran a test with your suggested code, but it didn’t work. It didn’t throw any error messages, but none of the messages were moved between the queues.

I’ve finally worked it out with the help of one of our dev guys. This script does the job. Hopefully this will be helpful to someone else

param
[
$Source,
$Destination
]

[Reflection.Assembly]::LoadWithPartialName("System.Messaging")

$SourceQueue = new-object System.Messaging.MessageQueue "$Source"
$DestinationQueue = new-object System.Messaging.MessageQueue "$Destination"

$msgTx = New-Object System.Messaging.MessageQueueTransaction

foreach ($message in $SourceQueue)
{
$msgTx.Begin()
$DestinationQueue.Send($message, $msgTx)
$msgTx.Commit()
}

$FromQueue.Purge()