@@ -4,7 +4,7 @@ function Get-DbaPrivilege {
44 Retrieves Windows security privileges critical for SQL Server performance from target computers.
55
66 . DESCRIPTION
7- Audits five Windows privileges that directly impact SQL Server performance and functionality: Lock Pages in Memory, Instant File Initialization, Logon as Batch, Generate Security Audits, and Logon as a Service. These privileges are essential for SQL Server service accounts to achieve optimal performance and proper operation.
7+ Audits six Windows privileges that directly impact SQL Server performance and functionality: Lock Pages in Memory, Instant File Initialization, Logon as Batch, Generate Security Audits, Logon as a Service, and Create Global Objects . These privileges are essential for SQL Server service accounts to achieve optimal performance and proper operation.
88
99 Use this to verify that SQL Server service accounts have the necessary Windows privileges configured, troubleshoot performance issues related to missing privileges, or audit security configurations across your SQL Server environment. The function exports the local security policy using secedit and parses the results to show which users and groups hold these critical privileges.
1010
@@ -36,7 +36,7 @@ function Get-DbaPrivilege {
3636 . OUTPUTS
3737 PSCustomObject
3838
39- Returns one object per unique user or group found across the five Windows security privileges being audited.
39+ Returns one object per unique user or group found across the six Windows security privileges being audited.
4040
4141 Properties:
4242 - ComputerName: The name of the computer where the privilege audit was performed
@@ -46,6 +46,7 @@ function Get-DbaPrivilege {
4646 - LockPagesInMemory: Boolean indicating if the user has SeLockMemoryPrivilege
4747 - GenerateSecurityAudit: Boolean indicating if the user has SeAuditPrivilege
4848 - LogonAsAService: Boolean indicating if the user has SeServiceLogonRight privilege
49+ - CreateGlobalObjects: Boolean indicating if the user has SeCreateGlobalPrivilege (required by some backup agents)
4950
5051 . EXAMPLE
5152 PS C:\> Get-DbaPrivilege -ComputerName sqlserver2014a
@@ -73,15 +74,17 @@ function Get-DbaPrivilege {
7374 )
7475
7576 begin {
76- function Convert-SIDToUserName ([string ] $SID ) {
77- try {
78- $objSID = New-Object System.Security.Principal.SecurityIdentifier ($SID )
79- $objUser = $objSID.Translate ([System.Security.Principal.NTAccount ])
80- $objUser.Value
81- } catch {
82- $SID
83- }
84- }
77+ $ResolveSIDToAccountName = @"
78+ function Convert-SIDToUserName ([string] `$ SID ) {
79+ try {
80+ `$ objSID = New-Object System.Security.Principal.SecurityIdentifier (`$ SID)
81+ `$ objUser = `$ objSID.Translate([System.Security.Principal.NTAccount])
82+ `$ objUser.Value
83+ } catch {
84+ `$ SID
85+ }
86+ }
87+ "@
8588
8689 $ComputerName = $ComputerName.ComputerName | Select-Object - Unique
8790
@@ -96,100 +99,135 @@ function Get-DbaPrivilege {
9699
97100 try {
98101 Write-Message - Level Verbose - Message " Exporting Privileges on $computer and cleaning up temporary files"
99- $secPol = Invoke-Command2 - Raw - ComputerName $computer - Credential $Credential - ScriptBlock {
102+ $privData = Invoke-Command2 - Raw - ComputerName $computer - Credential $Credential - ArgumentList $ResolveSIDToAccountName - ScriptBlock {
103+ param ($ResolveSIDToAccountName )
104+ . ([ScriptBlock ]::Create($ResolveSIDToAccountName ))
105+
100106 $temp = ([System.IO.Path ]::GetTempPath()).TrimEnd(" " )
101107 secedit / export / cfg $temp \secpolByDbatools.cfg > $null
102108 $CFG = Get-Content $temp \secpolByDbatools.cfg - Force
103109 Remove-Item $temp \secpolByDbatools.cfg - Force
104- $CFG
105- }
106110
107- Write-Message - Level Verbose - Message " Getting Batch Logon Privileges on $computer "
108- $blEntries = $secPol | Where-Object { $_ -like " SeBatchLogonRight*" }
109-
110- $bl = if ($null -ne $blEntries ) {
111- $blEntries.Substring (20 ).Split(" ," ) | ForEach-Object {
112- if ($_ -match ' ^\*S-' ) {
113- Convert-SIDToUserName - SID $_.TrimStart (' *' )
114- } else {
115- $_
111+ $blEntries = $CFG | Where-Object { $_ -like " SeBatchLogonRight*" }
112+ $bl = if ($null -ne $blEntries ) {
113+ $blEntries.Substring (20 ).Split(" ," ) | ForEach-Object {
114+ if ($_ -match ' ^\*S-' ) {
115+ <# DO NOT use Write-Message as this is inside of a script block #>
116+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
117+ } else {
118+ $_
119+ }
120+ }
121+ }
122+
123+ $ifiEntries = $CFG | Where-Object { $_ -like ' SeManageVolumePrivilege*' }
124+ $ifi = if ($null -ne $ifiEntries ) {
125+ $ifiEntries.Substring (26 ).Split(" ," ) | ForEach-Object {
126+ if ($_ -match ' ^\*S-' ) {
127+ <# DO NOT use Write-Message as this is inside of a script block #>
128+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
129+ } else {
130+ $_
131+ }
132+ }
133+ }
134+
135+ $lpimEntries = $CFG | Where-Object { $_ -like ' SeLockMemoryPrivilege*' }
136+ $lpim = if ($null -ne $lpimEntries ) {
137+ $lpimEntries.Substring (24 ).Split(" ," ) | ForEach-Object {
138+ if ($_ -match ' ^\*S-' ) {
139+ <# DO NOT use Write-Message as this is inside of a script block #>
140+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
141+ } else {
142+ $_
143+ }
144+ }
145+ }
146+
147+ $gsaEntries = $CFG | Where-Object { $_ -like ' SeAuditPrivilege*' }
148+ $gsa = if ($null -ne $gsaEntries ) {
149+ $gsaEntries.Substring (19 ).Split(" ," ) | ForEach-Object {
150+ if ($_ -match ' ^\*S-' ) {
151+ <# DO NOT use Write-Message as this is inside of a script block #>
152+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
153+ } else {
154+ $_
155+ }
156+ }
157+ }
158+
159+ $losEntries = $CFG | Where-Object { $_ -like " SeServiceLogonRight*" }
160+ $los = if ($null -ne $losEntries ) {
161+ $losEntries.Substring (22 ).split(" ," ) | ForEach-Object {
162+ if ($_ -match ' ^\*S-' ) {
163+ <# DO NOT use Write-Message as this is inside of a script block #>
164+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
165+ } else {
166+ $_
167+ }
168+ }
169+ }
170+
171+ $cgoEntries = $CFG | Where-Object { $_ -like " SeCreateGlobalPrivilege*" }
172+ $cgo = if ($null -ne $cgoEntries ) {
173+ $cgoEntries.Substring (26 ).Split(" ," ) | ForEach-Object {
174+ if ($_ -match ' ^\*S-' ) {
175+ <# DO NOT use Write-Message as this is inside of a script block #>
176+ Convert-SIDToUserName - SID $_.TrimStart (' *' )
177+ } else {
178+ $_
179+ }
116180 }
117181 }
182+
183+ [PSCustomObject ]@ {
184+ BatchLogon = $bl
185+ InstantFileInitialization = $ifi
186+ LockPagesInMemory = $lpim
187+ GenerateSecurityAudit = $gsa
188+ LogonAsAService = $los
189+ CreateGlobalObjects = $cgo
190+ }
118191 }
119192
193+ $bl = @ ($privData.BatchLogon )
194+ $ifi = @ ($privData.InstantFileInitialization )
195+ $lpim = @ ($privData.LockPagesInMemory )
196+ $gsa = @ ($privData.GenerateSecurityAudit )
197+ $los = @ ($privData.LogonAsAService )
198+ $cgo = @ ($privData.CreateGlobalObjects )
199+
200+ Write-Message - Level Verbose - Message " Getting Batch Logon Privileges on $computer "
120201 if ($bl.count -eq 0 ) {
121202 Write-Message - Level Verbose - Message " No users with Batch Logon Rights on $computer "
122203 }
123204
124205 Write-Message - Level Verbose - Message " Getting Instant File Initialization Privileges on $computer "
125- $ifiEntries = $secPol | Where-Object { $_ -like ' SeManageVolumePrivilege*' }
126-
127- $ifi = if ($null -ne $ifiEntries ) {
128- $ifiEntries.Substring (26 ).Split(" ," ) | ForEach-Object {
129- if ($_ -match ' ^\*S-' ) {
130- Convert-SIDToUserName - SID $_.TrimStart (' *' )
131- } else {
132- $_
133- }
134- }
135- }
136-
137206 if ($ifi.count -eq 0 ) {
138207 Write-Message - Level Verbose - Message " No users with Instant File Initialization Rights on $computer "
139208 }
140209
141210 Write-Message - Level Verbose - Message " Getting Lock Pages in Memory Privileges on $computer "
142- $lpimEntries = $secPol | Where-Object { $_ -like ' SeLockMemoryPrivilege*' }
143-
144- $lpim = if ($null -ne $lpimEntries ) {
145- $lpimEntries.Substring (24 ).Split(" ," ) | ForEach-Object {
146- if ($_ -match ' ^\*S-' ) {
147- Convert-SIDToUserName - SID $_.TrimStart (' *' )
148- } else {
149- $_
150- }
151- }
152- }
153-
154211 if ($lpim.count -eq 0 ) {
155212 Write-Message - Level Verbose - Message " No users with Lock Pages in Memory Rights on $computer "
156213 }
157214
158215 Write-Message - Level Verbose - Message " Getting Generate Security Audits Privileges on $computer "
159- $gsaEntries = $secPol | Where-Object { $_ -like ' SeAuditPrivilege*' }
160-
161- $gsa = if ($null -ne $gsaEntries ) {
162- $gsaEntries.Substring (19 ).Split(" ," ) | ForEach-Object {
163- if ($_ -match ' ^\*S-' ) {
164- Convert-SIDToUserName - SID $_.TrimStart (' *' )
165- } else {
166- $_
167- }
168- }
169- }
170-
171216 if ($gsa.count -eq 0 ) {
172217 Write-Message - Level Verbose - Message " No users with Generate Security Audits Rights on $computer "
173218 }
174219
175220 Write-Message - Level Verbose - Message " Getting Logon as a service Privileges on $computer "
176- $losEntries = $secPol | Where-Object { $_ -like " SeServiceLogonRight*" }
177-
178- $los = if ($null -ne $losEntries ) {
179- $losEntries.Substring (22 ).split(" ," ) | ForEach-Object {
180- if ($_ -match ' ^\*S-' ) {
181- Convert-SIDToUserName - SID $_.TrimStart (' *' )
182- } else {
183- $_
184- }
185- }
186- }
187-
188221 if ($los.count -eq 0 ) {
189222 Write-Message - Level Verbose - Message " No users with Logon as a service Rights on $computer "
190223 }
191224
192- $users = @ () + $bl + $ifi + $lpim + $gsa + $los | Select-Object - Unique
225+ Write-Message - Level Verbose - Message " Getting Create Global Objects Privileges on $computer "
226+ if ($cgo.count -eq 0 ) {
227+ Write-Message - Level Verbose - Message " No users with Create Global Objects Rights on $computer "
228+ }
229+
230+ $users = @ () + $bl + $ifi + $lpim + $gsa + $los + $cgo | Select-Object - Unique
193231 $users | ForEach-Object {
194232 [PSCustomObject ]@ {
195233 ComputerName = $computer
@@ -199,6 +237,7 @@ function Get-DbaPrivilege {
199237 LockPagesInMemory = $lpim -contains $_
200238 GenerateSecurityAudit = $gsa -contains $_
201239 LogonAsAService = $los -contains $_
240+ CreateGlobalObjects = $cgo -contains $_
202241 }
203242 }
204243
@@ -207,4 +246,4 @@ function Get-DbaPrivilege {
207246 }
208247 }
209248 }
210- }
249+ }
0 commit comments