Patch Management APIs
PM APIs return data on patches, asset patch status/compliance, and patch jobs.
Head's Up!: Qualys does not support MacOS for the patch management API.
After running:
You can use any of the endpoints currently supported:
PM Endpoints
API Call | Description |
---|---|
get_version |
Returns the version of the PM API. |
list_jobs |
Returns jobs that match given kwargs. |
get_job_results |
Returns a summary of a job. |
get_job_runs |
Returns a list of runs of a job. |
create_job |
Creates a new job. |
delete_job |
Deletes a job or a list of jobs. |
change_job_status |
Enable/disable a job or a list of jobs. |
lookup_cves |
Returns a list of CVEs and other details associated with a QID. |
get_patches |
Returns a list of patches. |
get_assets |
Returns a list of assets. |
get_patch_count |
Returns the number of patches for a given platform that match query and havingQuery . |
get_asset_count |
Returns the number of assets for a given platform that match query and havingQuery . |
lookup_host_uuids |
Returns a list of tuples, containing host UUIDs for a given list of asset IDs. |
get_patch_catalog |
Returns the patch catalog for a given platform according to patchId . |
Get PM Version API
get_version
returns the version of the PM API.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_version
auth = TokenAuth(<username>, <password>, platform='qg1')
get_version(auth)
>>>"3.1.0.0-29"
List Jobs API
list_jobs
returns a BaseList
of patch management jobs in the user's account that match the given kwargs. if platform='all'
, it uses threading to speed up the process.
Head's Up!: For the
filter
kwarg, see the linked documentation for the possible values: Windows Jobs, Linux Jobs
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
platform |
Literal['all', 'windows', 'linux']='all' |
The platform of the job | ❌ |
page_count |
Union[int, "all"] = "all" |
The number of pages to return | ❌ |
filter |
str |
The QQL filter to search for jobs | ❌ |
attributes |
str |
The attributes to return in the response as a comma-separated string | ❌ |
coauthorJob |
bool=False |
Only include jobs where the user is a coauthor | ❌ |
ownedJob |
bool=False |
Only include jobs where the user is the sole owner | ❌ |
pageSize |
int=10 |
The number of jobs to return per page | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import list_jobs
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get all Windows jobs:
win_jobs = list_jobs(auth, 'windows')
>>>[
PMJob(
name="My Job",
id="<job_guid>",
platform="Windows",
...
),
...
]
Get Job Results API
get_job_results
returns the results of a patch management job.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
jobId |
Union[str, BaseList[PMJob, str]] |
The ID(s) of the job to get results for. If a BaseList of PMJob objects is passed, the function will use threading. |
✅ |
jobInstanceId |
str |
The ID of the job instance to get results for. Should not be used with threading. | ❌ |
pageSize |
int=10 |
The number of results to return per page | ❌ |
sort |
str |
The field to sort the results by | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_job_results, list_jobs
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get some job:
job = list_jobs(auth, 'linux')[0]
# Get the results summary for the job:
results = get_job_results(auth, job.id)
>>>JobResultSummary(
id='11111111-2222-3333-4444-555555555555',
name='My Job',
assetCount=1,
patchCount=1,
createdBy=<username>,
createdOn=datetime.datetime(2020, 1, 2, 3, 12, 30, 777000),
assets=[
PMAssetJobView(
id='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
name='Patch Asset',
operatingSystem='Red Hat Enterprise Linux 9.5',
...
)
]
)
# Threading example:
jobs = list_jobs(auth)
results = get_job_results(auth, jobs)
Get Job Runs API
get_job_runs
returns a list of runs of a patch management job.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
jobId |
str |
The ID(s) of the job to get runs for | ✅ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_job_runs, list_jobs
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get some job:
job = list_jobs(auth, 'linux')[0]
# Get the runs for the job:
runs = get_job_runs(auth, job.id)
>>>[
PMRun(
jobInstanceId=1,
jobId='11111111-2222-3333-4444-555555555555',
scheduledDateTime=datetime.datetime(2020, 1, 1, 15, 32, 18, tzinfo=datetime.timezone.utc),
timezoneType='SPECIFIC_TZ'
)
]
Create Job API
create_job
creates a new patch management job.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
name |
str |
The name of the job | ✅ |
platform |
Literal["Windows", "Linux"] |
The platform of the job | ✅ |
jobType |
Literal["Install", "Rollback"] |
The type of job to create. Rollback is Windows-only. |
✅ |
scheduleType |
Literal["On-demand", "Once", "Daily", "Weekly", "Monthly"] |
The type of schedule to use | ✅ |
approvedPatches |
List[str] |
An explicit list of patche GUIDs to add to the job | ❌ |
assetIds |
List[str] |
The IDs of the assets to target | ❌ |
assetTagIds |
List[str] |
The IDs of the asset tags to target | ❌ |
filterType |
Literal["all", "any"] = "any" |
The type of filter to use | ❌ |
exclusionTagIds |
List[str] |
The IDs of the asset tags to exclude | ❌ |
exclusionAssetIds |
List[str] |
The IDs of the assets to exclude | ❌ |
description |
str |
The description of the job | ❌ |
coAuthorUserIds |
List[str] |
The IDs of the co-authors to add to the job | ❌ |
exclusionFilterType |
Literal["all", "any"] = "any" |
The type of exclusion filter to use | ❌ |
startDateTime |
str |
The start date and time of the job | ❌ for On-demand , ✅ for others |
recurring |
bool=False |
Whether the job is recurring | ❌ |
dayOfMonth |
int, 0 <= x <= 31 |
The day of the month to run the job | ❌ |
matchAllTagIds |
list[str] |
The IDs of the asset tags to match | ❌ |
recurringLastDayOfMonth |
bool=False |
Whether the job runs on the last day of the month | ❌ |
monthlyRecurringType |
Literal[0, 1, "0", "1"] |
If 1, run on Patch Tuesday | ❌ |
patchTuesdayPlusXDays |
int, -27 <= x <= 27 |
The number of days before or after Patch Tuesday to run the job | ❌ |
recurringDayOfMonth |
int, 1 <= x <= 5 |
Run the job on a specific weekday of the month | ❌ |
recurringWeekDayOfMonth |
int, 0 <= x <= 6 |
The day of the week to run the job | ❌ |
recurringWeekDays |
str like "0,0,0,0,0,0,0" |
Similar to cron. Replace a 0 with a 1 to run on that day. str[0] = Sunday | ❌ |
dynamicQQLType |
Literal[0,1,2] |
0 = Do not use QQL, 1 = use patch QQL, 2 = use vulnerability QQL | ❌ |
isDynamicPatchesQQL |
bool=False |
Whether to use dynamic patches QQL | ❌ |
dynamicPatchesQQL |
str |
The QQL to use for dynamic patches | ❌ |
continueOnPatchFailure |
bool=True |
(Linux only) Whether to continue the job if a patch fails | ❌ |
preDeployment |
str |
Specify a message to display before deployment starts | ❌ |
duringDeployment |
str |
Specify a message to display during deployment | ❌ |
postDeployment |
str |
Specify a message to display after deployment | ❌ |
onComplete |
str |
Specify a message to display when the job completes | ❌ |
rebootCountdown |
str |
Specify a message to display before a reboot | ❌ |
rebootOption |
str |
Specify a message for after a reboot | ❌ |
suppressReboots |
bool=False |
Allow users to suppress reboots | ❌ |
minimizeWindow |
bool=False |
Allow users to minimize the deployment window | ❌ |
status |
Literal["Disabled", "Enabled"] = "Disabled" |
The status of the job | ❌ |
timeout |
int 1 <= x <= 168 for hours, int 1 <= x <= 10080 for minutes |
The timeout for the job in hours or minutes (specified by timeoutUnit) | ❌ |
timeoutUnit |
Literal["HOURS", "MINUTES"] | The unit of the timeout | ❌ |
timezoneType |
Literal["AGENT_TZ", "SPECIFIC_TZ"] |
The timezone type to use | ❌ |
timezone |
str |
The (timezone)[https://docs.qualys.com/en/pm/api/deployment_job_resource/time_zones.htm] to use. For example: "America/New_York" |
❌ |
opportunisticDownloads |
bool=False |
Whether to use opportunistic downloads. Only available for Windows | ❌ |
linkedJobId |
str |
The ID of the job to link to | ❌ |
notificationType |
bool |
If true, email notifications are sent | ❌ |
notificationConfigRecipientEmail |
str |
The email to send notifications to | ❌ |
notificationConfigCompletedPercentage |
int 1 <= x <= 100 |
The percentage of completion to send notifications at | ❌ |
notificationEvents |
bool |
If true, send notifications when onJobStart or onJobComplete are triggered |
❌ |
downloadRandomizeTime |
str |
Provide the job randomize time in hours or minutes. Max is 2 hours or 120 minutes and must be less than the timeout/timeoutUnit | ❌ |
downloadRandomizeTimeUnit |
Literal["HOURS", "MINUTES"] |
The unit of the randomize time | ❌ |
additionalDynamicQQLType |
Literal[1,2] |
1 = Use patch QQL, 2 = Use vulnerability QQL | ❌ |
There are a few ways to pass in certain assets. If you have very particular assets in mind, you can make a GAV API call to get the agentIds of the assets you want to target:
Example 1 with GAV Query
from qualysdk.auth import TokenAuth
from qualysdk.pm import create_job
from qualysdk.gav import query_assets
auth = TokenAuth(<username>, <password>, platform='qg1')
windows_assets = query_assets(
auth,
filter="operatingSystem.category: `Windows / Server`",
includeFields="agentId",
)
# PM uses GUIDs for almost everything, so we need
# to extract the GUIDs from the assets:
windows_assets_ids = [asset.agentId for asset in windows_assets]
# Create a new job for Windows servers. Let's
# focus on critical patches only:
job = create_job(
auth,
platform='Windows',
jobType='Install',
scheduleType='On-demand',
assetIds=windows_assets_ids,
name='My Job',
dynamicPatchesQQL="vendorSeverity:`Critical`",
dynamicQQLType=1,
isDynamicPatchesQQL=True,
status="Enabled", # Immediately enable the job. By default, the job is disabled!
)
>>>"11111111-2222-3333-4444-555555555555"
Or you can use asset tags to dynamically target assets.
Using PM tag GUIDs is a bit more cumbersome since Qualys does not provide an easy way to look up tag GUIDs, but this method is much more flexible since new assets are picked up automatically by the job:
Example 2 with Tag GUIDs
from qualysdk.auth import TokenAuth
from qualysdk.pm import create_job
auth = TokenAuth(<username>, <password>, platform='qg1')
# Create a new job for Windows servers. Let's
# assume we have a tag for all Windows servers
# with GUID 22222222-3333-4444-5555-666666666666:
job = create_job(
auth,
platform='Windows',
jobType='Install',
scheduleType='On-demand',
assetTagIds=['22222222-3333-4444-5555-666666666666'],
name='My Job',
dynamicPatchesQQL="vendorSeverity:`Critical`",
dynamicQQLType=1,
isDynamicPatchesQQL=True,
status="Enabled", # Immediately enable the job. By default, the job is disabled!
)
>>>"11111111-2222-3333-4444-555555555555"
Delete Job API
delete_job
deletes a patch management job or a list of jobs.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
jobId |
Union[str, BaseList[str]] |
The ID(s) of the job to delete | ✅ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import delete_job, list_jobs
auth = TokenAuth(<username>, <password>, platform='qg1')
# Delete a single job:
job = list_jobs(auth, 'linux')[0]
delete_job(auth, job.id)
>>>[
{
"id":"11111111-2222-3333-4444-555555555555",
"name":"My job",
"status":"success"
}
]
# Delete multiple jobs:
jobs = list_jobs(auth)
delete_job(auth, [job.id for job in jobs])
>>>[
{
"id":"11111111-2222-3333-4444-555555555555",
"name":"My job",
"status":"success"
},
{
"id":"22222222-3333-4444-5555-666666666666",
"name":"My other job",
"status":"success"
},
...
]
Change Job Status API
change_job_status
enables or disables a patch management job or a list of jobs.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
action |
Literal["enable", "disable"] |
The action to perform | ✅ |
jobId |
Union[str, BaseList[str]] |
The ID(s) of the job to change the status of | ✅ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import change_job_status, list_jobs
auth = TokenAuth(<username>, <password>, platform='qg1')
# Disable a single job:
job = list_jobs(auth, 'linux')[0]
change_job_status(auth, 'disable', job.id)
>>>[
{
"id":"11111111-2222-3333-4444-555555555555",
"name":"My job",
"status":"success"
}
]
# Disable multiple jobs:
jobs = list_jobs(auth)
change_job_status(auth, 'disable', [job.id for job in jobs])
>>>[
{
"id":"11111111-2222-3333-4444-555555555555",
"name":"My job",
"status":"success"
},
{
"id":"22222222-3333-4444-5555-666666666666",
"name":"My other job",
"status":"success"
},
...
]
Lookup CVEs for QIDs API
lookup_cves
returns a list of CVEs and other details associated with specified QIDs as a BaseList
of PMVulnerability
objects.
This function accepts either a single QID as a string or integer, a list/BaseList of strings/integers, or a comma-separated string of QIDs.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
qids |
Union[str, int, BaseList/list[str, int]] |
The QID(s) to look up. Can be a list of strings/ints, a single int/string, or a comma-separated string | ✅ |
threads |
int=5 |
The number of threads to use for the lookup. ⚠️ Thread mode is only used if 1K+ qids are passed |
❌ |
from qualysdk.auth import TokenAuth, BasicAuth
from qualysdk.vmdr import query_kb
from qualysdk.pm import lookup_cves
token = TokenAuth(<username>, <password>, platform='qg1')
basic = BasicAuth(<username>, <password>, platform='qg1')
# Get some QIDs:
qids = query_kb(basic, page_count=1, ids='10000-11000')
# Get the PM details/CVEs:
cves = lookup_cves(token, [qid.QID for qid in qids])
>>>[
PMVulnerability(
id=10230,
title='Viralator CGI Input Validation Remote Shell Command Vulnerability',
cves=['CVE-2001-0849'],
detectedDate=datetime.datetime(2001, 11, 7, 16, 15, 57),
severity=5,
vulnType='VULNERABILITY'
),
PMVulnerability(
id=10310,
title='Suspicious file register.idc',
cves=None, # Sometimes there are no CVEs!
detectedDate=datetime.datetime(2001, 4, 3, 4, 12, 9),
severity=1,
vulnType='POTENTIAL'
),
...
]
# Or you can pass in a single QID:
cve = lookup_cves(token, 10230)
>>>PMVulnerability(
id=10230,
title='Viralator CGI Input Validation Remote Shell Command Vulnerability',
cves=['CVE-2001-0849'],
detectedDate=datetime.datetime(2001, 11, 7, 16, 15, 57),
severity=5,
vulnType='VULNERABILITY'
)
Get Patches API
get_patches
returns a BaseList
of Patch
objects that match the given kwargs.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
page_count |
Union[int, "all"] = "all" |
The number of pages to return | ❌ |
pageSize |
int=1000 |
The number of patches to return per page | ❌ |
platform |
Literal["all", "windows", "linux"] = "all" |
The platform of the patches to return | ❌ |
query |
str="patchStatus:[Missing,Installed] and isSuperseded:false FOR WINDOWS |
A patch QQL query to filter with. By default returns all of the latest patches if platform=windows |
❌ |
havingQuery |
str |
A PM host QQL query to filter with | ❌ |
attributes |
str |
The attributes to return in the response as a comma-separated string | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_patches
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get all patches that are severity 5
# and only return their titles & IDs:
patches = get_patches(auth, query="vendorSeverity:5", attributes="id,title")
>>>[
Patch(
id='11111111-2222-3333-4444-555555555555',
title='My Patch',
...
),
Patch(
id='22222222-3333-4444-5555-666666666666',
title='My Other Patch',
...
),
...
]
# Just get windows patches:
windows_patches = get_patches(auth, platform='windows')
>>>[
Patch(
id='11111111-2222-3333-4444-555555555555',
title='My Patch',
platform='Windows',
...
),
Patch(
id='22222222-3333-4444-5555-666666666666',
title='My Other Patch',
...
),
...
]
Get Assets API
get_assets
returns a BaseList
of Asset
objects that match the given kwargs.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
page_count |
Union[int, "all"] = "all" |
The number of pages to return | ❌ |
pageSize |
int=400 |
The number of assets to return per page | ❌ |
platform |
Literal["all", "windows", "linux"] = "all" |
The platform of the assets to return | ❌ |
query |
str |
A patch QQL query to filter with | ❌ |
havingQuery |
str |
A PM host QQL query to filter with | ❌ |
attributes |
str |
The attributes to return in the response as a comma-separated string | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_assets
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get all assets that are missing patches:
assets = get_assets(auth, query="patchStatus:Missing")
>>>[
Asset(
id='11111111-2222-3333-4444-555555555555',
name='My Asset',
...
),
Asset(
id='22222222-3333-4444-5555-666666666666',
name='My Other Asset',
...
),
...
]
Get Patch Count API
get_patch_count
returns the number of patches for a given platform that match the given query and havingQuery.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
platform |
Literal["windows", "linux"] = "windows" |
The platform of the patches to return | ✅ |
query |
str |
A patch QQL query to filter with | ❌ |
havingQuery |
str |
A PM host QQL query to filter with | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_patch_count
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get the number of patches for Windows
# that are critical severity:
count = get_patch_count(auth, platform='windows', query="vendorSeverity:Critical")
>>>100
Lookup Host UUIDs from Asset IDs API
lookup_host_uuids
returns a list of host UUIDs for a given list of asset IDs.
assetIds
can be a list/BaseList of strings/integers, a single int/string, or a comma-separated string.
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
assetIds |
Union[list[str, int], BaseList[str, int], str, int] |
The IDs of the assets to look up | ✅ |
Example 1 with GAV Query
from qualysdk.auth import TokenAuth
from qualysdk.pm import lookup_host_uuids
from qualysdk.gav import query_assets # Could also use get_all_assets!
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get some assets. All we need is assetId.
# We can also filter for assets activated for PM:
assets = query_assets(
auth,
includeFields='assetId',
filter='sensors.activatedForModules:`PM`
)
# Get the host UUIDs for the assets:
uuids = lookup_host_uuids(auth, [asset.assetId for asset in assets])
>>>[
(
123456789,
'11111111-2222-3333-4444-555555555555'
),
(
987654321,
'22222222-3333-4444-5555-666666666666'
),
...
]
Example 2 with List of assetIds
from qualysdk.auth import TokenAuth
from qualysdk.pm import lookup_host_uuids
auth = TokenAuth(<username>, <password>, platform='qg1')
ids = [123456789, 987654321]
uuids = lookup_host_uuids(auth, ids)
>>>[
(
123456789,
'11111111-2222-3333-4444-555555555555'
),
(
987654321,
'22222222-3333-4444-5555-666666666666'
)
]
Example 3 with Comma-Separated String of assetIds
from qualysdk.auth import TokenAuth
from qualysdk.pm import lookup_host_uuids
auth = TokenAuth(<username>, <password>, platform='qg1')
ids = '123456789,987654321'
uuids = lookup_host_uuids(auth, ids)
>>>[
(
123456789,
'11111111-2222-3333-4444-555555555555'
),
(
987654321,
'22222222-3333-4444-5555-666666666666'
)
]
Get Patch Catalog API
get_patch_catalog
returns the patch catalog for a given platform according to patchId
.
patchId
can be a list/BaseList of strings/integers, a single int/string, or a comma-separated string.
Head's Up!: You should only pass in one platform at a time. If you pass in a mix of both Windows and Linux patches, the function will only return the patches that match the
platform
parameter (default is Windows).
Parameter | Possible Values | Description | Required |
---|---|---|---|
auth |
qualysdk.auth.TokenAuth |
Authentication object | ✅ |
patchId |
Union[list[str, int], BaseList[str, int], str, int] |
The IDs of the patches to look up | ✅ |
platform |
Literal["windows", "linux"] = "windows" |
The platform of the patches to return. Defaults to windows | ❌ |
attributes |
str |
The attributes to return in the response as a comma-separated string | ❌ |
from qualysdk.auth import TokenAuth
from qualysdk.pm import get_patch_catalog, get_patches
auth = TokenAuth(<username>, <password>, platform='qg1')
# Get some Linux patches:
patches = get_patches(
auth,
platform='linux',
attributes="id"
)
# Get the catalog entries:
catalog = get_patch_catalog(
auth,
[patch.id for patch in patches],
platform='linux'
)
>>>[
CatalogPatch(
"patchId": "11111111-2222-3333-4444-555555555555",
"title": "My Patch",
"vendor": "My Vendor",
...
),
CatalogPatch(
"patchId": "22222222-3333-4444-5555-666666666666",
"title": "My Other Patch",
...
),
...
]
qualysdk-pm
CLI tool
The qualysdk-pm
CLI tool is a command-line interface for the PM portion of the SDK. It allows you to quickly pull down results from PM APIs and save them to an XLSX/TXT file.
Use --help
on each command to see the available options.
Usage
usage: qualysdk-pm [-h] -u USERNAME -p PASSWORD [-P {qg1,qg2,qg3,qg4}] {list_jobs,get_job_results,get_job_runs,lookup_cves,get_patches,get_patch_count,get_assets,get_patch_catalog} ...
CLI script to quickly perform Patch Management (PM) operations using qualysdk
positional arguments:
{list_jobs,get_job_results,get_job_runs,lookup_cves,get_patches,get_patch_count,get_assets,get_patch_catalog}
Action to perform
list_jobs Get a list of PM jobs.
get_job_results Get results for a PM job.
get_job_runs Get runs for a PM job.
lookup_cves Look up CVEs for a given QID(s).
get_patches Get patches for a given platform.
get_patch_count Get the number of patches available for a platform according to query and havingQuery.
get_assets Get assets for a given platform.
get_patch_catalog Get patch catalog entries for a given platform.
options:
-h, --help show this help message and exit
-u USERNAME, --username USERNAME
Qualys username
-p PASSWORD, --password PASSWORD
Qualys password
-P {qg1,qg2,qg3,qg4}, --platform {qg1,qg2,qg3,qg4}
Qualys platform