Install - vFunction .NET Core / Standard Distributed Agent running on a Windows Host as a Windows Service



Installation Steps

Take the following steps to install the vFunction Distributed Agent and configure it to send traces to the vFunction Server:

  1. Gather the vFunction Server UI’s UUID for the vFunction Distributed Application
  1. Log into the vFunction Server UI
  2. In the top-left corner, click the dropdown
  3. Click Add Application from the dropdown menu
  4. Type a name for the Application in the Application Name text field
  5. Toggle the slider to Distributed
  6. Click the blue Create button
  7. In the dialog box that launches, toggle the tabs to .NET
  8. In the text box with OTEL Environment Variables, find the OTEL_EXPORT_OTLP_ENDPOINT and OTEL_EXPORTER_OTLP_HEADER. These will be used at a later stage of the installation
  1. Download the OpenTelemetry .NET AutoInstrumentation ZIP. Note that, as an alternative, PowerShell Modules can be downloaded to accomplish this same goal
  2. Extract the downloaded opentelemetry-dotnet-instrumentation-windows.zip to a location on the Application’s filesystem, such as C:\otel.
  3. Add the OpenTelemetry Agent to the Registry for the Windows Services
############### VF Dist Values ##########################################################################
$HOST_URL              = "https://vfunction.mycompany.com"
$APP_UUID              = "APP-UUID-FROM-VFSERVER-UI"
$APP_NAME              = "My_APP"
$BASE_DIR              = "C:\home\otel"
$RUN_APP               = "C:\path\to\executable.exe"

############### Service Names ###########################################################################
############### These names should match the Registry Names for these Services ##########################
$Service_Targets = @(
    "WindowsService1",
    "WindowsService2",
    "WindowsServer3"
)

############### Set Execution ###########################################################################
# Requires -RunAsAdministrator
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force

############### Validate base directory exists before proceeding ########################################
if (-not (Test-Path $BASE_DIR)) {
    Write-Error "Base directory '$BASE_DIR' not found. Aborting."
    exit 1
}

############### Set Permissions #########################################################################

Write-Host "Setting permissions and unblocking files..." -ForegroundColor Gray
icacls "$BASE_DIR\" /grant Everyone:F /T | Out-Null
Get-ChildItem -Path $BASE_DIR -Recurse | Unblock-File

############### Write Registry Values for Agent #########################################################

foreach ($svc in $Service_Targets) {
    $svcObj = Get-Service -Name $svc -ErrorAction SilentlyContinue

    if ($svcObj) {
        Write-Host "Found service: $svc. Configuring OpenTelemetry Agent..." -ForegroundColor Cyan

        # Set environment variables in registry
        $regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\$svc"
        $envValues = @(
            "CORECLR_PROFILER_PATH=${BASE_DIR}\win-x64\OpenTelemetry.AutoInstrumentation.Native.dll",
            "CORECLR_ENABLE_PROFILING=1",
            "CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}",
            "COR_PROFILER_PATH=${BASE_DIR}\win-x64\OpenTelemetry.AutoInstrumentation.Native.dll",
            "COR_ENABLE_PROFILING=1",
            "COR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}",
            "OTEL_DOTNET_AUTO_INSTALL_DIR=${BASE_DIR}",
            "OTEL_DOTNET_AUTO_HOME=${BASE_DIR}",
            "OTEL_EXPORTER_OTLP_ENDPOINT=${HOST_URL}/api/unauth/otlp",
            "OTEL_EXPORTER_OTLP_HEADERS=X-VF-APP=${APP_UUID}",
            "OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf",
            "DOTNET_ADDITIONAL_DEPS=${BASE_DIR}\AdditionalDeps",
            "DOTNET_SHARED_STORE=${BASE_DIR}\store",
            "DOTNET_STARTUP_HOOKS=${BASE_DIR}\net\OpenTelemetry.AutoInstrumentation.StartupHook.dll",
            "OTEL_TRACES_EXPORTER=otlp",
            "OTEL_METRICS_EXPORTER=none",
            "OTEL_LOGS_EXPORTER=none",
            "OTEL_SERVICE_NAME=${APP_NAME}",
            "OTEL_DOTNET_AUTO_SQLCLIENT_SET_DBSTATEMENT_FOR_TEXT=true"
        )

        try {
            Set-ItemProperty -Path $regPath -Name "Environment" -Value $envValues -Type MultiString -ErrorAction Stop
        } catch {
            Write-Warning "Failed to set registry values for '$svc': $_"
            continue
        }

        # Restart service with error handling
        Write-Host "Restarting service '$svc'..." -ForegroundColor Gray
        try {
            Restart-Service -Name $svc -Force -ErrorAction Stop
            Write-Host "Service '$svc' restarted successfully." -ForegroundColor Green
        } catch {
            Write-Warning "Failed to restart service '$svc': $_"
        }

    } else {
        Write-Host "Skipping: Windows Service '$svc' not found on this server." -ForegroundColor Yellow
    }
}

Write-Host "vFunction configuration complete." -ForegroundColor Green