Skip to content

Commit 5e0b70d

Browse files
Set-DbaPrivilege: Use per-service SID (NT SERVICE\ServiceName) for IFI, LPIM, SecAudit (#10228)
1 parent 2472ea8 commit 5e0b70d

1 file changed

Lines changed: 21 additions & 7 deletions

File tree

public/Set-DbaPrivilege.ps1

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,27 @@ function Convert-UserNameToSID ([string] `$Acc ) {
9696
$temp = ([System.IO.Path]::GetTempPath()).TrimEnd(""); secedit /export /cfg $temp\secpolByDbatools.cfg > $NULL;
9797
}
9898

99-
$SQLServiceAccounts = @();
99+
$SQLServiceAccounts = @()
100+
$SQLPerServiceSIDs = @()
100101
if (Test-Bound 'User') {
101-
$SQLServiceAccounts += $User;
102+
$SQLServiceAccounts += $User
103+
$SQLPerServiceSIDs += $User
102104
} else {
103105
Write-Message -Level Verbose -Message "Getting SQL Service Accounts on $computer"
104-
$SQLServiceAccounts += (Get-DbaService -ComputerName $computer -Type Engine).StartName
106+
$services = Get-DbaService -ComputerName $computer -Type Engine
107+
$SQLServiceAccounts += $services.StartName
108+
# Per-service SIDs (NT SERVICE\<ServiceName>) are added to the service token by Windows
109+
# for all services on Vista/Server 2008 and later. SQL Server uses the per-service SID
110+
# for file operations (IFI) and memory operations (LPIM), matching setup.exe behavior.
111+
$SQLPerServiceSIDs += $services | ForEach-Object { "NT SERVICE\$($_.ServiceName)" }
105112
}
106113
if ($SQLServiceAccounts.count -ge 1) {
107114
Write-Message -Level Verbose -Message "Setting Privileges on $Computer"
108-
Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -Verbose -ArgumentList $ResolveAccountToSID, $SQLServiceAccounts, $Type -ScriptBlock {
115+
Invoke-Command2 -Raw -ComputerName $computer -Credential $Credential -Verbose -ArgumentList $ResolveAccountToSID, $SQLServiceAccounts, $SQLPerServiceSIDs, $Type -ScriptBlock {
109116
[CmdletBinding()]
110117
param ($ResolveAccountToSID,
111118
$SQLServiceAccounts,
119+
$SQLPerServiceSIDs,
112120
$Type
113121
)
114122
. ([ScriptBlock]::Create($ResolveAccountToSID))
@@ -137,7 +145,9 @@ function Convert-UserNameToSID ([string] `$Acc ) {
137145
}
138146
if ('IFI' -in $Type) {
139147
$IFIline = Get-Content $tempfile | Where-Object { $_ -match "SeManageVolumePrivilege" }
140-
ForEach ($acc in $SQLServiceAccounts) {
148+
# Use per-service SIDs for IFI: SQL Server uses the NT SERVICE\<ServiceName>
149+
# SID for volume maintenance tasks, matching SQL Server setup.exe behavior.
150+
ForEach ($acc in $SQLPerServiceSIDs) {
141151
$SID = Convert-UserNameToSID -Acc $acc;
142152
if (-not $IFIline) {
143153
$IFIline = "SeManageVolumePrivilege = *$SID"
@@ -158,7 +168,9 @@ function Convert-UserNameToSID ([string] `$Acc ) {
158168
}
159169
if ('LPIM' -in $Type) {
160170
$LPIMline = Get-Content $tempfile | Where-Object { $_ -match "SeLockMemoryPrivilege" }
161-
ForEach ($acc in $SQLServiceAccounts) {
171+
# Use per-service SIDs for LPIM: SQL Server uses the NT SERVICE\<ServiceName>
172+
# SID for locked memory pages, matching SQL Server setup.exe behavior.
173+
ForEach ($acc in $SQLPerServiceSIDs) {
162174
$SID = Convert-UserNameToSID -Acc $acc;
163175
if (-not $LPIMline) {
164176
$LPIMline = "SeLockMemoryPrivilege = *$SID"
@@ -179,7 +191,9 @@ function Convert-UserNameToSID ([string] `$Acc ) {
179191
}
180192
if ('SecAudit' -in $Type) {
181193
$Line = Get-Content $tempfile | Where-Object { $_ -match "SeAuditPrivilege" }
182-
ForEach ($acc in $SQLServiceAccounts) {
194+
# Use per-service SIDs for SecAudit: SQL Server uses the NT SERVICE\<ServiceName>
195+
# SID when writing security audit events, matching SQL Server setup.exe behavior.
196+
ForEach ($acc in $SQLPerServiceSIDs) {
183197
$SID = Convert-UserNameToSID -Acc $acc;
184198
if (-not $Line) {
185199
$Line = "SeAuditPrivilege = *$SID"

0 commit comments

Comments
 (0)