我正在尝试使用powershell配置帐户凭据,但我需要授予帐户"作为服务登录"权限才能使其正常工作.我怎么能在PowerShell中做到这一点?
gre*_*ade 19
下面的PowerShell脚本将授予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
Run Code Online (Sandbox Code Playgroud)
kb4*_*000 10
这个函数很好地平衡了简洁和功能。在尝试授予用户权限之前,它会检查用户是否已经拥有该权限。
我尚未针对所有类型的特权对此进行测试,但它应该适用于大多数。
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'
Run Code Online (Sandbox Code Playgroud)
移动
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'
Run Code Online (Sandbox Code Playgroud)
我是这样解决的:
基于:本文
首先导入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"
}
Run Code Online (Sandbox Code Playgroud)
有一个 Windows API 提供对本地安全策略AdvAPI32.dll
和Lsa*
方法的访问。
您可以利用 PowerShell 将 .NET 类型添加到当前会话的功能,以及 .NET 的 P/Invoke 来调用 Windows API,以便从 PowerShell 向用户授予“作为服务登录”权限。
作为一个最小的示例*,您首先需要向当前 PowerShell 会话添加一些新的 .NET 类型以使用 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);
}
'@
Run Code Online (Sandbox Code Playgroud)
然后,您需要打开本地安全策略的句柄:
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
}
}
Run Code Online (Sandbox Code Playgroud)
要添加新权限,您首先需要创建一个新权限:
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后您可以将该权限添加到安全策略中:
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"
}
}
Run Code Online (Sandbox Code Playgroud)
因此,将它们放在一起,您就可以使用这些函数:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以AdvAPI32
枚举用户的帐户权限、删除权限等。
--
*我按照Azure DevOps Pipeline Agent 存储库中的代码来了解如何使用AdvAPI32
.
您也可以在PSH中执行此链接。http://www.derkeiler.com/Newsgroups/microsoft.public.windowsxp.security_admin/2003-12/2865.html。
问题在于,实际上没有任何公共API可以管理这些设置,因此使用ResKits中提供的命令行工具会使您有些困惑。
这不是纯粹的 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
Run Code Online (Sandbox Code Playgroud)
小智 5
使用碳!上面的一些建议已经过时了,以下是对我有用的建议:
(在具有提升权限的 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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27682 次 |
最近记录: |