SQL Powershell:删除-SqlAvailabilityDatabase

SQL Powershell: Remove-SqlAvailabilityDatabase

我正在编写一个 Powershell 脚本来在高可用性环境中备份和恢复数据库(一切都需要使用 SMO 完成)。这包括几个步骤(或多或少:从主服务器上的可用性组中删除数据库,删除辅助服务器上的数据库,创建备份,恢复备份,再次添加数据库)。

脚本在其中一台数据库服务器上执行时 运行 运行良好。但现在我必须 运行 它在 Management/Application 服务器上。这现在给了我几个新问题...

与服务器的连接工作正常。 然后我从可用性组读取所有数据库:

$Global:ProdKopieDatabases = $server.AvailabilityGroups[$Global:ProdKopieAvailabailityGroup].AvailabilityDatabases

如果我检查 $ProdKopieDatabases,它会准确显示我期望的数据库数量。它也是 Microsoft.SqlServer.Management.Smo.AvailabilityDatabase

类型的对象

在脚本的下方,我需要从可用性组中删除数据库

foreach($DatabaseToRemove in $Global:ProdKopieDatabases)
    {
        try
        {
            Remove-SqlAvailabilityDatabase -InputObject $Global:ProdKopieDatabases[$DatabaseToRemove.Name.ToString()] -ErrorAction Stop
            #Remove-SqlAvailabilityDatabase -Path $($Private:MyAgPrimaryPath + "\AvailabilityDatabases\" + $DatabaseToRemove.Name.ToString()) -ErrorAction Stop
            Start-Sleep -Seconds 5
            Write-Host .. OK.
        }
        catch
        {
            Log-Write ($Error[0].ToString())
            Return 1
        }
    }

如果我在第一个 foreach 之前检查 $Global:ProdKopieDatabases 变量,我会看到所有数据库(即 3)。但是在 Remove-SqlAvailabilityDatabase 之后,已经从组中删除的数据库也从 $Global:ProdKopieDatabases 变量中删除了。因此,当 foreach 进入第二轮时,我得到一个错误:

Error: Collection was modified; enumeration operation may not execute.

我不明白为什么?好像变量 "by reference" 已连接到可用性数据库。如果是这个原因,我该如何更改?

如果我尝试将它添加到另一个变量并仅使用 $c,甚至会发生这种情况:

$c = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityDatabase #$Global:ProdKopieDatabases
$c = $Global:ProdKopieDatabases | Select *

当我直接在 SQL 服务器上 运行 运行脚本时,我可以通过以下方式完成

$Private:MyAgPrimaryPath = "SQLSERVER:\SQL$PrimaryServer\DEFAULT\AvailabilityGroups$Global:ProdKopieAvailabailityGroup"

$Global:ProdKopieDatabases = dir $Private:MyAgPrimaryPath\AvailabilityDatabases

foreach 相同,但 remove 不同:

Remove-SqlAvailabilityDatabase -Path $($Private:MyAgPrimaryPath + "\AvailabilityDatabases\" + $DatabaseToRemove.Name.ToString()) -ErrorAction Stop

执行此 Remove-SqlAvailabilityDatabase 命令后,变量 $Global:ProdKopieDatabases 中仍然包含所有数据库...

我完全不知道了。我理解错误信息,但我不明白为什么变量也被改变了..

非常感谢任何帮助!

提前致谢

我找到了一个 solution/workaround...(很丑)

首先我填写变量:

$Global:ProdKopieDatabases = $server.AvailabilityGroups[$Global:ProdKopieAvailabailityGroup].AvailabilityDatabases

然后在 foreach 之前,我创建了一个新变量,其中只有名称:

$c = $Global:ProdKopieDatabases | Select Name

我让 foreach 运行 覆盖新创建的变量,对于 -InputObject,我每次重新确定对象...

foreach($DatabaseToRemove in $c)
    {
        try
        {
            Remove-SqlAvailabilityDatabase -InputObject $server.AvailabilityGroups[$Global:ProdKopieAvailabailityGroup].AvailabilityDatabases[$DatabaseToRemove.Name.ToString()] -ErrorAction Stop

            Start-Sleep -Seconds 2
        }
        catch
        {                
            $Error[0] | Format-List -Force
            Return 1
        }
    }

在脚本的下方,我只使用 $c 变量,不再使用 $Global:...

也许有一天我会明白为什么我的 $Global: 变量会那样。直到现在,我都不知道...

希望这篇 post 有一天能对某些人有所帮助 ;-)