Skip to content

Commit 59c5c40

Browse files
authored
Get-SqlDscServerPermission: Check for both login and role (#2131)
1 parent 755ad31 commit 59c5c40

File tree

51 files changed

+1334
-402
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1334
-402
lines changed

CHANGELOG.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3636
- Fixed environment variable persistence by using $GITHUB_ENV instead of
3737
job-level env declaration.
3838
- `Grant-SqlDscServerPermission`
39-
- Added new public command to grant server permissions to a principal (Login or ServerRole) on a SQL Server Database Engine instance.
39+
- Added new public command to grant server permissions to a principal
40+
(Login or ServerRole) on a SQL Server Database Engine instance.
4041
- `Deny-SqlDscServerPermission`
41-
- Added new public command to deny server permissions to a principal (Login or ServerRole).
42+
- Added new public command to deny server permissions to a principal
43+
(Login or ServerRole).
4244
- `Revoke-SqlDscServerPermission`
43-
- Added new public command to revoke server permissions from a principal (Login or ServerRole).
45+
- Added new public command to revoke server permissions from a principal
46+
(Login or ServerRole).
4447
- `Test-SqlDscServerPermission`
45-
- Added new public command with Grant/Deny parameter sets (and `-WithGrant`) to test server permissions for a principal.
48+
- Added new public command with Grant/Deny parameter sets (and `-WithGrant`)
49+
to test server permissions for a principal.
4650
- `Assert-SqlDscLogin`
4751
- Added new public command to validate that a specified SQL Server principal
4852
is a login.
4953
- `Enable-SqlDscLogin`
5054
- Added new public command to enable a SQL Server login.
55+
- `Get-SqlDscServerPermission`
56+
- Enhanced command to support pipeline input for Login and ServerRole
57+
objects while maintaining backward compatibility with the original
58+
parameter set.
5159
- `Disable-SqlDscLogin`
5260
- Added new public command to disable a SQL Server login.
5361
- `Test-SqlDscIsLoginEnabled`
@@ -88,6 +96,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8896
- Added documentation for `SqlIntegrationTest` user and
8997
`IntegrationTestSqlLogin` login.
9098
- Added run order information for `New-SqlDscLogin` integration test.
99+
- `Get-SqlDscServerPermission`
100+
- Enhanced the command to support server roles in addition to logins by
101+
utilizing `Test-SqlDscIsRole` alongside the existing `Test-SqlDscIsLogin`
102+
check.
103+
- The command now accepts both login principals and server role principals
104+
as the `Name` parameter (issue [#2063](https://github.com/dsccommunity/SqlServerDsc/issues/2063)).
91105
- `azure-pipelines.yml`
92106
- Remove `windows-2019` images fixes [#2106](https://github.com/dsccommunity/SqlServerDsc/issues/2106).
93107
- Move individual tasks to `windows-latest`.

RequiredModules.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
Sampler = 'latest'
2929
'Sampler.GitHubTasks' = 'latest'
3030
MarkdownLinkCheck = 'latest'
31-
'DscResource.Test' = 'latest'
31+
'DscResource.Test' = '0.17.2'
3232
xDscResourceDesigner = 'latest'
3333

3434
# Build dependencies needed for using the module

azure-pipelines.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,6 @@ stages:
317317
'tests/Integration/Commands/Remove-SqlDscDatabase.Integration.Tests.ps1'
318318
'tests/Integration/Commands/Remove-SqlDscRole.Integration.Tests.ps1'
319319
'tests/Integration/Commands/Remove-SqlDscLogin.Integration.Tests.ps1'
320-
321320
# Group 9
322321
'tests/Integration/Commands/Uninstall-SqlDscServer.Integration.Tests.ps1'
323322
)

source/Public/Deny-SqlDscServerPermission.ps1

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,25 +104,19 @@ function Deny-SqlDscServerPermission
104104
$permissionSet.$permissionName = $true
105105
}
106106

107-
# Get the permissions names that are set to $true in the ServerPermissionSet.
108-
$permissionName = $permissionSet |
109-
Get-Member -MemberType 'Property' |
110-
Select-Object -ExpandProperty 'Name' |
111-
Where-Object -FilterScript {
112-
$permissionSet.$_
113-
}
114-
115107
try
116108
{
117109
$serverObject.Deny($permissionSet, $principalName)
118110
}
119111
catch
120112
{
121-
$errorMessage = $script:localizedData.ServerPermission_Deny_FailedToDenyPermission -f $principalName, $serverObject.InstanceName
113+
$errorMessage = $script:localizedData.ServerPermission_Deny_FailedToDenyPermission -f $principalName, $serverObject.InstanceName, ($Permission -join ',')
114+
115+
$exception = [System.InvalidOperationException]::new($errorMessage, $_.Exception)
122116

123117
$PSCmdlet.ThrowTerminatingError(
124118
[System.Management.Automation.ErrorRecord]::new(
125-
$errorMessage,
119+
$exception,
126120
'DSDSP0001', # cSpell: disable-line
127121
[System.Management.Automation.ErrorCategory]::InvalidOperation,
128122
$principalName

source/Public/Get-SqlDscServerPermission.ps1

Lines changed: 145 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
<#
22
.SYNOPSIS
3-
Returns the current permissions for the principal.
3+
Returns the current permissions for a SQL Server login or server role.
44
55
.DESCRIPTION
6-
Returns the current permissions for the principal.
6+
Returns the current permissions for a SQL Server login or server role.
7+
The command can retrieve permissions for both user-defined and built-in
8+
server principals including SQL Server logins and server roles.
9+
10+
The command supports two modes of operation:
11+
1. By name: Specify ServerObject, Name, and optionally PrincipalType
12+
2. By object: Pass Login or ServerRole objects via pipeline
713
814
.PARAMETER ServerObject
9-
Specifies current server connection object.
15+
Specifies current server connection object. This parameter is used in the
16+
default parameter set for backward compatibility.
1017
1118
.PARAMETER Name
12-
Specifies the name of the principal for which the permissions are
13-
returned.
19+
Specifies the name of the SQL Server login or server role for which
20+
the permissions are returned. This parameter is used in the default
21+
parameter set for backward compatibility.
22+
23+
.PARAMETER PrincipalType
24+
Specifies the type(s) of principal to check. Valid values are 'Login'
25+
and 'Role'. If not specified, both login and role checks will be performed.
26+
If specified, only the specified type(s) will be checked. This parameter
27+
is used in the default parameter set for backward compatibility.
28+
29+
.PARAMETER Login
30+
Specifies the Login object for which the permissions are returned.
31+
This parameter accepts pipeline input.
32+
33+
.PARAMETER ServerRole
34+
Specifies the ServerRole object for which the permissions are returned.
35+
This parameter accepts pipeline input.
1436
1537
.OUTPUTS
1638
[Microsoft.SqlServer.Management.Smo.ServerPermissionInfo[]]
@@ -21,51 +43,157 @@
2143
2244
Get the permissions for the principal 'MyPrincipal'.
2345
46+
.EXAMPLE
47+
$serverInstance = Connect-SqlDscDatabaseEngine
48+
Get-SqlDscServerPermission -ServerObject $serverInstance -Name 'sysadmin'
49+
50+
Get the permissions for the server role 'sysadmin'.
51+
52+
.EXAMPLE
53+
$serverInstance = Connect-SqlDscDatabaseEngine
54+
Get-SqlDscServerPermission -ServerObject $serverInstance -Name 'MyLogin' -PrincipalType 'Login'
55+
56+
Get the permissions for the login 'MyLogin', only checking if it exists as a login.
57+
58+
.EXAMPLE
59+
$serverInstance = Connect-SqlDscDatabaseEngine
60+
Get-SqlDscServerPermission -ServerObject $serverInstance -Name 'MyRole' -PrincipalType 'Role'
61+
62+
Get the permissions for the server role 'MyRole', only checking if it exists as a role.
63+
64+
.EXAMPLE
65+
$serverInstance = Connect-SqlDscDatabaseEngine
66+
$login = $serverInstance | Get-SqlDscLogin -Name 'MyLogin'
67+
68+
Get-SqlDscServerPermission -Login $login
69+
70+
Get the permissions for the login 'MyLogin' using a Login object.
71+
72+
.EXAMPLE
73+
$serverInstance = Connect-SqlDscDatabaseEngine
74+
$role = $serverInstance | Get-SqlDscRole -Name 'MyRole'
75+
76+
$role | Get-SqlDscServerPermission
77+
78+
Get the permissions for the server role 'MyRole' using a ServerRole object from the pipeline.
79+
80+
.EXAMPLE
81+
$serverInstance = Connect-SqlDscDatabaseEngine
82+
83+
$serverInstance | Get-SqlDscLogin | Get-SqlDscServerPermission
84+
85+
Get the permissions for all logins from the pipeline.
86+
2487
.NOTES
2588
If specifying `-ErrorAction 'SilentlyContinue'` then the command will silently
2689
ignore if the principal (parameter **Name**) is not present. In such case the
2790
command will return `$null`. If specifying `-ErrorAction 'Stop'` the command
2891
will throw an error if the principal is missing.
92+
93+
The Login or ServerRole object must come from the same SQL Server instance
94+
where the permissions will be retrieved.
2995
#>
3096
function Get-SqlDscServerPermission
3197
{
3298
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '', Justification = 'Because the rule does not understands that the command returns [System.String[]] when using , (comma) in the return statement')]
3399
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('UseSyntacticallyCorrectExamples', '', Justification = 'Because the rule does not yet support parsing the code when a parameter type is not available. The ScriptAnalyzer rule UseSyntacticallyCorrectExamples will always error in the editor due to https://github.com/indented-automation/Indented.ScriptAnalyzerRules/issues/8.')]
34100
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('AvoidThrowOutsideOfTry', '', Justification = 'Because the code throws based on an prior expression')]
35-
[CmdletBinding()]
101+
[CmdletBinding(DefaultParameterSetName = 'ByName')]
36102
[OutputType([Microsoft.SqlServer.Management.Smo.ServerPermissionInfo[]])]
37103
param
38104
(
39-
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
105+
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'ByName')]
40106
[Microsoft.SqlServer.Management.Smo.Server]
41107
$ServerObject,
42108

43-
[Parameter(Mandatory = $true)]
109+
[Parameter(Mandatory = $true, ParameterSetName = 'ByName')]
44110
[System.String]
45-
$Name
111+
$Name,
112+
113+
[Parameter(ParameterSetName = 'ByName')]
114+
[ValidateSet('Login', 'Role')]
115+
[System.String[]]
116+
$PrincipalType,
117+
118+
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'Login')]
119+
[Microsoft.SqlServer.Management.Smo.Login]
120+
$Login,
121+
122+
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'ServerRole')]
123+
[Microsoft.SqlServer.Management.Smo.ServerRole]
124+
$ServerRole
46125
)
47126

