Skip to content

Register Linux servers in Active Directory as computer objects. Makes Linux boxes visible in AD Users and Computers alongside Windows servers.

License

Notifications You must be signed in to change notification settings

larro1991/AD-LinuxInventory

Repository files navigation

AD-LinuxInventory

PowerShell module that registers Linux, macOS, FreeBSD, and any non-Windows server as real computer objects in Active Directory -- complete with OS name and version in the standard AD properties. Includes a self-registration agent that non-Windows systems can install to announce themselves automatically.

The Problem

Non-Windows servers are invisible in AD. You open ADUC to find a server, it's not there, and 10 minutes later you figure out it's a Linux box that was never joined to the domain. Or you need to check a macOS build machine, but it doesn't exist in AD because macOS doesn't domain-join in any useful way. Or your FreeBSD firewall, your Solaris database, your AIX backend -- none of them show up alongside your Windows servers.

Every mixed-environment admin has been there. AD is the natural place to see all your servers, but anything that isn't Windows just doesn't show up. And even when someone manually creates a computer object, the operatingSystem and operatingSystemVersion fields are blank -- so the object is there but tells you nothing useful.

Two Ways to Register

1. Admin-Driven (PowerShell Side)

You run PowerShell commands from a Windows admin workstation to register servers manually or via CSV import. This is the original v1.0 workflow.

# Register a single server
Register-LinuxServer -Name "web-prod-01" -IPAddress "10.1.2.50" -OperatingSystem "Ubuntu 24.04.1 LTS" -OperatingSystemVersion "24.04.1"

# Bulk import from CSV
Import-LinuxInventory -CsvPath .\linux-servers.csv

2. Self-Registration (Agent Side) -- NEW in v2.0

The non-Windows box installs a lightweight shell agent and announces itself. The agent detects its own OS, collects system info (hostname, IPs, CPU, memory, disk, services, packages), and drops a JSON file on a shared folder. The PowerShell side picks it up and creates the AD object automatically.

One-liner install on any Linux box:

curl -sL https://raw.githubusercontent.com/larro1991/AD-LinuxInventory/master/agent/install.sh | sudo sh -s -- \
  --share '//fileserver/registrations$' \
  --token 'your-shared-secret'

The agent runs hourly as a cron job (or launchd on macOS), keeping the AD record up to date with current IPs, uptime, and a "last seen" timestamp. No listening ports, no inbound connections, no SSH keys required.

What Shows Up in AD

When a macOS machine registers itself, ADUC shows:

Name:                    MACBOOK-DEV-01
Operating System:        macOS 15.2 Sequoia
Operating System Version: 15.2
IPv4 Address:            10.1.4.30
Description:             macOS | 10 cores | 16GB RAM | Last seen: 2026-02-17T10:30:00Z

Same for Linux:

Name:                    WEB-PROD-01
Operating System:        Ubuntu 24.04.1 LTS
Operating System Version: 24.04.1
IPv4 Address:            10.1.2.50
Description:             Linux | 8 cores | 32GB RAM | Last seen: 2026-02-17T10:30:00Z

FreeBSD:

Name:                    FIREWALL-01
Operating System:        FreeBSD 14.1-RELEASE
Operating System Version: 14.1
IPv4 Address:            10.1.7.1
Description:             FreeBSD | 4 cores | 8GB RAM | Last seen: 2026-02-17T10:30:00Z

Supported Operating Systems

OS Family Examples Detection Method
Linux Ubuntu, Debian, RHEL, CentOS, Rocky, Alma, SUSE, Fedora, Arch, Alpine /etc/os-release, /etc/redhat-release
macOS Ventura, Sonoma, Sequoia sw_vers
FreeBSD FreeBSD 13.x, 14.x freebsd-version
Solaris/illumos Solaris 11, OmniOS, SmartOS /etc/release
AIX AIX 7.x oslevel
Other Unix OpenBSD, NetBSD, HP-UX uname -s/-r

Agent Installation

Linux (any distro)

curl -sL https://raw.githubusercontent.com/larro1991/AD-LinuxInventory/master/agent/install.sh | sudo sh -s -- \
  --share '//fileserver/registrations$' \
  --token 'your-shared-secret'

macOS

curl -sL https://raw.githubusercontent.com/larro1991/AD-LinuxInventory/master/agent/install.sh | sudo sh -s -- \
  --share '//fileserver/registrations$' \
  --token 'your-shared-secret'

FreeBSD

fetch -o - https://raw.githubusercontent.com/larro1991/AD-LinuxInventory/master/agent/install.sh | sudo sh -s -- \
  --share '//fileserver/registrations$' \
  --token 'your-shared-secret'

Setting Up the SMB Share (Windows Side)

Before agents can deliver their registrations, create a Windows file share:

  1. Create a folder, e.g., C:\Registrations
  2. Share it as registrations$ (the $ makes it a hidden share)
  3. Grant write access to the service account or allow anonymous writes for the agent
  4. Point agents to the share with --share '//fileserver/registrations$'

Alternatively, use --endpoint to POST to an HTTPS endpoint instead of SMB.

Agent Installer Options

Option Description
--share PATH SMB share path (e.g., //fileserver/registrations$)
--endpoint URL HTTPS endpoint URL for JSON POST delivery
--token SECRET Shared secret for authentication
--ou NAME Target OU name (default: Non-Windows Servers)
--smb-user USER SMB username for authenticated shares
--smb-domain DOM SMB domain for authenticated shares
--uninstall Remove the agent and all configuration

Uninstalling the Agent

sudo sh /path/to/install.sh --uninstall
# or
sudo sh /path/to/uninstall.sh

Installing via Package Manager

Pre-built packages are available for major platforms. Download from the Releases page or use a package manager directly.

Debian / Ubuntu

wget https://github.com/larro1991/AD-LinuxInventory/releases/latest/download/ad-register_2.0.0_all.deb
sudo dpkg -i ad-register_2.0.0_all.deb

RHEL / CentOS / Rocky / Fedora

wget https://github.com/larro1991/AD-LinuxInventory/releases/latest/download/ad-register-2.0.0.noarch.rpm
sudo rpm -i ad-register-2.0.0.noarch.rpm

macOS (Homebrew)

brew tap larro1991/tools
brew install ad-register

After installing via any package manager, copy the example config and run the agent:

sudo cp /etc/ad-register/config.conf.example /etc/ad-register/config.conf
sudo nano /etc/ad-register/config.conf
sudo ad-register

See packaging/README.md for full details on all package formats, building packages locally, and uninstalling.

Processing Registrations (Windows Side)

# Process all pending registrations (auto-approve new entries)
Import-AgentRegistration -RegistrationPath '\\fileserver\registrations$' -Token 'your-shared-secret' -AutoApprove

# Process with manual confirmation for new systems
Import-AgentRegistration -RegistrationPath '\\fileserver\registrations$' -Token 'your-shared-secret'

# Check heartbeat status
Get-RegistrationHeartbeat -RegistrationPath '\\fileserver\registrations$' -StaleHours 2 -OfflineHours 24

# Generate an HTML heartbeat dashboard
Get-RegistrationHeartbeat -RegistrationPath '\\fileserver\registrations$' -OutputPath .\heartbeat-report.html

Functions Reference

Function Purpose
Register-LinuxServer Manually create an AD computer object for any non-Windows server
Import-LinuxInventory Bulk import from CSV
Get-LinuxInventory List all registered servers with optional ping status
Update-LinuxServer Update properties on existing entries
Sync-LinuxInventory Ping all servers, stamp last-seen timestamps
Import-AgentRegistration NEW -- Process self-registration JSON files from the agent
Get-RegistrationHeartbeat NEW -- Monitor which systems are actively checking in

Quick Start (Admin-Driven)

Import-Module .\AD-LinuxInventory.psd1

# Register a single server
Register-LinuxServer -Name "web-prod-01" -IPAddress "10.1.2.50" -OperatingSystem "Ubuntu 22.04 LTS" -Description "Production web server"

# Bulk import from CSV
Import-LinuxInventory -CsvPath .\linux-servers.csv

# See everything with online status
Get-LinuxInventory -Online | Format-Table

# Sync and stamp descriptions
Sync-LinuxInventory -UpdateDescription

Example Output

Register a server:

Name            : WEB-PROD-01
DNSHostName     : web-prod-01.contoso.com
IPv4Address     : 10.1.2.50
OperatingSystem : Ubuntu 22.04 LTS
Description     : Production web server
ManagedBy       :
Status          : Registered

Get inventory with ping status:

Name            IPv4Address   OperatingSystem          Description                 Online  ResponseTime
----            -----------   ---------------          -----------                 ------  ------------
WEB-PROD-01    10.1.2.50     Ubuntu 24.04.1 LTS       Production web server        True             2
MACBOOK-DEV-01 10.1.4.30     macOS 15.2 Sequoia       macOS dev workstation        True             3
DB-PROD-01     10.1.3.10     RHEL 9.3                 Production PostgreSQL        True             1
FIREWALL-01    10.1.7.1      FreeBSD 14.1-RELEASE     Border firewall              True             1
MONITOR-01     10.1.5.20     Debian 12                Grafana + Prometheus         True             4
LEGACY-APP-01  10.1.4.100    CentOS 7                 Legacy CRM application      False

Heartbeat status:

ComputerName     OperatingSystem          Status    HoursSinceHeartbeat
------------     ---------------          ------    -------------------
WEB-PROD-01     Ubuntu 24.04.1 LTS       Active                    0.3
MACBOOK-DEV-01  macOS 15.2 Sequoia       Active                    0.5
DB-PROD-01      RHEL 9.3                 Stale                     4.2
FIREWALL-01     FreeBSD 14.1-RELEASE     Offline                  48.1
LEGACY-APP-01   CentOS 7                 Never

Agent registration import summary:

RegistrationPath : \\fileserver\registrations$
Processed        : 5
NewRegistrations : 2
Updated          : 2
Rejected         : 1
Errors           : 0

HTML Dashboard:

See Samples/sample-report.html for the full dark-themed dashboard with online/offline indicators.

CSV Template

Name,IPAddress,OperatingSystem,OperatingSystemVersion,Description,ManagedBy
web-prod-01,10.1.2.50,Ubuntu 24.04.1 LTS,24.04.1,Production web server,jsmith
web-prod-02,10.1.2.51,Ubuntu 24.04.1 LTS,24.04.1,Production web server,jsmith
db-prod-01,10.1.3.10,RHEL 9.3,9.3,Production PostgreSQL primary,mgarcia
macbook-dev-01,10.1.4.30,macOS 15.2 Sequoia,15.2,Developer workstation,achen
firewall-01,10.1.7.1,FreeBSD 14.1-RELEASE,14.1,Border firewall,bwilson
monitor-01,10.1.5.20,Debian 12,12,Grafana + Prometheus monitoring,achen

Installation

From PSGallery (when published):

Install-Module AD-LinuxInventory

Manual / git clone:

git clone https://github.com/larro1991/AD-LinuxInventory.git
Copy-Item -Path .\AD-LinuxInventory -Destination "$env:USERPROFILE\Documents\PowerShell\Modules\" -Recurse

Requirements

  • PowerShell 5.1+
  • ActiveDirectory module (RSAT)
  • Permission to create computer objects in the target OU
  • ICMP access to servers (for -Online and Sync-LinuxInventory)
  • For agent self-registration: a Windows file share or HTTPS endpoint

Design Decisions

  • Real computer objects, not contacts -- The servers show up as actual computer icons in ADUC. Group Policy won't target them (they're not domain-joined), but they're visible in every tool that queries AD for computers. This is the right object class for inventory purposes.
  • Dedicated OU keeps things organized -- Default is "OU=Linux Servers" for admin-driven registration (backward compatible with v1.0) and "OU=Non-Windows Servers" for agent-based self-registration. Separates entries from domain-joined Windows machines so you can filter or delegate permissions cleanly. The OU is auto-created on first use.
  • Ping-based health check is simple and firewall-friendly -- ICMP is the lowest-common-denominator connectivity test. No agents, no SSH keys, no WinRM. The Sync-LinuxInventory function stamps the description with timestamps so you can see health at a glance in ADUC.
  • Agent uses /bin/sh for maximum portability -- The agent scripts avoid bash-specific features and run under any POSIX shell. Works on Alpine (ash), FreeBSD (sh), Solaris, AIX, and macOS without requiring bash to be installed.
  • File-based delivery (SMB) is the simplest path -- The agent drops a JSON file on a Windows share. No API server to run, no database, no certificates to manage. For environments that prefer HTTPS, the agent also supports POSTing to an endpoint.
  • Token-based authentication -- A shared secret prevents unauthorized registrations. New registrations can also require manual approval by omitting -AutoApprove.
  • CSV import for day-one bulk load -- Most teams already have a spreadsheet of their servers somewhere. Export it as CSV, run one command, and they're all in AD.
  • ShouldProcess on write operations -- Register-LinuxServer, Update-LinuxServer, and Import-AgentRegistration support -WhatIf and -Confirm so you can preview changes before committing to AD.

