Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
# Demo code used in blog post
# Created by Stuart Clarkson (17 January 2017)
# This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
# Uses the Qualys API v2
# Set your Qualys username & password here
$QualysUsername = 'username'
$QualysPassword = 'Pa$$w0rd'
# Set your Qualys Platform domain name here
$QualysPlatform = ''
# This section forms a string with the username & password in the 'Basic Authentication' standard format (RFC 1945)
# See &
$BasicAuthString = [System.text.Encoding]::UTF8.GetBytes("$QualysUsername`:$QualysPassword")
$BasicAuthBase64Encoded = [System.Convert]::ToBase64String($BasicAuthString)
$BasicAuthFormedCredential = "Basic $BasicAuthBase64Encoded"
# Form a key/value hashtable with the HTTP headers we'll be sending in the HTTP request
$HttpHeaders = @{'Authorization' = $BasicAuthFormedCredential;
'X-Requested-With'='PowerShell Script'} # Qualys API documentation required the X-Requested-With header be set to something
# Qualys QID 45038 is the QID where host scan time information is contained
$qualys_scan_qid = 45038
# Limit the number of hosts to return
$TruncationLimit = 500
# Set the URL
# Output format is set to XML so XML data is returned
# show_igs is set to 1 as we want to show the information gathered
$URL = "https://$QualysPlatform/api/2.0/fo/asset/host/vm/detection/?action=list&qids=$qualys_scan_qid&truncation_limit=$TruncationLimit&output_format=XML&show_igs=1"
# Invoke-WebRequest sends the HTTP request and the returned data is stored in $response
# If going through a proxy, '-Proxy, -ProxyUseDefaultCredentials or -ProxyCredential may need to be set too
$HttpResponse = Invoke-WebRequest -Uri $URL -Headers $HttpHeaders
# The content of the HTTP response is in the Content property of the $HTTPResponse. Form this as an XML object
$QualysXMLResponse = [xml]$HttpResponse.Content
# Check that the Qualys reponse contains a HOST_LIST_VM_DETECTION_OUTPUT.RESPONSE.HOST_LIST.HOST element
# $AllHosts will contain the host data for all the hosts returned by the Qualys API
# $HostAssets will be the array of PowerShell objects representing the information for each host
$HostAssets = @()
# Lets loop round each host in AllHosts
foreach($IndividualHost in $AllHosts)
# Quick method to create a custom PowerShell object with specific attributes
$asset = "" | select Name, IP, LastScanDate, LastScanDuration
# Set the attributes to be the values of the XML
$asset.Name = $IndividualHost.dns.InnerText
$asset.IP = $IndividualHost.IP
# XML attribute LAST_SCAN_DATETIME contains the date represented in string form
# We form a PowerShell DateTime object from it here
$asset.LastScanDate = [DateTime]$IndividualHost.LAST_SCAN_DATETIME
# Scan duration field may not exist if the scan isn't a recent one. Wrap a try/catch block around it
# LAST_VM_SCANNED_DURATION is an integer of the number of seconds the scan took.
# Form a PowerShell TimeSpan object for it
$asset.LastScanDuration = New-TimeSpan -Seconds $IndividualHost.LAST_VM_SCANNED_DURATION
Write-Verbose -Message ("No scan duration value for "+$asset.Name)
# Add the asset object to the HostAssets array
# Write verbose details
Write-Verbose -Message ("Formed "+$asset.Name+" information")
Write-Warning -Message "Response from Qualys wasn't what we expected:-"
# $HostAssets is now a fully formed array of PowerShell Objects
Write-Output $HostAssets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.