Tôi đang viết một dịch vụ giám sát sử dụng WMI để lấy thông tin từ các máy từ xa. Có quyền quản trị cục bộ trên tất cả các máy này là không thể vì lý do chính trị.
Điều này có thể không? Người dùng của tôi yêu cầu những quyền/quyền gì cho việc này?
Các hoạt động sau đây trên Window 2003 R2 SP 2, Windows Server 2012 R2
wmimgmt.msc
). Trong tab Bảo mật, tô sáng Root/CIMV2
, nhấp Bảo mật; thêm Người dùng theo dõi hiệu suất và bật các tùy chọn: Enable Account
và Remote Enable
dcomcnfg
. Tại Dịch vụ thành phần> Máy tính> Máy tính của tôi, trong tab bảo mật COM của hộp thoại Thuộc tính, nhấp vào "Chỉnh sửa giới hạn" cho cả Access Permissions
và Launch and Activation Permissions
. Thêm người dùng theo dõi hiệu suất và cho phép truy cập từ xa, khởi chạy từ xa và kích hoạt từ xa.Remote Launch
và Remote Activation
đặc quyền cho Người dùng theo dõi hiệu suất Nhóm.Ghi chú:
Root
và lặp lại các quyền đối với không gian tên phụ thông qua cửa sổ Advanced
trong Security
Tất cả những gì tôi đã làm trên Windows 8 đã được thêm người dùng vào nhóm "Người dùng quản lý từ xa" và các yêu cầu WQL từ xa đã hoạt động.
Theo mặc định, chỉ nhóm Quản trị viên cục bộ mới có quyền truy cập từ xa vào WMI. Bạn sẽ phải tùy chỉnh các quyền "Kích hoạt từ xa" của WMI.
Bạn cũng có thể phải cấp "quyền truy cập từ xa DCOM" và/hoặc "quyền khởi chạy và kích hoạt từ xa DCOM" tùy thuộc vào chính xác những gì bạn đang cố gắng thực hiện. Bài viết MSDN này đưa ra quy trình từng bước.
Những điều sau đây làm việc cho tôi trong môi trường miền 2012 r2 mặc dù tôi chỉ quản lý để làm điều đó trên mỗi máy chủ chứ không phải toàn bộ tên miền:
1) Thêm người dùng vào Nhóm người dùng Nhật ký hiệu suất. 2) Chạy wmimgmt.msc, nhấp chuột phải vào "Điều khiển WMI (LOCAL), tab goto Security và cấp cho người dùng thích hợp" Kích hoạt tài khoản "và" Kích hoạt từ xa "trên không gian tên mong muốn (thông thường CIMV2).
Nếu tôi quản lý để hoàn thành nó cho toàn bộ tên miền, tôi sẽ quay lại và cập nhật.
Dựa trên câu trả lời đã chọn, tôi đã sửa đổi tập lệnh từ Microsoft để đặt bảo mật WMI. Người dùng thử nghiệm của tôi là người dùng miền không phải quản trị viên, là thành viên của "Người dùng quản lý từ xa" trên hệ thống cục bộ vì lý do không liên quan đối với vấn đề này . Sau khi cấp cho người dùng của tôi các quyền EnableAccount, RemoteEnable và ExecuteMethods trên không gian tên đích, tôi đã có thể truy cập WMI.
Vì vậy, tôi đã không thêm người dùng của mình vào Người dùng theo dõi hiệu suất hoặc Người dùng COM phân tán cục bộ các nhóm.
Một vài lưu ý liên quan đến kịch bản:
$OBJECT_INHERIT_ACE_FLAG
Kịch bản dưới đây. Tôi đặt tên cho nó là Set-WMINamespaceSsecurity.ps1
Param ([Parameter(Mandatory=$true,Position=0)] [string]$Namespace,
[Parameter(Mandatory=$true,Position=1)] [ValidateSet("Add","Remove")] [string]$Operation,
[Parameter(Mandatory=$true,Position=2)] [string] $Account,
[Parameter(Mandatory=$false,Position=3)] [ValidateSet("EnableAccount","ExecuteMethods","FullWrite","PartialWrite","ProviderWrite","RemoteEnable","ReadSecurity","WriteSecurity")] [string[]] $Permissions=$null,
[Parameter(Mandatory=$false)] [switch]$AllowInherit,
[Parameter(Mandatory=$false)] [switch]$Deny,
[Parameter(Mandatory=$false)] [string]$ComputerName=".",
[Parameter(Mandatory=$false)] [System.Management.Automation.PSCredential]$Credential=$null)
$OBJECT_INHERIT_ACE_FLAG = 0x1
$CONTAINER_INHERIT_ACE_FLAG = 0x2
$ACCESS_ALLOWED_ACE_TYPE = 0x0
$ACCESS_DENIED_ACE_TYPE = 0x1
$WBEM_ENABLE = 0x01
$WBEM_METHOD_EXECUTE = 0x02
$WBEM_FULL_WRITE_REP = 0x04
$WBEM_PARTIAL_WRITE_REP = 0x08
$WBEM_WRITE_PROVIDER = 0x10
$WBEM_REMOTE_ACCESS = 0x20
$WBEM_RIGHT_SUBSCRIBE = 0x40
$WBEM_RIGHT_PUBLISH = 0x80
$READ_CONTROL = 0x20000
$WRITE_DAC = 0x40000
$WBEM_S_SUBJECT_TO_SDS = 0x43003
$ErrorActionPreference = "Stop"
[email protected]{Namespace=$Namespace;Path="[email protected]";ComputerName=$ComputerName}
if ($PSBoundParameters.ContainsKey("Credential")) { $InvokeParams+= @{Credential=$Credential}}
$output = Invoke-WmiMethod @InvokeParams -Name "GetSecurityDescriptor"
if ($output.ReturnValue -ne 0) { throw "GetSecurityDescriptor failed: $($output.ReturnValue)" }
$ACL = $output.Descriptor
if ($Account.Contains('\')) {
$Domain=$Account.Split('\')[0]
if (($Domain -eq ".") -or ($Domain -eq "BUILTIN")) { $Domain = $ComputerName }
$AccountName=$Account.Split('\')[1]
}
elseif ($Account.Contains('@')) {
$Somain=$Account.Split('@')[1].Split('.')[0]
$AccountName=$Account.Split('@')[0]
}
else {
$Domain = $ComputerName
$AccountName = $Account
}
$GetParams = @{Class="Win32_Account" ;Filter="Domain='$Domain' and Name='$AccountName'"}
$Win32Account = Get-WmiObject @GetParams
if ($Win32Account -eq $null) { throw "Account was not found: $Account" }
# Add Operation
if ($Operation -eq "Add") {
if ($Permissions -eq $null) { throw "Permissions must be specified for an add operation" }
# Construct AccessMask
$AccessMask=0
$WBEM_RIGHTS_FLAGS=$WBEM_ENABLE,$WBEM_METHOD_EXECUTE,$WBEM_FULL_WRITE_REP,$WBEM_PARTIAL_WRITE_REP,$WBEM_WRITE_PROVIDER,$WBEM_REMOTE_ACCESS,$READ_CONTROL,$WRITE_DAC
$WBEM_RIGHTS_STRINGS="EnableAccount","ExecuteMethods","FullWrite","PartialWrite","ProviderWrite","RemoteEnable","ReadSecurity","WriteSecurity"
[email protected]{}
for ($i=0; $i -lt $WBEM_RIGHTS_FLAGS.Count; $i++) { $PermissionTable.Add($WBEM_RIGHTS_STRINGS[$i].ToLower(), $WBEM_RIGHTS_FLAGS[$i]) }
foreach ($Permission in $Permissions) { $AccessMask+=$PermissionTable[$Permission.ToLower()] }
$ACE=(New-Object System.Management.ManagementClass("Win32_Ace")).CreateInstance()
$ACE.AccessMask=$AccessMask
# Do not use $OBJECT_INHERIT_ACE_FLAG. There are no leaf objects here.
if ($AllowInherit.IsPresent) { $ACE.AceFlags=$CONTAINER_INHERIT_ACE_FLAG }
else { $ACE.AceFlags=0 }
$Trustee=(New-Object System.Management.ManagementClass("Win32_Trustee")).CreateInstance()
$Trustee.SidString = $Win32Account.SID
$ACE.Trustee=$Trustee
if ($Deny.IsPresent) { $ACE.AceType = $ACCESS_DENIED_ACE_TYPE } else { $ACE.AceType = $ACCESS_ALLOWED_ACE_TYPE }
$ACL.DACL+=$ACE
}
#Remove Operation
else {
if ($Permissions -ne $null) { Write-Warning "Permissions are ignored for a remove operation" }
[System.Management.ManagementBaseObject[]]$newDACL = @()
foreach ($ACE in $ACL.DACL) {
if ($ACE.Trustee.SidString -ne $Win32Account.SID) { $newDACL+=$ACE }
}
$ACL.DACL = $newDACL
}
[email protected]{Name="SetSecurityDescriptor"; ArgumentList=$ACL}+$InvokeParams
$output = Invoke-WmiMethod @SetParams
if ($output.ReturnValue -ne 0) { throw "SetSecurityDescriptor failed: $($output.ReturnValue)" }