Issuing creating domain users with module win_dsc and resource xADuser parsing pscredentials

I’m trying to create a bunch of domain application test accounts with the same password using DSC Resource xADUser.

I have a file called secrets.yml that contains the password for these accounts - secrets.yml is encrypted via Vault. This also includes ansible_admin_user and ansible_admin_pwd

I get a warning when running the play of "[WARNING]: failed to cast property Password from ‘XXXXXXX’ of type System.String to type System.Management.Automation.PSCredential, the DSC engine may ignore this property with an invalid cast

And the play fails with… “msg”: “Convert property ‘Password’ value from type ‘STRING’ to type ‘INSTANCE’ failed”…

Running Ansible 2.7

Domain controllers are W2K12 R2

  • hosts: dcs gather_facts: no vars_files: - vars/secrets.yml tasks: - name: Create new test accounts (DEV + Test Env) win_dsc: resource_name: xADUser

PsDscRunAsCredential_username: “{{ ansible_admin_user }}” PsDscRunAsCredential_password: “{{ ansible_admin_pwd }}” # This is stored in secrets.yml DomainName: test.com UserName: “{{ item.user }}” Password: “{{ testuser_pwd }}” # This is stored in secrets.yml - encrypted via Vault Ensure: present Path: “{{ testers_ou }}” DisplayName: “{{ item.user }}” GivenName: “{{ item.user }}” Description: “{{ item.description }}” Enabled: true PasswordNeverExpires: true loop: “{{ testers }}” #list defined in group_vars

The psdscrunascredential_username I specified above is a domain admin account that Ansible uses to run tasks against Windows boxes - password stored in “PsDscRunAsCredential_password” is not the pwd stored in parameter “password”/variable “testuser_pwd” as per first post.

Looking at the code, it seems like the Password option is actually of the type PSCredential and not just a SecureString https://github.com/PowerShell/xActiveDirectory/blob/dev/DSCResources/MSFT_xADUser/MSFT_xADUser.psm1#L101. This means that you need to setup the Password like you any other PSCredential field by setting Password_username and Password_password. The module win_dsc scans each property for the expected type and tries to cast the input value from Ansible to what it expects but in the case of a PSCredential we need to know both the username and password to create it. You can see this in the warning message when it says it failed to convert Password (System.String) to a PSCredential.

I’m not sure why a Password field is expecting the full credential so maybe you can set ‘Password_username’ as an empty string or set it to the same value as ‘UserName’. This is more a question for the actual module itself as we have no control over this.

On a side note, we do have the win_domain_user module https://docs.ansible.com/ansible/latest/modules/win_domain_user_module.html and from a glance it should give you what you need without relying on the DSC resource.

Thanks

Jordan

Thanks, Jordan - I tried your suggestion for the username and password parameter …

Password_username: “{{ item.user }}”
Password_password: “{{ testuser_pwd }}” # This is stored in secrets.yml - encrypted via Vault

New error is:

“module_stderr”: “Exception calling "Add" with "2" argument(s): "Item has already been added. \r\nKey in dictionary: ‘Password’ Key being added: ‘Password’"\r\nAt line:229 char:13\r\n+ $config.Property.Add($key.Replace("_username",""),$KeyVal …\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : NotSpecified: (:slight_smile: , ParentContainsErrorRecordE \r\n xception\r\n + FullyQualifiedErrorId : ArgumentException\r\n \r\n\r\n”,

Setting parameter “Password_username” bombed out with a different error of…

““module_stderr”: “New-Object : Exception calling ".ctor" with "2" argument(s): "Cannot process \r\nargument because the value of argument "userName" is not valid. Change the \r\nvalue of the "userName" argument and run the operation again."\r\nAt line:228 char:25\r\n+ … $KeyValue = New-Object System.Management.Automation.PSCredential ($Pr …\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : InvalidOperation: (:slight_smile: [New-Object], MethodInvoca \r\n tionException\r\n + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.Power \r\n Shell.Commands.NewObjectCommand\r\n \r\n\r\n”,”

Prior to trying this module, I was trying to use win_domain_user module - however, I strike a different issue with this. It creates a user in AD but fails to set the password even though I can confirm the password meets policy requirements (complexity, length, history etc). I confirmed this via creating the account via PS, manually and also writing the password to a txt file via Ansible.

In addition, even after returning the attributes of a newly created user it reports “server is not operational”

The code I used was…

  • name: create new test accounts (dev + test env)
    win_domain_user:
    name: “{{ item.user }}”
    firstname: “{{ item.user }}”
    groups_action: add
    state: present
    enabled: yes
    path: “ou=employees,dc=domain,dc=test”
    password: “{{ testuser_pwd | quote }}” # this is stored in secrets.yml - encrypted via vault
    password_never_expires: yes
    user_cannot_change_password: yes
    upn: “{{ item.upn }}”
    groups: “{{ item.groups }}”
    loop : “{{ testers }}” #definted in group_vars

“msg”: “The server is not operational”,
“password_updated”: true,

The groups also aren’t added to the user (these are defined in a list)… this is stored in group_vars

testers:

  • user: test1
    groups:
  • group1
  • group2
    description: ‘tester’
    upn: test1@domain.test

That error you just received is because you still have Password defined when you need to have only ‘Password_username’ and ‘Password_password’. After removing the duplicate Password entry I then come across another issue “The server could not be contacted.”. I’ve added DomainController and tried DOmainAdministratorCredential (user/pass) but this doesn’t seem to fix the problem.

I’m not sure why the last issue is happening but I’m more interested why win_domain_user doesn’t work for you. When you say it fails to set the password, do you mean the password set for it is incorrect or it errors saying something about an invalid password?

Thanks

Jordan

I got the play working user dsc by removing the duplicate password entry, but I also had to add the field of “PasswordAuthentication” and set this to “Negotiate” for it to work! Thanks for your help.

In regards to your last question I get the error of “your username or password is incorrect, try again”.

My other issue is adding these users to groups… I’ve sussed getting them into the groups I need but it’s also creating a new group in AD merging the groups I have listed in the dict. An example of the newly created (and unwanted group) is named “group1 group2” Snippet of dict is below (have multiple users being setup with same structure as below)

testers:

  • user: tester1
    groups:

  • group1

  • group2
    description: ‘tester’
    ou: “ou=Employees,dc=test,dc=com”
    upn: ‘tester1@test.com’

  • user: tester2
    groups:

  • group1

  • group2
    description: ‘tester’
    ou: “ou=Employees,dc=test,dc=com”
    upn: ‘tester2@test.com’

Within the play I have…

upn: “{{ item.upn }}”
groups: “{{ item.groups }}”
loop : “{{ testers }}” #Definted in group_vars

What am I doing wrong? Pretty new to using lists in dicts etc… I did try with_dict etc and specifying a list for the loop…

TIA.

Please ignore formatting in the last pasted bit of code - upn and groups are in a line indented from loop.