it-swarm-vi.tech

Người dùng cần những quyền / quyền nào để có quyền truy cập WMI trên các máy từ xa?

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?

34
jpoh

Các hoạt động sau đây trên Window 2003 R2 SP 2, Windows Server 2012 R2

  1. Thêm người dùng được đề cập vào nhóm Người dùng theo dõi hiệu suất nhóm
  2. Trong Dịch vụ và Ứng dụng, hiển thị hộp thoại thuộc tính của Điều khiển WMI (hoặc chạy 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 AccountRemote Enable
  3. Chạy 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 PermissionsLaunch 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.
  4. Chọn Thiết bị quản lý Windows trong Dịch vụ thành phần> Máy tính> Máy tính của tôi> Cấu hình DCOM và cung cấp Remote LaunchRemote Activation đặc quyền cho Người dùng theo dõi hiệu suất Nhóm.

Ghi chú:

  • Thay vào đó là bước 3 và 4, người ta có thể chỉ định người dùng cho nhóm Người dùng COM phân tán (Đã thử nghiệm trên Windows Server 2012 R2)
  • Nếu người dùng cần quyền truy cập vào tất cả các không gian tên, bạn có thể đặt cài đặt ở 2. ở cấp độ 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
32
jpoh

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.

4
Bunyk

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.

1
ThatGraemeGuy

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.

1
KevinH

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.

0
JustAGuy

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:

  1. Bạn phải chỉ định đường dẫn đầy đủ của không gian tên. Trong trường hợp của tôi, không gian tên là Root/Microsoft/SqlServer
  2. Kế thừa đã sai. Bởi vì không có đối tượng lá nào bạn không thể sử dụng $OBJECT_INHERIT_ACE_FLAG
  3. Tôi đã loại bỏ chức năng nhúng vì nó quá nhỏ và nó chỉ được sử dụng một lần.

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)" }