Powershell远程删除MSMQ

Powershell delete MSMQ remotely

我想知道是否可以通过 PowerShell 远程删除队列?我有以下脚本:

cls

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

$computers = @("comp1","comp2","comp3");

foreach($computer in $computers) {

    $messageQueues = [System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($computer);

    foreach ($queue in $messageQueues) {
        $endpoint = [string]::Format("FormatName:DIRECT=OS:{0}\{1}", $computer, $queue.QueueName);

        Write-Host $endpoint
        [System.Messaging.MessageQueue]::Delete($endpoint);        
    }
}

这很好用,如果我 运行 在我想删除其队列的机器上使用它,但是当我 运行 这个远程时我得到错误:

The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted.

有什么想法可以做到吗?

编辑

奇怪的是,我认为我可以通过 PowerShell 远程访问机器并执行脚本块。但是,我不明白做之间的区别:

这个:

$endpoint = [string]::Format("FormatName:DIRECT=OS:{0}\{1}", $computer, $queue.QueueName);
Invoke-Command -ComputerName $computer -ScriptBlock { [Reflection.Assembly]::LoadWithPartialName("System.Messaging"); [System.Messaging.MessageQueue]::Delete($endpoint) };

还有这个:

Invoke-Command -ComputerName $computer -ScriptBlock { [Reflection.Assembly]::LoadWithPartialName("System.Messaging"); [System.Messaging.MessageQueue]::Delete("FormatName:DIRECT=OS:MY_SERVER\some.endpoint") };

$endpoint 的值是相同的,但是由于某些奇怪的原因,它不喜欢变量方法,尽管两个值是相同的。我通过设置 $endpoint 然后调用 delete 来测试这个。我收到错误:

Exception calling "Delete" with "1" argument(s): "Invalid value  for parameter path."

我想说的是,如果我将值硬编码为参数的一部分,它可以工作,但将它分配给一个变量,然后调用该方法,我会得到一个错误

您不能删除远程专用队列。 您需要在队列本地执行操作。

来自 MQDeleteQueue

备注
(第 2 段)
"Private queues registered on a remote computer ... cannot be deleted."

出于历史目的,如果其他人遇到此问题或想知道如何远程删除队列,请参阅下文。

  1. 如何删除远程计算机上的私有队列? 可以远程删除队列。这可以使用命令 Enable-PSRemoting -Force 来实现。如果没有这个,您会遇到@JohnBreakWell 指出的问题(请参阅他对 MSDN 的 link)。

  2. 使用Invoke-Command时变量的范围?我发现的问题是我声明的变量超出了范围(脚本块无法看见)。为了纠正这个问题,我只是做了以下操作:

重要的一点是 argument listparam 的使用。

 $computers = @("comp1","comp2");

    foreach($computer in $computers) {
        [Reflection.Assembly]::LoadWithPartialName("System.Messaging"); 

        $messageQueues = [System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($computer);

        foreach ($queue in $messageQueues) {
            $endpoint = [string]::Format("FormatName:DIRECT=OS:{0}\{1}", $computer, $queue.QueueName);

            Enable-PSRemoting -Force
            Invoke-Command -ComputerName $computer -ScriptBlock {
                param ($computer, $endpoint)
                [Reflection.Assembly]::LoadWithPartialName("System.Messaging"); 
                [System.Messaging.MessageQueue]::Delete($endpoint) 
            }

        } -ArgumentList $computer, $endpoint

    }

正如 Schizo 博士提到的,您需要执行

Enable-PSRemoting -Force

在远程计算机上,但是,假设您使用的是 Server 2012 r2,它就像:

Invoke-Command -ComputerName COMPUTERNAME { Get-MsmqQueue -Name QUEUENAME | Remove-MsmqQueue }