Use PowerShell to move MSMQ messages

Tagged: 

This topic contains 4 replies, has 2 voices, and was last updated by Profile photo of Nick Chard Nick Chard 2 years, 2 months ago.

  • Author
    Posts
  • #19054
    Profile photo of Nick Chard
    Nick Chard
    Participant

    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

  • #19055
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    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

  • #19063
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    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

  • #19069
    Profile photo of Nick Chard
    Nick Chard
    Participant

    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.

  • #19319
    Profile photo of Nick Chard
    Nick Chard
    Participant

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

You must be logged in to reply to this topic.