Skip to content

Remove-DbaPrivilege - Revoking a Windows privilege still means hand-editing a secedit export #10617

Description

@andreasjordan

Summary

dbatools can audit Windows privileges (Get-DbaPrivilege) and grant them (Set-DbaPrivilege), but it cannot revoke one. There is no Remove-DbaPrivilege, so undoing a grant - a wrongly targeted LPIM, an IFI grant that a security review wants gone, a service account that changed - currently means exporting the local security policy with secedit /export, hand-editing the SID out of the right's line, and re-importing with secedit /configure. That is exactly the manual work the Get/Set pair was written to remove.

Looking through the history, the gap seems to be nobody-asked rather than a decision: the pair arrived as bare initial commits, no issue or PR for a remove has ever existed, and the closest discussion (#7433) was about process token privileges, which the maintainers correctly identified as a different problem.

Proposed command

Remove-DbaPrivilege, mirroring Set-DbaPrivilege:

Remove-DbaPrivilege -ComputerName sql1 -Type LPIM,IFI                      # revoke from SQL service accounts / per-service SIDs
Remove-DbaPrivilege -ComputerName sql1 -Type IFI -User "CONTOSO\OldSvc"    # revoke from a specific account

Same -Type set (IFI, LPIM, BatchLogon, SecAudit, ServiceLogon, CreateGlobalObjects), same automatic service-account discovery when -User is not given (including the NT SERVICE\<ServiceName> per-service SIDs that Set-DbaPrivilege uses for IFI/LPIM/SecAudit), SupportsShouldProcess, and a warning when the account does not hold the privilege.

Two implementation shapes

  1. Reuse the secedit machinery. Set-DbaPrivilege already exports the policy, edits the SeXxx = *SID,*SID line, and runs secedit /configure /areas USER_RIGHTS. Removing is the inverse edit: strip the SID position-independently from the line and re-apply. Smallest possible diff, consistent with the existing pair, inherits its remoting/credential behavior.

  2. Use the LSA API. LsaRemoveAccountRights (with LsaAddAccountRights / LsaEnumerateAccountsWithUserRight for the rest of the family) is the API that secedit itself sits on: no temp files, no cfg parsing, no fixed-offset Substring() calls. Verified working remotely over RPC/SMB, including with alternate credentials via LogonUser/LOGON32_LOGON_NEW_CREDENTIALS impersonation - but that is a bigger P/Invoke investment and changes the transport (port 445 instead of WinRM), so it would make more sense as a later reimplementation of the whole privilege family than as the price of admission for a remove command.

Shape 1 gets users unblocked; shape 2 is the better long-term home. I am happy to contribute shape 1 if there is interest.

Related: #10616 fixes the credential handling of the existing pair.


created by Claude and reviewed by Andreas Jordan

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions