-
-
Notifications
You must be signed in to change notification settings - Fork 81
Environment Variables
- Introduction
- Environment Variable Expansion
- GUI
- CLI Option:
--envVars - CLI Example
- PowerShell Option:
-EnvVars - PowerShell Example
- Tips
Servy allows you to define environment variables for the service process, enabling fine-grained control over the runtime context.
Environment variable expansion is supported in multiple areas of Servy configuration:
- Service binary paths (
--path/-Path) -
Startup directories (
--startupDir/-StartupDir) -
Process parameters (
--params/-Params) -
Environment variables (
--envVars/-EnvVars)
This makes it possible to reference existing system variables, user-defined variables, or paths dynamically in your configuration.
Servy uses a sophisticated expansion engine that allows variables to reference each other. The resolution follows this specific order:
- System Environment: All current system and process environment variables are loaded first.
-
Custom Overrides: Variables defined in the Environment Variables field (or
--envVars) are added next. If a custom variable has the same name as a system variable, the custom value wins. -
Cross-Reference Expansion: Finally, all variables are scanned for
%VAR%placeholders. These placeholders are resolved using the final merged set of variables.
For security reasons Servy refuses to let --envVars / -EnvVars override a hard-coded list of variables that would otherwise enable privilege escalation or runtime injection (DLL/JIT profiler hijacking, debugger probes, search-path attacks, etc.). Any attempt to override one of these is silently ignored each time the service starts (during environment-variable expansion) and a warning is recorded in %ProgramData%\Servy\logs\Servy.Service.log:
Security: Blocked an attempt to override protected variable 'PATH'. Custom values for this variable are ignored to prevent privilege escalation.
The current list includes:
| Category | Environment Variables | Security / Integrity Purpose |
|---|---|---|
| System Integrity |
PATH, COMSPEC, SYSTEMROOT, WINDIR, SYSTEMDRIVE, TEMP, TMP, PATHEXT, PROGRAMFILES, PROGRAMFILES(X86), PROGRAMW6432, COMMONPROGRAMFILES, COMMONPROGRAMFILES(X86), COMMONPROGRAMW6432
|
Protects core operating system paths, shell execution binaries, executable extension resolution rules, and system-wide temporary layout storage areas from redirection or manipulation. |
| Profile & Identity Redirection |
APPDATA, LOCALAPPDATA, PUBLIC, HOMEDRIVE, HOMEPATH, HOME, USERDOMAIN, USERDOMAIN_ROAMINGPROFILE, LOGONSERVER
|
Prevents the malicious redirection of active user profile locations, local cache repositories, home path scopes, or domain network logons which could allow credential harvesting or state poisoning. |
| User & Profile Integrity |
USERNAME, USERPROFILE, ALLUSERSPROFILE, PROGRAMDATA, PSMODULEPATH
|
Safeguards system configuration and initialization boundaries, tracking contexts, and default PowerShell utility module path discovery scopes from arbitrary interference. |
| .NET Runtime Injection & Diagnostics |
COR_ENABLE_PROFILING, COR_PROFILER, COR_PROFILER_PATH, CORECLR_ENABLE_PROFILING, CORECLR_PROFILER, CORECLR_PROFILER_PATH, DOTNET_STARTUP_HOOKS, DOTNET_ROOT, DOTNET_ROOT(x86), DOTNET_HOST_PATH, DOTNET_BUNDLE_EXTRACT_BASE_DIR, DOTNET_ADDITIONAL_DEPS, DOTNET_SHARED_STORE, DOTNET_DiagnosticPorts, COMPlus_DiagnosticPorts, DOTNET_EnableDiagnostics, COMPlus_EnableDiagnostics, DOTNET_EnableDiagnostics_IPC, COMPlus_EnableDiagnostics_IPC, DOTNET_EnableDiagnostics_Profiler, COMPlus_EnableDiagnostics_Profiler, DOTNET_EnableEventPipe, COMPlus_EnableEventPipe, DOTNET_GCName, COMPlus_GCName, DOTNET_GCPath, COMPlus_GCPath, DOTNET_LegacyHostPolicy, COMPlus_LegacyHostPolicy, DOTNET_LegacyTransform, COMPlus_LegacyTransform, DOTNET_PerfMapEnabled, COMPlus_PerfMapEnabled, DOTNET_ZapDisable, COMPlus_ZapDisable, DOTNET_DbgEnableMiniDump, COMPlus_DbgEnableMiniDump, DOTNET_DbgMiniDumpName, COMPlus_DbgMiniDumpName, DOTNET_DbgMiniDumpType, COMPlus_DbgMiniDumpType
|
Shuts down execution hijacking and process attachment pathways targeting legacy, modern, and cross-compiled .NET/CoreCLR runtimes. This blocks unauthorized remote diagnostic socket endpoint exposure (DiagnosticPorts), runtime profiler/assembly DLL injection setups, custom Garbage Collector (GCPath) hijacking vectors, and the redirection of sensitive process memory dumps (DbgMiniDumpName) to insecure disk areas. |
| Java Injection |
JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JAVA_OPTS, JAVA_OPTIONS, CATALINA_OPTS, CATALINA_JAVA_OPTS, MAVEN_OPTS, M2_OPTS, GRADLE_OPTS, ANT_OPTS, JBOSS_JAVA_OPTS, WILDFLY_OPTS, CLASSPATH, JAVA_HOME, JRE_HOME, JDK_HOME
|
Blocks execution exploits (such as malicious -javaagent arguments) loaded through native JVM diagnostics or shell-wrapper scripts commonly deployed in enterprise application frameworks like Tomcat, JBoss, Maven, and Gradle. |
| Node.js & NPM Injection |
NODE_OPTIONS, NODE_PATH, NODE_EXTRA_CA_CERTS, NPM_CONFIG_PREFIX, NPM_CONFIG_USERCONFIG, NPM_CONFIG_GLOBALCONFIG
|
Defends Node.js runtime instances against preload option injections, local dependency resolution adjustments, rogue Certificate Authority additions (preventing Man-In-The-Middle traffic decryption), and npm registry config tampering. |
| Python Injection |
PYTHONSTARTUP, PYTHONPATH, PYTHONHOME, PYTHONIOENCODING, PYTHONFAULTHANDLER, PYTHONUSERBASE, PYTHONEXECUTABLE
|
Prevents arbitrary script parsing or site-package source location hijacking through specialized system initialization hooks, site library layout directories, or custom interpreter path redirections. |
| Ruby & Perl Injection |
RUBYOPT, RUBYLIB, PERL5OPT, PERL5LIB
|
Disallows option mapping switches and internal code inclusion path manipulations within local Ruby and Perl execution setups. |
| PHP Injection |
PHPRC, PHP_INI_SCAN_DIR
|
Blocks attackers from supplying custom configuration directives or dynamically scanning arbitrary directories for malicious extension modules via modified initialization file search paths. |
| Global/Unix Fallback |
LD_PRELOAD, LD_LIBRARY_PATH
|
Controls dynamic tracking or link-editor behaviors within Unix compatibility frameworks, MinGW subsystems, WSL boundaries, or Cygwin sandboxes to stop arbitrary binary instrumentation. |
| Windows AppCompat |
__COMPAT_LAYER, SHIM_FILE_LOG, SHIM_DEBUG_LEVEL, _NT_SYMBOL_PATH, _NT_ALT_SYMBOL_PATH, _NT_SOURCE_PATH, MICROSOFT_TELEMETRY_ENV_OVERRIDE
|
Hardens execution trees against debugging diagnostics vectors, system symbol repository redirections, and application compatibility shim injection layer techniques. |
| PowerShell Hardening Bypass |
__PSLockDownPolicy, PSExecutionPolicyPreference
|
Mitigates unauthorized administrative policy changes at process initialization by blocking programmatic overrides targeting Windows execution restrictions or the system LanguageMode. |
If you need to extend PATH for the service process, modify the system PATH or use a custom variable name and reference it inside your application configuration.
If your system has TEMP=C:\Windows\Temp and you define:
MY_ROOT=C:\ServyAppMY_LOGS=%MY_ROOT%\logsAPP_TEMP=%TEMP%
The final environment seen by your process will be:
-
MY_ROOT:C:\ServyApp -
MY_LOGS:C:\ServyApp\logs -
APP_TEMP:C:\Windows\Temp
Note
Variable Ordering and Circular References:
Variables are resolved using a multi-pass fixed-point algorithm, so the order in which you define them does not matter - MY_LOGS=%MY_ROOT%\logs resolves correctly even if MY_ROOT is defined later in the list. The expansion engine runs up to 5 passes; chains deeper than that will leave unresolved %VAR% placeholders and Servy logs a warning ("Environment variable expansion reached maximum pass limit").
Avoid circular references:
-
Self-reference (
A=%A%): caught as soon as the expansion engine encounters a value that contains its own%NAME%token. Logged asDirect cycle detected for variable 'A'; leaving literal placeholder.and the placeholder is left literal (unless the OS already exports a value forA, in which case the inherited value is substituted to mimic WindowsPATH-append semantics). -
Multi-variable cycles (
A=%B%,B=%A%, or longer chains likeA=%B%,B=%C%,C=%A%): not detected by a dedicated check. The fixed-point loop is allowed up to 5 passes (AppConfig.MaxEnvVarExpansionPasses); if values are still changing when the limit is hit, the loop exits and Servy logsEnvironment variable expansion reached maximum pass limit. Indirect circular reference detected (e.g., A=%B%, B=%A%).Two-variable cycles typically degenerate into a self-reference inside the loop and so also surface asDirect cycle detectedon a later pass.
The advanced tab in Servy allows setting environment variables for the service process:
The --envVars command-line option lets you specify environment variables for the service process.
-
Syntax:
--envVars="VAR1=value1; VAR2=value2" - Separate multiple variables with semicolons (;) - Special characters can be escaped:
-
\=to escape= -
\"to escape" -
\;to escape; -
\\to escape\ -
%%to escape%(collapses to a single%, matchingcmd.exebehaviors) (starting from v8.5+)
-
- Supports environment variable expansion. Example:
--envVars="VAR1=%ProgramData%\MyApp; VAR2=%VAR1%\bin; CHANCE=100%%" - Useful for setting runtime context without changing system-wide environment variables.
servy-cli install `
--name="MyNodeService" `
--description="My NodeJS Server" `
--path="%ProgramFiles%\nodejs\node.exe" `
--startupDir="C:\Apps\App" `
--params="C:\Apps\App\index.js" `
--startupType="Automatic" `
--envVars="NODE_ENV=production; APP_CONFIG=C:\Apps\App\config.json"The -EnvVars parameter lets you define environment variables when installing a service via PowerShell.
-
Type:
string(semicolon-separated list, optional) - Apply the same escaping rules as the CLI.
- Multiple variables are separated with semicolons (;)
- Variables are applied only to the service process, not system-wide.
Import-Module "C:\Program Files\Servy\Servy.psm1" -Force
$installParams = @{
Name = "MyNodeService"
Description = "My NodeJS Server"
Path = "C:\Program Files\nodejs\node.exe"
StartupDir = "C:\Apps\App"
Params = "C:\Apps\App\index.js"
StartupType = "Automatic"
EnvVars = "NODE_ENV=production; APP_CONFIG=C:\Apps\App\config.json"
}
Install-ServyService @installParams-
Case Insensitivity: Environment variable names are case-insensitive. Defining
node_envwill correctly override an existingNODE_ENV. -
Expansion Order: You can reference both existing system variables (like
%ProgramData%) and other custom variables defined in the same list. -
Safe Percent Escaping: To pass a literal percent character into your environment safely and prevent it from being processed as an expansion block, use a double percent sign (
%%). For example, definingALERT_MSG=Battery at 100%%will expand correctly toBattery at 100%inside the service process. - Verification: To troubleshoot, if you aren't sure if your variables are applying correctly, run this to dump the environment to a file (PowerShell Admin):
servy-cli install --name="EnvTest" --path="C:\Windows\System32\cmd.exe" --params="/c set > C:\servy_env.txt && timeout /t 3600 /nobreak > nul" --envVars="MY_ROOT=C:\ServyApp; MY_LOGS=%MY_ROOT%\logs"
servy-cli restart --name="EnvTest"
Get-Content C:\servy_env.txt | Select-String "MY_LOGS"Copyright © Akram El Assas. All rights reserved.
- Home
- Overview
- Installation Guide
- Advanced Configuration
- Usage
- Servy Desktop App
- Servy Manager
- Servy CLI
- PowerShell Module
- Examples & Recipes
- Logging & Log Rotation
- Health Monitoring & Recovery
- Environment Variables
- Service Dependencies
- Pre-Launch & Post-Launch Actions
- Pre-Stop & Post-Stop Actions
- Shutdown & Teardown
- Export/Import Services
- Automation & CI/CD
- Integration with Monitoring Tools
- Service Event Notifications
- Comparison with Alternatives
- Security
- Architecture
- Building from Source
- Troubleshooting
- FAQ