# Attachment Commands

### Overview

This section covers all the Keeper Commander commands for managing file attachments within vault records. These commands allow users to download, upload, or delete attachments from records in the vault. They are especially useful for tasks such as backup, organization, and maintenance.

This section supports following commands

* [Upload Attachments Command](#upload-attachments-command)
* [Download Attachments Commands](#download-attachment-command)
* [Remove Attachments Commands](#remove-attachment-command)

### Upload Attachments Command

Upload a new file into your vault and link it to a record. Securely adds files (e.g., documents, config files, certificates) to an existing record.

<details>

<summary>DotNet CLI</summary>

**Command:** `upload-attachment`&#x20;

**Parameters:**

| Parameter    | Description                |
| ------------ | -------------------------- |
| `record`     | Keeper record path or UID  |
| `-f, --file` | Path to the file to upload |

**Options:**

| Option      | Description                 |
| ----------- | --------------------------- |
| `--help`    | Display help screen         |
| `--version` | Display version information |

**Example:**

```bash
My Vault> upload-attachment record_uid  -f <path_of_file>
```

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**  `UploadAttachment`

```csharp
Task UploadAttachment(KeeperRecord record, IAttachmentUploadTask uploadTask);
```

**Parameters:**&#x20;

* `FileName`   - Name of the attachment file on record
* `record Uid`  - UID of record to which this file is to be uploaded and attached to

**Example:**

```csharp
var uploadTask = new FileAttachmentUploadTask(<FileName>);

//the vault instance has to be created before we call the next function
await vault.UploadAttachment(record, uploadTask); 
```

</details>

<details>

<summary>Power Commander</summary>

**Command:** `Copy-FileToKeeperRecord`

**Parameters:**&#x20;

* `-Filename`  : Attachment name which need to be uploaded to the record
* `-Record`  : Record Uid

**Example:**

```bash
PS> Copy-FileToKeeperRecord -Filename <path_of_the_file> -Record record_uid 
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `upload-attachment` or `ua`

**Parameter:**&#x20;

* `PATH` : record path or UID (required)
* `--file` : FILE file name to upload  (required)

**Example:**

```bash
My Vault> upload-attachment record_uid  --file <path_of_the_file>
```

</details>

<details>

<summary>Python SDK</summary>

**Function:** `upload_attachments`

**Arguments:**&#x20;

* `vault`                      `VaultOnline` Object which handles the records
* `record`                    `PasswordRecord` or a `TypesRecord` object.
* `files`                       list of files processed using `FileUploadTask`
* `stop_on_error`      Boolean - dictates if to stop if upload fails

**Example:**

```python
upload_attachments(self, vault: vault_online.VaultOnline,
                           record: Union[vault_record.PasswordRecord, vault_record.TypedRecord],
                           files: List[ParsedFieldValue],
                           stop_on_error: bool)
```

</details>

### Download Attachment Command

Downloads all files attached to a specified record—or entire folders if used recursively.

* This command retrieves files attached to vault records and saves them to a specified local directory.
* Users can download individual records or recursively fetch all attachments from a folder and its subfolders.

<details>

<summary>DotNet CLI</summary>

**Command** : `download-attachment`&#x20;

**Parameters:**

* `record path or uid (pos. 0`) : Required. Keeper Record
* `-o, --output-dir`  : Output directory

**Flag** :&#x20;

* `-f, --file`  : Attachment UID, name, or title
* `--help` : Display this help screen.
* `--version`  : Display version information.

**Example:**

```bash
My Vault> download-attachment record_uid -f "custom-json.json" -o .
Downloading custom-json.json ... Done.
```

</details>

<details>

<summary>DotNet SDK</summary>

Download attachments or files from Keeper records to local storage. Use `DownloadAttachmentFile` for regular record attachments and `DownloadFile` for file-type records.

**Function:** `DownloadAttachmentFile`  or `DownloadFile` based on record type

```csharp
public async Task DownloadAttachmentFile(string recordUid, AttachmentFile attachment, Stream destination)
```

```csharp
public async Task DownloadFile(FileRecord fileRecord, Stream destination)
```

**Parameters:**

| Parameter     | Type           | Description                                      |
| ------------- | -------------- | ------------------------------------------------ |
| `recordUid`   | string         | The UID of the record containing the attachment  |
| `attachment`  | AttachmentFile | The attachment file object to download           |
| `fileRecord`  | FileRecord     | The file record object to download               |
| `destination` | Stream         | The output stream where the file will be written |

**Example:**&#x20;

```csharp
# atta here is attachment
using (var stream = File.OpenWrite(Path.Combine(options.OutputDirectory, atta.Name)))
{
    switch (atta)
    {
        case AttachmentFile af:
            await context.Vault.DownloadAttachmentFile(record.Uid, af, stream);
            break;
        case FileRecord fr:
            await context.Vault.DownloadFile(fr, stream);
            break;
    }
}
```

</details>

<details>

<summary>PowerCommander</summary>

**Command:** `Copy-KeeperFileAttachment`  or `kda`

**Parameters:**

| Parameter | Required | Description                                       |
| --------- | -------- | ------------------------------------------------- |
| `-Path`   | Yes      | Output folder path where files will be downloaded |

**Flags:**

| Option       | Description                                                |
| ------------ | ---------------------------------------------------------- |
| `-Record`    | Record UID to download attachment from                     |
| `-Folder`    | Folder UID to download attachments from                    |
| `-Name`      | Name of the specific file to download (use with `-Record`) |
| `-Recursive` | Download all attachments from the folder and subfolders    |

**Example:**

```powershell
PS> Copy-KeeperFileAttachment -Record "ABC123XYZ456" -Name "custom-json.json" -Path .
PS> kda -Record "ABC123XYZ456" -Name "config.yaml" -Path ./downloads
# Downloads all the files for the respective folder
PS> Copy-KeeperFileAttachment -Folder record_uid  -Path . -Recursive
PS> kda -Folder "FOLDER_UID_123" -Path ./backup -Recursive
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `download-attachment`&#x20;

**Aliases:**  `da`

**Parameters:**&#x20;

* `PATH`  : Record or folder path or UID (required)

**Options:**

* `-r, --recursive` : Download recursively through subfolders
* `--out-dir` : OUT\_DIR Local folder for downloaded files
* `--preserve-dir` : Preserve vault folder structure
* `--record-title` : Add record title to attachment file.

**Example:**

```python
My Vault> download-attachment --out-dir .  record_uid
Downloading 'service_config.yaml'
```

</details>

<details>

<summary>Python SDK</summary>

**Function:** `download_to_file`

```python
download_to_file(self, file_name: str) -> None
```

**Example:**&#x20;

```python
for atta in attachments:
    file_name = atta.title
    if title:
        file_name = f'{title}-{atta.title}'
    file_name = os.path.basename(file_name)
    name = os.path.join(subfolder_path, file_name)
    if os.path.isfile(name):
        base_name, ext = os.path.splitext(file_name)
        name = os.path.join(subfolder_path, f'{base_name}({record_uid}){ext}')
    if os.path.isfile(name):
        base_name, ext = os.path.splitext(file_name)
        name = os.path.join(subfolder_path, f'{base_name}({atta.file_id}){ext}')
    atta.download_to_file(str(name))

```

</details>

### Remove Attachment Command

Deletes one or more attachments from a Keeper record.

* Permanently removes an attached file from a record.
* Useful for cleaning up **outdated or redundant attachments** and managing vault storage.

<details>

<summary>DotNet CLI</summary>

**Command:** `delete-attachment`

**Flag:**&#x20;

* `record` : record path or UID
* `-h, --help` show this help message and exit
* `--file` : NAME attachment file name or ID. Can be repeated.

**Example:**

```bash
My Vault> delete-attachment record_uid --file "custom-json.json, custom-json-1.json"  
```

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**&#x20;

```csharp
Task DeleteAttachmentCommand(this VaultContext context, DeleteAttachmentOptions options)
```

**Flag** :&#x20;

* Attachment ID

**Example:**

```csharp
var attachments = context.Vault.RecordAttachments(record).ToArray();
await context.Vault.DeleteAttachment(record, attachmentToDelete.Id);
```

</details>

<details>

<summary>PowerCommander</summary>

**Command** : `Remove-KeeperFileAttachment`&#x20;

**Aliases:** `krfa`

**Flag** :&#x20;

* `-Record` : Record Uid
* `-FileName` : Attachment name to delete
* `-Confirm`  : `-Confirm: $false` will not ask prompt.

**Example:**

```powershell
PS> Remove-KeeperFileAttachment -Record record_uid -FileName "custom-json.json", "custom-json-1.json"
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `delete-attachment`&#x20;

**Parameters:**&#x20;

* `RECORD` : record path or UID (required)

**Options**:

* `-h, --help` : show this help message and exit
* `--name` : NAME attachment file name or ID. Can be repeated (required)

**Example:**

```bash
My Vault> delete-attachment --name "service_config.yaml" record_uid
```

</details>

<details>

<summary>Python SDK</summary>

**Function:**  `update_record`

Use the update record function to remove attachments from existing records

</details>
