From bc92374c4d5f3839029be29941f065ac80dc2439 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 16:31:18 +0000 Subject: [PATCH] Update-SqlPermission - Remove unnecessary SqlConnectionObject.Close() calls The Close() calls were added as a workaround for SMO DataReader conflicts, but modern SMO properly manages its own connection lifecycle - all Enum* methods (EnumMembers, EnumServerPermissions, EnumDatabasePermissions, etc.) open and close their DataReaders internally via SqlDataAdapter.Fill(). The calls were harmless with normal pooled connections (Close() returns to the pool, next Open() gets a fresh connection) but catastrophic with DAC connections: each Close() terminates the single DAC TCP slot, and the reconnect attempt to ADMIN:server fails when the slot hasn't been freed yet, generating "max 1 dedicated administrator connections" errors. The worst case was the Close() pair inside the foreach ($role in $sourceDb.Roles) loop - called once per role per database per login, producing 30-40 DAC errors in the scenario reported in #10284. Fixes #10284 (do Sync-DbaAvailabilityGroup) Co-authored-by: Andreas Jordan --- private/functions/Update-SqlPermission.ps1 | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/private/functions/Update-SqlPermission.ps1 b/private/functions/Update-SqlPermission.ps1 index d6ce3e31cf88..16bbf2d0a1a5 100644 --- a/private/functions/Update-SqlPermission.ps1 +++ b/private/functions/Update-SqlPermission.ps1 @@ -59,10 +59,6 @@ function Update-SqlPermission { } } - # gotta close because enum repeatedly causes problems with the datareader - $null = $SourceServer.ConnectionContext.SqlConnectionObject.Close() - $null = $DestServer.ConnectionContext.SqlConnectionObject.Close() - # Server Roles: sysadmin, bulklogin, etc foreach ($role in $SourceServer.Roles) { $roleName = $role.Name @@ -132,9 +128,6 @@ function Update-SqlPermission { Securables: Connect SQL, View any database, Administer Bulk Operations, etc. #> - $null = $sourceServer.ConnectionContext.SqlConnectionObject.Close() - $null = $destServer.ConnectionContext.SqlConnectionObject.Close() - $perms = $SourceServer.EnumServerPermissions($loginName) foreach ($perm in $perms) { $permState = $perm.PermissionState @@ -259,8 +252,6 @@ function Update-SqlPermission { } } - $null = $sourceDb.Parent.ConnectionContext.SqlConnectionObject.Close() - $null = $destDb.Parent.ConnectionContext.SqlConnectionObject.Close() # Remove Connect, Alter Any Assembly, etc $destPerms = $destDb.EnumDatabasePermissions($newLoginName) $perms = $sourceDb.EnumDatabasePermissions($loginName) @@ -292,9 +283,6 @@ function Update-SqlPermission { } # Adding database mappings and securables - $null = $SourceLogin.Parent.ConnectionContext.SqlConnectionObject.Close() - $null = $DestServer.ConnectionContext.SqlConnectionObject.Close() - foreach ($db in $SourceLogin.EnumDatabaseMappings()) { $dbName = $db.DbName $destDb = $DestServer.Databases[$dbName] @@ -355,8 +343,6 @@ function Update-SqlPermission { } else { # Database Roles: db_owner, db_datareader, etc foreach ($role in $sourceDb.Roles) { - $null = $sourceDb.Parent.ConnectionContext.SqlConnectionObject.Close() - $null = $destDb.Parent.ConnectionContext.SqlConnectionObject.Close() if ($role.EnumMembers() -contains $loginName) { $roleName = $role.Name $destDbRole = $destDb.Roles[$roleName] @@ -375,7 +361,6 @@ function Update-SqlPermission { } } # Connect, Alter Any Assembly, etc - $null = $sourceDb.Parent.ConnectionContext.SqlConnectionObject.Close() $perms = $sourceDb.EnumDatabasePermissions($loginName) foreach ($perm in $perms) { $permState = $perm.PermissionState