Solutions
Device management
Remotely manage, and protect laptops and mobile devices.
Orchestration
Automate tasks across devices, from app installs to scripts.
Software management
Inventory, patch, and manage installed software.
Extend Fleet
Integrate your favorite tools with Fleet.
Customers
Stripe + Fleet
Stripe consolidates multiple tools with Fleet.
Foursquare + Fleet
Foursquare quickly migrates to Fleet for device management.
What people are saying
Stories from the Fleet community.
More
Fleet’s built-in queries for collecting and storing important device information.
Software
Gathers information about software installed on a device running Windows.
WITH cached_users AS (WITH cached_groups AS (select * from groups)
SELECT uid, username, type, groupname, shell
FROM users LEFT JOIN cached_groups USING (gid)
WHERE type <> 'special' AND shell NOT LIKE '%/false' AND shell NOT LIKE '%/nologin' AND shell NOT LIKE '%/shutdown' AND shell NOT LIKE '%/halt' AND username NOT LIKE '%$' AND username NOT LIKE '\_%' ESCAPE '\' AND NOT (username = 'sync' AND shell ='/bin/sync' AND directory <> ''))
SELECT
name AS name,
version AS version,
'' AS extension_id,
'' AS browser,
'programs' AS source,
publisher AS vendor,
install_location AS installed_path
FROM programs
UNION
SELECT
name AS name,
version AS version,
'' AS extension_id,
'' AS browser,
'ie_extensions' AS source,
'' AS vendor,
path AS installed_path
FROM ie_extensions
UNION
SELECT
name AS name,
version AS version,
identifier AS extension_id,
browser_type AS browser,
'chrome_extensions' AS source,
'' AS vendor,
path AS installed_path
FROM cached_users CROSS JOIN chrome_extensions USING (uid)
UNION
SELECT
name AS name,
version AS version,
identifier AS extension_id,
'firefox' AS browser,
'firefox_addons' AS source,
'' AS vendor,
path AS installed_path
FROM cached_users CROSS JOIN firefox_addons USING (uid)
UNION
SELECT
name AS name,
version AS version,
'' AS extension_id,
'' AS browser,
'chocolatey_packages' AS source,
'' AS vendor,
path AS installed_path
FROM chocolatey_packages
# Get installed Windows programs from registry
$programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName } | ForEach-Object {
[PSCustomObject]@{
name = $_.DisplayName
version = $_.DisplayVersion
type = "Program (Windows)"
source = "programs"
}
}
# Get installed Python packages (if pip is available)
$python_pkgs = @()
try {
$pipOutput = & pip list --format=freeze 2>$null
if ($pipOutput) {
foreach ($line in $pipOutput) {
if ($line -match "^(.*?)==(.*)$") {
$python_pkgs += [PSCustomObject]@{
name = $matches[1]
version = $matches[2]
type = "Package (Python)"
source = "python_packages"
}
}
}
}
} catch {
# pip not found or error occurred
}
# Get Internet Explorer extensions from registry
$ie_extensions = @()
$ieRegKey = "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Extensions"
if (Test-Path $ieRegKey) {
$ieData = Get-ItemProperty -Path $ieRegKey -ErrorAction SilentlyContinue
if ($ieData) {
foreach ($prop in $ieData.PSObject.Properties) {
# Using property name as the identifier; version info is not normally stored
$ie_extensions += [PSCustomObject]@{
name = $prop.Name
version = ""
type = "Browser plugin (IE)"
source = "ie_extensions"
}
}
}
}
# Get Chrome extensions by reading installed extension manifests
$chrome_extensions = @()
$chromeExtPath = Join-Path $env:LOCALAPPDATA "Google\Chrome\User Data\Default\Extensions"
if (Test-Path $chromeExtPath) {
$extDirs = Get-ChildItem -Path $chromeExtPath -Directory -ErrorAction SilentlyContinue
foreach ($ext in $extDirs) {
$versionDirs = Get-ChildItem -Path $ext.FullName -Directory -ErrorAction SilentlyContinue
foreach ($verDir in $versionDirs) {
$manifestPath = Join-Path $verDir.FullName "manifest.json"
if (Test-Path $manifestPath) {
try {
$manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json
$extName = $manifest.name
$extVersion = $manifest.version
} catch {
$extName = $ext.Name
$extVersion = $verDir.Name
}
} else {
$extName = $ext.Name
$extVersion = $verDir.Name
}
$chrome_extensions += [PSCustomObject]@{
name = $extName
version = $extVersion
type = "Browser plugin (Chrome)"
source = "chrome_extensions"
}
}
}
}
# Get Firefox add-ons by locating extensions.json in profile directories and parsing it
$firefox_addons = @()
$firefoxProfilesPath = Join-Path $env:APPDATA "Mozilla\Firefox\Profiles"
if (Test-Path $firefoxProfilesPath) {
$profiles = Get-ChildItem -Path $firefoxProfilesPath -Directory -ErrorAction SilentlyContinue
foreach ($profile in $profiles) {
$extensionsJson = Join-Path $profile.FullName "extensions.json"
if (Test-Path $extensionsJson) {
try {
$json = Get-Content $extensionsJson -Raw | ConvertFrom-Json
if ($json.addons) {
foreach ($addon in $json.addons) {
if ($addon.type -eq "extension") {
$firefox_addons += [PSCustomObject]@{
name = $addon.name
version = $addon.version
type = "Browser plugin (Firefox)"
source = "firefox_addons"
}
}
}
}
} catch {
# Skip profiles with parsing issues
}
}
}
}
# Get installed Chocolatey packages (if choco is available)
$chocolatey_packages = @()
try {
$chocoOutput = & choco list --local-only --limit-output 2>$null
if ($chocoOutput) {
foreach ($line in $chocoOutput) {
if ($line -match "^(.*?)\|(.*)$") {
$chocolatey_packages += [PSCustomObject]@{
name = $matches[1]
version = $matches[2]
type = "Package (Chocolatey)"
source = "chocolatey_packages"
}
}
}
}
} catch {
# choco not found or error occurred
}
# Combine all results
$result = $programs + $python_pkgs + $ie_extensions + $chrome_extensions + $firefox_addons + $chocolatey_packages
# Output the result to stdout in table format
$result | Format-Table -AutoSize
PowerShell commands are currently work in progress, contributions welcome.
Bash commands are currently work in progress, contributions welcome.
Vitals