Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions private/functions/Get-EncryptedObjectKeystream.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ function Get-EncryptedObjectKeystream {
- Invoke-DbaDbDecryptObject

.PARAMETER FamilyGuid
The family GUID of the database that holds the object, as reported by dbi_familyGUID of DBCC DBINFO.
One value per database, stable for the life of the database.
The family GUID of the database that holds the object, as reported by family_guid of the catalog view
sys.database_recovery_status. One value per database, stable for the life of the database.

.PARAMETER ObjectId
The object id of the encrypted object.
Expand Down
20 changes: 13 additions & 7 deletions public/Invoke-DbaDbDecryptObject.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,9 @@ function Invoke-DbaDbDecryptObject {
Stop-Function -Message "Reading the encrypted objects on $instance without a dedicated admin connection uses DBCC PAGE, which $azurePlatform does not support." -Target $instance -Continue
}

# DBCC PAGE and DBCC DBINFO are limited to sysadmin, so checking up front gives a clear
# message instead of a permission error in the middle of reading the pages.
# DBCC PAGE is limited to sysadmin, so checking up front gives a clear message instead of
# a permission error in the middle of reading the pages. sys.database_recovery_status, which
# supplies the family GUID, needs only VIEW SERVER STATE, which a sysadmin already holds.
$querySysadmin = @"
SELECT IS_SRVROLEMEMBER('sysadmin') AS IsSysadmin
"@
Expand Down Expand Up @@ -450,16 +451,21 @@ AND p.is_ms_shipped = 0
$familyGuid = $null
$imageValueMap = @{ }

# The family GUID comes from the catalog view sys.database_recovery_status, a typed
# uniqueidentifier present since SQL Server 2005, rather than by scraping dbi_familyGUID
# out of DBCC DBINFO's text dump. The two were measured byte for byte across SQL Server
# 2019, 2022 and 2025, for user databases and master, and always agree, so the swap keeps
# the keystream input identical while dropping a trace flag toggle and a regex over prose.
try {
$familyGuidRow = @($db.Query("DBCC DBINFO WITH TABLERESULTS") | Where-Object Field -eq "dbi_familyGUID")
$familyGuidRow = @($db.Query("SELECT family_guid FROM sys.database_recovery_status WHERE database_id = DB_ID()"))
} catch {
Stop-Function -Message "Couldn't read dbi_familyGUID of database $($db.Name) on $instance" -ErrorRecord $_ -Target $instance -Continue
Stop-Function -Message "Couldn't read the family GUID of database $($db.Name) on $instance" -ErrorRecord $_ -Target $instance -Continue
}

if ($familyGuidRow.Count -eq 0) {
Stop-Function -Message "Couldn't read dbi_familyGUID of database $($db.Name) on $instance" -Target $instance -Continue
if ($familyGuidRow.Count -eq 0 -or $null -eq $familyGuidRow[0].family_guid -or $familyGuidRow[0].family_guid -is [System.DBNull]) {
Stop-Function -Message "Couldn't read the family GUID of database $($db.Name) on $instance" -Target $instance -Continue
}
$familyGuid = [guid]$familyGuidRow[0].VALUE
$familyGuid = [guid]$familyGuidRow[0].family_guid

$wantedObjectId = @($objectCollection.ID)

Expand Down
8 changes: 4 additions & 4 deletions tests/Invoke-DbaDbDecryptObject.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -723,8 +723,8 @@ SELECT 'áéíñóú¡¿' as SampleUTF8;"
$routeText = InModuleScope dbatools -Parameters @{ DatabaseName = $dbname; Instance = $TestConfig.InstanceMulti1 } {
$server = Connect-DbaInstance -SqlInstance $Instance
$db = $server.Databases[$DatabaseName]
$familyGuidRow = @($db.Query("DBCC DBINFO WITH TABLERESULTS") | Where-Object Field -eq "dbi_familyGUID")
$familyGuid = [guid]$familyGuidRow[0].VALUE
$familyGuidRow = @($db.Query("SELECT family_guid FROM sys.database_recovery_status WHERE database_id = DB_ID()"))
$familyGuid = [guid]$familyGuidRow[0].family_guid
$encryptedId = @(@($db.Query("SELECT m.object_id AS ObjectId FROM sys.sql_modules AS m WHERE m.definition IS NULL")) | ForEach-Object { [int]$PSItem.ObjectId })

$result = @{ }
Expand Down Expand Up @@ -773,8 +773,8 @@ SELECT 'áéíñóú¡¿' as SampleUTF8;"
$scanText = InModuleScope dbatools -Parameters @{ DatabaseName = $dbname; Instance = $TestConfig.InstanceMulti1 } {
$server = Connect-DbaInstance -SqlInstance $Instance
$db = $server.Databases[$DatabaseName]
$familyGuidRow = @($db.Query("DBCC DBINFO WITH TABLERESULTS") | Where-Object Field -eq "dbi_familyGUID")
$familyGuid = [guid]$familyGuidRow[0].VALUE
$familyGuidRow = @($db.Query("SELECT family_guid FROM sys.database_recovery_status WHERE database_id = DB_ID()"))
$familyGuid = [guid]$familyGuidRow[0].family_guid

$encryptedId = @($db.Query("SELECT m.object_id AS ObjectId FROM sys.sql_modules AS m WHERE m.definition IS NULL")) | ForEach-Object { [int]$PSItem.ObjectId }

Expand Down