属性指南

此集合中模块的一个常见用例是管理各种 Active Directory 对象,例如用户、组、计算机等等。其中一些选项作为直接的模块选项公开,但其他属性可能需要通过此集合中大多数模块共有的attributes选项来设置。

LDAP 属性

Microsoft Active Directory (AD) 的一个核心组件是轻量级目录访问协议 (LDAP) 数据库。此数据库包含与 AD 环境相关的所有信息,例如用户、计算机、组织单位等等。每个对象都包含一组动态属性来描述对象并符合模式。例如,用户包含firstNamecountrysAMAccountName等属性来描述对象本身。Microsoft 在其AD 属性模式中记录了 AD 中的所有内置属性。例如SAM-Account-Name 属性包含此属性周围的元数据。它包括以下字段:

  • Ldap-Display-Name - LDAP 显示名称

  • Syntax - 属性存储的基础值类型

  • System-Only - 属性是否由系统设置,实际上使其成为只读属性

  • Is-Single-Value - 属性值是单个值还是值数组/列表

Ldap-Display-Name是 Ansible 模块引用的属性名称/键。例如,要管理SAM-Account-Name属性,可以使用键sAMAccountName引用它。每个属性至少与一个值关联,但某些属性可以具有多个值。例如,sAMAccountName是一个Is-Single-Value属性,因此只有一个值,但userCert可以包含多个值。Active Directory Users and Computers管理单元 (或dsa.msc) 可用于在高级模式下查看这些 LDAP 属性。这对于查看现有值以及可以在对象上设置哪些属性非常有用。

AD 中的 LDAP 模式也可以扩展以添加组织的自定义属性。此集合中的模块也支持这些自定义属性。要获取属性的 LDAP 模式信息,可以在 PowerShell 中运行以下命令:

Function Get-AttributeMetadata {
    [CmdletBinding()]
    param ([Parameter(ValueFromPipeline)][string[]]$Name)

    begin {
        $schema = (Get-ADRootDSE -Properties subschemaSubentry).subschemaSubentry
        $getParams = @{
            SearchBase = $schema
            LDAPFilter = '(objectClass=*)'
            Properties = 'attributeTypes'
        }
        $attributes = (Get-ADObject @getParams).attributeTypes
        $queried = $false
    }

    process {
        foreach ($n in $Name) {
            $queried = $true
            $attributes | Where-Object {
                $_ -like "*Name '$n'*"
            }
        }
    }

    end {
        if (-not $queried) {
            $attributes
        }
    }
}

# Display all attributes
Get-AttributeMetadata

# Get specific attributes
Get-AttributeMetadata -Name sAMAccountName, o, objectGuid

输出格式如下:

( $ATTRIBUTE_OID NAME '$ATTRIBUTE_NAME' SYNTAX '$TYPE_OID' [SINGLE-VALUE|NO-USER-MODIFICATION] )

$TYPE_OID指定可用于此属性的值类型。在线搜索 OID 以了解更多信息。SINGLE-VALUE指定属性是否只能存储一个值。NO-USER-MODIFICATION指定属性是否为只读且无法设置。

最后一个示例输出:

( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
( 2.5.4.10 NAME 'o' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
( 1.2.840.113556.1.4.2 NAME 'objectGUID' SYNTAX '1.3.6.1.4.1.1466.115.121.1.40' SINGLE-VALUE NO-USER-MODIFICATION )

这表明sAMAccountName是一个只能有一个值的字符串。o属性也是字符串,但可以存储多个值。objectGUID是一个只能有一个值的字节数组值,也是只读的。

设置属性

每个管理 Active Directory 对象的模块都有一个attributes选项,用于直接配置 LDAP 属性。字典接受三个键:

  • add - 如果不存在,则添加属性值

  • remove - 如果存在,则移除属性值

  • set - 用指定的属性值替换现有属性值。

这些键中的每一个都包含一个字典值,其中键是按ldapDisplayName排列的 LDAP 属性名及其要设置的值。由于 LDAP 属性可以包含多个值,因此指定的值可以是单个值或值列表,例如:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        comment: My Comment
        extensionName:
        - Extension Value 1
        - Extension Value 2
        - Extension Value 3

上面的示例将MyUser对象的comment LDAP 属性设置为指定的值。它还将确保extensionName属性设置为这三个值,如果存在,则删除任何其他值。

add键可用于确保将指定的 LDAP 属性值添加到属性值列表中。remove键下的属性也是如此。如果指定的属性值存在于目标属性中,则将其移除。例如:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      add:
        extensionName:
        - Extension Value 1
        - Extension Value 3
      remove:
        extensionName:
        - Extension Value 2

上面的示例将确保extensionName具有值Extension Value 1Extension Value 3,并删除Extension Value 2(如果已设置)。因为没有使用set,所以除非存在于remove条目中,否则不会更改任何现有值。

注意

仅对可以包含多个值的 LDAP 属性使用addremoveIs-Single-Value属性将导致未定义的行为。

要清除属性值,请在set下定义属性,并将值设置为null (~)或空列表。例如:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        # Null can either be represented by no value
        # or with tilde (~)
        comment: ~
        company:
        extensionName: []

此任务将确保commentcompanyextensionName属性清除任何值。

属性类型

属性中可以存储几种不同的值类型。常见类型包括:

  • 字符串

  • 整数

  • 布尔值

  • 字节数组

  • 日期

  • 安全描述符

通过 Ansible 任务设置字符串、整数或布尔值,只需使用 YAML 语法即可,例如:

string: This is a string
integer: 1
boolean: true

注意

字符串比较区分大小写,即 "String" != "string"

这些简单类型也可以用一个字典表示,字典的键为 typevalue。type 键可以设置为以下值之一:

  • bool - 值将转换为布尔值

  • bytes - 值将被解码为 base64 字符串

  • date_time - 值将被解码为 ISO 8601 日期时间字符串

  • int - 值将被解码为整数

  • security_descriptor - 值将被解码为 SDDL 字符串

  • string - 值将转换为字符串

  • raw - 值将原样使用 - 这是默认使用的类型

如下所示:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        # comment: A raw value that is a string
        comment:
          type: raw
          value: A string

        # userAccountControl: 1234
        userAccountControl:
          type: int
          value: 1234

        # extensionName: ['Value 1', 'Value 2']
        extensionName:
        - type: raw
          value: Value 1
        - type: raw
          value: Value 2

只有对于下面列出的更复杂的类型,才真正需要使用带有 typevalue 结构的复杂字典值。如果省略,则值将被视为 type: raw

字节数组

由于 YAML 中无法表示原始字节,因此要使用字节数组值设置属性,请使用以下格式:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        # Attribute with single value
        dsaSignature:
          type: bytes
          value: YmluYXJ5
        # Attribute with multiple values
        userCertificate:
        - type: bytes
          value: Zm9vYmFy
        - type: bytes
          value: YmFyZm9v

此处指定的值是作为 base64 字符串编码的字节。

可以使用 ansible.builtin.b64encode 过滤器 实时编码字符串,并可以使用 ansible.builtin.file lookup 从文件读取数据。

- vars:
    sig_data: "{{ lookup('ansible.builtin.file', '/path/to/my/sig') }}"
  microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        # Attribute with single value
        dsaSignature:
          type: bytes
          value: "{{ sig_data | ansible.builtin.b64encode }}"

日期

具有日期时间值的属性在技术上是整数值,但表示一个时间点。为方便使用,这些条目可以表示为 ISO 8601 扩展格式日期时间,并在内部由整数值表示。要以日期时间格式指定属性值,请使用与上面相同的字典值结构,但将 type 设置为 date_time。例如:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        dateAttributeSingleValue:
          type: date_time
          value: '2019-09-07T15:50:00+00:00'
        dateAttributeMultipleValue:
        - type: date_time
          value: '2019-09-07T15:50:00Z'
        - type: date_time
          value: '2019-09-07T11:50:00-04:00'

在内部,日期时间将转换为 UTC 时间,并转换为自 1601-01-01 以来以 100 纳秒增量表示的数值。这段 PowerShell 代码片段显示了内部获取整数值的过程:

$dt = '2019-09-07T15:50:00Z'
$dtVal = [DateTimeOffset]::ParseExact(
    $dt,
    [string[]]@("yyyy-MM-dd'T'HH:mm:ss.FFFFFFFK"),
    [System.Globalization.CultureInfo]::InvariantCulture,
    [System.Globalization.DateTimeStyles]::AssumeUniversal)
$dtVal.UtcDateTime.ToFileTimeUtc()

注意

如果未指定时区,则假定为 UTC。

安全描述符

安全描述符存储在属性中的字节数组中,但可以使用 security_descriptor 类型更方便地在剧本中表示此值。指定的值是 安全描述符定义语言 (SDDL)。此字符串在内部转换为设置 SDDL 所需的字节数组。设置此类型属性的示例如下:

- microsoft.ad.user:
    name: MyUser
    state: present
    attributes:
      set:
        nTSecurityDescriptor:
          type: security_descriptor
          value: O:DAG:DAD:PAI(A;CI;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

SDDL 字符串可能非常复杂,因此不建议手动构建它们。建议在 Active Directory Users and Computers 管理单元(或 dsa.msc)中构建测试对象,并在“安全”选项卡中根据需要设置安全设置。然后,可以通过以下方式检索 SDDL 字符串:

$dn = 'CN=ObjectName,DC=domain,DC=test'
$obj = Get-ADObject -Identity $dn -Properties nTSecurityDescriptor
$obj.nTSecurityDescriptor.GetSecurityDescriptorSddlForm('All')

DN 查询属性

活动目录中某些属性存储为引用另一个 AD 对象的区分名称 (DN) 值。某些模块提供了一种使用更易于理解的值(例如 managed_by)来查找 DN 的方法。这些选项值必须是字符串,或者是一个包含键 name 和可选键 server 的字典。字符串值或 name 的值是要查找的标识,而 server 是要在其上查找标识的域服务器。查找标识值可以指定为 distinguishedNameobjectGUIDobjectSidsAMAccountNameuserPrincipalName。以下是使用字符串值或字典形式使用 sAMAccountName 查找 DN 的示例:

- name: Find managed_by using string value
  microsoft.ad.group:
    name: My Group
    scope: global
    managed_by: Domain Admins

- name: Find managed_by using dictionary value with a server
  microsoft.ad.group:
    name: My Group
    scope: global
    managed_by:
      name: Domain Admins
      server: OtherDC

还有一些模块选项可以为属性设置 DN 值列表。这些选项的列表值与单值属性相同,其中每个 DN 查询都设置为字符串或一个包含 name 和可选 server 键的字典。

- name: Specify a list of DNs to set
  microsoft.ad.computer:
    identity: TheComputer
    delegates:
      set:
      - FileShare
      - name: ServerA
        server: OtherDC

对于具有 add/remove/set 子键选项的列表属性,还可以将 lookup_failure_action 选项设置为 fail(默认)、ignorewarnfail 选项将在任何查找失败时使任务失败,ignore 将忽略任何无效查找,而 warn 将发出警告,但仍会在查找失败时继续。

- name: Specify a list of DNs to set - ignoring lookup failures
  microsoft.ad.computer:
    identity: TheComputer
    delegates:
      lookup_failure_action: ignore
      set:
      - FileShare
      - MissingUser

提供 server 键时,将使用指定的服务器值进行查找。也可以使用 domain_credentials 选项仅为该服务器提供显式凭据。

- name: Set member with lookup on different server
  microsoft.ad.group:
    name: MyGroup
    state: present
    members:
      add:
      - GroupOnDefaultDC
      - name: GroupOnDefaultDC2
      - name: GroupOnOtherDC
        server: OtherDC
    domain_credentials:
    - username: UserForDefaultDC
      password: PasswordForDefaultDC
    - name: OtherDC
      username: UserForOtherDC
      password: PasswordForOtherDC

在上述示例中,GroupOnOtherDC 将使用 OtherDC 和用户名 UserForOtherDC 进行查找。

模块选项的文档将标识该选项是否支持查找行为,或者是否必须显式提供 DN 值。