chef / ohai

Ohai profiles your system and emits JSON
https://docs.chef.io/ohai.html
Apache License 2.0
681 stars 449 forks source link

Request: windows_updates plugin (code in description) #1706

Open chef-davin opened 3 years ago

chef-davin commented 3 years ago

Describe the Enhancement

I would like to get a list of windows updates either on the system or available to the system.

Describe the Need

I'm working on a resource for installing specific updates on a windows system and it would be helpful if ohai had some info gathering capability so that it didn't have to be a part of the resource and other people could use it for their own resources and reporting.

Current Alternative

Sure, I can put this code into a helper library or into a custom resource in a cookbook. It's not essential that this go in ohai, but I thought it would be a nice to have.

Can We Help You Implement This?

I have the code for the plugin already. I just have never setup tests for ohai PRs and don't have the time to learn it right this minute, but can work on that later if people think this is a good idea to add into the plugin list.

Ohai.plugin(:WindowsUpdates) do
  provides 'windows_updates'
  def get_windows_updates
    cmd = [
    'powershell.exe -NoLogo -NonInteractive -NoProfile -command',
    '"$session = New-Object -ComObject \"Microsoft.Update.Session\";',
    '$updatesearcher = $session.CreateUpdateSearcher();',
    '$searchresult = $updatesearcher.Search(\"IsInstalled=0 or IsInstalled=1\");',
    '$system_updates = @{};',
    'foreach ($update in $searchresult.Updates) {',
        '$this_update = @{',
            '\"$($update.Title)\" = New-Object -Type PSCustomObject -Property @{',
                '\'uuid\' = $($update.Identity.UpdateID);',
                '\'kbid\'   = \"KB$($update.KBArticleIDs)\";',
                '\'isinstalled\' = $($update.IsInstalled);',
                '\'rebootrequired\' = $($update.RebootRequired);',
            '}',
        '};',
        '$system_updates += $this_update',
    '};',
    '$system_updates | ConvertTo-Json"'].join(' ')
    so = shell_out(cmd)

    if so.exitstatus == 0
      JSON.parse(so.stdout)
    end
  end

  collect_data(:windows) do
    require 'json' unless defined?(JSON)

    windows_updates Mash.new
    windows_updates get_windows_updates
  end
end

I've tested this out on windows 10 systems, and it should work as far back as windows 2008r2 I believe.

The only issue here is that using the Microsoft.Update.Session ComObject is a slow thing. If added, we might want to consider making it one of those plugins that's not enabled by default. Just because it will definitely add several seconds to the ohai run.

tas50 commented 2 years ago

@chef-davin Any chance you want to open a PR for this with some tests?