Classes/UacManager.ps1

class UacManager {
    [LibraryContext]$Context
    
    UacManager([LibraryContext]$context) {
        $this.Context = $context
    }

    [void]SetUac([string]$action) {
        # Define the registry path
        $path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"

        # Define the property values for each action
        $settings = @{
            "enabled" = @{
                'ConsentPromptBehaviorAdmin' = 5
                'ConsentPromptBehaviorUser' = 3
                'EnableInstallerDetection' = 1
                'EnableLUA' = 1
                'EnableVirtualization' = 1
                'PromptOnSecureDesktop' = 1
                'ValidateAdminCodeSignatures' = 0
                'FilterAdministratorToken' = 0
            }
            "disabled" = @{
                'ConsentPromptBehaviorAdmin' = 0
                'ConsentPromptBehaviorUser' = 0
                'EnableInstallerDetection' = 0
                'EnableLUA' = 0
                'EnableVirtualization' = 0
                'PromptOnSecureDesktop' = 0
                'ValidateAdminCodeSignatures' = 0
                'FilterAdministratorToken' = 0
            }
        }

        # Select the appropriate settings based on the action
        $properties = $settings[$action]

        # Loop through the properties and apply the registry changes
        foreach ($property in $properties.GetEnumerator()) {
            $this.Context.LogManager.Log("Setting $($property.Key) to $($property.Value)")
            New-ItemProperty -Path $path -Name $property.Key -Value $property.Value -PropertyType DWORD -Force | Out-Null
        }

        $this.Context.LogManager.Log("UAC has been $action.")
    }

    [void] AddLocalAdmin([string]$username) {
        # Resolve the (localized) Administrators group name from its SID
        $adminSid = [System.Security.Principal.SecurityIdentifier]::new(
            [System.Security.Principal.WellKnownSidType]::BuiltinAdministratorsSid, $null
        )
        $adminGroupName = ($adminSid.Translate([System.Security.Principal.NTAccount])).Value.Split('\')[-1]
        
        # Ensure local user exists (create with a random password if missing)
        $user = Get-LocalUser -Name $username -ErrorAction SilentlyContinue
        if (-not $user) {
            $passwd = ConvertTo-SecureString -String (-join ((33..126) | Get-Random -Count 20 | ForEach-Object {[char]$_})) -AsPlainText -Force
            $user = New-LocalUser -Name $username -Password $passwd -Description "Windows LAPS Admin Account" -AccountNeverExpires -PasswordNeverExpires -ErrorAction Stop
            $this.Context.LogManager.Log("Created local user '$username'")
        } else {
            $this.Context.LogManager.Log("User '$username' already exists -- skip create", "INFO", $false)
        }
    
        # Add to Administrators if not already a member (compare by SID)
        $userSid = $user.SID.Value
        $members = Get-LocalGroupMember -Group $adminGroupName -ErrorAction SilentlyContinue
        $inAdmins = ($members | Where-Object { $_.SID.Value -eq $userSid }) -ne $null
        
        if ($inAdmins) {
            $this.Context.LogManager.Log("User '$username' is already a local admin -- skip adding", "INFO", $false)
        } else {
            Add-LocalGroupMember -Group $adminGroupName -Member $username -ErrorAction Stop
            $this.Context.LogManager.Log("Added user '$username' to '$adminGroupName'")
        }
    }

    [void] RemoveLocalUser([string]$username) {
        # Ensure local user exists (create with a random password if missing)
        $user = Get-LocalUser -Name $username -ErrorAction SilentlyContinue
        if ($user) {
            Remove-LocalUser -Name $username -ErrorAction Stop
            $this.Context.LogManager.Log("Removed local user '$username'")
        } else {
            $this.Context.LogManager.Log("No local user '$username'", "INFO", $false)
        }
    }
}