A C# binary PowerShell module providing Linux *-Service cmdlets (Get-Service, Start-Service, Stop-Service, Restart-Service, Set-Service, New-Service, Remove-Service) via D-Bus systemd API. Designed as a drop-in replacement for Windows ServiceController-based cmdlets on Linux.
Part of the PowerShell Linux Commands project.
# Build
dotnet build -c Release
# Run tests (requires pwsh)
pwsh -c "Import-Module ./src/Services.Linux.Native/bin/Release/net8.0/Services.Linux.Native.dll; Invoke-Pester ./tests/"src/Services.Linux.Native/
├── Commands/ # Cmdlet implementations
│ ├── ServiceUnixBase.cs # Base class — resolves unit names, common logic
│ ├── GetServiceCommand.cs
│ ├── StartServiceCommand.cs
│ ├── StopServiceCommand.cs
│ ├── RestartServiceCommand.cs
│ ├── SetServiceCommand.cs
│ ├── NewServiceCommand.cs
│ ├── RemoveServiceCommand.cs
│ ├── SuspendServiceCommand.cs # Stub
│ └── ResumeServiceCommand.cs # Stub
├── Helpers/
│ ├── ErrorMessages.cs # Centralized error message constants
│ └── SystemdHelper.cs # D-Bus calls (ListUnits, Enable/Disable, DaemonReload, etc.)
└── Models/
├── LinuxServiceController.cs # Main output type, inherits Component
├── ServiceControllerStatus.cs # Status enum (matches Windows values)
├── ServiceStartupType.cs # Startup type enum
└── ServiceType.cs # Linux-native service type enum (1000+ range)
- D-Bus is the native API —
Tmds.DBus.Protocolfor directsystemdcommunication. Subprocess (systemctl) is last resort only. LinuxServiceController : Component— matches WindowsServiceControllerinheritance for cross-platform type alignment (Rule 9).- Reactive elevation — D-Bus polkit errors are caught and translated to
"root privileges are required."No proactiveid -ucheck. -WhatIfsafety —ServiceUnixBase.ProcessRecord()resolves unit names without opening D-Bus, so-WhatIfworks for non-root users.
Full rules: docs/linux-rules.md
- Single source of truth:
<Version>in.csproj - Must match:
STATUS.md**Version:**line, README.md version history table (latest entry) - Bump rule:
.csprojfirst, thenSTATUS.md, then README.md — in that order
- Framework: Pester 5
- Runner:
pwsh -c "Invoke-Pester ./tests/" - GHA: 5-distro matrix (Ubuntu 24.04, Debian 12, Fedora 40, openSUSE Tumbleweed, Arch Linux) + Windows
- Container images:
ghcr.io/peppekerstens/pwsh-pester-* - Test file:
tests/Services.Linux.Native.Tests.ps1
Tests load the DLL directly: Import-Module ./src/.../Services.Linux.Native.dll
See STATUS.md for module state, open issues, and next steps.
Open issues: 8 (2 MUST, 6 SHOULD) — see Issues
- Source code (
src/Services.Linux.Native/) - Pester tests (
tests/) - CI/CD (
.github/workflows/) - Module status (
STATUS.md) - Contributor guide (
AGENTS.md) - Development rules (
docs/linux-rules.md) - OpenCode config (
.opencode/)
- Cross-repo planning, status aggregation, project plan → https://github.com/peppekerstens/opencode
- Other modules → https://github.com/peppekerstens/
- PowerShell fork (upstream contribution) → https://github.com/peppekerstens/PowerShell
- Blog posts → https://peppekerstens.github.io
This module is part of a larger project. Cross-repo planning lives at:
- Coordination repo: https://github.com/peppekerstens/opencode
- Project plan: https://github.com/peppekerstens/opencode/blob/main/plan.md
- PowerShell fork: https://github.com/peppekerstens/PowerShell (branch:
feature/service-unix-systemctl)
