# Offline Patching Tool
A command-line tool for administrators to download system and third-party application patch installers for offline deployment to individual devices.

---

## Requirements

- Windows operating system

## Usage

1. Open a command prompt.
2. Run the tool with the required parameters:

  ```
  Usage: OWCPatchingTool [--get-system-patch|--get-app-patch] --mode <mode> --input-file <csv_path> [options]
  ```

  **Options:**
  ```
  --get-system-patch      Enable system patch downloading.
  --get-app-patch         Enable 3rd apps patch downloading.
  --mode <mode>           Mode: 0 (manual, use CSV for manual input, default), 1 (automatic, use CSV exported from Patch Management UI)
  --input-file <path>     CSV file with filters. (Required)
  --output-path <dir>     Output directory. (Default: current)
  --threads <num>         Number of download threads. (Default: 8)
  --timeout <seconds>     Download timeout in seconds. (Default: no timeout)
  --package               Package downloaded patches into a ZIP archive and generate a manifest (YML) for upload.
  --db-date <yyyymmdd>    Use database resources from a specific date (format: yyyymmdd). When set, the tool will attempt to use SDK resources for that date instead of the latest.
  --version               Show current version.
  ```

  **Examples:**
  ```
  OWCPatchingTool.exe --get-system-patch --input-file system_missing_patches.csv
  OWCPatchingTool.exe --get-system-patch --mode 1 --input-file system_missing_patches.csv
  OWCPatchingTool.exe --get-app-patch --input-file 3rd_patches.csv
  ```

---

## Output

Downloaded patch installers are saved in the following directory structure:

```
.
└── windows/
   ├── <1103>/           # System patches
   │   └── patch_id/
   │       ├── installer.cab/msu
   │       └── metadata.json
   ├── <signature>/      # 3rd-party patches
   │   └── patch_id/
   │       └── version
   │           └── architecture/
   │               └── language/
   │                   ├── installer.exe
   │                   └── metadata.json    
   └── databases/
      ├── metadata.json
      ├── wuo.dat
      ├── patch.dat
      └── wmod-ma.dat
```

A log file is created in the `logs` folder. Check this folder for patch download and packaging results.

---

## CSV Data

### System Patches CSV Format

**Manual CSV Format (`--mode 0`):**

| kb_id   | os_id   | architecture | tag   |
|---------|---------|--------------|-------|
| 5001330 | 59      | x86_64       | now   |
| 5012599 | 59      | x86_64       | never |

