Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Grant multiple privileges with Powershell

I had to learn how to grant local security privileges programmatically. I found a solution (Script Grant "Log on as a service" rights by using PowerShell [gal ****lery.technet.microsoft.com]) for granting one privilege. I needed to grant multiple privileges to a service account, so I added a simple array and loop through them. I'm sure it's inefficient, but for modifying under 10 lines from the original script, I can live with it. And yes, of course I know that domain group policy can handle this better. This was just a quick-and-dirty fix for testing. And there's nothing more permanent than temporary!

param($accountToAdd)
#written by Ingo Karstein, http://blog.karstein-consulting.com
#  v1.0, 01/03/2014
#  v1.1 2020-03-04

# References
#    script found at https://gallery.technet.microsoft.com/scriptcenter/Grant-Log-on-as-a-service-11a50893
#    why to run this at all https://social.technet.microsoft.com/wiki/contents/articles/24494.sharepoint-2013-an-exception-occurred-when-trying-to-establish-endpoint-for-context-could-not-load-file-or-assembly.aspx
#    additional priv names https://support.microsoft.com/en-us/help/821546/overview-of-the-impersonate-a-client-after-authentication-and-the-crea

## <--- Configure here if( [string]::IsNullOrEmpty($accountToAdd) ) { Write-Host "no account specified" exit } ## ---> End of Config

$sidstr = $null
try {
    $ntprincipal = new-object System.Security.Principal.NTAccount "$accountToAdd"
    $sid = $ntprincipal.Translate([System.Security.Principal.SecurityIdentifier])
    $sidstr = $sid.Value.ToString()
} catch {
    $sidstr = $null
}

Write-Host "Account: $($accountToAdd)" -ForegroundColor DarkCyan

if( [string]::IsNullOrEmpty($sidstr) ) {
    Write-Host "Account not found!" -ForegroundColor Red
    exit -1
}

Write-Host "Account SID: $($sidstr)" -ForegroundColor DarkCyan

$tmp = [System.IO.Path]::GetTempFileName()

Write-Host "Export current Local Security Policy" -ForegroundColor DarkCyan
secedit.exe /export /cfg "$($tmp)"

$c = Get-Content -Path $tmp

$RightsToGrant = @( "SeServiceLogonRight", "SeBatchLogonRight", "SeImpersonatePrivilege" )
$currentSetting = ""

ForEach ($thisRight in $RightsToGrant) {
    ForEach ($s in $c) {
        if( $s -like "$thisRight*") {
            $x = $s.split("=",[System.StringSplitOptions]::RemoveEmptyEntries)
            $currentSetting = $x[1].Trim()
        }
    }

    if( $currentSetting -notlike "*$($sidstr)*" ) {
        Write-Host "Modify Setting ""$thisRight""" -ForegroundColor DarkCyan

        if( [string]::IsNullOrEmpty($currentSetting) ) {
            $currentSetting = "*$($sidstr)"
        } else {
            $currentSetting = "*$($sidstr),$($currentSetting)"
        }

        Write-Host "$currentSetting"

        $outfile = @"
[Unicode]
Unicode=yes
[Version]
signature="`$CHICAGO`$"
Revision=1
[Privilege Rights]
$($thisRight) = $($currentSetting)
"@

        $tmp2 = [System.IO.Path]::GetTempFileName()

        Write-Host "Import new settings to Local Security Policy" -ForegroundColor DarkCyan
        $outfile | Set-Content -Path $tmp2 -Encoding Unicode -Force

        #notepad.exe $tmp2
        Push-Location (Split-Path $tmp2)

        try {
            secedit.exe /configure /db "secedit.sdb" /cfg "$($tmp2)" /areas USER_RIGHTS 
            #write-host "secedit.exe /configure /db ""secedit.sdb"" /cfg ""$($tmp2)"" /areas USER_RIGHTS "
        } finally { 
            Pop-Location
        }
    } else {
        Write-Host "NO ACTIONS REQUIRED! Account already in ""$thisRight""" -ForegroundColor DarkCyan
    }

}

Write-Host "Done." -ForegroundColor DarkCyan

Comments