@@ -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