Author Posts

September 24, 2014 at 12:26 am

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:

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

$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

September 24, 2014 at 12:41 am

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

September 24, 2014 at 5:53 am

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

September 24, 2014 at 8:00 am

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.

October 3, 2014 at 7:20 am

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()