Microsoft.ad.object

A need has arisen to implement asset tagging on Linux objects in Active Directory. I have been testing with the module named in the subject line, but I keep getting this error:
“New-ADObject failed: An attempt was made to add an object to the directory with a name that is already in use.”

This network is isolated, so getting the full error output (-vvv) is a little difficult. The documentation suggests that editing an existing Active Directory computer object is possible.

microsoft.ad.object module – Manage Active Directory objects — Ansible Documentation

Does anyone have any experience with this particular module, or any suggestions to try for getting past this error?

Probably going to need more information. Can you share a snippet of the code you’re using? Are you running this module against a linux or a windows target (not the AD object)? Have you tried using microsoft.ad.computer module – Manage Active Directory computer objects — Ansible Documentation instead?

1 Like

Below is the code from my test playbook, with some fields sanitized. Previously we had a requirement to update just the description field, so we were using win_domain_computer, but that module is very limited in what it can do. The vars at the bottom are required for that module to work, so I assume they are needed for most microsoft.ad modules, which is why I left them in place. I did try using microsoft.ad.computer, but was not able to get it to work either. The hosts are Linux, which use adcli and sssd to domain-join and authenticate users against an Active Directory infrastructure.

**Please ignore any format issues, since I hand-typed this into this message.

  • hosts: all
    gather_facts: true
    tasks:
    • name: Test microsoft.ad module
      microsoft.ad.object:
      domain_server: ‘{{ ad_preferred_dc }}’
      domain_username: ‘{{ domain_username }}’
      domain_password: ‘{{ domain_password }}’
      name: ‘{{ inventory_hostname }}’
      identity: ‘{{ inventory_hostname }}’
      path: ‘{{ ad_computer_ou }}’
      attributes:
      set:
      ENVIRONMENT: ‘[env_name]’
      PLATFORM: ‘Rocky8]’
      BRANCH: ‘[branch_name]’
      type: computer
      state: present
      delegate_to: ‘{{ ad_preferred_dc }}’
      vars:
      ansible_connection: winrm
      ansible_winrm_server_cert_validation: ignore
      ansible_winrm_transport: ntlm
      ansible_port: [port]
      ansible_become: no
      ansible_become_method: runas
      ansible_user: ‘{{ domain_username }}’
      ansible_password: ‘{{ domain_password }}’
      ansible_become_flags: logon_type=interactive logon_flags=with_profile
      ignore_errors: yes

First, I don’t see any module argument that you’re using for microsoft.ad.object that isn’t in microsoft.ad.computer. I do however see that using both the name and identity arguments may attempt to name, rename, or move an object if the name does not match the property found by identity (if one is found at all, then we would try to create a new object by that name). The ‘name’ argument appends ‘$’ to the value to determine the sAMAccountName. Some other arguments, such as identity, don’t appear to do this. So, your name and identity will never both match “{{ inventory_hostname }}”, and thus trigger creating a New-ADObject using a name that already exists.

Assuming inventory_hostname is the short hostname and not the fqdn, try something like this:

- hosts: all
  gather_facts: true
  tasks:
    - name: Test microsoft.ad module
      microsoft.ad.object:
        domain_server: "{{ ad_preferred_dc }}"
        domain_username: "{{ domain_username }}"
        domain_password: "{{ domain_password }}"
        name: "{{ inventory_hostname }}"
        identity: "{{ inventory_hostname }}$" # appending the '$' should force searching for sAMAccountName's
        sam_account_name: "{{ inventory_hostname }}" # sam_account_name appends missing '$' automatically
        path: "{{ ad_computer_ou }}"
        attributes:
          set:
            ENVIRONMENT: "[env_name]"
            PLATFORM: "[Rocky8]"
            BRANCH: "[branch_name]"
        type: computer
        state: present
      delegate_to: "{{ ad_preferred_dc }}"
      vars:
        ansible_connection: winrm
        ansible_winrm_server_cert_validation: ignore
        ansible_winrm_transport: ntlm
        ansible_port: [port]
        ansible_become: no
        ansible_become_method: runas
        ansible_user: "{{ domain_username }}"
        ansible_password: "{{ domain_password }}"
        ansible_become_flags: logon_type=interactive logon_flags=with_profile
        ignore_errors: yes

The changes you suggested worked when I tested them, so thanks for that. However, when I changed the hard-coded key-pair values for variables it complains about undefined variables. For example:

POC-EMAIL: group-name@outlook.com
vs
POC-EMAIL: ‘{{ cm_poc_email }}’

That and other key-pair variables are defined in the group_vars for this particular set of workstations, so they are defined somewhere. Does this particular module require hard-coded key-pair values?

I think you might be using single quotes when you should be using double-quotes. Single quotes tell Ansible to use literal strings, so ‘{{ cm_poc_email }}’ is literally {{ cm_poc_email }}, while “{{ cm_poc_email }}” expands to group-name@outlook.com.

You might also be running into issues with how delegate_to handles variables relating to the host. The vars you’re using may be undefined in this context. In this case, you may need to use "{{ hostvars[inventory_hostname]['cm_poc_email'] }}".