Я пишу сценарий Powershell для резервного копирования и восстановления базы данных в среде высокой доступности (все нужно делать с помощью SMO). Это включает в себя пару шагов (более или менее: удалить базу данных из группы доступности на первичном сервере, удалить базу данных на вторичном сервере, создать резервные копии, восстановить резервные копии, снова добавить базу данных).
Сценарий работал нормально, хотя выполнялся на одном из серверов баз данных. Но теперь мне нужно запустить его на сервере управления/приложений. Это дает мне теперь пару новых проблем...
Подключение к серверу работает нормально. Затем я читаю все базы данных из группы доступности:
$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
}
}
Если я проверю переменную $Global:ProdKopieDatabases перед первым foreach, я увижу все базы данных (т.е. 3). Но после Remove-SqlAvailabilityDatabase база данных, которая была удалена из группы, также была удалена из переменной $Global:ProdKopieDatabases. Поэтому, когда foreach доходит до второго раунда, я получаю ошибку:
Error: Collection was modified; enumeration operation may not execute.
Я не понимаю, почему? Как будто переменная "по ссылке" связана с базой данных доступности. Если причина в этом, как я могу это изменить?
Это даже происходит, если я пытаюсь добавить его в другую переменную и работать только с $c:
$c = New-Object Microsoft.SqlServer.Management.Smo.AvailabilityDatabase #$Global:ProdKopieDatabases
$c = $Global:ProdKopieDatabases | Select *
Пока я запускал скрипт непосредственно на SQL Server, я смог сделать это следующим образом.
$Private:MyAgPrimaryPath = "SQLSERVER:\SQL\$PrimaryServer\DEFAULT\AvailabilityGroups\$Global:ProdKopieAvailabailityGroup"
$Global:ProdKopieDatabases = dir $Private:MyAgPrimaryPath\AvailabilityDatabases
foreach был таким же, но удаление было другим:
Remove-SqlAvailabilityDatabase -Path $($Private:MyAgPrimaryPath + "\AvailabilityDatabases\" + $DatabaseToRemove.Name.ToString()) -ErrorAction Stop
После этой команды Remove-SqlAvailabilityDatabase переменная $Global:ProdKopieDatabases по-прежнему содержит все базы данных...
Я больше ничего не знаю. Я понимаю сообщение об ошибке, но я не понимаю, почему переменная также изменяется.
Любая помощь высоко ценится!
заранее спасибо
$Global:ProdKopieDatabases
. Если я заполню егоdir $Private:MyAgPrimaryPath\AvailabilityDatabases
,Remove-SqlAvailabilityDatabase -InputObject
будет работать отлично... Если я заполню его$server.AvailabilityGroups[$Global:ProdKopieAvailabailityGroup].AvailabilityDatabases
, он будет вести себя по-другому... Есть идеи? Что я могу проверить? Есть ли что-то вроде byValue вместо byReference? - person Dan Stef   schedule 15.10.2015dir $Privat...
, а другой с$server.Avail
) и обнаружил, что переменная, которая работает, имеет 7 записей NoteProperty (DisplayName, PSChildName, PSDrive, PSIsContainer, PSParentPath, PSPath и PSProvider)... Откуда они берутся? из??? Почему? Смущенный.... :-( - person Dan Stef   schedule 15.10.2015