As a follow up, I found that applying the RAISERROR will create a message in the queue with a status = 1, but does not automatically disable the queue, as will take place with actual message poisoning (following five consecutive rollbacks of a transaction). Since duplicating this with a problem transaction can be tricky from one system to another, the best approach is to just send a message and force five rollbacks with the following SQL (applying your own queue name in place of the <> brackets).
DECLARE @ch UNIQUEIDENTIFIER
DECLARE @messagetypename NVARCHAR(256)
DECLARE @messagebody XML
WHILE (1=1)
BEGIN
BEGIN TRANSACTION
WAITFOR (
RECEIVE TOP (1)
@ch = conversation_handle,
@messagetypename = message_type_name,
@messagebody = CAST(message_body AS XML)
FROM <queue name> --TargetQueue
), TIMEOUT 60000
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION
BREAK
END
-- Rolling back the current transaction
PRINT 'Rollback the current transaction - simulating a poison message...'
ROLLBACK TRANSACTION
END
GO
In the Message tab below this should display five lines beginning with "Rollback" and a final line stating that queue is currently disabled. This will take around 30 seconds to return.
To clean up the queue, find each unique conversation_handle in the queue with a status = 1 and manually apply one at a time in the following SQL. For the above code, there should only be one unique conversation handle.
Format:
END CONVERSATION '<conversation_handle>' WITH CLEANUP
Example:
END CONVERSATION '28D53504-42CB-E311-9E82-B8CA3A5EE06C' WITH CLEANUP
When done, re-enable the queue with the following SQL.
ALTER QUEUE <queue name> WITH ACTIVATION (STATUS = ON)