Skip to main content
Version: 7.0

Windows update server

Getting the script​

To obtain the files needed on the update server, we provide a PowerShell script. You can download it in your browser or from a terminal:

(New-Object System.Net.WebClient).DownloadFile("https://repos.passwork.pro/repository/powershell/get_desktops.ps1",  "$pwd\get_desktops.ps1")

Benefits​

  • Downloads only the required version from our repository — the one that matches your backend. The remote repository is used as the file source, not the version source: it hosts all desktop application versions. Which XXYY to download is determined by the script from the API or a local file.
  • Supports proxy (HTTP_PROXY), which is important in air-gapped networks that reach the internet via a proxy.
  • Can be run on a schedule (cron / Task Scheduler) so the update server stays in sync with your backend.

Where the version (which XXYY to download) comes from:

  1. Backend API — if PASSWORK_DOMAIN is set, the script requests the available desktop version via your Passwork server API and downloads the corresponding XXYY.
  2. Local file — the LOCAL_VERSIONS_FILE file contains a line with the version.

No other version sources are used: the file repository is used only for downloading, not for determining the version.

Each run downloads one XXYY version. If the backend switches to a new version — on the next run the script will get the new XXYY (from the API or updated file) and download the update files.

Variables​

VariableDescription
REPO_BASE_URLURL of the repository with built desktop installers (file source).
OUTPUT_DIRDirectory for saved files (update server root or a copy).
PASSWORK_DOMAINBackend URL for version request via API (recommended if accessible).
LOCAL_VERSIONS_FILEPath to the versions file when API is not used.
HTTP_PROXYProxy for outbound requests (e.g. http://proxy:3128).
LOG_FILEPath to the log file (optional).
STATUS_FILEPath to the status file for monitoring (optional, see “Monitoring”).
KEEP_RELEASESHow many old XXYY directories to keep in OUTPUT_DIR (default 2).
LOCK_FILELock file to prevent concurrent runs (Task Scheduler); empty string to disable.

Dry run​

.\get_desktop.ps1 --dry-run

Running​

# Once or on a schedule (Task Scheduler)
$env:PASSWORK_DOMAIN = "https://your-backend.example.com"
$env:OUTPUT_DIR = "C:\inetpub\wwwroot\passwork\updates"
$env:HTTP_PROXY = "http://proxy.example.com:3128" # if needed
.\get_desktop.ps1

The script checks disk space, creates a lock if needed to avoid two instances running at once (e.g. from Task Scheduler), compares manifests with already downloaded files, and downloads only when something changed.

Monitoring​

To verify that synchronization ran and content is up to date:

  1. Script exit code

    • 0 — success; no update needed or update completed, or --dry-run.
    • 1 — error (network, repository, disk space, etc.).
      Monitoring systems (Task Scheduler + check script, Zabbix, Prometheus, etc.) can use the script exit code.
  2. Status file (STATUS_FILE)
    If STATUS_FILE is set, the script overwrites this file after each run with lines in key=value format:

    • status — ok or error;
    • version — current XXYY version (or empty if error before version was determined);
    • timestamp — time in UTC (ISO);
    • message — short message (e.g. “Update complete for version 0002” or “All latest YAML unchanged”).

    Example content after a successful run:

status=ok
version=0002
timestamp=2025-02-17T12:00:00Z
message=Update complete for version 0002

On error (including before version is determined), the script writes status=error and optionally message=exit N. For monitoring: read STATUS_FILE, ensure status=ok, and optionally check freshness via timestamp or presence of OUTPUT_DIR\<version>\latest.yml.

  1. Log (LOG_FILE)
    If LOG_FILE is set, all script messages are written there. You can scan the log for errors or lines like “Update complete” / “Repository unreachable”.

Example check for monitoring (PowerShell):

$env:STATUS_FILE = "C:\inetpub\wwwroot\passwork\updates\.sync_status"
.\get_desktop.ps1

# Check after run (or from another scheduled script):
$status = (Get-Content $env:STATUS_FILE | Where-Object { $_ -match '^status=' }) -replace '^status=', ''
if ($status -eq 'ok') { Write-Host "Sync OK" } else { Write-Host "Sync FAIL" }

# or by freshness (e.g. not older than 25 hours):
$tsLine = Get-Content $env:STATUS_FILE | Where-Object { $_ -match '^timestamp=' }
$tsStr = ($tsLine -split '=', 2)[1]
$syncTime = [DateTime]::ParseExact($tsStr.Trim(), "yyyy-MM-ddTHH:mm:ss'Z'", [Globalization.CultureInfo]::InvariantCulture, [Globalization.DateTimeStyles]::AssumeUniversal)
$hoursOld = (Get-Date).ToUniversalTime().Subtract($syncTime).TotalHours
if ($hoursOld -le 25) { Write-Host "Sync recent" } else { Write-Host "Sync may be stale" }