Skip to content

Instantly share code, notes, and snippets.

@mavaddat
Last active May 28, 2023 19:37
Show Gist options
  • Save mavaddat/68c1084c5ae12f2288442e9286d51802 to your computer and use it in GitHub Desktop.
Save mavaddat/68c1084c5ae12f2288442e9286d51802 to your computer and use it in GitHub Desktop.
Grant a user Symbolic Links rights on Windows machines with PowerShell
#Requires -Version 3.0
function Add-SymLinkPermissions {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]
$UserAccount = $env:USERNAME
)
Write-Host 'Checking SymLink permissions...'
$sidstr = $null
if ( "$accountToAdd" -eq 'Everyone' ) {
$sidstr = 'S-1-1-0'
}
else {
try {
$NtPrincipal = New-Object System.Security.Principal.NTAccount "$UserAccount"
$sid = $NtPrincipal.Translate([System.Security.Principal.SecurityIdentifier])
$sidstr = $sid.Value.ToString()
}
catch {
$sidstr = $null
}
}
Write-Host "Account: $($UserAccount)" -ForegroundColor DarkCyan
if ( [string]::IsNullOrEmpty($sidstr) ) {
throw [System.ArgumentException]::new('UserAccount', 'UserAccount is not valid')
}
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
$currentSetting = ''
foreach ($s in $c) {
if ( $s -like 'SECreateSymbolicLinkPrivilege*') {
$x = $s.split('=', [System.StringSplitOptions]::RemoveEmptyEntries)
$currentSetting = $x[1].Trim()
}
}
if ( $currentSetting -notlike "*$($sidstr)*" ) {
Write-Host 'Need to add permissions to SymLink' -ForegroundColor Yellow
Write-Host 'Modify Setting "Create SymLink"' -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]
SECreateSymbolicLinkPrivilege = $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
Push-Location (Split-Path $tmp2)
try {
secedit.exe /configure /db 'secedit.sdb' /cfg "$($tmp2)" /areas USER_RIGHTS
}
finally {
Pop-Location
}
}
else {
Write-Host 'NO ACTIONS REQUIRED! Account already in "Create SymLink"' -ForegroundColor DarkCyan
Write-Host "Account $UserAccount already has permissions to SymLink" -ForegroundColor Green
return $true
}
}
If ($MyInvocation.InvocationName -eq '.') {
# Restart in admin rights if not already
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
$arguments = "& '" + $MyInvocation.MyCommand.Definition + "'"
Start-Process (Get-Process -PID $PID | Resolve-Path) -Verb runAs -ArgumentList $arguments
Break
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment