我正在尝试使用 powershell 配置帐户凭据,但我需要授予帐户“作为服务登录”的权限才能使其正常工作。如何在 powershell 中执行此操作?
12 回答
下面的 Powershell 脚本会将 computerName 指定的主机上的 SeServiceLogonRight 授予username指定的用户(该脚本摘自此处: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"
}
这不是纯 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
这个函数在简洁和实用之间取得了很好的平衡。在尝试授予权限之前,它会检查用户是否已经拥有该权限。
我没有对所有类型的特权进行测试,但它应该适用于大多数。
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
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"
Set-Content -Path $TempConfigFile -Encoding ascii -Value $newConfig
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'
有一个 Windows API 提供对本地安全策略的访问:AdvAPI32.dll
和Lsa*
方法。
您可以利用 PowerShell 将 .NET 类型添加到当前会话的能力,以及 .NET 的 P/Invoke 调用 Windows API,以便从 PowerShell 授予用户“作为服务登录”权限。
作为一个最小示例*,您首先需要将一些新的 .NET 类型添加到当前 PowerShell 会话以使用 Windows API:
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 存储库中的代码来了解如何使用AdvAPI32
.
使用碳!上面的一些建议已经过时了,这对我有用:
(在具有提升权限的 powershell 中)
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)
PowerShell 没有执行此操作的任何本机方法,这意味着您可能会查看 WMI 或 ADSI - 您更有可能在 VBScript 中找到示例,它已经存在了更长的时间,尽管我个人认为没有我曾经想出如何以编程方式分配用户权限。但这并不意味着它不能完成,但您可能会专门寻找 PowerShell 领域之外的东西。
不导入整个数据库的解决方案
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'
扩展@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)
您可以使用以下脚本远程和本地修改安全策略,使用我的脚本,您可以针对多台机器、用户和用户权限运行: 链接到 GitHub 上的 Powershell 脚本。
您可以将脚本复制并粘贴到 Powershell ISE,只需编辑第 290 行 (靠近脚本底部)以包含所需的参数-UserRight
。其他参数是可选的-ComputerName
,-UserName
:
<#
.Synopsis
Grant User Right(s) to defined user(s) and computer(s).
.DESCRIPTION
Add User Rights via Powershell.
.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 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" to CONTOSO\User:
.\Add-UserRights.ps1 -Username CONTOSO\User -UserRight SeServiceLogonRight
Add User Right "Log on as a batch job" to CONTOSO\User:
.\Add-UserRights.ps1 -Username CONTOSO\User -UserRight SeBatchLogonRight
Add User Right "Allow log on locally" to current user:
.\Add-UserRights.ps1 -UserRight SeInteractiveLogonRight
Multiple Users / Services / Computers
Add User Right "Log on as a service" and "Log on as a batch job" to CONTOSO\User and run on, local machine and SQL.contoso.com:
.\Add-UserRights.ps1 -UserRight SeServiceLogonRight, SeBatchLogonRight -ComputerName $env:COMPUTERNAME, SQL.contoso.com -UserName CONTOSO\User1, CONTOSO\User2
.Notes
Original Creator: Bill Loytty (weloytty)
Based heavily on the 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/Add-UserRights.ps1
My blog post: https://blakedrumm.com/blog/add-and-check-user-rights-assignment/#/
Author: Blake Drumm (blakedrumm@microsoft.com)
First Created on: January 5th, 2022
Last Modified on: January 11th, 2022
#>
param
(
[Parameter(Position = 0)]
[Alias('computer')]
[array]$ComputerName,
[Parameter(Position = 1)]
[Alias('user')]
[array]$Username,
[Parameter(Mandatory = $false,
Position = 2)]
[ValidateSet('SeAssignPrimaryTokenPrivilege', 'SeAuditPrivilege', 'SeBackupPrivilege', 'SeBatchLogonRight', 'SeChangeNotifyPrivilege', 'SeCreateGlobalPrivilege', 'SeCreatePagefilePrivilege', 'SeCreateSymbolicLinkPrivilege', 'SeDebugPrivilege', 'SeDelegateSessionUserImpersonatePrivilege', 'SeImpersonatePrivilege', 'SeIncreaseBasePriorityPrivilege', 'SeIncreaseQuotaPrivilege', 'SeIncreaseWorkingSetPrivilege', 'SeInteractiveLogonRight', 'SeLoadDriverPrivilege', 'SeManageVolumePrivilege', 'SeNetworkLogonRight', 'SeProfileSingleProcessPrivilege', 'SeRemoteInteractiveLogonRight', 'SeRemoteShutdownPrivilege', 'SeRestorePrivilege', 'SeSecurityPrivilege', 'SeServiceLogonRight', 'SeShutdownPrivilege', 'SeSystemEnvironmentPrivilege', 'SeSystemProfilePrivilege', 'SeSystemtimePrivilege', 'SeTakeOwnershipPrivilege', 'SeTimeZonePrivilege', 'SeUndockPrivilege', 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 -Format "MM/dd/yyyy hh:mm:ss tt"
return "$TimeStamp - "
}
}
PROCESS
{
function Add-UserRights
{
param
(
[Parameter(Position = 0)]
[Alias('computer')]
[array]$ComputerName,
[Parameter(Position = 1)]
[Alias('user')]
[array]$Username = ("{0}\{1}" -f $env:USERDOMAIN, $env:Username),
[Parameter(Mandatory = $true,
Position = 2)]
[ValidateSet('SeAssignPrimaryTokenPrivilege', 'SeAuditPrivilege', 'SeBackupPrivilege', 'SeBatchLogonRight', 'SeChangeNotifyPrivilege', 'SeCreateGlobalPrivilege', 'SeCreatePagefilePrivilege', 'SeCreateSymbolicLinkPrivilege', 'SeDebugPrivilege', 'SeDelegateSessionUserImpersonatePrivilege', 'SeImpersonatePrivilege', 'SeIncreaseBasePriorityPrivilege', 'SeIncreaseQuotaPrivilege', 'SeIncreaseWorkingSetPrivilege', 'SeInteractiveLogonRight', 'SeLoadDriverPrivilege', 'SeManageVolumePrivilege', 'SeNetworkLogonRight', 'SeProfileSingleProcessPrivilege', 'SeRemoteInteractiveLogonRight', 'SeRemoteShutdownPrivilege', 'SeRestorePrivilege', 'SeSecurityPrivilege', 'SeServiceLogonRight', 'SeShutdownPrivilege', 'SeSystemEnvironmentPrivilege', 'SeSystemProfilePrivilege', 'SeSystemtimePrivilege', 'SeTakeOwnershipPrivilege', 'SeTimeZonePrivilege', 'SeUndockPrivilege', IgnoreCase = $true)]
[Alias('right')]
[array]$UserRight
)
if (!$ComputerName)
{
$ComputerName = $env:ComputerName
}
foreach ($user in $Username)
{
foreach ($rights in $UserRight)
{
foreach ($computer in $ComputerName)
{
if ($computer -match $env:COMPUTERNAME)
{
Function Time-Stamp
{
$TimeStamp = Get-Date -Format "MM/dd/yyyy hh:mm:ss tt"
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 }
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)Granting `"$UserLogonRight`" to user account: $Username on host: $computer.")
$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
foreach ($line in @("[Unicode]", "Unicode=yes", "[System Access]", "[Event Audit]", "[Registry Values]", "[Version]", "signature=`"`$CHICAGO$`"", "Revision=1", "[Profile Description]", "Description=Grant $UserLogonRight to $Username", "[Privilege Rights]", "$sids,*$sid"))
{
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: $computer.")
Write-Output $error[0]
}
}
else
{
Invoke-Command -ComputerName $Computer -Script {
param ([string]$Username,
[Parameter(Mandatory = $true)]
[array]$UserRight,
[string]$ComputerName,
[int]$VerbosePreference)
Function Time-Stamp
{
$TimeStamp = Get-Date -Format "MM/dd/yyyy hh:mm:ss tt"
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 }
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)Granting `"$UserLogonRight`" to user account: $Username on host: $ComputerName.")
$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
foreach ($line in @("[Unicode]", "Unicode=yes", "[System Access]", "[Event Audit]", "[Registry Values]", "[Version]", "signature=`"`$CHICAGO$`"", "Revision=1", "[Profile Description]", "Description=Grant $UserLogonRight to $Username", "[Privilege Rights]", "$sids,*$sid"))
{
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 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: $ComputerName.")
Write-Output $error[0]
}
} -ArgumentList $user, $rights, $Computer, $VerbosePreference
}
}
}
}
}
if ($ComputerName -or $Username -or $UserRight)
{
foreach ($user in $Username)
{
Add-UserRights -ComputerName $ComputerName -Username $user -UserRight $UserRight
}
}
else
{
<# Edit line 290 to modify the default command run when this script is executed.
Example:
Add-UserRights -UserRight SeServiceLogonRight, SeBatchLogonRight -ComputerName $env:COMPUTERNAME, SQL.contoso.com -UserName CONTOSO\User1, CONTOSO\User2
#>
Add-UserRights
}
}
END
{
Write-Output "$(Time-Stamp)Script Completed!"
}
作为 powershell 中的简单解决方案
赶紧跑
.".\Add Account To LogonAsService.ps1" "DOMAIN\Account"
https://gallery.technet.microsoft.com/scriptcenter/Grant-Log-on-as-a-service-11a50893