DISCLAIMER: This is not an efficient script by any means, but it gets the job done. We created a separate InsightVM user just for API access. You can set this script up to run daily and tag new Windows machines without an owner. We have AD Audit+ in our environment, so everything is ported to the “Description” field within each AD computer. The first part of the description is “username”, so we only pull that info for each computer. If the computer does not have an AD user associated with it, it will be tagged as “No AD User”. In a future iteration of this script, we hope to have this integrated with SCCM so we can get (maybe) more accurate username tagging. Our company plays musical assets, so at times it is difficult to know who is the true owner of specific assets.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor
[Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
#################################################
#Pass Creds through API
#################################################
$Rapid7_User = 'USERNAME'
$Rapid7_Password = 'PASSWORD OR READ-HOST'
$Rapid7_Server = 'INSIGHT ON-PREM SERVER'
$Rapid7_BaseUrl = "https://$($Rapid7_Server):PORTIFNECESSARY/api/3"
$Rapid7_Headers = @{Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Rapid7_User):$($Rapid7_Password)")))"}
#################################################
#Function to Remove ALL Owner Tags (commented out)
#################################################
<# Removing All Owner Tags
function DeleteOwnerTags {
$QueryTags = (Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags?size=4000" -Headers $Rapid7_Headers).resources
foreach ($tag in $QueryTags)
{
if ($tag.type -contains "owner")
{
Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags/$($tag.id)" -Headers $Rapid7_Headers -Method Delete -Verbose -ErrorAction Stop
}
}#end of foreach
}#end of function DeleteTags
DeleteOwnerTags
#>
#################################################
#Asset Search Filter for API
#################################################
$Rapid7_AssetSearch = [pscustomobject]@{
match = 'all'
filters = @(
[pscustomobject]@{
field = 'operating-system'
operator = 'contains'
value = 'windows'
},
[pscustomobject]@{
field = 'owner-tag'
operator = 'is-not-applied'
}
)
}
######################################################################
#Grab Hostname from R7 Database using API Query Based on Above Search
######################################################################
$GetPages = (Invoke-RestMethod -Uri "$Rapid7_BaseUrl/assets/search?page=1" -Body $($Rapid7_AssetSearch | ConvertTo-Json) -Method Post -ContentType 'Application/JSON' -Headers $Rapid7_Headers)
$TotalAssetPages = $GetPages.page | Select totalPages -ExpandProperty totalPages
#$AssetPage=$null
#####################################################################
# Loop through all of the objects within every page in the API
#####################################################################
for ($AssetPage=0; $AssetPage -le $TotalAssetPages; $AssetPage++)
{ #START OF FOR LOOP
$Rapid7_AssetResults = (Invoke-RestMethod -Uri "$Rapid7_BaseUrl/assets/search?page=$AssetPage" -Body $($Rapid7_AssetSearch | ConvertTo-Json) -Method Post -ContentType 'Application/JSON' -Headers $Rapid7_Headers).resources
Write-Host "Now Processing page $AssetPage of $TotalAssetPages... Continuing on"
$Rapid7_AssetResults | ForEach-Object {
try
{
if ($($_.hostname) -match "FQDN")
{
$Rapid7_Hostname = ($($_.hostname))
$Rapid7_Hostname = $Rapid7_Hostname.Replace(".FQDN","")
$Rapid7_AssetID = ($($_.id))
$User_Name = $((Get-ADComputer -Identity $Rapid7_Hostname -Properties * | Select Description -ExpandProperty Description).Split('|')[0]) -replace '`' -replace ""
$User_Name = $User_Name -replace "'" -replace ""
$User_Name = $User_Name.ToLower()
Write-Host "FQDN $Rapid7_Hostname Found and Trimmed!"
$User_Name
}
if ($($_.hostname) -notmatch "FQDN")
{
$Rapid7_Hostname = ($($_.hostname))
$Rapid7_AssetID = ($($_.id))
$User_Name = $((Get-ADComputer -Identity $Rapid7_Hostname -Properties * | Select Description -ExpandProperty Description).Split('|')[0]) -replace '`' -replace ""
$User_Name = $User_Name -replace "'" -replace ""
$User_Name = $User_Name.ToLower()
Write-Host "FQDN $Rapid7_Hostname Not Found"
$User_Name
}
}
catch
{
Write-Host "Unable to query AD using this hostname $Rapid7_Hostname"
$User_Name = "No AD User"
}
finally
{
$QueryTags = (Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags?page=1" -Headers $Rapid7_Headers)
$TotalTagPages = $QueryTags.page | Select totalPages -ExpandProperty totalPages
###################################################
#API format to query/get/append tag info
###################################################
$Rapid7_Body = [pscustomobject]@{
name = ($($User_Name))
type = 'owner'
}
try {#Create Tag
$Rapid7_Tag = Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags" -Body ($Rapid7_Body | ConvertTo-Json) -Headers $Rapid7_Headers -Method Post -ContentType 'application/json' -ErrorAction Stop
Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags/$($Rapid7_Tag.id)/assets/$($Rapid7_AssetID)" -Headers $Rapid7_Headers -Method Put -Verbose -ErrorAction Stop
}#End of Finally 1 - Try
catch {#Query Tag (If already created)
##########################################################
#For Loop used to iterate through all Tag Pages
##########################################################
for ($TagPage=0; $TagPage -le $TotalTagPages; $TagPage++)
{
$QueryTags = (Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags?page=$TagPage" -Headers $Rapid7_Headers).resources
Write-Host "Now searching through tag page $TagPage of $TotalTagPages for $User_Name"
foreach ($tag in $QueryTags) {
if ($User_Name -match ($($tag.name)))
{
Write-Host "Match!" -ForegroundColor Magenta
try {
Invoke-RestMethod -Uri "$Rapid7_BaseUrl/tags/$($tag.id)/assets/$($Rapid7_AssetID)" -Headers $Rapid7_Headers -Method Put -Verbose -ErrorAction Stop
Write-Host "Appending known user tag to asset $Rapid7_AssetID" -ForegroundColor Green
}#End of Try (Nested within Foreach-If)
catch {
Write-Host "The tag $($tag.name) with ID $($tag.id) has already been created, and the asset $($Rapid7_Hostname) has already been tagged with this particular tag. Continuing on..."
}#End of Catch (Nested within Foreach-If)
}#End of If (Nested within Foreach)
}#End of Nested Foreach #2 - Inner Block
}#End of For #2 Inner Block - Tag page search iteration
}#End of Finally1 - Catch
}#finally 1 outer block
}#Foreach-Object Loop #1 outer block
}#End of For Loop #1 Outer Block - Asset page search iteration