### Linux/macOS Bootstrap Installer Script Source: https://context7.com/fogproject/fog-client/llms.txt Installs the Mono runtime and downloads/runs the FOG Universal Installer. Requires root privileges and the FOG server URL to be pre-configured. Supports multiple Linux distributions and macOS. ```bash # Usage: run as root on the managed machine # The URL variable must be set to the FOG server address before distribution. url="fog.example.com" # set before deployment # Supported distributions: # Fedora / RHEL / CentOS -> yum # Ubuntu / Debian -> apt-get # Arch / Antergos -> pacman # macOS -> opens Mono download page in browser # Step 1 — run as root sudo bash install.sh # Step 2 — dependency check (auto-installs if missing): # unzip, curl, pkill, pgrep, wall, mono, mono-service # Step 3 — download and launch the Universal Installer: curl -o /tmp/fog.exe http://${url}/client/UniversalInstaller.exe mono /tmp/fog.exe rm /tmp/fog.exe # Expected console output (abridged): # Checking for unzip....Passed!! # Checking for mono....Passed!! # Downloading FOG Client Universal Installer....Done! # [Mono installer UI or silent install proceeds] ``` -------------------------------- ### Clone FOG Client Repository Source: https://github.com/fogproject/fog-client/blob/master/README.md Use Git Bash to clone the FOG Client repository. Ensure Git for Windows is installed and added to your PATH. ```bash IEUser@WIN7 MINGW32 ~/Desktop $ git clone https://github.com/FOGProject/fog-client Cloning into 'fog-client'... ... ``` -------------------------------- ### PrinterManager Module Logic Source: https://context7.com/fogproject/fog-client/llms.txt Implements printer installation and removal based on server-configured modes. Handles different printer types and applies configurations. Ensure the PrintManagerBridge is correctly initialized for the target platform. ```csharp // DataContract from server: // { // "mode": "ar", // "printers": [ // { "name": "HP-LaserJet-4F", "type": "Network", "ip": "192.168.1.50", "port": "9100" }, // { "name": "Canon-MF445dw", "type": "CUPS", "file": "/ppd/canon.ppd" } // ], // "allprinters": ["HP-LaserJet-4F", "Canon-MF445dw"] // } public class PrinterManager : AbstractModule { private readonly PrintManagerBridge _instance; // WindowsPrinterManager or UnixPrinterManager private readonly List _configuredPrinters = new(); protected override void DoWork(Response data, DataContracts.PrinterManager msg) { if (msg.Mode == "0") return; // module disabled var installedPrinters = _instance.GetPrinters(); // "ar" mode: remove ALL printers not in the assigned list // "fm" mode: only remove printers that FOG previously installed RemoveExtraPrinters(msg.Printers, msg, installedPrinters); foreach (var printer in msg.Printers) { if (installedPrinters.Contains(printer.Name)) CleanPrinter(printer.Name); // clean up "(Copy" duplicates else if (!_configuredPrinters.Contains(printer.ToString())) printer.Add(_instance); // install new printer } BatchConfigure(msg.Printers); // apply settings (default printer, etc.) _instance.ApplyChanges(); // commit all pending printer operations } } ``` -------------------------------- ### SnapinClient DoWork Method Source: https://context7.com/fogproject/fog-client/llms.txt Processes a list of snapins received from the FOG server. It handles downloading, hash verification, execution, and reporting exit codes. Supports optional post-install power actions like reboot. ```csharp // DataContract from server (one or more snapins per response): // { // "snapins": [{ // "jobtaskid": 1042, // "name": "Deploy-Chrome", // "filename": "ChromeSetup.exe", // "args": "/silent /install", // "runwith": "", // "runwithargs": "", // "hash": "a3f5...d9c1", // SHA-512 hex // "pack": false, // "hide": true, // "timeout": 120, // "action": "reboot", // "url": "" // }] // } protected override void DoWork(Response data, DataContracts.SnapinClient msg) { foreach (var snapin in msg.Snapins) { var localPath = Path.Combine(Settings.Location, "tmp", snapin.FileName); // 1. Download from FOG server (or external URL) var endpoint = $"/service/snapins.file.php?mac={Configuration.MACAddresses()}&taskid={snapin.JobTaskID}"; var downloaded = string.IsNullOrWhiteSpace(snapin.Url) ? Communication.DownloadFile(endpoint, localPath) : Communication.DownloadExternalFile(snapin.Url + endpoint, localPath); if (!downloaded) { Communication.Contact($"/service/snapins.checkin.php?taskid={snapin.JobTaskID}&exitcode=-1", true); return; } // 2. Verify SHA-512 hash before execution var sha512 = Hash.SHA512(localPath); if (!sha512.ToUpper().Equals(snapin.Hash.ToUpper())) { Log.Error(Name, $"Hash mismatch — expected {snapin.Hash}, got {sha512}"); Communication.Contact($"/service/snapins.checkin.php?taskid={snapin.JobTaskID}&exitcode=-1", true); return; } // 3. Execute — SnapinPack (zip) or plain file var exitCode = snapin.Pack ? ProcessSnapinPack(snapin, localPath) // extracts zip then runs RunWith : StartSnapin(snapin, localPath); // runs directly or via RunWith // 4. Report exit code Communication.Contact($"/service/snapins.checkin.php?taskid={snapin.JobTaskID}&exitcode={exitCode}", true); // 5. Optional post-install power action if (snapin.Action.Equals("reboot", StringComparison.OrdinalIgnoreCase)) { Power.Restart("Snapin requested restart", Power.ShutdownOptions.Delay, "This computer needs to reboot to apply new software."); break; } } } ``` -------------------------------- ### Build FOG Client Source: https://github.com/fogproject/fog-client/blob/master/README.md Execute the build script for FOG Client using PowerShell. The compiled binaries will be located in the 'bin' directory within the client's root folder. ```powershell powershell "C:\path\to\fog-client\build.ps1" ``` -------------------------------- ### HostnameChanger Module Implementation Source: https://context7.com/fogproject/fog-client/llms.txt Implements computer renaming, Active Directory domain management, and Windows product key activation. Uses OS-specific implementations via the IHostName interface. Requires encrypted server responses and checks for logged-in users before performing actions. ```csharp // DataContract deserialized from server response: // { // "hostname": "LAB-PC-042", // "ad": true, // "addom": "corp.example.com", // "adou": "OU=Labs,DC=corp,DC=example,DC=com", // "aduser": "domain\\joiner", // "adpass": "", // "enforce": true, // "key": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" // } public class HostnameChanger : AbstractModule { private readonly IHostName _instance; // Windows / Linux / Mac implementation protected override void DoWork(Response data, DataContracts.HostnameChanger msg) { if (data.Error) return; if (!data.Encrypted) { Log.Error(Name, "Response was not encrypted"); return; } // 1. Activate Windows product key (no-op on Linux/Mac or if key is empty) ActivateComputer(msg); // calls WinActivation.SetProductKey(key) // 2. Honour enforce flag: skip rename/domain ops if users are logged in if (!msg.Enforce && User.AnyLoggedIn()) return; // 3. Rename — triggers a delayed reboot on success if (!RenameComputer(msg) || Power.ShuttingDown || Power.Requested) return; // 4. Join/re-join domain if AD is enabled RegisterComputer(msg); } } ``` ```csharp // IHostName interface — implemented per OS: internal interface IHostName { bool RenameComputer(DataContracts.HostnameChanger msg); bool RegisterComputer(DataContracts.HostnameChanger msg); // join domain bool UnRegisterComputer(DataContracts.HostnameChanger msg); // leave domain void ActivateComputer(string key); } ``` ```csharp // Windows P/Invoke calls used internally: // NetJoinDomain() - join domain // NetUnjoinDomain() - leave domain // NetRenameMachineInDomain()- rename while domain-joined // SetComputerNameEx() - rename workgroup machine // // Return code reference (subset): // 0 -> Success // 5 -> Access Denied // 1326 -> Bad credentials // 2691 -> Already joined to domain ``` -------------------------------- ### PowerManagement Module Implementation Source: https://context7.com/fogproject/fog-client/llms.txt Schedules shutdown and restart jobs using Quartz.NET, supporting both immediate and time-based actions. Converts Unix cron expressions to Quartz format. Requires encrypted server responses for scheduled tasks. ```csharp // DataContract from server: // Scheduled task: { "tasks": [{ "cron": "0 22 * * 1-5", "action": "shutdown" }], "ondemand": "" } // On-demand: { "tasks": [], "ondemand": "restart" } public class PowerManagement : AbstractModule { private IScheduler _scheduler; private Dictionary _triggers = new(); protected override void DoWork(Response data, DataContracts.PowerManagement msg) { if (!data.Encrypted) { ClearAll(); return; } // On-demand actions fire immediately if (msg.OnDemand.Equals("shutdown", StringComparison.OrdinalIgnoreCase)) { Power.Shutdown("FOG PowerManagement"); return; } if (msg.OnDemand.Equals("restart", StringComparison.OrdinalIgnoreCase)) { Power.Restart("FOG PowerManagement"); return; } // Scheduled tasks: diff against existing triggers and add/remove as needed CreateTasks(msg.Tasks); } // Quartz cron conversion example: // Unix CRON "30 22 * * 1-5" (weekdays at 22:30) // Quartz: "0 30 22 ? * 2-6" (seconds prepended; DOW shifted by +1; DOM=?) } ``` ```csharp // Task data model public class Task { public string CRON = ""; // Unix cron: "0 2 * * 0" (Sunday at 02:00) public string Action = ""; // "shutdown" | "reboot" public string ToQuartz() { // Prepend 0 for seconds; resolve DOM/DOW conflict; shift DOW index // "0 2 * * 0" -> "0 0 2 ? * 1" } } ``` ```csharp // Quartz job implementations: internal class ShutdownJob : IJob { async Task IJob.Execute(IJobExecutionContext context) => await Power.Shutdown("FOG PowerManagement"); } internal class RestartJob : IJob { async Task IJob.Execute(IJobExecutionContext context) => await Power.Restart("FOG PowerManagement"); } ``` -------------------------------- ### GenerateProcess Method for Snapin Execution Source: https://context7.com/fogproject/fog-client/llms.txt Configures and returns a Process object for executing a snapin. It handles direct execution, interpreter-based execution (RunWith/RunWithArgs), and command-line arguments. Supports environment variable expansion for RunWith paths. ```csharp // Process builder — honours RunWith (interpreter), RunWithArgs, Args, and timeout private static Process GenerateProcess(Snapin snapin, string snapinPath) { var process = new Process { StartInfo = { CreateNoWindow = true, UseShellExecute = false } }; if (!string.IsNullOrEmpty(snapin.RunWith)) { // e.g., RunWith="msiexec", RunWithArgs="/i", Args="/quiet" process.StartInfo.FileName = Environment.ExpandEnvironmentVariables(snapin.RunWith); process.StartInfo.Arguments = $"{snapin.RunWithArgs.Trim()} \"{snapinPath}\" {snapin.Args}".Trim(); } else { process.StartInfo.FileName = snapinPath; process.StartInfo.Arguments = snapin.Args; } return process; } // Environment variables available to snapin processes: // FOG_URL - FOG server address // FOG_SNAPIN_TASK_ID - current task ID // FOG_MAC_ADDRESSES - client MAC addresses ``` -------------------------------- ### AutoLogOut Module Implementation Source: https://context7.com/fogproject/fog-client/llms.txt This module monitors user inactivity and logs out the user after a server-configured timeout. It enforces a minimum inactivity timeout of 300 seconds and provides a 20-second grace period after a notification before logging out. ```csharp public class AutoLogOut : AbstractModule { private readonly int _minimumTime = 300; // 5-minute floor protected override void DoWork(Response data, DataContracts.AutoLogOut msg) { // Skip if no one is logged in if (!User.AnyLoggedIn()) return; // Reject timeouts below the 300-second minimum var timeOut = (msg.Time >= _minimumTime) ? msg.Time : 0; if (timeOut <= 0) return; var inactiveTime = User.InactivityTime(); // seconds since last input if (inactiveTime < timeOut) return; // user is still active // Warn the user via desktop notification Notification.Emit(ALOStrings.NOTIFICATION_TITLE, ALOStrings.NOTIFICATION_BODY, global: false); // Wait 20 s and re-check — user activity cancels the logout Thread.Sleep(20000); if (User.InactivityTime() >= timeOut) Power.LogOffUser(); } } ``` ```csharp // Server JSON payload example // POST /service/autologout.php -> { "time": 900 } // // Expected behaviour: // - If user has been inactive >= 900 s -> notification shown, then logout after 20 s // - If user.InactivityTime() < 900 s -> no action taken ``` -------------------------------- ### Windows DisplayManager Module Source: https://context7.com/fogproject/fog-client/llms.txt Manages display settings on Windows by changing screen resolution and refresh rate using WMI and Win32 APIs. Ensure settings are populated before attempting changes and validate input values. ```csharp public class DisplayManager : AbstractModule { private Display _display; protected override void DoWork(Response data, DataContracts.DisplayManager msg) { _display ??= new Display(); _display.LoadDisplaySettings(); // reads current DEVMODE via ChangeDisplaySettings if (!_display.PopulatedSettings) { Log.Error(Name, "Settings are not populated; will not attempt to change resolution"); return; } if (msg.X <= 0 || msg.Y <= 0) { Log.Error(Name, "Invalid settings provided"); return; } // Get first monitor via WMI Win32_DesktopMonitor var device = GetDisplays().FirstOrDefault() ?? ""; ChangeResolution(device, msg.X, msg.Y, msg.R); } private static List GetDisplays() { var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor"); return searcher.Get() .Cast() .Select(m => m["Name"].ToString()) .ToList(); // Example output: ["Generic PnP Monitor", "Dell U2722D"] } } ``` ```csharp public class DisplayManager { public int X = 0; // horizontal resolution, e.g. 1920 public int Y = 0; // vertical resolution, e.g. 1080 public int R = 0; // refresh rate (Hz), e.g. 60 } ``` -------------------------------- ### Printer Data Model Source: https://context7.com/fogproject/fog-client/llms.txt Defines the structure for printer information, including type, network details, driver paths, and configuration. The ToString() method provides a unique key for detecting duplicate configurations. ```csharp // Printer data model public class Printer { public enum PrinterType { iPrint, Network, Local, CUPS } public string Name; public string IP; public string Port; public string File; // driver/PPD file path public string ConfigFile; public string Model; public PrinterType Type; public void Add(PrintManagerBridge instance) { instance.Add(this); } public void Remove(PrintManagerBridge instance) { instance.Remove(Name); } public void SetDefault(PrintManagerBridge instance) { instance.Default(Name); } // Key used to detect duplicate configuration: // "HP-LaserJet-4F | 192.168.1.50 | 9100 | | | LaserJet" public override string ToString() => $"{Name} | {IP} | {Port} | {File} | {ConfigFile} | {Model}"; } ``` -------------------------------- ### Set PowerShell Execution Policy Source: https://github.com/fogproject/fog-client/blob/master/README.md Configure PowerShell to allow script execution by setting the execution policy to RemoteSigned. This command must be run from an administrator command prompt. ```powershell powershell "Set-ExecutionPolicy RemoteSigned" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.