Last updated at Wed, 30 Aug 2017 14:32:22 GMT

If you are looking to balance out your scan schedule or add new scans to the mix, it can be helpful to get some direct insight into how much time a new scan is going to take. One way to estimate that is based upon how long your current scans are already taking.

To that end, I threw together a script that looks at current scan history and calculates average scan time per asset. To keep some balance, I only look at Full audit scans and their live assets. I then calculate the average number of minutes that each asset takes to scan. The script uses version 0.1.7 of the Nexpose gem to access the API.

Here is the code for analyze_average_scan_time.rb

require 'nexpose'
include Nexpose nsc ='host', 'user', 'password') nsc.login at_exit
{ nsc.logout }
engine_times = {}
engine_assets = {}
nsc.sites.each do |site|
config = Site.load(nsc,
next unless config.scan_template =~ /full-audit/
scan_history = nsc.site_scan_history(
scan_history.each do |scan|
next unless scan.end_time
# Skip running scans.
engine = scan.engine_id
live =
    if scan.nodes
        start_time = scan.start_time
        end_time = scan.end_time
        if live
            engine_times[engine] ||= 0
            engine_times[engine] = (end_time - start_time)
            engine_assets[engine] ||= 0
            engine_assets[engine] = live
engines = nsc.engines engine_times.each do |id, time|
name = engines.find
{ |eng| == id }.name
avg_time = '%.2f' % (time / engine_assets[id] / 60)
puts "#{name} : #{avg_time} minutes / asset"

The script produced the following output in my environment:

remote-engine-one : 1.35 minutes / asset
remote-engine-two : 1.33 minutes / asset

Since both of my scan engines are nearly identical in hardware, it's not much surprise that their results were so close.


There are a few things I should mention about the limitations of this script.

Paused scans: For one thing, if you are performing scheduled scans that pause and resume, the time calculations are going to be completely useless. The script assumed that scans start and then run to completion in one run. It doesn't account for a twelve hour gap because of scheduling.

Scan template: This average time is not really how long it takes to scan one asset, but how long it takes to scan one asset alongside however many are running together. I was using the default scan templates, which means that as many ten assets were being scanned in parallel for each scan. This would imply that I could scan ten assets in about 1.35 minutes, not 13.5 minutes.

Variation: If there are aberrant scans that take an inordinate amount of time, it is going to throw off the metrics. Likewise, if you have a mix of credentialed and un-credentialed scans, it would make sense to isolate those to take measurements separately.

Historical changes: Another thing to watch out for is that sites that have had their configuration changed between scans can skew results. The script handles different Scan engine IDs, but it doesn't account for a scan that ran using a different scan template before.

Live assets: This script is also just checking against live assets. There is a certain amount of time used up searching for inactive assets if they are part of the configuration. This would be easy to adjust in the script. You could also do some additional map on what percentage of assets are not live across your configurations.