파워셸을 사용하여 계정에 "서비스로 로그온"을 부여하려면 어떻게 해야 합니까?
파워셸을 사용하여 계정 자격 증명을 구성하려고 하는데 "서비스로 로그온" 계정을 바로 부여해야 작동할 수 있습니다.파워셸에서 이걸 어떻게 해요?
아래 Powershell 스크립트는 computerName에서 지정한 호스트에서 사용자 이름으로 지정한 사용자에게 SeServiceLogonRight를 부여합니다(스크립트는 여기서 발췌한 것입니다: https://gist.github.com/grenade/8519655) :
<#
.Synopsis
Grant logon as a service right to the defined user.
.Parameter computerName
Defines the name of the computer where the user right should be granted.
Default is the local computer on which the script is run.
.Parameter username
Defines the username under which the service should run.
Use the form: domain\username.
Default is the user under which the script is run.
.Example
Usage:
.\GrantSeServiceLogonRight.ps1 -computerName hostname.domain.com -username "domain\username"
#>
param(
[string] $computerName = ("{0}.{1}" -f $env:COMPUTERNAME.ToLower(), $env:USERDNSDOMAIN.ToLower()),
[string] $username = ("{0}\{1}" -f $env:USERDOMAIN, $env:USERNAME)
)
Invoke-Command -ComputerName $computerName -Script {
param([string] $username)
$tempPath = [System.IO.Path]::GetTempPath()
$import = Join-Path -Path $tempPath -ChildPath "import.inf"
if(Test-Path $import) { Remove-Item -Path $import -Force }
$export = Join-Path -Path $tempPath -ChildPath "export.inf"
if(Test-Path $export) { Remove-Item -Path $export -Force }
$secedt = Join-Path -Path $tempPath -ChildPath "secedt.sdb"
if(Test-Path $secedt) { Remove-Item -Path $secedt -Force }
try {
Write-Host ("Granting SeServiceLogonRight to user account: {0} on host: {1}." -f $username, $computerName)
$sid = ((New-Object System.Security.Principal.NTAccount($username)).Translate([System.Security.Principal.SecurityIdentifier])).Value
secedit /export /cfg $export
$sids = (Select-String $export -Pattern "SeServiceLogonRight").Line
foreach ($line in @("[Unicode]", "Unicode=yes", "[System Access]", "[Event Audit]", "[Registry Values]", "[Version]", "signature=`"`$CHICAGO$`"", "Revision=1", "[Profile Description]", "Description=GrantLogOnAsAService security template", "[Privilege Rights]", "$sids,*$sid")){
Add-Content $import $line
}
secedit /import /db $secedt /cfg $import
secedit /configure /db $secedt
gpupdate /force
Remove-Item -Path $import -Force
Remove-Item -Path $export -Force
Remove-Item -Path $secedt -Force
} catch {
Write-Host ("Failed to grant SeServiceLogonRight to user account: {0} on host: {1}." -f $username, $computerName)
$error[0]
}
} -ArgumentList $username
이렇게 해결했습니다.
기준: 이 기사
카본은 여기서 다운받으실 수 있습니다.
먼저 다음과 같이 Carbon 모듈을 가져옵니다.
Import-Module -Name $Path_To_Carbon -Global -Prefix CA
[array]$UserPrivileges = Get-CAPrivileges -Identity $UserName;
[bool]$LogOnAsAServiceprivilegeFound = $false;
if ($UserPrivileges.Length > 0)
{
if ($UserPrivileges -contains "SeServiceLogonRight")
{
$LogOnAsAServiceprivilegeFound = $true;
}
}
if ($LogOnAsAServiceprivilegeFound -eq $false)
{
Grant-CAPrivilege -Identity $UserName "SeServiceLogonRight"
}
인 하는 Windows API 에 수 .AdvAPI32.dll
고.Lsa*
방법들.
PowerShell의 추가 기능을 활용할 수 있습니다.현재 세션에 대한 NET 입력 및 .NET의 P/Invoke는 사용자에게 PowerShell에서 '서비스로 로그온' 권한을 부여하기 위해 Windows API를 호출합니다.
최소한의 예*로, 먼저 새로운 것을 추가해야 합니다.현재 PowerShell 세션에 Windows API와 함께 작동하도록 NET 입력:
Add-Type @'
using System;
using System.Runtime.InteropServices;
public enum LSA_AccessPolicy : long
{
// Other values omitted for clarity
POLICY_ALL_ACCESS = 0x00001FFFL
}
[StructLayout(LayoutKind.Sequential)]
public struct LSA_UNICODE_STRING
{
public UInt16 Length;
public UInt16 MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct LSA_OBJECT_ATTRIBUTES
{
public UInt32 Length;
public IntPtr RootDirectory;
public LSA_UNICODE_STRING ObjectName;
public UInt32 Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
public static partial class AdvAPI32 {
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern uint LsaOpenPolicy(
ref LSA_UNICODE_STRING SystemName,
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
uint DesiredAccess,
out IntPtr PolicyHandle);
[DllImport("advapi32.dll")]
public static extern Int32 LsaClose(IntPtr ObjectHandle);
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
public static extern uint LsaAddAccountRights(
IntPtr PolicyHandle,
byte[] AccountSid,
LSA_UNICODE_STRING[] UserRights,
uint CountOfRights);
}
'@
그런 다음 로컬 보안 정책에 대한 핸들을 열어야 합니다.
function Get-LsaPolicyHandle() {
$system = New-Object LSA_UNICODE_STRING
$attrib = New-Object LSA_OBJECT_ATTRIBUTES -Property @{
Length = 0
RootDirectory = [System.IntPtr]::Zero
Attributes = 0
SecurityDescriptor = [System.IntPtr]::Zero
SecurityQualityOfService = [System.IntPtr]::Zero
};
$handle = [System.IntPtr]::Zero
$hr = [AdvAPI32]::LsaOpenPolicy([ref] $system, [ref]$attrib, [LSA_AccessPolicy]::POLICY_ALL_ACCESS, [ref]$handle)
if (($hr -ne 0) -or ($handle -eq [System.IntPtr]::Zero)) {
Write-Error "Failed to open Local Security Authority policy. Error code: $hr"
} else {
$handle
}
}
새 권한을 추가하려면 먼저 새 권한을 만들어야 합니다.
function New-Right([string]$rightName){
$unicodeCharSize = 2
New-Object LSA_UNICODE_STRING -Property @{
Buffer = [System.Runtime.InteropServices.Marshal]::StringToHGlobalUni($rightName)
Length = $rightName.Length * $unicodeCharSize
MaximumLength = ($rightName.Length + 1) * $unicodeCharSize
}
}
그런 다음 해당 권한을 보안 정책에 추가할 수 있습니다.
function Grant-Rights([System.IntPtr]$policyHandle, [byte[]]$sid, [LSA_UNICODE_STRING[]]$rights) {
$result = [AdvAPI32]::LsaAddAccountRights($policyHandle, $sid, $rights, 1)
if ($result -ne 0) {
Write-Error "Failed to grant right. Error code $result"
}
}
이 모든 것을 종합하면 다음과 같은 기능을 사용할 수 있습니다.
function Grant-LogonAsServiceRight([byte[]]$sid) {
$logonAsServiceRightName = "SeServiceLogonRight"
try {
$policy = Get-LsaPolicyHandle
$right = New-Right $logonAsServiceRightName
Grant-Rights $policy $sid @($right)
}
finally {
if($null -ne $policy){
[AdvAPI32]::LsaClose($policy) | Out-Null
}
}
}
에는 .AdvAPI32
사용자의 계정 권한을 열거하고, 권한을 삭제하는 등의 방법.
--
*Azure DevOps Pipeline Agent Repo의 코드를 따라 로컬 보안 정책 메소드를 사용하는 방법을 알아봤습니다.AdvAPI32
.
이 기능은 간결하고 기능적인 균형을 잘 이루고 있습니다.권한 부여를 시도하기 전에 사용자가 이미 권한을 가지고 있는지 확인합니다.
나는 모든 종류의 권한에 대해 이것을 테스트한 적은 없지만 대부분의 경우에 효과가 있을 것입니다.
function Add-RightToUser([string] $Username, $Right) {
$tmp = New-TemporaryFile
$TempConfigFile = "$tmp.inf"
$TempDbFile = "$tmp.sdb"
Write-Host "Getting current policy"
secedit /export /cfg $TempConfigFile
$sid = ((New-Object System.Security.Principal.NTAccount($Username)).Translate([System.Security.Principal.SecurityIdentifier])).Value
$currentConfig = Get-Content -Encoding ascii $TempConfigFile
$newConfig = $null
if ($currentConfig | Select-String -Pattern "^$Right = ") {
if ($currentConfig | Select-String -Pattern "^$Right .*$sid.*$") {
Write-Host "Already has right"
}
else {
Write-Host "Adding $Right to $Username"
$newConfig = $currentConfig -replace "^$Right .+", "`$0,*$sid"
}
}
else {
Write-Host "Right $Right did not exist in config. Adding $Right to $Username."
$newConfig = $currentConfig -replace "^\[Privilege Rights\]$", "`$0`n$Right = *$sid"
}
if ($newConfig) {
Set-Content -Path $TempConfigFile -Encoding ascii -Value $newConfig
Write-Host "Validating configuration"
$validationResult = secedit /validate $TempConfigFile
if ($validationResult | Select-String '.*invalid.*') {
throw $validationResult;
}
else {
Write-Host "Validation Succeeded"
}
Write-Host "Importing new policy on temp database"
secedit /import /cfg $TempConfigFile /db $TempDbFile
Write-Host "Applying new policy to machine"
secedit /configure /db $TempDbFile /cfg $TempConfigFile
Write-Host "Updating policy"
gpupdate /force
Remove-Item $tmp* -ea 0
}
}
#Example
Add-RightToUser -Username 'MyDomain\MyUser' -Right 'SeServiceLogonRight'
제거
function Remove-RightFromUser([string] $Username, $Right) {
$tmp = New-TemporaryFile
$TempConfigFile = "$tmp.inf"
$TempDbFile = "$tmp.sdb"
Write-Host "Getting current policy"
secedit /export /cfg $TempConfigFile
$sid = ((New-Object System.Security.Principal.NTAccount($Username)).Translate([System.Security.Principal.SecurityIdentifier])).Value
$currentConfig = Get-Content -Encoding ascii $TempConfigFile
if ($currentConfig | Select-String -Pattern "^$Right .*$sid.*$") {
Write-Host "Removing $Right from $Username"
$newConfig = $currentConfig -replace "^($Right = .*?)(?>,\*$sid(.*?$)|\*$sid,(.*?$)|\*$sid$)", '$1$2$3'
Set-Content -Path $TempConfigFile -Encoding ascii -Value $newConfig
Write-Host "Validating configuration"
$validationResult = secedit /validate $TempConfigFile
if ($validationResult | Select-String '.*invalid.*') {
throw $validationResult;
}
else {
Write-Host "Validation Succeeded"
}
Write-Host "Importing new policy on temp database"
secedit /import /cfg $TempConfigFile /db $TempDbFile
Write-Host "Applying new policy to machine"
secedit /configure /db $TempDbFile /cfg $TempConfigFile
Write-Host "Updating policy"
gpupdate /force
Remove-Item $tmp* -ea 0
}
else {
Write-Host "User $Username did not have right"
}
}
#Example
Remove-RightFromUser -Username 'MyDomain\MyUser' -Right 'SeServiceLogonRight'
이것은 순수한 PowerShell은 아니지만 적어도 타사 도구는 필요 없습니다.
모든 것이 컴퓨터에 이미 있고 명령줄에서 작동합니다.
#Requires -RunAsAdministrator
#The SID you want to add
$AccountSid = 'S-1-5-21-1234567890-1234567890-123456789-500'
$ExportFile = 'c:\temp\CurrentConfig.inf'
$SecDb = 'c:\temp\secedt.sdb'
$ImportFile = 'c:\temp\NewConfig.inf'
#Export the current configuration
secedit /export /cfg $ExportFile
#Find the current list of SIDs having already this right
$CurrentServiceLogonRight = Get-Content -Path $ExportFile |
Where-Object -FilterScript {$PSItem -match 'SeServiceLogonRight'}
#Create a new configuration file and add the new SID
$FileContent = @'
[Unicode]
Unicode=yes
[System Access]
[Event Audit]
[Registry Values]
[Version]
signature="$CHICAGO$"
Revision=1
[Profile Description]
Description=GrantLogOnAsAService security template
[Privilege Rights]
{0}*{1}
'@ -f $(
if($CurrentServiceLogonRight){"$CurrentServiceLogonRight,"}
else{'SeServiceLogonRight = '}
), $AccountSid
Set-Content -Path $ImportFile -Value $FileContent
#Import the new configuration
secedit /import /db $SecDb /cfg $ImportFile
secedit /configure /db $SecDb
여기 PS 내에서도 할 수 있는 링크가 있습니다: original | archive.
문제는 이러한 설정을 관리하기 위한 공개 API가 실제로 없기 때문에 ResKits에 제공된 명령줄 도구를 사용하는 데 다소 어려움이 있다는 것입니다.
탄소를 사용하세요!위의 제안 중 일부는 구식이며, 제게 효과가 있었던 것은 다음과 같습니다.
(Priv가 높은 파워셸 내)
Install-Module -Name 'Carbon' -AllowClobber
Import-Module 'Carbon'
$Identity = "<username>"
$privilege = "SeServiceLogonRight"
$CarbonDllPath = "C:\Program Files\WindowsPowerShell\Modules\Carbon\2.10.2\bin\fullclr\Carbon.dll"
[Reflection.Assembly]::LoadFile($CarbonDllPath)
[Carbon.Security.Privilege]::GrantPrivileges($Identity, $privilege)
전체 DB를 가져오지 않은 솔루션
function setSecurityPolicy {
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $username,
[Parameter(Mandatory=$true, Position=1)]
[string] $securityField
)
$sid;
if($username -like "*\*"){
$user = $username.split('\')
$domain=$user[0]
$usernametemp=$user[1]
$sid=(get-wmiobject Win32_useraccount -filter "name='$usernametemp' and Domain='$domain'").SID
} else {
$sid=(get-wmiobject Win32_useraccount -filter "name='$username' and Domain='$($env:COMPUTERNAME)'").SID
}
if(-not($sid)){
try{
$sid= (Get-Localgroup "$username").SID.VALUE
} catch{
}
}
if(-not($sid)) {
$Host.UI.WriteErrorLine("setSecurityPolicy error : Account $username not found!")
exit 1
}
$tmp = [System.IO.Path]::GetTempFileName()
secedit.exe /export /cfg "$tmp" | Out-Null
$currentSetting = Select-String -Pattern "$securityField = (.*)" -path $tmp | select -Expand Matches | % { $_.Groups[1].Value }
remove-item $tmp -Force
if($currentSetting -notlike "*$sid*" ){
Write-Host "Modify Setting ""$securityField"""
if( [string]::IsNullOrEmpty($currentSetting) ) {
$currentSetting = "*$sid"
} else {
$currentSetting = "*$sid,$currentSetting"
}
$outfile = @"
[Unicode]
Unicode=yes
[Version]
signature="`$CHICAGO`$"
Revision=1
[Privilege Rights]
$securityField = $currentSetting
"@
$tmp2 = [System.IO.Path]::GetTempFileName()
Write-Host "Import new settings to Local Security Policy"
$outfile | Set-Content -Path $tmp2 -Encoding Unicode -Force
try {
secedit.exe /configure /db "secedit.sdb" /cfg "$tmp2" /areas USER_RIGHTS
} finally {
remove-item $tmp2 -Force
}
}
}
#example usage
setSecurityPolicy -username 'IIS_IUSRS' -securityField 'SeServiceLogonRight'
setSecurityPolicy -username 'IIS_IUSRS' -securityField 'SeBatchLogonRight'
setSecurityPolicy -username 'IIS_IUSRS' -securityField 'SeImpersonatePrivilege'
PowerShell에는 기본적인 방법이 없으므로 WMI 또는 ADSI를 살펴보실 수 있습니다. 개인적으로는 사용자 권한을 프로그래밍 방식으로 할당하는 방법을 파악해 본 적이 없지만 오래된 VB스크립트에서 예를 찾을 수 있습니다.하지만 이 작업을 수행할 수 없다는 의미는 아니지만, PowerShell의 영역 밖을 구체적으로 살펴보게 될 것입니다.
@Brendan Lane 답변에서 확장 중입니다.
사용자의 "Sid"를 얻으려면 다음 기능을 사용합니다.
function Get-SidForUser {
param ([string]$UserName)
$sid = ((New-Object System.Security.Principal.NTAccount($UserName)).Translate([System.Security.Principal.SecurityIdentifier]))
[byte[]]$bytes = New-Object byte[] $sid.BinaryLength;
$sid.GetBinaryForm($bytes, 0);
return $bytes
}
이 모든 것을 종합하면:
Grant-LogonAsServiceRight (Get-SidForUser -UserName $ServiceAccount)
다음 스크립트를 사용하여 원격 및 로컬로 보안 정책을 수정할 수 있습니다. 내 스크립트를 사용하면 여러 컴퓨터, 사용자 및 사용자 권한에 대해 실행할 수 있습니다. 내 Get / Set User Rights Blog Post 링크가 있습니다.
스크립트를 Powershell ISE에 복사하여 붙여넣을 수 있습니다. 필요한 매개 변수를 포함하도록 줄 392(스크립트 하단 근처)를 편집하기만 하면 됩니다.-UserRight
그리고.-Add
아니면 -Remove
. 다른 파라미터는 옵션입니다.-ComputerName
,-UserName
:
<#
.Synopsis
Add and Remove User Right(s) for defined user(s) and computer(s).
.DESCRIPTION
Add and Remove User Rights via Powershell.
.PARAMETER AddRight
You want to Add a user right.
.Parameter ComputerName
Defines the name of the computer where the user right should be granted. This can be multiple values, comma seperated.
Default is the local computer on which the script is run.
.PARAMETER RemoveRight
You want to Remove a user right.
.Parameter Username
Defines the Username under which the service should run. This can be multiple values, comma seperated.
Use the form: domain\Username.
Default is the user under which the script is run.
.PARAMETER UserRight
Defines the User Right you want to set. This can be multiple values, comma seperated.
Name of the right you want to add to: SeServiceLogonRight
There is no default for this argument
Some (but not all) of the Options you can use:
"Log on as a batch job (SeBatchLogonRight)"
"Allow log on locally (SeInteractiveLogonRight)"
"Access this computer from the network (SeNetworkLogonRight)"
"Allow log on through Remote Desktop Services (SeRemoteInteractiveLogonRight)"
"Log on as a service (SeServiceLogonRight)"
"Deny log on as a batch job (SeDenyBatchLogonRight)"
"Deny log on locally (SeDenyInteractiveLogonRight)"
"Deny access to this computer from the network (SeDenyNetworkLogonRight)"
"Deny log on through Remote Desktop Services (SeDenyRemoteInteractiveLogonRight)"
"Deny log on as a service (SeDenyServiceLogonRight)"
.Example
Usage:
Single Users
Add User Right "Log on as a service" for CONTOSO\User:
.\Set-UserRights.ps1 -AddRight -Username CONTOSO\User -UserRight SeServiceLogonRight
Add User Right "Log on as a batch job" for CONTOSO\User:
.\Set-UserRights.ps1 -AddRight -Username CONTOSO\User -UserRight SeBatchLogonRight
Remove User Right "Log on as a batch job" for CONTOSO\User:
.\Set-UserRights.ps1 -RemoveRight -Username CONTOSO\User -UserRight SeBatchLogonRight
Add User Right "Allow log on locally" for current user:
.\Set-UserRights.ps1 -AddRight -UserRight SeInteractiveLogonRight
Remove User Right "Allow log on locally" for current user:
.\Set-UserRights.ps1 -RemoveRight -UserRight SeInteractiveLogonRight
Multiple Users / Services / Computers
Add User Right "Log on as a service" and "Log on as a batch job" for CONTOSO\User and run on, local machine and SQL.contoso.com:
.\Set-UserRights.ps1 -AddRight -UserRight SeServiceLogonRight, SeBatchLogonRight -ComputerName $env:COMPUTERNAME, SQL.contoso.com -UserName CONTOSO\User1, CONTOSO\User2
.Notes
Original Creator: Bill Loytty (weloytty)
Based on this script found here: https://github.com/weloytty/QuirkyPSFunctions/blob/ab4b02f9cc05505eee97d2f744f4c9c798143af1/Source/Users/Grant-LogOnAsService.ps1
I modified to my own needs: https://github.com/blakedrumm/SCOM-Scripts-and-SQL/blob/master/Powershell/General%20Functions/Set-UserRights.ps1
My blog post: https://blakedrumm.com/blog/set-and-check-user-rights-assignment/
Author: Blake Drumm (blakedrumm@microsoft.com)
First Created on: January 5th, 2022
Last Modified on: April 23rd, 2022
#>
param
(
[Parameter(Position = 0,
HelpMessage = 'You want to Add a user right.')]
[Alias('add')]
[switch]$AddRight,
[Parameter(Position = 1)]
[Alias('computer')]
[array]$ComputerName,
[Parameter(Position = 2,
HelpMessage = 'You want to Remove a user right.')]
[switch]$RemoveRight,
[Parameter(Position = 3)]
[Alias('user')]
[array]$Username,
[Parameter(Mandatory = $false,
Position = 4)]
[ValidateSet('SeNetworkLogonRight', 'SeBackupPrivilege', 'SeChangeNotifyPrivilege', 'SeSystemtimePrivilege', 'SeCreatePagefilePrivilege', 'SeDebugPrivilege', 'SeRemoteShutdownPrivilege', 'SeAuditPrivilege', 'SeIncreaseQuotaPrivilege', 'SeIncreaseBasePriorityPrivilege', 'SeLoadDriverPrivilege', 'SeBatchLogonRight', 'SeServiceLogonRight', 'SeInteractiveLogonRight', 'SeSecurityPrivilege', 'SeSystemEnvironmentPrivilege', 'SeProfileSingleProcessPrivilege', 'SeSystemProfilePrivilege', 'SeAssignPrimaryTokenPrivilege', 'SeRestorePrivilege', 'SeShutdownPrivilege', 'SeTakeOwnershipPrivilege', 'SeDenyNetworkLogonRight', 'SeDenyInteractiveLogonRight', 'SeUndockPrivilege', 'SeManageVolumePrivilege', 'SeRemoteInteractiveLogonRight', 'SeImpersonatePrivilege', 'SeCreateGlobalPrivilege', 'SeIncreaseWorkingSetPrivilege', 'SeTimeZonePrivilege', 'SeCreateSymbolicLinkPrivilege', 'SeDelegateSessionUserImpersonatePrivilege', 'SeMachineAccountPrivilege', 'SeTrustedCredManAccessPrivilege', 'SeTcbPrivilege', 'SeCreateTokenPrivilege', 'SeCreatePermanentPrivilege', 'SeDenyBatchLogonRight', 'SeDenyServiceLogonRight', 'SeDenyRemoteInteractiveLogonRight', 'SeEnableDelegationPrivilege', 'SeLockMemoryPrivilege', 'SeRelabelPrivilege', 'SeSyncAgentPrivilege', IgnoreCase = $true)]
[Alias('right')]
[array]$UserRight
)
BEGIN
{
Write-Output '==================================================================='
Write-Output '========================== Start of Script ======================='
Write-Output '==================================================================='
$checkingpermission = "Checking for elevated permissions..."
$scriptout += $checkingpermission
Write-Output $checkingpermission
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
$currentPath = $myinvocation.mycommand.definition
$nopermission = "Insufficient permissions to run this script. Attempting to open the PowerShell script ($currentPath) as administrator."
$scriptout += $nopermission
Write-Warning $nopermission
# We are not running "as Administrator" - so relaunch as administrator
# ($MyInvocation.Line -split '\.ps1[\s\''\"]\s*', 2)[-1]
Start-Process powershell.exe "-File", ('"{0}"' -f $MyInvocation.MyCommand.Path) -Verb RunAs
break
}
else
{
$permissiongranted = " Currently running as administrator - proceeding with script execution..."
Write-Output $permissiongranted
}
Function Time-Stamp
{
$TimeStamp = Get-Date -UFormat "%B %d, %Y @ %r"
return "$TimeStamp - "
}
}
PROCESS
{
function Inner-SetUserRights
{
param
(
[Parameter(Position = 0,
HelpMessage = 'You want to Add a user right.')]
[Alias('add')]
[switch]$AddRight,
[Parameter(Position = 1)]
[Alias('computer')]
[array]$ComputerName,
[Parameter(Position = 2,
HelpMessage = 'You want to Remove a user right.')]
[switch]$RemoveRight,
[Parameter(Position = 3)]
[Alias('user')]
[array]$Username,
[Parameter(Mandatory = $false,
Position = 4)]
[Alias('right')]
[array]$UserRight
)
if (!$UserRight)
{
Write-Warning "Inner Function: Unable to continue because you did not supply the '-UserRight' parameter."
break
}
if (!$AddRight -and !$RemoveRight)
{
Write-Warning "Inner Function: Unable to continue because you did not supply the '-AddRight' or '-RemoveRight' switches."
break
}
elseif ($AddRight -and $RemoveRight)
{
Write-Warning "Inner Function: Unable to continue because you used both the '-AddRight' and '-RemoveRight' switches. Run again with just one of these present, either Add or Remove."
break
}
elseif ($AddRight)
{
Write-Verbose "Inner Function: Detected -AddRight switch in execution."
$ActionType = 'Adding'
}
elseif ($RemoveRight)
{
Write-Verbose "Inner Function: Detected -RemoveRight switch in execution."
$ActionType = 'Removing'
}
else
{
Write-Warning "Something is wrong, detected logic is broken before executing main function. Exiting."
break
}
Function Time-Stamp
{
$TimeStamp = Get-Date -UFormat "%B %d, %Y @ %r"
return "$TimeStamp - "
}
$tempPath = [System.IO.Path]::GetTempPath()
$import = Join-Path -Path $tempPath -ChildPath "import.inf"
if (Test-Path $import) { Remove-Item -Path $import -Force }
$export = Join-Path -Path $tempPath -ChildPath "export.inf"
if (Test-Path $export) { Remove-Item -Path $export -Force }
$secedt = Join-Path -Path $tempPath -ChildPath "secedt.sdb"
if (Test-Path $secedt) { Remove-Item -Path $secedt -Force }
$Error.Clear()
try
{
foreach ($right in $UserRight)
{
$UserLogonRight = switch ($right)
{
"SeBatchLogonRight" { "Log on as a batch job (SeBatchLogonRight)" }
"SeDenyBatchLogonRight" { "Deny log on as a batch job (SeDenyBatchLogonRight)" }
"SeDenyInteractiveLogonRight" { "Deny log on locally (SeDenyInteractiveLogonRight)" }
"SeDenyNetworkLogonRight" { "Deny access to this computer from the network (SeDenyNetworkLogonRight)" }
"SeDenyRemoteInteractiveLogonRight" { "Deny log on through Remote Desktop Services (SeDenyRemoteInteractiveLogonRight)" }
"SeDenyServiceLogonRight" { "Deny log on as a service (SeDenyServiceLogonRight)" }
"SeInteractiveLogonRight" { "Allow log on locally (SeInteractiveLogonRight)" }
"SeNetworkLogonRight" { "Access this computer from the network (SeNetworkLogonRight)" }
"SeRemoteInteractiveLogonRight" { "Allow log on through Remote Desktop Services (SeRemoteInteractiveLogonRight)" }
"SeServiceLogonRight" { "Log on as a service (SeServiceLogonRight)" }
Default { "($right)" }
}
Write-Output ("$(Time-Stamp)$ActionType `"$UserLogonRight`" right for user account: '$Username' on host: '$env:COMPUTERNAME'")
if ($Username -match "^S-.*-.*-.*$|^S-.*-.*-.*-.*-.*-.*$|^S-.*-.*-.*-.*-.*$|^S-.*-.*-.*-.*$")
{
$sid = $Username
}
else
{
$sid = ((New-Object System.Security.Principal.NTAccount($Username)).Translate([System.Security.Principal.SecurityIdentifier])).Value
}
secedit /export /cfg $export | Out-Null
#Change the below to any right you would like
$sids = (Select-String $export -Pattern "$right").Line
if ($ActionType -eq 'Adding')
{
$sidList = "$sids,*$sid"
}
elseif ($ActionType -eq 'Removing')
{
$sidList = "$($sids.Replace("*$sid", '').Replace("$Username", '').Replace(",,", ',').Replace("= ,", '= '))"
}
foreach ($line in @("[Unicode]", "Unicode=yes", "[System Access]", "[Event Audit]", "[Registry Values]", "[Version]", "signature=`"`$CHICAGO$`"", "Revision=1", "[Profile Description]", "Description=$ActionType `"$UserLogonRight`" right for user account: $Username", "[Privilege Rights]", "$sidList"))
{
Add-Content $import $line
}
}
secedit /import /db $secedt /cfg $import | Out-Null
secedit /configure /db $secedt | Out-Null
gpupdate /force | Out-Null
Write-Verbose "The script will not delete the following paths due to running in verbose mode, please remove these files manually if needed:"
Write-Verbose "`$import : $import"
Write-Verbose "`$export : $export"
Write-Verbose "`$secedt : $secedt"
if ($VerbosePreference.value__ -eq 0)
{
Remove-Item -Path $import -Force | Out-Null
Remove-Item -Path $export -Force | Out-Null
Remove-Item -Path $secedt -Force | Out-Null
}
}
catch
{
Write-Output ("$(Time-Stamp)Failure occurred while granting `"$right`" to user account: '$Username' on host: '$env:COMPUTERNAME'")
Write-Output "Error Details: $error"
}
}
$InnerSetUserRightFunctionScript = "function Inner-SetUserRights { ${function:Inner-SetUserRights} }"
function Set-UserRights
{
param
(
[Parameter(Position = 0,
HelpMessage = 'You want to Add a user right.')]
[Alias('add')]
[switch]$AddRight,
[Parameter(Position = 1)]
[Alias('computer')]
[array]$ComputerName,
[Parameter(Position = 2,
HelpMessage = 'You want to Remove a user right.')]
[switch]$RemoveRight,
[Parameter(Position = 3)]
[Alias('user')]
[array]$Username,
[Parameter(Mandatory = $false,
Position = 4)]
[ValidateSet('SeNetworkLogonRight', 'SeBackupPrivilege', 'SeChangeNotifyPrivilege', 'SeSystemtimePrivilege', 'SeCreatePagefilePrivilege', 'SeDebugPrivilege', 'SeRemoteShutdownPrivilege', 'SeAuditPrivilege', 'SeIncreaseQuotaPrivilege', 'SeIncreaseBasePriorityPrivilege', 'SeLoadDriverPrivilege', 'SeBatchLogonRight', 'SeServiceLogonRight', 'SeInteractiveLogonRight', 'SeSecurityPrivilege', 'SeSystemEnvironmentPrivilege', 'SeProfileSingleProcessPrivilege', 'SeSystemProfilePrivilege', 'SeAssignPrimaryTokenPrivilege', 'SeRestorePrivilege', 'SeShutdownPrivilege', 'SeTakeOwnershipPrivilege', 'SeDenyNetworkLogonRight', 'SeDenyInteractiveLogonRight', 'SeUndockPrivilege', 'SeManageVolumePrivilege', 'SeRemoteInteractiveLogonRight', 'SeImpersonatePrivilege', 'SeCreateGlobalPrivilege', 'SeIncreaseWorkingSetPrivilege', 'SeTimeZonePrivilege', 'SeCreateSymbolicLinkPrivilege', 'SeDelegateSessionUserImpersonatePrivilege', 'SeMachineAccountPrivilege', 'SeTrustedCredManAccessPrivilege', 'SeTcbPrivilege', 'SeCreateTokenPrivilege', 'SeCreatePermanentPrivilege', 'SeDenyBatchLogonRight', 'SeDenyServiceLogonRight', 'SeDenyRemoteInteractiveLogonRight', 'SeEnableDelegationPrivilege', 'SeLockMemoryPrivilege', 'SeRelabelPrivilege', 'SeSyncAgentPrivilege', IgnoreCase = $true)]
[Alias('right')]
[array]$UserRight
)
if (!$Username)
{
$Username = "$env:USERDOMAIN`\$env:USERNAME"
}
if (!$UserRight)
{
Write-Warning "Main Function: Unable to continue because you did not supply the '-UserRight' parameter."
break
}
if (!$AddRight -and !$RemoveRight)
{
Write-Warning "Main Function: Unable to continue because you did not supply the '-AddRight' or '-RemoveRight' switches."
break
}
elseif ($AddRight -and $RemoveRight)
{
Write-Warning "Main Function: Unable to continue because you used both the '-AddRight' and '-RemoveRight' switches. Run again with just one of these present, either Add or Remove."
break
}
elseif ($AddRight)
{
Write-Verbose "Main Function: Detected -AddRight switch in execution."
$ActionType = 'Adding'
}
elseif ($RemoveRight)
{
Write-Verbose "Main Function: Detected -RemoveRight switch in execution."
$ActionType = 'Removing'
}
if (!$ComputerName)
{
$ComputerName = $env:ComputerName
}
foreach ($user in $Username)
{
foreach ($right in $UserRight)
{
foreach ($computer in $ComputerName)
{
if ($computer -match $env:COMPUTERNAME)
{
Inner-SetUserRights -UserRight $right -Username $user -AddRight:$AddRight -RemoveRight:$RemoveRight
}
else
{
Invoke-Command -ComputerName $Computer -Script {
param ($script,
[string]$Username,
[Parameter(Mandatory = $true)]
[array]$UserRight,
$AddRight,
$RemoveRight,
$VerbosePreference)
. ([ScriptBlock]::Create($script))
$VerbosePreference = $VerbosePreference
$Error.Clear()
try
{
if ($VerbosePreference -eq 0)
{
Inner-SetUserRights -Username $Username -UserRight $UserRight -AddRight:$AddRight -RemoveRight:$RemoveRight
}
else
{
Inner-SetUserRights -Username $Username -UserRight $UserRight -AddRight:$AddRight -RemoveRight:$RemoveRight -Verbose
}
}
catch
{
$info = [PSCustomObject]@{
Exception = $Error.Exception.Message
Reason = $Error.CategoryInfo.Reason
Target = $Error.CategoryInfo.TargetName
Script = $Error.InvocationInfo.ScriptName
Line = $Error.InvocationInfo.ScriptLineNumber
Column = $Error.InvocationInfo.OffsetInLine
Date = Get-Date
User = $env:username
}
Write-Warning "$info"
}
} -ArgumentList $InnerSetUserRightFunctionScript, $user, $right, $AddRight, $RemoveRight, $VerbosePreference
}
}
}
}
}
if ($ComputerName -or $Username -or $UserRight -or $RemoveRight)
{
foreach ($user in $Username)
{
Set-UserRights -ComputerName $ComputerName -Username $user -UserRight $UserRight -AddRight:$AddRight -RemoveRight:$RemoveRight
}
}
else
{
<# Edit line 392 to modify the default command run when this script is executed.
Example:
Set-UserRights -AddRight -UserRight SeServiceLogonRight, SeBatchLogonRight -ComputerName $env:COMPUTERNAME, SQL.contoso.com -UserName CONTOSO\User1, CONTOSO\User2
or
Set-UserRights -AddRight -UserRight SeBatchLogonRight -Username S-1-5-11
or
Set-UserRights -RemoveRight -UserRight SeBatchLogonRight -Username CONTOSO\User2
or
Set-UserRights -RemoveRight -UserRight SeServiceLogonRight, SeBatchLogonRight -Username CONTOSO\User1
#>
Set-UserRights
}
}
END
{
Write-Output "$(Time-Stamp)Script Completed!"
}
TechNet Gallery에서는 이를 처리하는 PowerShell 스크립트를 사용할 수 있었습니다.WayBack Machine을 통해서도 다운로드할 수 있습니다.
그럼 달리시면 됩니다.
.".\Add Account To LogonAsService.ps1" "DOMAIN\Account"
언급URL : https://stackoverflow.com/questions/313831/using-powershell-how-do-i-grant-log-on-as-service-to-an-account
'source' 카테고리의 다른 글
Android에서 상대 레이아웃의 Z 순서 보기 정의 (0) | 2023.10.08 |
---|---|
파워셸 ISE에서 런스페이스를 재설정할 수 있습니까? (0) | 2023.10.08 |
Ordered Dict를 생성자를 사용하여 초기 데이터의 순서를 유지하도록 초기화하는 올바른 방법은 무엇입니까? (0) | 2023.10.08 |
푸시 대 이동 비용(스택 대 메모리 근처), 함수 호출 오버헤드 (0) | 2023.10.08 |
디브의 내용물을 포장하지 않는 방법? (0) | 2023.10.08 |