- **kb_id**: Knowledge Base article ID (**required**)
- **os_id**: Operating system ID (**optional**) (see [Supported Operating Systems](#supported-operating-systems))
- **architecture**: Target architecture: `x86_32`, `x86_64`, or `arm64` (**required**)
- **tag**: Custom label for each patch (**optional**). Use to add notes or categorize patches as needed.

**Tips:**
- For OS-related KBs, fill in `os_id`.
- For application KBs, `os_id` can be blank.
- If a KB is not found, try leaving `os_id` blank to broaden the search.

**Exported CSV Format (`--mode 1`):**

| id                                   | kb_id   | tag   |
|--------------------------------------|---------|-------|
| 93e6fdce-b5ae-4e98-9cca-b2a331023981 | 5001330 | now   |
| 22053fe8-307c-47b5-a555-8da7504fba6a | 5001330 | never |

- **id**: Unique patch identifier (**required**)
- **kb_id**: Knowledge Base article ID (**optional**)
- **tag**: Custom label for each patch (**optional**). Use to add notes or categorize patches as needed.

### 3rd-Party Patches CSV Format

**Manual CSV Format (`--mode 0`):**

| name                 | architecture | language | product_release_id    | channel           | exclude_apps                                 |
|----------------------|--------------|----------|-----------------------|-------------------|---------------------------------------------|
| Microsoft Edge       | 32-bit       | en-US    |                       |                   |                                             |
| Microsoft Office 365 | 64-bit       | en-US    | O365ProPlusRetail     | Current           | groove,infopath,lync,excel                  |
| Microsoft Office 365 | 64-bit       | en-US    | O365ProPlusRetail     | SemiAnnual        | groove                                      |
| Microsoft Office 365 | 64-bit       | en-US    | O365ProPlusRetail     | MonthlyEnterprise | groove                                      |
| Microsoft Office 2019| 64-bit       | en-US    | Professional2019Retail| Current           | groove                                      |
| Microsoft Office 2016| 32-bit       | en-US    | ProfessionalRetail    | Current           | groove                                      |

- **name**: Product name (**required**)
- **architecture**: Product architecture (**required**)
- **language**: Product language (**required**)

> **Note:** The columns `product_release_id`, `channel`, and `exclude_apps` are only required for Microsoft Office products. For other 3rd-party applications, these columns can be left blank.

---

## Collecting Office Configuration Data

To collect `product_release_id`, `channel`, and `exclude_apps` for Microsoft Office installations, use the provided PowerShell script `GetOfficeConfiguration.ps1`.

Open a PowerShell console as administrator and set the execution policy:

```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force
```

Run the script to collect Office configuration data:

```powershell
.\scripts\GetOfficeConfiguration.ps1
```

The script will output the required Office configuration details, which you can use to populate the corresponding columns in your CSV file.

---

## How to Download a Specific Version of an App

Each time an application is released, it includes a release date. The Patching Tool supports querying the latest version available at a specific point in time.

Use the `--db-date` option with a date in `yyyymmdd` format to retrieve the version that was latest on that date:

```powershell
OWCPatchingTool.exe --get-app-patch --input-file 3rd.csv --db-date 20251021
```

This allows you to download application patches as they existed on a particular date from patches databases, rather than always downloading the current latest version.

## Supported Operating Systems

| OS Family Name                       | ID  |
|--------------------------------------|-----|
| Windows 10                           | 59  |
| Windows 11                           | 76  |
| Windows 7                            | 30  |
| Windows 8                            | 43  |
| Windows 8.1                          | 51  |
| Windows Server 2003                  | 6   |
| Windows Server 2003 R2               | 11  |
| Windows Server 2008                  | 24  |
| Windows Server 2008 R2               | 37  |
| Windows Server 2012                  | 48  |
| Windows Server 2012 R2               | 56  |
| Windows Server 2016                  | 63  |
| Windows Server 2019                  | 83  |
| Windows Server 2022                  | 80  |
| Windows Server 2025                  | 85  |
| Windows Vista                        | 16  |
| Windows XP                           | 1   |

---

## Changelog
### 1.0.9
- Added `--timeout <seconds>` option to enable download timeout (default: no timeout).

### 1.0.8
- Added support for packing downloaded app patches.
- Added `--db-date` option to use database resources from a specific date (available from 20251015; format: yyyymmdd).

### 1.0.7
- Added support for `--mode 1` to look up application patches from exported CSV file.
- Added support for reading custom tags for OS patches from CSV file.
- Fixed bugs.

### 1.0.6
- Added `--package` argument to enable packing of downloaded patches.
- Fixed bugs.

### 1.0.5
- Added support for downloading the latest installers for 3rd-party applications.
- Added `--mode` argument to specify manual or exported CSV input.

### 1.0.4
- Added support for reading CSV data exported from the Patch Management UI.
- Fixed bugs.

### 1.0.3
- Added ability to update and download the latest patch database files.

### 1.0.2
- Restructured output installers.
- Updated README.md.
- Only package all patches when the `--pack-all` argument is provided.

### 1.0.1
- Added SHA1 validation for installer files.
- Exclude failed downloads from package.
- Added log file message writing.

### 1.0.0
- Initial release.
- Download and package missing patch installers from CSV input.
- Digital signature and manifest generation.
- Multi-threaded downloads and per-patch packaging options.

---