Functions/Add-ECSLocalGPOUserRightAssignment.ps1
Function Add-ECSLocalGPOUserRightAssignment { <# .SYNOPSIS Adds an identity to a Local Group Policy Object (GPO) user right assignments. .DESCRIPTION Add-ECSLocalGPOUserRightAssignment will add and identity to a Local Group Policy Object (GPO) user right assignments. This function is useful if you're looking to add a user right assignments to your local GPO. This function utilizes the Windows builtin SecEdit.exe to export the user rights list, and then this function parses the exported file. .PARAMETER Identity This parameter can be an array of identities. Local, Domain and SIDs are all vailed options. .EXAMPLE This example adds multiple users to the shutdown right. Both sids and local users. Add-ECSLocalGPOUserRightAssignment -Identity @("PCName\LocalGroup","S-1-5-32-555","domain\exampleuser") -SeShutdownPrivilege #> [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $True, HelpMessage="Enter an identity in the format of an NTAccount, SamAccountName of SID" )] [ValidateNotNullorEmpty()] [Alias('SID','AccountName','UserPrincipalName','SAMAccountName','NTAccount')] $Identity, [Parameter(Mandatory=$true)] [Validatescript( { #Getting a list of valid parameter values $SeceditNameValidationSet = $null $AllSeceditNamesToValidate = Show-ECSLocalGPOAvailableUserRightAssignments | Select-object -ExpandProperty SecEditName | sort-object #Creating a single line string, so if we find an invalid parameter, we can tell the user all the correct values Foreach ($SeceditNameToValidate in $AllSeceditNamesToValidate) { $SeceditNameValidationSet += """$SeceditNameToValidate""" } $SeceditNameValidationSet = $SeceditNameValidationSet -replace ('""','","') #Finally we validate the parameter If ($SeceditNameValidationSet -like "*$_*") { $true } else { Throw "Incorrect value, please use one of the following $($SeceditNameValidationSet)" } } )] [String]$SecEditName ) Process { ########################################################################################################## #Dynamic Params $TempDirectory = Get-childitem -Path env: | Where-Object {$_.name -eq "temp"} | select-object -ExpandProperty value $CurrentDateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $ExportOfSecuritySettingsName = "secedit_userrightassignment_export.tmp" $ExportofSecuritySettingsNameAndPath = $TempDirectory + "\" + $CurrentDateTime + "_" + $ExportOfSecuritySettingsName $ImportOfSecuritySettingsName = "secedit_userrightassignment_Import.tmp" $ImportofSecuritySettingsNameAndPath = $TempDirectory + "\" + $CurrentDateTime + "_" + $ImportOfSecuritySettingsName $SecEditStdOutPutFullFileName = $TempDirectory + "\" + $CurrentDateTime + "_" + "SeceditStdOutput.txt" $SecEditErrOutPutFullFileName = $TempDirectory + "\" + $CurrentDateTime + "_" + "SeceditErrOutput.txt" $FunctionRootPath = $PSScriptRoot $PowershellModuleRootPath = $($FunctionRootPath).Replace("\Functions","") $SIDRegexPattern = "S-\d-\d-\d+" #End Dynamic Parameters ########################################################################################################## ########################################################################################################## #Arrays to store results $AllDesiredIdentities = New-Object System.Collections.ArrayList $AllIdentities = New-Object System.Collections.ArrayList $FinalIdentites = New-Object System.Collections.ArrayList #End Arrays to store results ########################################################################################################## ########################################################################################################## #In verbose mode, we'll output the running values Write-Verbose -Message "##########################################################################################################" Write-Verbose -Message "Running Values" Write-verbose -Message "Export / Import Directory: $($TempDirectory)" Write-verbose -Message "TimeStamp Used for export file name: $($CurrentDateTime)" Write-verbose -Message "Export of user right assignment file name: $($ExportofSecuritySettingsNameAndPath)" Write-verbose -Message "Import of user right assignment file name: $($ImportofSecuritySettingsNameAndPath)" Write-verbose -Message "Secedit Standard Output file name: $($SecEditStdOutPutFullFileName)" Write-verbose -Message "Secedit Error Output file name: $($SecEditErrOutPutFullFileName)" Write-Verbose -Message "Function Root Path = $($FunctionRootPath)" Write-Verbose -Message "Powershell Module Root Path: $($PowershellModuleRootPath)" Write-Verbose -Message "User Right Assignment Selected: $($SecEditName)" Write-Verbose -Message "END Running Values" Write-Verbose -Message "##########################################################################################################" #End In verbose mode, we'll output the running values ########################################################################################################## ########################################################################################################## #Let's start by confirming all of desired ID's to add are legit. Write-Verbose -Message "##########################################################################################################" Write-Verbose -Message "Verifying ID's" Try { Foreach ($ID in $Identity) { If ($ID -match $SIDRegexPattern) { Write-Verbose -Message "The ID $($ID) is a SID, attempting a SID to account name translation" $SIDToAccount = Convert-ECSSIDToAccount -SID $ID -ErrorAction Stop $AllDesiredIdentities.Add($SIDToAccount) | Out-Null } Else { Write-Verbose -Message "The ID $($ID) is NOT a SID, attempting an account name to SID translation" $AccountToSID = Convert-ECSAccountToSID -AccountName $ID -ErrorAction Stop $AllDesiredIdentities.Add($AccountToSID) | Out-Null } } } Catch { $Exception = $_.Exception Write-error "$($Exception.Message)" Throw "We failed to translate at least one of the identities entered." } #End Let's start by confirming all of desired ID's to add are legit. ########################################################################################################## ########################################################################################################## #Let's get the current list of security rights Write-Verbose -Message "##########################################################################################################" Write-Verbose -Message "Getting current user rights assignments" Try { Write-Verbose "Attepting to get a current list of ID's that have access for the requested right" $AllCurrentSecurityRights = Get-ECSLocalGPOUserRightAssignment | Where-Object {$_.SecEditUserRightName -like $SecEditName} } Catch { $Exception = $_.Exception Write-error "$($Exception.Message)" Throw "We failed to get a current list of ID's." } #End Let's get the current list of security rights ########################################################################################################## ########################################################################################################## #Let's merge the SIDS and filter out redudancies Write-Verbose -Message "##########################################################################################################" Write-Verbose -Message "Merging current and desired ID's" Try { $AllIdentities += $AllDesiredIdentities | Select-Object -ExpandProperty SID $AllIdentities += $AllCurrentSecurityRights | Select-Object -ExpandProperty SIDWithOutTheAsterix $AllIdentities = $AllIdentities | Select-Object -Unique } Catch { $Exception = $_.Exception Write-error "$($Exception.Message)" Throw "We failed to get a current list of ID's." } Write-Verbose "We are importing the following SIDS" Foreach ($SID_ID in $AllIdentities) { Write-Verbose -Message "SID: $($SID_ID)" } #End Let's merge the SIDS and filter out redudancies ########################################################################################################## ########################################################################################################## #Format the SID arry as a single string so we can import it. Write-Verbose -Message "##########################################################################################################" Write-Verbose -Message "Formatting SID's for the import" If ($AllIdentities -ne $null) { $FinalIdentites = "$($SecEditName) = " Foreach ($SID_ID in $AllIdentities) { $FinalIdentites += "*$($SID_ID)," } #removing the trailing comma $FinalIdentites = $FinalIdentites -replace ",$","" Write-Verbose "Formatted String: $($FinalIdentites)" } Else { Write-Verbose "There are no SIDS to import!!!" } #End Format the SID arry as a single string so we can import it. ########################################################################################################## ########################################################################################################## #Complete the desired import Write-Verbose -Message "##########################################################################################################" If ($AllIdentities -ne $null) { Write-Verbose -Message "Executing import" $SeceditFile= @" [Unicode] Unicode=yes [Version] signature="`$CHICAGO`$" Revision=1 [Privilege Rights] $($FinalIdentites) "@ #Export new file $SeceditFile | Set-Content -Path $ImportofSecuritySettingsNameAndPath -Encoding Unicode -Force #Finally we'll attempt to import the setting $ImportLocalSecurity = Start-process -FilePath "secedit.exe" -ArgumentList "/configure /db ""secedit.sdb"" /cfg ""$ImportofSecuritySettingsNameAndPath"" /areas USER_RIGHTS " -Wait -NoNewWindow -PassThru -RedirectStandardOutput $($SecEditStdOutPutFullFileName) -RedirectStandardError $($SecEditErrOutPutFullFileName) -ErrorAction Stop if ($ImportLocalSecurity.ExitCode -ne 0) { Throw "Exit code $($ImportLocalSecurity.ExitCode) was not 0" } } #End Complete the desired import ########################################################################################################## } } |