48127
# cSpell: ignore GSDSP
49128
process
50129
{
51130
$getSqlDscServerPermissionResult = $null
52131

53-
$testSqlDscIsLoginParameters = @{
54-
ServerObject = $ServerObject
55-
Name = $Name
132+
# Determine which parameter set we're using and set up variables accordingly
133+
if ($PSCmdlet.ParameterSetName -eq 'Login')
134+
{
135+
$principalName = $Login.Name
136+
$serverObject = $Login.Parent
137+
$isLogin = $true
138+
$isRole = $false
139+
}
140+
elseif ($PSCmdlet.ParameterSetName -eq 'ServerRole')
141+
{
142+
$principalName = $ServerRole.Name
143+
$serverObject = $ServerRole.Parent
144+
$isLogin = $false
145+
$isRole = $true
56146
}
147+
else
148+
{
149+
# ByName parameter set (default for backward compatibility)
150+
$principalName = $Name
151+
$serverObject = $ServerObject
57152

58-
$isLogin = Test-SqlDscIsLogin @testSqlDscIsLoginParameters
153+
$testSqlDscIsPrincipalParameters = @{
154+
ServerObject = $serverObject
155+
Name = $principalName
156+
}
157+
158+
# Determine which checks to perform based on PrincipalType parameter
159+
$checkLogin = $true
160+
$checkRole = $true
161+
162+
if ($PSBoundParameters.ContainsKey('PrincipalType'))
163+
{
164+
$checkLogin = $PrincipalType -contains 'Login'
165+
$checkRole = $PrincipalType -contains 'Role'
166+
}
167+
168+
# Perform the appropriate checks
169+
$isLogin = if ($checkLogin)
170+
{
171+
Test-SqlDscIsLogin @testSqlDscIsPrincipalParameters
172+
}
173+
else
174+
{
175+
$false
176+
}
177+
178+
$isRole = if ($checkRole)
179+
{
180+
Test-SqlDscIsRole @testSqlDscIsPrincipalParameters
181+
}
182+
else
183+
{
184+
$false
185+
}
186+
}
59187

60-
if ($isLogin)
188+
if ($isLogin -or $isRole)
61189
{
62-
$getSqlDscServerPermissionResult = $ServerObject.EnumServerPermissions($Name)
190+
$getSqlDscServerPermissionResult = $serverObject.EnumServerPermissions($principalName)
63191
}
64192
else
65193
{
66-
$missingPrincipalMessage = $script:localizedData.ServerPermission_MissingPrincipal -f $Name, $ServerObject.InstanceName
194+
$missingPrincipalMessage = $script:localizedData.ServerPermission_MissingPrincipal -f $principalName, $serverObject.InstanceName
67195

68-
Write-Error -Message $missingPrincipalMessage -Category 'InvalidOperation' -ErrorId 'GSDSP0001' -TargetObject $Name
196+
Write-Error -Message $missingPrincipalMessage -Category 'InvalidOperation' -ErrorId 'GSDSP0001' -TargetObject $principalName
69197
}
70198

71199
return , [Microsoft.SqlServer.Management.Smo.ServerPermissionInfo[]] $getSqlDscServerPermissionResult

source/Public/Grant-SqlDscServerPermission.ps1

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,6 @@ function Grant-SqlDscServerPermission
119119
$permissionSet.$permissionName = $true
120120
}
121121

122-
# Get the permissions names that are set to $true in the ServerPermissionSet.
123-
$permissionName = $permissionSet |
124-
Get-Member -MemberType 'Property' |
125-
Select-Object -ExpandProperty 'Name' |
126-
Where-Object -FilterScript {
127-
$permissionSet.$_
128-
}
129-
130122
try
131123
{
132124
if ($WithGrant.IsPresent)
@@ -140,11 +132,13 @@ function Grant-SqlDscServerPermission
140132
}
141133
catch
142134
{
143-
$errorMessage = $script:localizedData.ServerPermission_Grant_FailedToGrantPermission -f $principalName, $serverObject.InstanceName
135+
$errorMessage = $script:localizedData.ServerPermission_Grant_FailedToGrantPermission -f $principalName, $serverObject.InstanceName, ($Permission -join ', ')
136+
137+
$exception = [System.InvalidOperationException]::new($errorMessage, $_.Exception)
144138

145139
$PSCmdlet.ThrowTerminatingError(
146140
[System.Management.Automation.ErrorRecord]::new(
147-
$errorMessage,
141+
$exception,
148142
'GSDSP0001', # cSpell: disable-line
149143
[System.Management.Automation.ErrorCategory]::InvalidOperation,
150144
$principalName

source/Public/Revoke-SqlDscServerPermission.ps1

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,6 @@ function Revoke-SqlDscServerPermission
117117
$permissionSet.$permissionName = $true
118118
}
119119

120-
# Get the permissions names that are set to $true in the ServerPermissionSet.
121-
$permissionName = $permissionSet |
122-
Get-Member -MemberType 'Property' |
123-
Select-Object -ExpandProperty 'Name' |
124-
Where-Object -FilterScript {
125-
$permissionSet.$_
126-
}
127-
128120
try
129121
{
130122
if ($WithGrant.IsPresent)
@@ -138,11 +130,13 @@ function Revoke-SqlDscServerPermission
138130
}
139131
catch
140132
{
141-
$errorMessage = $script:localizedData.ServerPermission_Revoke_FailedToRevokePermission -f $principalName, $serverObject.InstanceName
133+
$errorMessage = $script:localizedData.ServerPermission_Revoke_FailedToRevokePermission -f $principalName, $serverObject.InstanceName, ($Permission -join ',')
134+
135+
$exception = [System.InvalidOperationException]::new($errorMessage, $_.Exception)
142136

143137
$PSCmdlet.ThrowTerminatingError(
144138
[System.Management.Automation.ErrorRecord]::new(
145-
$errorMessage,
139+
$exception,
146140
'RSDSP0001', # cSpell: disable-line
147141
[System.Management.Automation.ErrorCategory]::InvalidOperation,
148142
$principalName

source/Public/Test-SqlDscIsRole.ps1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<#
22
.SYNOPSIS
3-
Returns whether the database principal exists and is a database role.
3+
Returns whether the server principal exists and is a server role.
44
55
.DESCRIPTION
6-
Returns whether the database principal exist and is a database role.
6+
Returns whether the server principal exist and is a server role.
77
88
.PARAMETER ServerObject
99
Specifies current server connection object.
1010
1111
.PARAMETER Name
12-
Specifies the name of the database principal.
12+
Specifies the name of the server principal.
1313
1414
.OUTPUTS
1515
[System.Boolean]
@@ -18,7 +18,7 @@
1818
$serverInstance = Connect-SqlDscDatabaseEngine
1919
Test-SqlDscIsRole -ServerObject $serverInstance -Name 'MyPrincipal'
2020
21-
Returns $true if the principal exist as role, if not $false is returned.
21+
Returns $true if the principal exist as a server role, if not $false is returned.
2222
#>
2323
function Test-SqlDscIsRole
2424
{

0 commit comments

Comments
 (0)