2

I created a Powershell script in order to produce custom Ansible facts on target Windows machine listing installed software. For now I can't get my software list properly parsed within my playbook.

I can see the raw content of custom facts, but it seems like JSON is not properly parsed because I can't get a proper list object to be processed by a loop statement. A fatal error occurs:

The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'\n\n

All custom facts (meaning Windows software list generated by Powershell custom fact) are stored automatically by Ansible within an autogenerated variable/attribute of ansible_facts called 'ansible_softwarelist' ('ansible_' suffix + name of my fact file without extension).

Custom fact (Powershell)

$software = get-wmiobject -class Win32_Product | select-object name,version,vendor
$software_count = ($software | measure).count
$software_list | % { `
    $i++

    if ($i -lt ($software_count-1))
    {
        $separator = ","
    }
    else
    {
        $separator = ""
    }

    write-host "{`"name`":`"$($_.name)`",`"version`":`"$($_.version)`",`"vendor`":`"$($_.vendor)`"}$separator"

}

Raw Powershell output

{"name":"Software 1","version":"14.0.7015.1000","vendor":"Vendor 1"},
{"name":"Software 2","version":"14.1.1000","vendor":"Vendor 1"},
{"name":"Software 3","version":"1.5.2","vendor":"Vendor 1"}

Ansible playbook

tasks:         

     - name: "Deploy Powershell script (custom Windows facts)"
       win_copy:
         src: "/etc/ansible/files/facts/softwarelist.ps1"
         dest: "C:\\remotedir\\softwarelist.ps1"

     - name: "Gather custom facts"
       setup:
         fact_path: "C:\\remotedir"

     - name: "View software list in Ansible by name"
       debug:
         msg: "{{ item.name }}"  
       loop: "{{ ansible_softwarelist }}"  
donmelchior
  • 893
  • 3
  • 13
  • 31
  • Removing espace characters '`' and replacing all commas of "get-wmiobject" output in Powershell output produces the same error message in Ansible. Is my JSON output valid? – donmelchior Mar 13 '19 at 15:29

2 Answers2

2

I have implemented this just now and have few suggestions for you if you are still working on this.

  1. Don't use Win32_Product class on any non-dev servers as this process also initiates a consistency check of packages installed, verifying and repairing the install.

  2. I recommend you to take a look at the script, to get the list of installed programs.

  3. You don't need to return values of Json format from powershell script. Output of type List, Collection will do. I would actually recommend this as it would help in browsing through the cache database like mongodb if you are using one. If you return a json format output from your powershell script, the objects would be stored in string format "{"key":"value"}" in database.

raghavendrap
  • 141
  • 8
  • 1
    The win32_product remark here is important to remember. I've seen some custom software settings get reset to default on production machines because a junior admin ran this command over multiple machines because of a repair on all msi's. – bluuf Jan 19 '20 at 09:46
  • Which script do you refer to in https://learn.microsoft.com/en-us/samples/browse/?redirectedfrom=TechNet-Gallery ? – Kok How Teh Mar 31 '21 at 02:29
  • What should be used in place of Win32_Product? – Kok How Teh Mar 31 '21 at 02:30
  • 1
    Updated the script link. The script didn't use the powershell functions instead it uses the registry values. – raghavendrap Apr 03 '21 at 22:40
  • 1
    @KokHowTeh Either `Win32reg_addRemovePrograms` or `Sms_InstalledSoftware`, both of which I believe are installed by SCCM. Otherwise: https://stackoverflow.com/questions/25268491/alternative-to-win32-product – Bacon Bits Apr 04 '21 at 23:32
  • if you don't have SCCM, you can't use either Win32reg_addRemovePrograms or Sms_InstallSoftware. – raghavendrap Apr 05 '21 at 09:46
0

Try to set Filter : "| to_json" this should format your values correctly