調整一般使用者擁有特定服務啟動/關閉權限
程式有二個參數:
Username
帶入指定的使用者(一般使用者)的帳號名稱ServiceName
帶入指定的 Windows 服務名稱
(使用系統管理員的 Powershell 來執行)
範例:
.\Adjust-ServicePermissions.ps1 -Username Tony -ServiceName MyService
互動式程式,按下 y 確認
# Adjust-ServicePermissions.ps1 | |
# A script to adjust permissions for Windows services and SCMANAGER | |
param( | |
[Parameter(Mandatory=$true, Position=0, HelpMessage="Username to grant permissions to")] | |
[string]$Username, | |
[Parameter(Mandatory=$true, Position=1, HelpMessage="Service name to modify")] | |
[string]$ServiceName | |
) | |
function Write-Log { | |
param([string]$Message) | |
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" | |
$logMessage = "[$timestamp] $Message" | |
Write-Host $logMessage | |
# Create logs directory if it doesn't exist | |
$logDir = Join-Path -Path $PSScriptRoot -ChildPath "logs" | |
if (-not (Test-Path -Path $logDir)) { | |
New-Item -ItemType Directory -Path $logDir | Out-Null | |
} | |
# Append to log file | |
$logFile = Join-Path -Path $logDir -ChildPath "service_permissions_$(Get-Date -Format 'yyyyMMdd').log" | |
Add-Content -Path $logFile -Value $logMessage | |
} | |
function Show-Usage { | |
Write-Host "USAGE: .\Adjust-ServicePermissions.ps1 <username> <servicename>" | |
Write-Host " <username> : Username to grant permissions to" | |
Write-Host " <servicename> : Service name to modify permissions for" | |
Exit 1 | |
} | |
function Apply-Permissions { | |
param( | |
[string]$UserSid, | |
[string]$ServiceSddl, | |
[string]$ScManagerSddl, | |
[string]$ModifiedServiceSddl, | |
[string]$ModifiedScManagerSddl | |
) | |
try { | |
Write-Log "Applying new permissions to service '$ServiceName'..." | |
sc.exe sdset $ServiceName $ModifiedServiceSddl | |
Write-Log "Applying new permissions to SCMANAGER..." | |
sc.exe sdset SCMANAGER $ModifiedScManagerSddl | |
Write-Log "Permissions applied successfully." | |
# Verify changes | |
$newServiceSddl = & sc.exe sdshow $ServiceName | |
$newScManagerSddl = & sc.exe sdshow SCMANAGER | |
Write-Log "New service SDDL: $newServiceSddl" | |
Write-Log "New SCMANAGER SDDL: $newScManagerSddl" | |
Write-Host -ForegroundColor Green "Permissions have been successfully applied." | |
} | |
catch { | |
Write-Log "ERROR: Failed to apply permissions: $_" | |
Write-Host -ForegroundColor Red "Failed to apply permissions. Check the log for details." | |
} | |
} | |
# Validate parameters | |
if (-not $Username -or -not $ServiceName) { | |
Show-Usage | |
} | |
# Starting | |
Write-Host "=======================================================" | |
Write-Host " Windows Service and SCMANAGER Permission Adjuster " | |
Write-Host "=======================================================" | |
# Step 1: Log the current state | |
Write-Log "Starting permission adjustment process" | |
Write-Log "Username: $Username, Service: $ServiceName" | |
# Get user SID | |
try { | |
$userSid = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$Username'").SID | |
if (-not $userSid) { | |
Write-Log "ERROR: Could not find SID for user '$Username'" | |
Write-Host -ForegroundColor Red "User '$Username' not found. Please check the username and try again." | |
Exit 1 | |
} | |
Write-Log "User SID: $userSid" | |
} | |
catch { | |
Write-Log "ERROR: Failed to retrieve SID for user '$Username': $_" | |
Write-Host -ForegroundColor Red "Failed to retrieve SID for user '$Username'. Please check the username and try again." | |
Exit 1 | |
} | |
# Get current service SDDL | |
try { | |
$serviceSddl = (cmd /c sc sdshow $ServiceName) | Select-Object -Last 1 | |
if ($LASTEXITCODE -ne 0) { | |
Write-Log "ERROR: Failed to retrieve SDDL for service '$ServiceName'" | |
Write-Host -ForegroundColor Red "Service '$ServiceName' not found or access denied. Please check the service name and try again." | |
Exit 1 | |
} | |
Write-Log "Current service SDDL: $serviceSddl" | |
} | |
catch { | |
Write-Log "ERROR: Exception when retrieving service SDDL: $_" | |
Write-Host -ForegroundColor Red "Failed to retrieve permissions for service '$ServiceName'. Please check the service name and try again." | |
Exit 1 | |
} | |
# Get current SCMANAGER SDDL | |
try { | |
$scManagerSddl = (cmd /c sc sdshow SCMANAGER) | Select-Object -Last 1 | |
Write-Log "Current SCMANAGER SDDL: $scManagerSddl" | |
} | |
catch { | |
Write-Log "ERROR: Failed to retrieve SDDL for SCMANAGER: $_" | |
Write-Host -ForegroundColor Red "Failed to retrieve permissions for SCMANAGER. You may not have sufficient privileges." | |
Exit 1 | |
} | |
# Step 2: Modify the permissions | |
function Modify-ServiceSddl { | |
param( | |
[string]$Sddl, | |
[string]$PermissionToAdd | |
) | |
$modifiedSddl = $Sddl.Trim() | |
if ($modifiedSddl.LastIndexOf("S:") -ge 0) { | |
$daclPart = $modifiedSddl.Substring(0, $modifiedSddl.LastIndexOf("S:")) | |
$saclPart = $modifiedSddl.Substring($modifiedSddl.LastIndexOf("S:")) | |
} else { | |
$daclPart = $modifiedSddl | |
$saclPart = '' | |
} | |
# Check if the permission is already present | |
if ($daclPart -match [regex]::Escape($PermissionToAdd)) { | |
Write-Log "The specified permissions are already granted." | |
} else { | |
$daclPart = $daclPart + $PermissionToAdd | |
$modifiedSddl = $daclPart + $saclPart | |
} | |
return $modifiedSddl | |
} | |
# Step 2: Modify the permissions | |
# For the service | |
$permissionToAdd = "(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$userSid)" | |
$modifiedServiceSddl = Modify-ServiceSddl -Sddl $serviceSddl -PermissionToAdd $permissionToAdd | |
# For SCMANAGER | |
$scManagerPermissionToAdd = "(A;;CCLCSWRPWPDTLOCRRC;;;$userSid)" | |
$modifiedScManagerSddl = Modify-ServiceSddl -Sddl $scManagerSddl -PermissionToAdd $scManagerPermissionToAdd | |
# Step 3: Preview the changes and confirm with the user | |
Write-Host "`nCurrent permissions:" | |
Write-Host "------------------------" | |
Write-Host "Service '$ServiceName': $serviceSddl" | |
Write-Host "SCMANAGER: $scManagerSddl" | |
Write-Host "`nNew permissions to be applied:" | |
Write-Host "------------------------" | |
Write-Host "Service '$ServiceName': $modifiedServiceSddl" | |
Write-Host "SCMANAGER: $modifiedScManagerSddl" | |
$confirmation = Read-Host "`nDo you want to apply these changes? (y/n)" | |
if ($confirmation -eq 'y') { | |
Apply-Permissions -UserSid $userSid -ServiceSddl $serviceSddl -ScManagerSddl $scManagerSddl -ModifiedServiceSddl $modifiedServiceSddl -ModifiedScManagerSddl $modifiedScManagerSddl | |
} else { | |
Write-Host "Operation cancelled by user." | |
Write-Log "User cancelled the permission change operation." | |
} | |
Write-Host "`nOperation completed. See logs for details." |
Adjust the permissions for a regular user to start/stop a specific service.
The script has two parameters:
Username
: Specify the account name of the regular user.ServiceName
: Specify the name of the Windows service.(Execute using an administrator's PowerShell.)
Example:
.\Adjust-ServicePermissions.ps1 -Username Tony -ServiceName MyService
Interactive script, Press 'y' to confirm.