Asset Groups are a convenient feature for organizing assets based upon different criteria, including criteria that you could not have known when you configured and first ran your site scans. But many times you would actually like to run scans based off your asset groups. Here are some approaches to bridging that gap using the 0.1.8 version of the Nexpose gem to access the API.

Rescanning Assets

Since rescanning the assets in an asset group is a common need, particularly to check remediation, I added a rescan_assets method to the AssetGroup class in the gem. Here's a snippet of code that will launch a re-scan of all the assets in the group, regardless of what sites the assets belong to.

$ irb -r nexpose
include Nexpose nsc = Nexpose::Connection.new('host', 'user', 'password')
nsc.login group_id = nsc.asset_groups.find
    {
        |group| group.name == 'Cisco'
    }
    .id group = AssetGroup.load(nsc, group_id)
    group.rescan_assets(nsc)

This output for me:

[
    {
        :scan_id=>36, :engine_id=>3
    },
    {
        :scan_id=>37, :engine_id=>4
    },
    {
        :scan_id=>38, :engine_id=>3
    }
]

So I had Cisco machines on three different sites. This launched three adhoc device scans across two different engines. Underneath, it is using the site_device_scan_start method, which uses the Site's current configuration to launch a scan against a subset of assets.

Convert Asset Group to Site

Maybe you want to convert the assets from an Asset Group into a site of its own. This is ideal if you have only done a discovery scan and want to break things up. Or maybe you need to scan a subset of assets using a different scan template.

I was just setting up my environment, so I'd only done discovery scans so far. I'd set up a dozen dynamic asset groups to separate them out, and now I want those to turn into sites. Here's my script:

#!/usr/bin/env
ruby require 'nexpose'
include Nexpose nsc = Connection.new('host', 'user', 'pass')
nsc.login at_exit
    {
        nsc.logout
    }
    groups = nsc.asset_groups.map
    { 
        |g| g.id
    }
    groups.each do |group_id|
    group = AssetGroup.load(nsc, group_id)
    name = "#{group.name} Assets"
    site = Site.new(name)
    site.description = group.description
    site.engine = 5
    devices = group.devices.map
    {
        |dev| dev.address
    }
    .uniq
    devices.each do |asset|
    site.add_asset(asset)
    end
    site.save(nsc)
    puts "Saved new site: #{name}"
end

This will produce sites with static assets, but using this script as a base, there's a script to be written which could update the assets on an existing site to match the assets of an asset group.