Skip to content

Commit a0eae5d

Browse files
andreasjordanclaude
andcommitted
Set-DbaLogin - Read only the logins of -Login from the instance
For -SqlInstance, the command called Get-DbaLogin without -Login and picked the logins of -Login out of the result afterwards. Get-DbaLogin processes every login it returns, so changing one login read all logins of the instance, which takes long on an instance with many logins or one far away. Sync-DbaLoginPassword calls it once per login and destination, so a sync of one login did the same. The call now passes -Login; the filter after it stays for the system logins. The new context changes one of two new logins with -Verbose and checks the messages Get-DbaLogin writes for every login it processes: only that login may be among them. Fixes #10807 (do Set-DbaLogin, Sync-DbaLoginPassword) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent d5da4b9 commit a0eae5d

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

‎public/Set-DbaLogin.ps1‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ function Set-DbaLogin {
330330
} catch {
331331
Stop-Function -Message "Failure" -Category ConnectionError -ErrorRecord $_ -Target $instance -Continue
332332
}
333-
$allLogins[$instance.ToString()] = Get-DbaLogin -SqlInstance $server
333+
# Only the logins of -Login: Get-DbaLogin processes every login it gets, and on an instance with many logins
334+
# or far away that took long for a single one (#10807).
335+
$allLogins[$instance.ToString()] = Get-DbaLogin -SqlInstance $server -Login $Login
334336
$InputObject += $allLogins[$instance.ToString()] | Where-Object { ($_.Name -in $Login) -and ($_.Name -notlike '##*') }
335337
}
336338

‎tests/Set-DbaLogin.Tests.ps1‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,69 @@ Describe "$CommandName Integration Tests" -Tag 'IntegrationTests' {
407407
}
408408
}
409409

410+
Context "Only the logins of -Login are read (#10807)" {
411+
BeforeAll {
412+
# We want to run all commands in the BeforeAll block with EnableException to ensure that the test fails if the setup fails.
413+
$PSDefaultParameterValues["*-Dba*:EnableException"] = $true
414+
415+
$readRandom = Get-Random
416+
$readLoginName = "dbatoolsci_readlogin_$readRandom"
417+
$readOtherName = "dbatoolsci_readother_$readRandom"
418+
$splatReadLogins = @{
419+
SqlInstance = $TestConfig.InstanceSingle
420+
Login = $readLoginName, $readOtherName
421+
SecurePassword = (ConvertTo-SecureString -String "dbatools.IO.Read7" -AsPlainText -Force)
422+
}
423+
$null = New-DbaLogin @splatReadLogins
424+
425+
# We want to run all commands outside of the BeforeAll block without EnableException to be able to test for specific warnings.
426+
$PSDefaultParameterValues.Remove("*-Dba*:EnableException")
427+
428+
# Get-DbaLogin writes a verbose message for every login it processes, the messages the issue shows. The
429+
# command read every login of the instance for the one of -Login.
430+
$splatReadDisable = @{
431+
SqlInstance = $TestConfig.InstanceSingle
432+
Login = $readLoginName
433+
Disable = $true
434+
Verbose = $true
435+
}
436+
$readRecords = @(Set-DbaLogin @splatReadDisable 4>&1)
437+
$readResult = $readRecords | Where-Object { $PSItem -isnot [System.Management.Automation.VerboseRecord] }
438+
$readProcessed = @(
439+
foreach ($record in $readRecords) {
440+
if ($record -is [System.Management.Automation.VerboseRecord] -and $record.Message -match "\[Get-DbaLogin\] Processing \[(?<name>.+?)\] on") {
441+
$Matches.name
442+
}
443+
}
444+
)
445+
}
446+
447+
AfterAll {
448+
# We want to run all commands in the AfterAll block with EnableException to ensure that the test fails if the cleanup fails.
449+
$PSDefaultParameterValues["*-Dba*:EnableException"] = $true
450+
451+
$splatRemoveReadLogins = @{
452+
SqlInstance = $TestConfig.InstanceSingle
453+
Login = $readLoginName, $readOtherName
454+
Force = $true
455+
}
456+
$null = Remove-DbaLogin @splatRemoveReadLogins
457+
458+
$PSDefaultParameterValues.Remove("*-Dba*:EnableException")
459+
}
460+
461+
It "changes the login of -Login" {
462+
$WarnVar | Should -BeNullOrEmpty
463+
$readResult.Name | Should -Be $readLoginName
464+
$readResult.IsDisabled | Should -BeTrue
465+
}
466+
467+
It "reads no other login of the instance" {
468+
$readProcessed | Should -Not -Contain $readOtherName
469+
$readProcessed | Should -Be $readLoginName
470+
}
471+
}
472+
410473
Context "Sets the password from a hash" {
411474
BeforeAll {
412475
# We want to run all commands in the BeforeAll block with EnableException to ensure that the test fails if the setup fails.

0 commit comments

Comments
 (0)