Private/Add-PrivilegeRight.ps1
function Add-PrivilegeRight { <# .SYNOPSIS Adds privilege rights (empty or parameter-based) to the specified collection. .DESCRIPTION The Add-PrivilegeRight function consolidates the logic for adding both empty privilege rights and parameter-based rights to a collection. It accepts a collection (or creates a new one if not provided) and a hashtable/dictionary of rights to add, where each key is the privilege right name and the value is a member list (which can be empty). The function uses internal mappings for privilege right descriptions and ensures consistent object structure for downstream processing. .PARAMETER Collection The collection to add privilege rights to. If not provided or null, a new System.Collections.Generic.List[object] collection will be created and returned. .PARAMETER RightsToAdd A hashtable or dictionary where keys are privilege right names and values are member lists (can be empty). Each right will be added to the collection with its associated members. .EXAMPLE $rightsCollection = [System.Collections.Generic.List[object]]::new() $rightsToAdd = @{ 'SeDenyInteractiveLogonRight' = @('Everyone') } Add-PrivilegeRight -Collection $rightsCollection -RightsToAdd $rightsToAdd Adds the 'SeDenyInteractiveLogonRight' privilege with 'Everyone' as a member to the specified collection. .EXAMPLE $rightsCollection = [System.Collections.Generic.List[object]]::new() $emptyRights = @{ 'SeTrustedCredManAccessPrivilege' = @() 'SeTcbPrivilege' = @() } Add-PrivilegeRight -Collection $rightsCollection -RightsToAdd $emptyRights Adds two empty privilege rights to the collection. .INPUTS System.Collections.Generic.List[object] System.Collections.IDictionary You can pipe a hashtable of rights to the RightsToAdd parameter. .OUTPUTS System.Collections.Generic.List[object] Returns the updated collection with the added privilege rights. .NOTES Used Functions: Name ║ Module/Namespace ═════════════════════════════════╬══════════════════════════════ Add-PrivilegeRight ║ EguibarIT.DelegationPS (Private) Write-Verbose ║ Microsoft.PowerShell.Utility Write-Warning ║ Microsoft.PowerShell.Utility Write-Debug ║ Microsoft.PowerShell.Utility Get-FunctionDisplay ║ EguibarIT.DelegationPS (Private) .NOTES Version: 3.1 DateModified: 06/Jun/2025 LastModifiedBy: Vicente Rodriguez Eguibar vicente@eguibarit.com Eguibar IT http://www.eguibarit.com .LINK https://github.com/vreguibar/EguibarIT.DelegationPS/blob/main/Private/Add-PrivilegeRight.ps1 .COMPONENT Group Policy .ROLE Security Configuration .FUNCTIONALITY Group Policy Management, Privilege Rights Consolidation #> [CmdletBinding( SupportsShouldProcess = $false, ConfirmImpact = 'Low' )] [OutputType([System.Collections.Generic.List[object]])] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, HelpMessage = 'Collection to add privilege rights to, most likely from PSBoundParameters from calling function', Position = 0)] [System.Collections.IDictionary] $RightsToAdd ) Begin { # mapping hashtable containing: # Keys as privilege right names (e.g. SeNetworkLogonRight, SeDenyNetworkLogonRight) # Values as description of the right (e.g. 'Access this computer from the network', 'Deny access to this computer from the network') # This mapping is used to provide descriptions for the rights being added $rightMappings = @{ # Empty by default rights 'SeTrustedCredManAccessPrivilege' = 'Access Credential Manager as a trusted caller' 'SeTcbPrivilege' = 'Act as part of the operating system' 'SeCreateTokenPrivilege' = 'Create a token object' 'SeCreatePermanentPrivilege' = 'Create permanent shared objects' 'SeDebugPrivilege' = 'Debug programs' 'SeLockMemoryPrivilege' = 'Lock pages in memory' # Parameter mapped rights 'SeDenyBatchLogonRight' = 'Deny log on as a batch job' 'SeDenyInteractiveLogonRight' = 'Deny log on locally' 'SeDenyNetworkLogonRight' = 'Deny access to this computer from the network' 'SeDenyRemoteInteractiveLogonRight' = 'Deny log on through Remote Desktop Services' 'SeDenyServiceLogonRight' = 'Deny log on as a service' 'SeEnableDelegationPrivilege' = 'Enable computer and user accounts to be trusted for delegation' 'SeNetworkLogonRight' = 'Access this computer from the network' 'SeRemoteInteractiveLogonRight' = 'Allow log on through Remote Desktop Services' 'SeBatchLogonRight' = 'Log on as a batch job' 'SeInteractiveLogonRight' = 'Allow log on locally' 'SeServiceLogonRight' = 'Log on as a service' 'SeMachineAccountPrivilege' = 'Add workstations to domain' 'SeIncreaseQuotaPrivilege' = 'Adjust memory quotas for a process' 'SeBackupPrivilege' = 'Back up files and directories' 'SeChangeNotifyPrivilege' = 'Bypass traverse checking' 'SeSystemtimePrivilege' = 'Change the system time' 'SeTimeZonePrivilege' = 'Change the time zone' 'SeCreatePagefilePrivilege' = 'Create a pagefile' 'SeCreateGlobalPrivilege' = 'Create global objects' 'SeCreateSymbolicLinkPrivilege' = 'Create symbolic links' 'SeRemoteShutdownPrivilege' = 'Force shutdown from a remote system' 'SeAuditPrivilege' = 'Generate security audits' 'SeImpersonatePrivilege' = 'Impersonate a client after authentication' 'SeIncreaseWorkingSetPrivilege' = 'Increase a process working set' 'SeIncreaseBasePriorityPrivilege' = 'Increase scheduling priority' 'SeLoadDriverPrivilege' = 'Load and unload device drivers' 'SeSecurityPrivilege' = 'Manage auditing and security log' 'SeRelabelPrivilege' = 'Modify an object label' 'SeSystemEnvironmentPrivilege' = 'Modify firmware environment values' 'SeDelegateSessionUserImpersonatePrivilege' = 'Obtain an impersonation token for another user in the same session' 'SeManageVolumePrivilege' = 'Perform volume maintenance tasks' 'SeProfileSingleProcessPrivilege' = 'Profile single process' 'SeSystemProfilePrivilege' = 'Profile system performance' 'SeUndockPrivilege' = 'Remove computer from docking station' 'SeAssignPrimaryTokenPrivilege' = 'Replace a process level token' 'SeRestorePrivilege' = 'Restore files and directories' 'SeShutdownPrivilege' = 'Shut down the system' 'SeSyncAgentPrivilege' = 'Synchronize directory service data' 'SeTakeOwnershipPrivilege' = 'Take ownership of files or other objects' } # mapping hashtable containing: # Keys as privilege right name (matching parameter name, e.g. NetworkLogon, DenyNetworkLogon) # values as the actual privilege right name (e.g. SeNetworkLogonRight, SeDenyNetworkLogonRight) # This mapping is used to convert parameter names to actual privilege right names $parameterMappings = @{ 'NetworkLogon' = 'SeNetworkLogonRight' 'DenyNetworkLogon' = 'SeDenyNetworkLogonRight' 'InteractiveLogon' = 'SeInteractiveLogonRight' 'DenyInteractiveLogon' = 'SeDenyInteractiveLogonRight' 'RemoteInteractiveLogon' = 'SeRemoteInteractiveLogonRight' 'DenyRemoteInteractiveLogon' = 'SeDenyRemoteInteractiveLogonRight' 'BatchLogon' = 'SeBatchLogonRight' 'DenyBatchLogon' = 'SeDenyBatchLogonRight' 'ServiceLogon' = 'SeServiceLogonRight' 'DenyServiceLogon' = 'SeDenyServiceLogonRight' 'MachineAccount' = 'SeMachineAccountPrivilege' 'IncreaseQuota' = 'SeIncreaseQuotaPrivilege' 'Backup' = 'SeBackupPrivilege' 'ChangeNotify' = 'SeChangeNotifyPrivilege' 'SystemTime' = 'SeSystemtimePrivilege' 'TimeZone' = 'SeTimeZonePrivilege' 'CreatePagefile' = 'SeCreatePagefilePrivilege' 'CreateGlobal' = 'SeCreateGlobalPrivilege' 'CreateSymbolicLink' = 'SeCreateSymbolicLinkPrivilege' 'EnableDelegation' = 'SeEnableDelegationPrivilege' 'RemoteShutdown' = 'SeRemoteShutdownPrivilege' 'Audit' = 'SeAuditPrivilege' 'Impersonate' = 'SeImpersonatePrivilege' 'IncreaseWorkingSet' = 'SeIncreaseWorkingSetPrivilege' 'IncreaseBasePriority' = 'SeIncreaseBasePriorityPrivilege' 'LoadDriver' = 'SeLoadDriverPrivilege' 'AuditSecurity' = 'SeSecurityPrivilege' 'Relabel' = 'SeRelabelPrivilege' 'SystemEnvironment' = 'SeSystemEnvironmentPrivilege' 'DelegateSessionUserImpersonate' = 'SeDelegateSessionUserImpersonatePrivilege' 'ManageVolume' = 'SeManageVolumePrivilege' 'ProfileSingleProcess' = 'SeProfileSingleProcessPrivilege' 'SystemProfile' = 'SeSystemProfilePrivilege' 'Undock' = 'SeUndockPrivilege' 'AssignPrimaryToken' = 'SeAssignPrimaryTokenPrivilege' 'Restore' = 'SeRestorePrivilege' 'Shutdown' = 'SeShutdownPrivilege' 'SyncAgent' = 'SeSyncAgentPrivilege' 'TakeOwnership' = 'SeTakeOwnershipPrivilege' 'TrustedCredMan' = 'SeTrustedCredManAccessPrivilege' } # Array containing privilege rights that are empty by default # These rights are added to the collection without any members $emptyRights = @( 'SeTrustedCredManAccessPrivilege', 'SeTcbPrivilege', 'SeCreateTokenPrivilege', 'SeCreatePermanentPrivilege', 'SeDebugPrivilege', 'SeLockMemoryPrivilege' ) Write-Warning -Message 'Creating a new collection.' $Collection = [System.Collections.Generic.List[object]]::new() } #end Begin Process { #region Process Empty Member Rights Write-Debug -Message ('Processing {0} empty member rights' -f $emptyRights.Count) # iterate over the empty rights and lookup each right in the mappings. finally add them to the collection foreach ($right in $emptyRights) { # Directly add the right to the collection to avoid parameter binding issues $rightHash = @{ Section = 'Privilege Rights' Key = $right Members = [System.Collections.Generic.List[string]]::new() Description = $rightMappings[$right] } try { # Adding empty right directly to collection $Collection.Add($rightHash) Write-Debug -Message ('Added empty right {0} directly to collection' -f $right) } catch { Write-Warning -Message ('Failed to add empty right {0}: {1}' -f $right, $_.Exception.Message) } #end try-catch } #end foreach #endregion Process Empty Member Rights # Start processing the privilege rights based on bound parameters $totalParameters = ($RightsToAdd.Keys | Where-Object { $RightsToAdd.ContainsKey($_) }).Count $current = 0 # iterate through each bound parameter (e.g. NetworkLogon, DenyNetworkLogon, etc.). # This is equal to the parameter name and is coming from the calling function PSBoundParameters # The right variable will be the key in the $parameterMappings dictionary foreach ($right in $RightsToAdd.Keys) { # Skip GpoToModify, Confirm, Debug, Verbose parameters, as those may be included in the PSBoundParameter collection if ($right -eq 'GpoToModify' -or $right -eq 'Confirm' -or $right -eq 'Verbose' -or $right -eq 'Debug' ) { continue } #end if # Check if parameter is in our mapping. (e.g. NetworkLogon, DenyNetworkLogon, etc.). # If it is, we will process it and add the right to the collection. # If not, we will skip it. if ($parameterMappings.ContainsKey($right)) { $current++ $percentComplete = ($current / $totalParameters) * 100 $Splat = @{ Activity = 'Processing privilege rights' Status = 'Processing {0}' -f $right PercentComplete = $percentComplete } Write-Progress @Splat # get the Key representing the right to add (e.g. SeNetworkLogonRight, SeDenyNetworkLogonRight, etc.) $rightKey = $parameterMappings[$right] # get the members to be assigned to the right. # This is the value pair og the key, coming the BoundParameters dictionary $members = $RightsToAdd[$right] # We have all information we need to add the right to the collection. # now we have to check members: # If KEY already contains members, check each member (SID string) and ensure it exists. # Then, process new members. Ensure each new member exist and has a SID. Extract the SID and add it to the members list. if ($null -eq $members) { $members = [System.Collections.Generic.List[string]]::new() } #end if $rightHash = @{ Section = 'Privilege Rights' Key = $rightKey Members = $members Description = $rightMappings[$right] } try { $Collection.Add($rightHash) Write-Debug -Message ('Added right {0} to collection' -f $right) } catch { Write-Warning -Message ('Failed to add right {0}: {1}' -f $right, $_.Exception.Message) } #end try-catch } #end if } #end foreach } #end Process End { Write-Verbose -Message ('Finalizing collection with {0} items' -f $Collection.Count) # Finalize the collection and return it return $Collection } #end End } #end function Add-PrivilegeRight |