Project Structure

AD-LinuxInventory/
├── AD-LinuxInventory.psd1              # Module manifest (v2.0.0)
├── AD-LinuxInventory.psm1              # Root module (dot-source loader)
├── Public/
│   ├── Register-LinuxServer.ps1        # Register a single server in AD
│   ├── Import-LinuxInventory.ps1       # Bulk import from CSV
│   ├── Get-LinuxInventory.ps1          # List registered servers with optional ping
│   ├── Update-LinuxServer.ps1          # Update server properties
│   ├── Sync-LinuxInventory.ps1         # Ping all servers, stamp descriptions
│   ├── Import-AgentRegistration.ps1    # Process agent JSON registrations (NEW)
│   └── Get-RegistrationHeartbeat.ps1   # Monitor agent heartbeat status (NEW)
├── Private/
│   ├── Initialize-LinuxOU.ps1          # Auto-create the target OU
│   └── New-HtmlDashboard.ps1           # Dark-themed HTML report generator
├── agent/                              # Self-registration agent (NEW)
│   ├── install.sh                      # Universal installer for all Unix-like OS
│   ├── register-agent.sh              # Agent script (collects info, delivers JSON)
│   ├── uninstall.sh                    # Clean removal script
│   └── README.md                       # Agent documentation
├── packaging/                          # Native OS package building (NEW)
│   ├── build-packages.sh              # Build .deb and .rpm via fpm
│   ├── post-install.sh                # Post-install script (config template, cron)
│   ├── pre-remove.sh                  # Pre-remove script (cleanup cron)
│   ├── homebrew/
│   │   └── ad-register.rb             # Homebrew formula for macOS
│   └── README.md                       # Packaging documentation
├── .github/
│   └── workflows/
│       └── build-packages.yml          # CI: auto-build packages on release
├── Tests/
│   └── AD-LinuxInventory.Tests.ps1     # Pester tests
├── Samples/
│   └── sample-report.html              # Example dashboard output
├── README.md
└── LICENSE

Security

  • The shared token prevents unauthorized registrations
  • New registrations can require manual approval (omit -AutoApprove)
  • Processed JSON files are archived to a "processed" subfolder, not deleted
  • The agent runs as a cron job -- no listening ports, no inbound connections needed
  • The agent config file is readable only by root (permissions 600)
  • The agent script is read-only on the managed system

Running Tests

Invoke-Pester .\Tests\ -Output Detailed

Feedback & Contributions

License

MIT

About

Register Linux servers in Active Directory as computer objects. Makes Linux boxes visible in AD Users and Computers alongside Windows servers.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •