Are you wanting Linux or windows information here?
If you are using Windows, you could have a look at this Powershell function, warp it up in a Powershell_Script ruby block as per this documentation.
You havenāt said how you want to collect the data, but putting it into CSV file and placing it in file share might be the go? A bit manual in the end, but yeahā¦
Here is a powershell_script chef resource that will list installed applications on a WINDOWS machine it is run and output a CSV file to the location specified in the variable right at the end $OutputFile - If left default on a machine called server01 the path would be C:\OutPut\server01.csv
Iāve expanded the recipe a little. This will now work on windows and linux (tested on CentOS 7.3).
Outputs the .csv file to the root of the systems drive in a folder called output and writes a file named after the DNS name of the machine it is run on.
#
# Cookbook:: list_installed_apps
# Recipe:: default
#
# Copyright:: 2017, SVucich, All Rights Reserved.
# Creates a var with the computers DNS name
machine_name = node['hostname'] # get the machine's DNS name
# Variable so we can use logic to get the platform 'windows/linux'
op_sys = node['os'] # get the OS type
# Windows work first
if op_sys == 'windows'
powershell_script 'List-Programs' do
code <<-EOH
Function Get-RemoteProgram {
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(ValueFromPipeline =$true,
ValueFromPipelineByPropertyName=$true,
Position=0
)]
[string[]]
$ComputerName = $env:COMPUTERNAME,
[Parameter(Position=0)]
[string[]]
$Property,
[switch]
$ExcludeSimilar,
[int]
$SimilarWord
)
begin {
$RegistryLocation = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\',
'SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\'
$HashProperty = @{}
$SelectProperty = @('ProgramName','ComputerName')
if ($Property) {
$SelectProperty += $Property
}
}
process {
foreach ($Computer in $ComputerName) {
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
$RegistryLocation | ForEach-Object {
$CurrentReg = $_
if ($RegBase) {
$CurrentRegKey = $RegBase.OpenSubKey($CurrentReg)
if ($CurrentRegKey) {
$CurrentRegKey.GetSubKeyNames() | ForEach-Object {
if ($Property) {
foreach ($CurrentProperty in $Property) {
$HashProperty.$CurrentProperty = ($RegBase.OpenSubKey("$CurrentReg$_")).GetValue($CurrentProperty)
}
}
$HashProperty.ComputerName = $Computer
$HashProperty.ProgramName = ($DisplayName = ($RegBase.OpenSubKey("$CurrentReg$_")).GetValue('DisplayName'))
if ($DisplayName) {
New-Object -TypeName PSCustomObject -Property $HashProperty |
Select-Object -Property $SelectProperty
}
}
}
}
} | ForEach-Object -Begin {
if ($SimilarWord) {
$Regex = [regex]"(^(.+?\\s){$SimilarWord}).*$|(.*)"
} else {
$Regex = [regex]"(^(.+?\\s){3}).*$|(.*)"
}
[System.Collections.ArrayList]$Array = @()
} -Process {
if ($ExcludeSimilar) {
$null = $Array.Add($_)
} else {
$_
}
} -End {
if ($ExcludeSimilar) {
$Array | Select-Object -Property *,@{
name = 'GroupedName'
expression = {
($_.ProgramName -split $Regex)[1]
}
} |
Group-Object -Property 'GroupedName' | ForEach-Object {
$_.Group[0] | Select-Object -Property * -ExcludeProperty GroupedName
}
}
}
}
}
}
$PathExists = Test-Path 'c:\\output'
if ($PathExists -eq $false)
{
New-Item -Path 'c:\' -Name Output -ItemType Directory
}
else
{
# Do nothing
}
$OutputFile = ('c:\\output\\'+"$env:COMPUTERNAME"+'.csv')
Get-RemoteProgram -Property DisplayVersion | Export-Csv -NoTypeInformation -Path $OutputFile
EOH
not_if { ::File.exists?("c:\\output\\"+"#{machine_name}")}
end
# Linux work here
elsif op_sys == 'linux'
directory '/output' do
owner 'root'
group 'wheel'
mode '0755'
action :create
end
bash 'List-Programs' do
code <<-EOH
outputfolder='/output/'
extension='.csv'
dnsname="#{machine_name}"
outfile=$outputfolder"#{machine_name}"$extension
yum list installed | awk '{ print $1,$2 }' | tail -n +1 | sed -e $'1i\\\\\\nPackage,Version' -e 's/ /,/g' | tail -n +1 >> $outfile
EOH
end
end
You will still need to build in some way to get the files off the machine. I am sure you could work on that
I thought someone said that (at least for Linux) Ohai already does package detection, so you could query node[āpackagesā][āopensslā] for information (or search with knife across multiple nodes). Iām having some hard time finding this but the Ohai packages.rb is listed on https://docs.chef.io/ohai.html so I think Iām just getting the attribute namespace wrong. And looking at https://github.com/chef/ohai/blob/master/lib/ohai/plugins/packages.rb it does appear to support Windows as well.