Мне не раз приходилось восстанавливать базы данных SQL Server из резервных файлов и при этом непременно либо резервная копия была получена с помощью не той системы, на которой предполагалось размещать восстановленную базу данных, либо эта копия поступала из неизвестного (но доверенного) источника. Так или иначе, перед тем, как приступать к восстановлению данных, я должен был получать сведения об именах файлов, о логических именах, местах размещения файлов, об их размерах и т.д. И уж во всяком случае, прежде чем браться за восстановление, мне приходилось получать информацию о том, какой объем пространства необходимо выделить для данной цели.

Получить сведения о деталях содержимого резервного файла средствами языка T-SQL довольно просто: для этого существует параметр FILELISTONLY команды RESTORE.

RESTORE FILELISTONLY FROM DISK = 'C:\MSSQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\TicketSalesDB.bak' WITH FILE = 1
GO

В итоге искомые подробности отображаются в формате таблицы результатов (в среде SQL Server Management Studio), см. экран 1.

 

Таблица результатов в SQL Server Management Studio
Экран 1. Таблица результатов в SQL Server Management Studio

Этот метод работает, но если нужно использовать данную информацию для решения других задач, могут возникнуть дополнительные сложности. Технология PowerShell в сочетании с объектами SQL Server Management Objects (SMO) обеспечивает универсальный вариант получения интересующих нас данных. Как всегда, нужно подключиться к SQL Server с помощью объекта SMO Server, а затем создать объект Restore.

$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') WS12SQL
$rs = new-object('Microsoft.SqlServer.Management.Smo.Restore')

Далее требуется определить элемент Backup Device Item, указывающий на резервный файл, и включить его в коллекцию Devices объекта Restore.

$bckfile = 'C:\MSSQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\TicketSalesDB.bak'
$bdi = new-object ('Microsoft.SqlServer.Management.Smo.BackupDeviceItem') ($bckfile, 'File')
$rs.Devices.Add($bdi)

Теперь объект SMO располагает всей необходимой информацией, и для того, чтобы извлечь из резервного файла нужные детали, следует воспользоваться методом ReadFileList() объекта Restore. Чтобы увидеть методы и свойства, получить которые можно из файла результатов (они возвращаются в виде объекта ADO.NET DataTable), можно воспользоваться командой Get-Member, см. экран 2.

$fl = $rs.ReadFileList($srv)

 

Объект ADO.NET DataTable
Экран 2. Объект ADO.NET DataTable

Далее вы можете извлечь интересующие вас свойства с помощью конвейера и преобразовать их в табличную форму, см. экран 3.

$fl | select LogicalName, Type, Size, PhysicalName | Format-Table –AutoSize

 

Таблица PowerShell
Экран 3. Таблица PowerShell

Картина будет еще более наглядной, если произвести над содержимым некоторые действия с помощью хэш-таблиц. К примеру, мне удобнее работать с информацией, когда объемы данных выражены не в байтах, а в мегабайтах или в гигабайтах. Я заменяю свойство Size хэш-таблицей, которая выглядит следующим образом:

@{Name='SizeMB';Expression={$_.Size / 1MB}}

В результате размеры отдельных файлов отображаются в мегабайтах. Подобным же образом я предпочитаю разбивать свойство PhysicalName на компоненты Drive, Folder и File. Эта операция легко выполняется с помощью таких хэш-таблиц:

@{Name='Drive';Expression={Split-Path $_.PhysicalName -Qualifier}}
@{Name='Folder';Expression={Split-Path $_.PhysicalName -Parent}}
@{Name='File';Expression={Split-Path $_.PhysicalName -Leaf}}

После внесения описанных изменений упомянутая выше команда приобретает вид:

$fl | select LogicalName, Type, @{Name='SizeMB';Expression={$_.Size / 1MB}},
@{Name='Drive';Expression={Split-Path $_.PhysicalName -Qualifier}},
@{Name='Folder';Expression={Split-Path $_.PhysicalName -Parent}}, @{Name='File';Expression={Split-
Path $_.PhysicalName -Leaf}} | Format-Table -AutoSize

Теперь читать результаты гораздо удобнее, см. экран 4.

 

Преобразованные результаты
Экран 4. Преобразованные результаты

Добавив к пространству имен Win32_LogicalDisk вызов WMI, вы быстро найдете дисковые накопители на текущей системе, их размер (в Гбайт), а также объем свободного пространства (тоже в Гбайт) и убедитесь, что интересующую вас базу данных можно спокойно восстанавливать на данном сервере, см. экран 5.

$dsk = Get-WMIObject -Query 'select * from Win32_LogicalDisk where DriveType = 3'
$dsk | select DeviceID, @{Name='SizeGB';Expression={$_.Size / 1GB}},
@{Name='FreeGB';Expression={$_.FreeSpace / 1GB }} | Format-Table -AutoSize

 

Информация о дисках системы для восстановления базы данных
Экран 5. Информация о дисках системы для восстановления базы данных

С помощью описанных инструментов вы можете осуществить быстрый анализ в порядке подготовки к восстановлению данных. Кроме того, на базе этих фрагментов кода можно создать сценарий, обеспечивающий автоматизацию всего процесса.