From ccbb7fe53fea4416ca376afe4d383c7c7cd35ddb Mon Sep 17 00:00:00 2001 From: andreasjordan Date: Wed, 3 Apr 2024 22:07:48 +0200 Subject: [PATCH 1/5] Add support for adding roles to roles (do Add-DbaDbRoleMember) --- public/Add-DbaDbRoleMember.ps1 | 38 +++++++++++++++++------------ tests/Add-DbaDbRoleMember.Tests.ps1 | 15 +++++++++--- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/public/Add-DbaDbRoleMember.ps1 b/public/Add-DbaDbRoleMember.ps1 index b4c9fb3211..8d6f8ce839 100644 --- a/public/Add-DbaDbRoleMember.ps1 +++ b/public/Add-DbaDbRoleMember.ps1 @@ -22,8 +22,8 @@ function Add-DbaDbRoleMember { .PARAMETER Role The role(s) to process. - .PARAMETER User - The user(s) to add to role(s) specified. + .PARAMETER Member + The user(s) or role(s) to add to role(s) specified. .PARAMETER InputObject Enables piped input from Get-DbaDbRole or Get-DbaDatabase @@ -51,29 +51,29 @@ function Add-DbaDbRoleMember { https://dbatools.io/Add-DbaDbRoleMember .EXAMPLE - PS C:\> Add-DbaDbRoleMember -SqlInstance localhost -Database mydb -Role db_owner -User user1 + PS C:\> Add-DbaDbRoleMember -SqlInstance localhost -Database mydb -Role db_owner -Member user1 Adds user1 to the role db_owner in the database mydb on the local default SQL Server instance .EXAMPLE - PS C:\> Add-DbaDbRoleMember -SqlInstance localhost, sql2016 -Role SqlAgentOperatorRole -User user1 -Database msdb + PS C:\> Add-DbaDbRoleMember -SqlInstance localhost, sql2016 -Role SqlAgentOperatorRole -Member user1 -Database msdb Adds user1 in servers localhost and sql2016 in the msdb database to the SqlAgentOperatorRole .EXAMPLE PS C:\> $servers = Get-Content C:\servers.txt - PS C:\> $servers | Add-DbaDbRoleMember -Role SqlAgentOperatorRole -User user1 -Database msdb + PS C:\> $servers | Add-DbaDbRoleMember -Role SqlAgentOperatorRole -Member user1 -Database msdb Adds user1 to the SqlAgentOperatorROle in the msdb database in every server in C:\servers.txt .EXAMPLE - PS C:\> Add-DbaDbRoleMember -SqlInstance localhost -Role "db_datareader","db_datawriter" -User user1 -Database DEMODB + PS C:\> Add-DbaDbRoleMember -SqlInstance localhost -Role "db_datareader","db_datawriter" -Member user1 -Database DEMODB Adds user1 in the database DEMODB on the server localhost to the roles db_datareader and db_datawriter .EXAMPLE PS C:\> $roles = Get-DbaDbRole -SqlInstance localhost -Role "db_datareader","db_datawriter" -Database DEMODB - PS C:\> $roles | Add-DbaDbRoleMember -User user1 + PS C:\> $roles | Add-DbaDbRoleMember -Member user1 Adds user1 in the database DEMODB on the server localhost to the roles db_datareader and db_datawriter @@ -86,7 +86,8 @@ function Add-DbaDbRoleMember { [string[]]$Database, [string[]]$Role, [parameter(Mandatory)] - [string[]]$User, + [Alias("User")] + [string[]]$Member, [parameter(ValueFromPipeline)] [object[]]$InputObject, [switch]$EnableException @@ -139,16 +140,23 @@ function Add-DbaDbRoleMember { $members = $dbRole.EnumMembers() - foreach ($username in $User) { - if ($db.Users.Name -contains $username) { - if ($members -notcontains $username) { - if ($PSCmdlet.ShouldProcess($instance, "Adding User $username to role: $dbRole in database $db")) { - Write-Message -Level 'Verbose' -Message "Adding User $username to role: $dbRole in database $db on $instance" - $dbRole.AddMember($username) + foreach ($newMember in $Member) { + if ($db.Users.Name -contains $newMember) { + if ($members -notcontains $newMember) { + if ($PSCmdlet.ShouldProcess($instance, "Adding user $newMember to role: $dbRole in database $db")) { + Write-Message -Level 'Verbose' -Message "Adding user $newMember to role: $dbRole in database $db on $instance" + $dbRole.AddMember($newMember) + } + } + } elseif ($db.Roles.Name -contains $newMember) { + if ($members -notcontains $newMember) { + if ($PSCmdlet.ShouldProcess($instance, "Adding role $newMember to role: $dbRole in database $db")) { + Write-Message -Level 'Verbose' -Message "Adding role $newMember to role: $dbRole in database $db on $instance" + $dbRole.AddMember($newMember) } } } else { - Write-Message -Level 'Warning' -Message "User $username does not exist in $db on $instance" + Write-Message -Level 'Warning' -Message "User or role $newMember does not exist in $db on $instance" } } } diff --git a/tests/Add-DbaDbRoleMember.Tests.ps1 b/tests/Add-DbaDbRoleMember.Tests.ps1 index c13a42d238..1c2862ad3d 100644 --- a/tests/Add-DbaDbRoleMember.Tests.ps1 +++ b/tests/Add-DbaDbRoleMember.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandpath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tags "UnitTests" { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object {$_ -notin ('whatif', 'confirm')} - [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'Role', 'User', 'InputObject', 'EnableException' + [object[]]$knownParameters = 'SqlInstance', 'SqlCredential', 'Database', 'Role', 'Member', 'InputObject', 'EnableException' $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object {$_}) -DifferenceObject $params).Count ) | Should Be 0 @@ -39,7 +39,7 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { Context "Functionality" { It 'Adds User to Role' { - Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role $role -User $user1 -Database $dbname -confirm:$false + Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role $role -Member $user1 -Database $dbname -confirm:$false $roleDBAfter = Get-DbaDbRoleMember -SqlInstance $server -Database $dbname -Role $role $roleDBAfter.Role | Should Be $role @@ -49,7 +49,7 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { It 'Adds User to Multiple Roles' { $roleDB = Get-DbaDbRoleMember -SqlInstance $server -Database msdb -Role db_datareader, SQLAgentReaderRole - Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role db_datareader, SQLAgentReaderRole -User $user1 -Database msdb -confirm:$false + Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role db_datareader, SQLAgentReaderRole -Member $user1 -Database msdb -confirm:$false $roleDBAfter = Get-DbaDbRoleMember -SqlInstance $server -Database msdb -Role db_datareader, SQLAgentReaderRole $roleDBAfter.Count | Should BeGreaterThan $roleDB.Count @@ -69,10 +69,17 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { } It 'Skip adding user to role if already a member' { - $messages = Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role $role -User $user1 -Database $dbname -confirm:$false -Verbose 4>&1 + $messages = Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role $role -Member $user1 -Database $dbname -confirm:$false -Verbose 4>&1 $messageCount = ($messages -match 'Adding user').Count $messageCount | Should Be 0 } + + It 'Adds Role to Role' { + Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role db_datawriter -Member $role -Database $dbname -confirm:$false + $roleDBAfter = Get-DbaDbRoleMember -SqlInstance $server -Database $dbname -Role db_datawriter + + $roleDBAfter.UserName | Should Be $role + } } } From 0257442e326db2610163b3b87c58cea34a70a9c3 Mon Sep 17 00:00:00 2001 From: andreasjordan Date: Mon, 8 Apr 2024 20:04:56 +0200 Subject: [PATCH 2/5] Return member roles --- public/Get-DbaDbRoleMember.ps1 | 41 ++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/public/Get-DbaDbRoleMember.ps1 b/public/Get-DbaDbRoleMember.ps1 index 4413a358da..f86a7c794a 100644 --- a/public/Get-DbaDbRoleMember.ps1 +++ b/public/Get-DbaDbRoleMember.ps1 @@ -160,23 +160,40 @@ function Get-DbaDbRoleMember { $members = $dbRole.EnumMembers() foreach ($member in $members) { - $user = $db.Users | Where-Object { $_.Name -eq $member } + $memberUser = $db.Users | Where-Object { $_.Name -eq $member } + $memberRole = $db.Roles | Where-Object { $_.Name -eq $member } if (Test-Bound -Not -ParameterName 'IncludeSystemUser') { - $user = $user | Where-Object { $_.IsSystemObject -eq $false } + $memberUser = $memberUser | Where-Object { $_.IsSystemObject -eq $false } } - if ($user) { + if ($memberUser) { [PSCustomObject]@{ - ComputerName = $server.ComputerName - InstanceName = $server.ServiceName - SqlInstance = $server.DomainInstanceName - Database = $db.Name - Role = $dbRole.Name - UserName = $user.Name - Login = $user.Login - SmoRole = $dbRole - SmoUser = $user + ComputerName = $server.ComputerName + InstanceName = $server.ServiceName + SqlInstance = $server.DomainInstanceName + Database = $db.Name + Role = $dbRole.Name + UserName = $memberUser.Name + Login = $memberUser.Login + MemberRole = $null + SmoRole = $dbRole + SmoUser = $memberUser + SmoMemberRole = $null + } + } elseif ($memberRole) { + [PSCustomObject]@{ + ComputerName = $server.ComputerName + InstanceName = $server.ServiceName + SqlInstance = $server.DomainInstanceName + Database = $db.Name + Role = $dbRole.Name + UserName = $null + Login = $memberUser.Login + MemberRole = $memberRole.Name + SmoRole = $dbRole + SmoUser = $null + SmoMemberRole = $memberRole } } } From ac4a7267fc8a572536e192fd561666d362e054a7 Mon Sep 17 00:00:00 2001 From: andreasjordan Date: Mon, 8 Apr 2024 20:08:28 +0200 Subject: [PATCH 3/5] Fix test --- tests/Add-DbaDbRoleMember.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Add-DbaDbRoleMember.Tests.ps1 b/tests/Add-DbaDbRoleMember.Tests.ps1 index 1c2862ad3d..b4f0e8daaf 100644 --- a/tests/Add-DbaDbRoleMember.Tests.ps1 +++ b/tests/Add-DbaDbRoleMember.Tests.ps1 @@ -79,7 +79,7 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role db_datawriter -Member $role -Database $dbname -confirm:$false $roleDBAfter = Get-DbaDbRoleMember -SqlInstance $server -Database $dbname -Role db_datawriter - $roleDBAfter.UserName | Should Be $role + $roleDBAfter.MemberRole | Should Be $role } } } From 829cf010b05f3f29e2e0a2fa25c3d9dc5f0a756e Mon Sep 17 00:00:00 2001 From: andreasjordan Date: Mon, 8 Apr 2024 20:45:10 +0200 Subject: [PATCH 4/5] fix test (do DbaDbRoleMember) --- tests/Add-DbaDbRoleMember.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Add-DbaDbRoleMember.Tests.ps1 b/tests/Add-DbaDbRoleMember.Tests.ps1 index b4f0e8daaf..9799d91aa3 100644 --- a/tests/Add-DbaDbRoleMember.Tests.ps1 +++ b/tests/Add-DbaDbRoleMember.Tests.ps1 @@ -79,7 +79,7 @@ Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { Add-DbaDbRoleMember -SqlInstance $script:instance2 -Role db_datawriter -Member $role -Database $dbname -confirm:$false $roleDBAfter = Get-DbaDbRoleMember -SqlInstance $server -Database $dbname -Role db_datawriter - $roleDBAfter.MemberRole | Should Be $role + $roleDBAfter.MemberRole | Should Contain $role } } } From 2ea1dd5a11a17c38186cdb194626ecef0d087dfb Mon Sep 17 00:00:00 2001 From: Andreas Jordan <66946165+andreasjordan@users.noreply.github.com> Date: Thu, 11 Apr 2024 17:37:49 +0200 Subject: [PATCH 5/5] rewording (do DbaDbRoleMember) Co-authored-by: Shawn Melton <11204251+wsmelton@users.noreply.github.com> --- public/Add-DbaDbRoleMember.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/Add-DbaDbRoleMember.ps1 b/public/Add-DbaDbRoleMember.ps1 index 8d6f8ce839..461fd6ffa4 100644 --- a/public/Add-DbaDbRoleMember.ps1 +++ b/public/Add-DbaDbRoleMember.ps1 @@ -23,7 +23,7 @@ function Add-DbaDbRoleMember { The role(s) to process. .PARAMETER Member - The user(s) or role(s) to add to role(s) specified. + The member(s) (user or role) to add to the Roles specified. .PARAMETER InputObject Enables piped input from Get-DbaDbRole or Get-DbaDatabase