-
-
Save AX-AMaxwell/f7475ab32bb7b98f5f17a90c624de6b8 to your computer and use it in GitHub Desktop.
Get Software Report
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
######################################### | |
# PARAMETERS | |
# define your Automox API key | |
$apiKey = '' | |
# define your Automox organization ID | |
$orgID = '' | |
# define the path you'd like | |
# your CSV report generated to | |
# the default value will output | |
# to the same folder as the script, | |
# or the PowerShell session's current | |
# directory | |
$filePath = '.\SoftwareInventory.csv' | |
######################################### | |
# VARS | |
# define the csv column headers | |
$headers = 'Computer', 'Display Name', 'Version', 'Install Date' | |
# define the starting page | |
$page = 0 | |
# define the number of results to return PER-PAGE | |
$limit = 500 | |
######################################### | |
# FUNCTIONS | |
# --! Local Functions !-- | |
function addCSVRow | |
{ | |
[ CmdletBinding() ] | |
param ( | |
[ Parameter() ] | |
[ System.String[] ] | |
$Values, | |
[ Parameter() ] | |
[ System.Management.Automation.SwitchParameter ] | |
$Overwrite | |
) | |
begin | |
{} | |
process | |
{ | |
# define a stringbuilder to construct the row | |
$builder = [ System.Text.StringBuilder ]::new() | |
# enumerate the values provided | |
foreach ( $value in $Values ) | |
{ | |
# define a default value if null | |
if ( $null -eq $value ) { $value = '' } | |
# sanitize the string | |
$value = $value -replace '"', '""' | |
# append to the stringbuilder | |
$builder.Append( "`"$value`"," ) | Out-Null | |
} | |
if ( $Overwrite ) | |
{ | |
# join and overwrite the csv file | |
Set-Content -Path $filePath -Value $builder.ToString() | |
} | |
else | |
{ | |
# join and append to the csv file | |
Add-Content -Path $filePath -Value $builder.ToString() | |
} | |
} | |
end | |
{} | |
} | |
function out | |
{ | |
[ Alias( 'err' ) ] | |
param( | |
[ Parameter( Mandatory, Position = 0, ValueFromPipeline, ValueFromRemainingArguments ) ] | |
[ System.String[] ] | |
$Message | |
) | |
begin | |
{ | |
if ( $MyInvocation.InvocationName -eq 'err' ) | |
{ | |
# capture the current console foreground color | |
$previous = [ System.Console ]::ForegroundColor | |
# set foreground color for error output | |
[ System.Console ]::ForegroundColor = 'Red' | |
# set the stream | |
$stream = [ System.Console ]::Error | |
} | |
else | |
{ | |
# set the stream | |
$stream = [ System.Console ]::Out | |
} | |
} | |
process | |
{ | |
foreach ( $m in $Message ) | |
{ | |
# write our error output | |
$stream.WriteLine( $m ) | |
} | |
} | |
end | |
{ | |
if ( $stream -eq [ System.Console ]::Error ) | |
{ | |
# restore the original foreground color | |
[ System.Console ]::ForegroundColor = $previous | |
} | |
} | |
} | |
######################################### | |
# REPORT GENERATION | |
# evaluate required vars | |
if ( $apiKey -eq [ System.String ]::Empty ) | |
{ | |
err 'The "apiKey" variable is required. Please supply a value for this variable in the "PARAMETERS" section and try again.' | |
exit 2 | |
} | |
elseif ( $orgID -eq [ System.String ]::Empty ) | |
{ | |
err 'The "orgID" variable is required. Please supply a value for this variable in the "PARAMETERS" section and try again.' | |
exit 2 | |
} | |
# create our header row | |
addCSVRow $headers -Overwrite | |
# instantiate a webclient | |
$client = [ System.Net.WebClient ]::new() | |
# construct boilerplate headers | |
$client.Headers.Add( 'User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36' ) | |
$client.Headers.Add( 'Content-Type', 'application/json' ) | |
# inject the bearer token header | |
$client.Headers.Add( 'Authorization', "Bearer $apiKey" ) | |
for ( $i = $page; $i -lt 10000; $i++ ) | |
{ | |
# assemble the URL | |
$url = "https://console.automox.com/api/servers?o=$orgID&page=$i&limit=$Limit" | |
try | |
{ | |
# retrieve the current page of servers, convert from JSON | |
$servers = $client.DownloadString( $url ) | ConvertFrom-Json | |
} | |
catch [ System.Net.WebException ] | |
{ | |
$statusCode = [ System.Int32 ] $_.Exception.Response.StatusCode | |
# attempt to provide some guidance based on status code | |
$advice = switch ( $statusCode ) | |
{ | |
400 | |
{ | |
@" | |
Is the requested URL formatted properly? | |
$url | |
"@ | |
} | |
{ $_ -in 401, 403 } | |
{ | |
# create stringbuilder to censor the api key | |
$censoredKey = [ System.Text.StringBuilder ]::new() | |
# enumerate apiKey characters | |
for ( $i = 0; $i -lt $apiKey.Length; $i++ ) | |
{ | |
# grab the current string character | |
$chr = $apiKey[ $i ] | |
# check if we're less than or equal to 6-characters from the end of the string | |
if ( $i -le $apiKey.Length - 6 ) | |
{ | |
# check if the character is a hyphen | |
if ( $chr -eq '-' ) | |
{ | |
# append the hyphen | |
$censoredKey.Append( '-' ) | Out-Null | |
} | |
else | |
{ | |
# append a masked character | |
$censoredKey.Append( '*' ) | Out-Null | |
} | |
} | |
else | |
{ | |
# append the current literal apiKey character | |
$censoredKey.Append( $apiKey[ $i ] ) | Out-Null | |
} | |
} | |
# assemble the constructed masked key | |
$censoredKey = $censoredKey.ToString() | |
@" | |
Authentication failed, is the API token valid? | |
$censoredKey | |
"@ | |
} | |
404 | |
{ | |
@" | |
The page you requested was not found. Is the endpoint you requested valid? | |
$url | |
"@ | |
} | |
} | |
err @" | |
Error: Failed to retrieve the server list. | |
HTTP Status Code: $statusCode | |
$advice | |
"@ | |
} | |
# break the loop when we run out of results | |
if ( $servers.Count -eq 0 ) { break } | |
# enumerate servers returned | |
foreach ( $server in $servers ) | |
{ | |
try | |
{ | |
# retrieve packages for the current server | |
$packages = $client.DownloadString( "https://console.automox.com/api/servers/$( $server.id )/packages?o=$orgID" ) | ConvertFrom-Json | Where-Object { $_.installed -eq $true } | |
} | |
catch [ System.Net.WebException ] | |
{ | |
$statusCode = [ System.Int32 ] $_.Exception.Response.StatusCode | |
err @" | |
Error: Failed to retrieve server packages. | |
Server ID: $( $server.id ) | |
HTTP Status Code: $statusCode | |
"@ | |
} | |
# enumerate packages | |
foreach ( $package in $packages ) | |
{ | |
# add a CSV row for each package | |
addCSVRow $server.name, $package.display_name, $package.version, ( [ System.DateTime ] $package.create_time ).ToString( 'MM/dd/yy' ) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment