> For the complete documentation index, see [llms.txt](https://docs.keeper.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keeper.io/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/nested-shared-folder-commands/nsf-folders-commands.md).

# NSF Folders Commands

Nested Shared Folders for folder-level commands

### Overview

With the introduction of **Nested Shared Folders with Role-Based Folder Permissions**, we’ve rebuilt the vault’s folder, sharing and permissions model from the ground up, delivering a more flexible and scalable experience for every user and team.

### Operations Supported

The Following operations are supported by NSF Shared Folders

1. [List NSF Shared Folders](/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/nested-shared-folder-commands.md#list-command)
2. [Get NSF Shared Folders](/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/nested-shared-folder-commands.md#get-command)
3. [Add NSF Shared Folders](#create-folder-command)
4. [Edit NSF Shared Folders](#update-folder-command)
5. [Delete NSF Shared Folders](#remove-folder-command)
6. [Share NSF](#share-folder-command)
7. [Unlink Record From Folder](#remove-unlink-record-command)
8. [Link Record to Folder](#link-record-to-folder-command)
9. [NSF Move](/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/nested-shared-folder-commands.md#move-command)

**Note:** In case you are using classic permission model, please refer to [Shared Folder Commands](/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/sharing-commands/shared-folder-commands.md)

### Create Folder command

Creates a new folder in Keeper NSF using the v3 API. Optionally places the folder under a parent, assigns a color, and controls whether permissions are inherited from the parent.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-mkdir`

**Parameters**:

| **Parameter**  | **Description**                                                                    |
| -------------- | ---------------------------------------------------------------------------------- |
| `--name`       | Name of the folder to create (required)                                            |
| `--parent`     | UID of the parent folder. If omitted, the folder is created at the Keeper NSF root |
| `--color`      | Optional folder color                                                              |
| `--no-inherit` | If specified, the new folder will not inherit permissions from its parent          |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-mkdir "a12" --parent MQ8GwV3F1sQvGmXt-4zv2A --color green --no-inherit
Folder 'a12' created successfully (UID: SDFAcBPpPETVmRKWyD-qHw).
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();
string rootFolderUid = await vault.CreateKeeperNSFFolder(folderName);
Console.WriteLine($"Created root folder: {rootFolderUid}");
string childFolderUid = await vault.CreateKeeperNSFFolder(
    folderName: folderName,
    parentFolderUid: parentFolderUid,
    color: color);
Console.WriteLine($"Created child folder: {childFolderUid}");
string isolatedFolderUid = await vault.CreateKeeperNSFFolder(
    folderName: folderName,
    parentFolderUid: parentFolderUid,
    color: null,
    inheritPermissions: false);
Console.WriteLine($"Created isolated folder: {isolatedFolderUid}");
```

**Batch Create Folder Command:**

{% code expandable="true" %}

```csharp
var folders = new List<KeeperNSFFolderCreateRequest>
{
    new KeeperNSFFolderCreateRequest
    {
        Name = "Batch Demo - Root Folder",
        Color = "#4A90D9",
        InheritPermissions = true
    },
    new KeeperNSFFolderCreateRequest
    {
        Name = "Batch Demo - Child Folder",
        ParentFolderUid = "<parentFolderUid>",
        Color = "#33FF57",
        InheritPermissions = true
    }
};

var results = await vault.CreateKeeperNSFFolders(folders);
foreach (var r in results)
{
    Console.WriteLine($"{(r.Success ? "[OK]" : "[FAIL]")} {r.Name}  UID={r.FolderUid}  {r.Message}");
}
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `New-KeeperNSFFolder`

**Alias**: `nsf-mkdir`

**Parameters**:

| **Parameter**           | **Description**                                                                    |
| ----------------------- | ---------------------------------------------------------------------------------- |
| `-Name`                 | Name of the folder to create (required)                                            |
| `-ParentFolderUid`      | UID of the parent folder. If omitted, the folder is created at the Keeper NSF root |
| `-Color`                | Optional folder color                                                              |
| `-NoInheritPermissions` | If specified, the new folder will not inherit permissions from its parent          |

**Examples**:

{% code expandable="true" %}

```ps1
PS >  New-KeeperNSFFolder -Name "KD12" -Color "red"
Folder 'KD12' created successfully (UID: cdfqw-SRqie3ZT9CdVB1ng).
cdfqw-SRqie3ZT9CdVB1ngqwe
```

{% endcode %}

**Batch Support:**

**Command** : `New-KeeperNSFFolders`

**Alias** : `nsf-mkdirs`

<table><thead><tr><th width="281">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code></td><td>Path to UTF-8 JSON batch file</td></tr><tr><td><code>-Json</code></td><td>Inline JSON</td></tr><tr><td><code>-DownloadSampleFolders</code></td><td>Write sample JSON (default: <code>nsf-folders-update-batch.sample.json</code>)</td></tr></tbody></table>

**Examples** :

{% code expandable="true" %}

```ps
PS > New-KeeperNSFFolder -DownloadSampleFolders
PS > New-KeeperNSFFolder -FilePath .\nsf-folders-update-batch.sample.json
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-mkdir`

**Parameters**:

`folder` Folder name (use "//" to embed a literal "/" in the name)\
`--color` {none, red, orange, yellow, green, blue, gray} Folder colour\
`--no-inherit` Do not inherit parent folder permissions

**Example**:

```shellscript
My Vault> nsf-mkdir "Test NSF New" --color red
NSF folder created: <folder_uid>
<folder_uid>
My Vault>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `create_nsf_folder`

```python
    FOLDER_PATH = "Projects/Demo"  # Use // for literal / in a name
    COLOR = None  # none, red, orange, yellow, green, blue, gray
    INHERIT_PERMISSIONS = True

    segments = [s.strip() for s in FOLDER_PATH.replace("//", "\x00").split("/") if s.strip()]
    if not segments:
        raise ValueError("Invalid folder path")

    parent_uid = None
    created_uid = None
    for idx, segment in enumerate(segments):
        segment = segment.replace("\x00", "/")
        is_leaf = idx == len(segments) - 1
        existing = nsf_management.find_nsf_child_folder(vault, segment, parent_uid)
        if existing:
            if is_leaf:
                print(f'Folder "{segment}" already exists: {existing}')
                return
            parent_uid = existing
            continue
        result = nsf_management.create_nsf_folder(
            vault,
            segment,
            parent_uid=parent_uid,
            color=COLOR if is_leaf else None,
            inherit_permissions=INHERIT_PERMISSIONS if is_leaf else True,
        )
        created_uid = result.folder_uid
        parent_uid = created_uid
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `mkdirNestedShareFolder`

```python
export async function mkdirNestedShareFolder(
    storage: InMemoryStorage,
    auth: Auth,
    input: MkdirNsfInput
): Promise<MkdirNsfResult> {
    const folderPath = (input.folder ?? '').trim()
    if (!folderPath) {
        throw new KeeperSdkError('Folder name is required.', ResultCodes.NSF_MKDIR_FAILED)
    }

```

</details>

### Update folder command

Renames a Keeper NSF folder and/or changes its color. Folder can be referenced by UID or by name.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-rndir`

**Parameters**:

| Parameter | Description                                                                          |
| --------- | ------------------------------------------------------------------------------------ |
| `--name`  | New folder name                                                                      |
| `--color` | New folder color: `none`, `red`, `orange`, `yellow`, `green`, `blue`, `gray`, `grey` |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-rndir MQ8GwV3F1sQvGmXt-4zv2A --color yellow         
Keeper NSF folder updated.
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();

if (vault.TryResolveKeeperNSFFolder(folderUidOrName, out var folder))
{
    var result = await vault.UpdateKeeperNSFFolder(
        folderUidOrName: folder.FolderUid,
        newName: newName,
        color: color);

    VaultOnline.ValidateFolderModifyResult(result);
    Console.WriteLine("Keeper NSF folder updated.");
}
```

**Batch Update Folder Command:**

{% code expandable="true" %}

```csharp
var updates = new List<KeeperNSFFolderUpdateRequest>
{
    new KeeperNSFFolderUpdateRequest
    {
        FolderUid = "<folderUid1>",
        Name = "Renamed Folder",
        Color = "#4A90D9"
    },
    new KeeperNSFFolderUpdateRequest
    {
        FolderUid = "<folderUid2>",
        InheritPermissions = false
    }
};

var results = await vault.UpdateKeeperNSFFolders(updates);
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `Set-KeeperNSFFolder`

**Alias**: `nsf-rndir`

**Parameters**:

| Parameter | Description                                                                          |
| --------- | ------------------------------------------------------------------------------------ |
| `-Folder` | Folder UID or name (required)                                                        |
| `-Name`   | New folder name                                                                      |
| `-Color`  | New folder color: `none`, `red`, `orange`, `yellow`, `green`, `blue`, `gray`, `grey` |

**Examples**:

{% code expandable="true" %}

```ps1
PS > Set-KeeperNSFFolder -Folder cdfqw-SRqie3ZT9CdVB1ng -Name "Updated_name1"
Keeper NSF folder updated.
PS > Set-KeeperNSFFolder -Folder cdfqw-SRqie3ZT9CdVB1ng -Color red            
Keeper NSF folder updated.
```

{% endcode %}

**Batch Support:**

**Command**: `Set-KeeperNSFFolders`

**Alias**: `nsf-folders-update`

<table><thead><tr><th width="281">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code></td><td>Path to UTF-8 JSON batch file</td></tr><tr><td><code>-Json</code></td><td>Inline JSON</td></tr><tr><td><code>-DownloadSampleFolders</code></td><td>Write sample JSON (default: <code>nsf-folders-update-batch.sample.json</code>)</td></tr></tbody></table>

JSON schema — `folders` array; each item: `uid` (required), optional `name`, `color`, `inherit_permissions` (`false` only).

**Examples**:

{% code expandable="true" %}

```ps1
PS > Set-KeeperNSFFolders -DownloadSampleFolders
PS > Set-KeeperNSFFolders -FilePath .\nsf-folders-update-batch.sample.json
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-rndir`

**Parameters**:

`folder` folder path or UID\
`-n, --name` NAME - folder new name\
`--color` {none, red, orange, yellow, green, blue, gray} Folder color\
`-q, --quiet` Suppress success message

**Example**:

```shellscript
My Vault> nsf-rndir <folder_uid> -n "New Name" --color gray
Folder "Name" has been renamed to "New Name"
My Vault>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `update_nsf_folder`

```python
    FOLDER_UID_OR_NAME = "Demo"
    NEW_NAME = "Demo Renamed"  # Set to None to only change color
    COLOR = None  # none, red, orange, yellow, green, blue, gray

    result = nsf_management.update_nsf_folder(
        vault,
        FOLDER_UID_OR_NAME,
        folder_name=NEW_NAME,
        color=COLOR,
    )
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `updateNestedShareFolder`

```python
export async function updateNestedShareFolder(
    storage: InMemoryStorage,
    auth: Auth,
    input: UpdateNsfFolderInput
): Promise<UpdateNsfFolderResult> {
    const folderArg = input.folder?.trim()
    if (!folderArg) {
        throw new KeeperSdkError('Enter the path or UID of existing folder.', ResultCodes.NSF_UPDATE_FAILED)
    }
```

</details>

### Remove folder command

Removes one or more Keeper NSF folders. Always runs a preview first, prints the impact, and asks for confirmation unless `-Force` is supplied.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-rmdir`

**Parameters**:

| Parameter             | Description                                                                               |
| --------------------- | ----------------------------------------------------------------------------------------- |
| `-o` or `--operation` | `folder-trash` (default, recoverable) or `delete-permanent` (irreversible cascade delete) |
| `-f` or `--force`     | Skip the confirmation prompt after preview                                                |
| `--dry-run`           | Preview only; do not remove folders                                                       |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-rmdir EhJ3-aznCbIAX9YzG8PIHg          

=== Keeper NSF Folder Remove Preview ===

Folder: EhJ3-aznCbIAX9YzG8PIHg
  Status: Success
  Impact:
    Folders:          1
    Records:          1
    Affected users:   1
    Affected teams:   0
Are you sure you want to remove the folder(s) above? (yes/No) y

Removing folders...

Keeper NSF folder removal completed.
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();

var removals = new List<KeeperNSFFolderRemoval>();
foreach (var name in folderUidsOrNames)
{
    if (vault.TryResolveKeeperNSFFolder(name, out var folder))
    {
        removals.Add(new KeeperNSFFolderRemoval
        {
            FolderUid = folder.FolderUid,
            Operation = KeeperNSFFolderRemoveOperation.FolderTrash,
        });
    }
}

var preview = await vault.RemoveKeeperNSFFolders(removals, dryRun: true);
VaultOnline.ValidateRemoveResponse(preview.PreviewResponse, throwOnWarnings: false);

var confirm = await vault.RemoveKeeperNSFFolders(removals, dryRun: false);
if (!confirm.Confirmed)
{
    throw new InvalidOperationException("Folder removal was not confirmed by the server.");
}

await vault.SyncDown(false);
```

**Batch Remove Folder Command:**

{% code expandable="true" %}

```csharp
var removals = new List<KeeperNSFFolderRemoval>
{
    new KeeperNSFFolderRemoval { FolderUid = "<folderUid1>", Operation = KeeperNSFFolderRemoveOperation.FolderTrash },
    new KeeperNSFFolderRemoval { FolderUid = "<folderUid2>", Operation = KeeperNSFFolderRemoveOperation.DeletePermanent }
};

// Preview first
var preview = await vault.RemoveKeeperNSFFolders(removals, dryRun: true);
// Confirm
var confirmed = await vault.ConfirmKeeperNSFFolders(removals, preview);
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `Remove-KeeperNSFFolder`

**Alias**: `nsf-rmdir`

**Parameters**:

| Parameter    | Description                                                                               |
| ------------ | ----------------------------------------------------------------------------------------- |
| `-Folder`    | One or more folder UIDs or names. Accepts pipeline input                                  |
| `-Operation` | `folder-trash` (default, recoverable) or `delete-permanent` (irreversible cascade delete) |
| `-Force`     | Skip the confirmation prompt after preview                                                |
| `-DryRun`    | Preview only; do not remove folders                                                       |

**Examples**:

{% code expandable="true" %}

```ps1
PS > Remove-KeeperNSFFolder -Folder <folder_uid> -Force

=== Keeper NSF Folder Remove Preview ===

Folder: <folder_uid>
  Status: Success
  Impact:
    Folders:          1
    Records:          0
    Affected users:   1
    Affected teams:   0

Removing folders...

Keeper NSF folder removal completed.
```

{% endcode %}

**Batch Support:**\
**Command**: `Remove-KeeperNSFFolders`

**Alias**: `nsf-rmdirs`

| Parameter                | Description                                                         |
| ------------------------ | ------------------------------------------------------------------- |
| `-FilePath`              | Path to UTF-8 JSON batch file                                       |
| `-Json`                  | Inline JSON                                                         |
| `-DownloadSampleFolders` | Write sample JSON (default: `nsf-folders-remove-batch.sample.json`) |
| `-Force`                 | Skip confirmation after preview                                     |
| `-DryRun`                | Preview only                                                        |

JSON schema — `folders` (or `removals`) array; each item: `uid` / `folder_uid` (required), optional `operation` (`folder-trash` default, or `delete-permanent`).

**Examples**:

{% code expandable="true" %}

```ps1
PS > Remove-KeeperNSFFolders -DownloadSampleFolders
PS > Remove-KeeperNSFFolders -FilePath .\nsf-folders-remove-batch.sample.json -DryRun
PS > Remove-KeeperNSFFolders -FilePath .\nsf-folders-remove-batch.sample.json -Force
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-rmdir`

**Parameters**:

`FOLDER` Folder UID(s) or name(s) to remove (max 100)\
`--operation, -o` {folder-trash, delete-permanent} Removal operation (default: folder-trash)\
`-q, --quiet` Suppress per-folder impact detail\
`--force, -f` Skip confirmation after preview\
`--dry-run` Preview only; do not delete

**Example**:

```shellscript
My Vault> nsf-rmdir <folder_uid>

The following folder will be folder-trash:
  New Name [<folder_uid>]
  This will affect: 1 sub-folder(s), 1 user(s)
Do you want to proceed with the folder deletion? [y/n]: y
Folder removal completed.
My Vault>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `remove_nsf_folders`

```python
    FOLDER_IDENTIFIERS = ["Demo Renamed"]  # UIDs or names
    OPERATION = "folder-trash"  # folder-trash, delete-permanent
    FORCE = True
    DRY_RUN = False

    removals = []
    for identifier in FOLDER_IDENTIFIERS:
        folder_uid = nsf_management.resolve_nsf_folder_uid(vault, identifier)
        if not folder_uid:
            raise ValueError(f'Folder "{identifier}" not found')
        removals.append({"folder_uid": folder_uid, "operation_type": OPERATION})

    preview = nsf_management.remove_nsf_folders(vault, removals, dry_run=True)
    for pr in preview.preview_results:
        print(f"  {pr.item_uid}: {pr.error or 'ok to remove'}")
    if DRY_RUN:
        print("[Dry-run] No folders were deleted.")
        return
    if not FORCE:
        answer = input("Proceed with folder deletion? [y/N]: ").strip().lower()
        if answer not in ("y", "yes"):
            print("Aborted.")
            return
    result = nsf_management.remove_nsf_folders(vault, removals, dry_run=False)
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `removeNestedShareFolders`

```python
export async function removeNestedShareFolders(
    storage: InMemoryStorage,
    auth: Auth,
    input: RemoveNsfFolderInput
): Promise<RemoveNsfFolderResult> {
    const operation = normalizeOperation(input.operation)
    const dryRun = input.dryRun ?? false
    const removals = buildRemovals(storage, auth, input.folders, operation)
    try {
        const previewResponse = await executeRemove(auth, removals, RemoveAction.REMOVE_ACTION_PREVIEW)
        const preview = mapPreview(removals, previewResponse)
        if (hasPreviewErrors(preview)) {
            throw new KeeperSdkError(
                formatRemoveNsfFolderPreview(preview, operation, input.quiet) || 'Folder removal preview failed.',
                ResultCodes.NSF_REMOVE_FAILED
            )
        }
```

</details>

### Share Folder command

Grants or removes user access on a Keeper NSF folder.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-share-folder`

**Parameters**:

| Parameter    | Description                                                                                                               |
| ------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `position 0` | UID of the folder to share (required)                                                                                     |
| `--action`   | `grant` (default) or `remove`                                                                                             |
| `--email`    | One or more user email addresses to grant or revoke access for (required)                                                 |
| `--role`     | Access role for `grant`: `viewer` (default), `shared-manager`, `content-manager`, `content-share-manager`, `full-manager` |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-share-folder MQ8GwV3F1sQvGmXt-4zv2A --action grant --email example@keepersecurity.com --role
 viewer
Granted 'viewer' access to 'example@keepersecurity.com' on folder 'MQ8GwV3F1sQvGmXt-4zv2A'.
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();

foreach (var entry in vault.GetKeeperNSFShortcuts())
{
    Console.WriteLine($"{entry.RecordUid}  {entry.Title}  [{entry.Folders.Count} folders]");
    foreach (var f in entry.Folders)
    {
        Console.WriteLine($"  - {f.Name} ({f.FolderUid})");
    }
}

var keepResult = await vault.KeepKeeperNSFRecordInFolder(recordUid, keepFolderUid);
foreach (var removal in keepResult.Removals)
{
    Console.WriteLine($"{(removal.Success ? "[OK]" : "[FAIL]")} {removal.FolderName} ({removal.FolderUid})");
}
```

#### Batch grant folder access command

Grants user or team access to NSF folders in batch (up to 500 entries per request). Independent of single-item `nsf-share-folder` / `Set-KeeperNSFFolderAccess`. Caller must have share/update-access on each folder.

{% code expandable="true" %}

```csharp
var grants = new List<KeeperNSFFolderAccessGrantRequest>
{
    new KeeperNSFFolderAccessGrantRequest
    {
        FolderUid = "<folderUid>",
        Accessor = "user1@example.com",
        Role = "viewer"
    },
    new KeeperNSFFolderAccessGrantRequest
    {
        FolderUid = "<folderUid>",
        Accessor = "Engineering Team",
        Role = "content-manager"
    }
};

var results = await vault.GrantKeeperNSFFolderAccesses(grants);
```

{% endcode %}

#### Batch update folder access command

Updates existing user/team access on NSF folders in batch (up to 500 entries per request).

{% code expandable="true" %}

```csharp
var updates = new List<KeeperNSFFolderAccessUpdateRequest>
{
    new KeeperNSFFolderAccessUpdateRequest
    {
        FolderUid = "<folderUid>",
        Accessor = "user1@example.com",
        Role = "content-manager"
    }
};

var results = await vault.UpdateKeeperNSFFolderAccesses(updates);
```

{% endcode %}

#### Batch revoke folder access command

Revokes user/team access from NSF folders in batch (up to 500 entries per request).

{% code expandable="true" %}

```csharp
var revokes = new List<KeeperNSFFolderAccessRevokeRequest>
{
    new KeeperNSFFolderAccessRevokeRequest
    {
        FolderUid = "<folderUid>",
        Accessor = "user1@example.com"
    }
};

var results = await vault.RevokeKeeperNSFFolderAccesses(revokes);
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `Set-KeeperNSFFolderAccess`

**Alias**: `nsf-share-folder`

**Parameters**:

| Parameter    | Description                                                                                                               |
| ------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `-FolderUid` | UID of the folder to share (required)                                                                                     |
| `-Action`    | `grant` (default) or `remove`                                                                                             |
| `-Email`     | One or more user email addresses to grant or revoke access for (required)                                                 |
| `-Role`      | Access role for `grant`: `viewer` (default), `shared-manager`, `content-manager`, `content-share-manager`, `full-manager` |

**Examples**:

{% code overflow="wrap" expandable="true" %}

```ps1
PS > Set-KeeperNSFFolderAccess -FolderUid wbxwceZdbPVcyuR-7IybjA -Email example1@keepersecurity.com  -Role viewer
Granted 'viewer' access to 'example1@keepersecurity.com' on folder 'wbxwceZdbPVcyuR-7IybjA'.
```

{% endcode %}

#### Batch grant folder access command

**Command**: `Share-KeeperNSFFolderAccesses`

**Alias**: `nsf-share-folders`

<table><thead><tr><th width="303">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code></td><td>Path to UTF-8 JSON batch file</td></tr><tr><td><code>-Json</code></td><td>Inline JSON</td></tr><tr><td><code>-DownloadSampleAccesses</code></td><td>Write sample JSON (default: <code>nsf-folders-access-grant-batch.sample.json</code>)</td></tr></tbody></table>

JSON schema — `accesses` array; each item: `folder_uid`, `accessor` (email / team name / team UID), optional `role` (default `viewer`), optional `expire_in` (e.g. `30d`) or `expire_at` (ISO datetime).

Roles: `viewer`, `share-manager`, `content-manager`, `content-share-manager`, `full-manager`

**Examples**:

{% code expandable="true" %}

```ps1
PS > Share-KeeperNSFFolderAccesses -DownloadSampleAccesses
PS > Share-KeeperNSFFolderAccesses -FilePath .\nsf-folders-access-grant-batch.sample.json
```

{% endcode %}

#### Batch update folder access command

**Command**: `Update-KeeperNSFFolderAccesses`

**Alias**: `nsf-update-folder-access`

| Parameter                 | Description                                                                |
| ------------------------- | -------------------------------------------------------------------------- |
| `-FilePath` / `-Json`     | Batch payload                                                              |
| `-DownloadSampleAccesses` | Write sample JSON (default: `nsf-folders-access-update-batch.sample.json`) |

Examples:

{% code expandable="true" %}

```ps1
PS > Update-KeeperNSFFolderAccesses -DownloadSampleAccesses
PS > Update-KeeperNSFFolderAccesses -FilePath .\nsf-folders-access-update-batch.sample.json
```

{% endcode %}

#### Batch revoke folder access command

**Command**: `Unshare-KeeperNSFFolderAccesses`

**Alias**: `nsf-unshare-folders`

<table><thead><tr><th width="272">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code> / <code>-Json</code></td><td>Batch payload</td></tr><tr><td><code>-DownloadSampleAccesses</code></td><td>Write sample JSON (default: <code>nsf-folders-access-revoke-batch.sample.json</code>)</td></tr></tbody></table>

JSON schema — `accesses` array; each item: `folder_uid`, `accessor`.

**Examples**:

{% code expandable="true" %}

```ps1
PS > Unshare-KeeperNSFFolderAccesses -DownloadSampleAccesses
PS > Unshare-KeeperNSFFolderAccesses -FilePath .\nsf-folders-access-revoke-batch.sample.json
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-share-folder`

**Parameters:**

`folder` folder UID or name\
`-a, --action` {grant, remove} grant (default) or remove access\
`-e, --email` USER email, team name/UID, or @existing for all folder accessors\
`-r, --role` {viewer, share-manager, content-manager, content-share-manager, full-manager}\
`--expire-at` TIMESTAMP\
`--expire-in` PERIOD

**Example:**

```
My Vault> nsf-share-folder -a grant -r full-manager -e user@keepersecurity.com <folder_uid>
user@keepersecurity.com: Access granted successfully
My Vault>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `grant_nsf_folder_access`

```python
    FOLDER_UID_OR_NAME = "Projects"
    RECIPIENT_EMAIL = "colleague@example.com"
    ACTION = "grant"  # grant or remove
    ROLE = "viewer"  # viewer, share-manager, content-manager, content-share-manager, full-manager
    EXPIRATION_TIMESTAMP = None  # Unix ms; optional for grant

    if ACTION == "remove":
        result = nsf_sharing.revoke_nsf_folder_access(
            vault, FOLDER_UID_OR_NAME, RECIPIENT_EMAIL
        )
    else:
        result = nsf_sharing.grant_nsf_folder_access(
            vault,
            FOLDER_UID_OR_NAME,
            RECIPIENT_EMAIL,
            role=ROLE,
            expiration_timestamp=EXPIRATION_TIMESTAMP,
        )
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `shareNestedShareRecord`

```python
function shareNestedShareRecord(
    storage: InMemoryStorage,
    auth: Auth,
    input: ShareNestedShareRecordInput
): Promise<ShareNestedShareRecordResult> {
    const action = normalizeRecordAction(input.action)
    const emails = input.emails.map((email) => email.trim()).filter(Boolean)
    const dryRun = input.dryRun ?? false

```

</details>

### Link Record to Folder command

Links (hard-links) a Keeper NSF record into a Keeper NSF folder, so the record appears in additional folders without being copied.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-ln`

**Parameters**:

| Parameter    | Description                                                             |
| ------------ | ----------------------------------------------------------------------- |
| `position 0` | Record UID or title (required)                                          |
| `position 1` | Destination folder UID, name, or `/` for the Keeper NSF root (required) |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-ln BZ--Sa17UztyFkh5JWWgBg  MQ8GwV3F1sQvGmXt-4zv2A                 
Keeper NSF record linked into folder.
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();

var result = await vault.LinkKeeperNSFRecordToFolder(
    recordUidOrTitle: recordUidOrTitle,
    folderUidOrName:  folderUidOrName);

VaultOnline.ValidateFolderRecordUpdateResult(result);
await vault.SyncDown(false);
Console.WriteLine("Keeper NSF record linked into folder.");
```

#### Batch Link Record to Folder Command:

{% code expandable="true" %}

```csharp
var links = new List<KeeperNSFFolderRecordLinkRequest>
{
    new KeeperNSFFolderRecordLinkRequest { FolderUid = "<folderUid1>", RecordUid = "<recordUid1>" },
    new KeeperNSFFolderRecordLinkRequest { FolderUid = "<folderUid1>", RecordUid = "<recordUid2>" }
};

var results = await vault.LinkKeeperNSFRecordsToFolders(links);
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `Link-KeeperNSFRecord`

**Alias**: `nsf-ln`

**Parameters**:

| Parameter | Description                                                             |
| --------- | ----------------------------------------------------------------------- |
| `-Record` | Record UID or title (required)                                          |
| `-Folder` | Destination folder UID, name, or `/` for the Keeper NSF root (required) |

**Examples**:

{% code overflow="wrap" expandable="true" %}

```powershell
PS > Link-KeeperNSFRecord -Record "0UWhXh5vjjlpaw9BpFR0mA" -Folder "ynvMwZsAU5JtTn5RSr1F0Q"
Keeper NSF record linked into folder.
```

{% endcode %}

**Batch Support:**

**Command**: `Link-KeeperNSFRecords`

**Alias**: `nsf-lns`

<table><thead><tr><th width="280">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code> / <code>-Json</code></td><td>Batch payload</td></tr><tr><td><code>-DownloadSampleLinks</code></td><td>Write sample JSON (default: <code>nsf-folder-records-link-batch.sample.json</code>)</td></tr></tbody></table>

JSON schema — `links` array; each item: `folder_uid`, `record_uid` (aliases accepted). Empty `folder_uid` maps to NSF root.

**Examples:**

{% code expandable="true" %}

```ps1
PS > Link-KeeperNSFRecords -DownloadSampleLinks
PS > Link-KeeperNSFRecords -FilePath .\nsf-folder-records-link-batch.sample.json
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-ln`

**Parameters**:

`src` record UID or title\
`dst` destination folder UID or name

**Example**:

```shellscript
My Vault> nsf-ln <record_uid> <folder_uid>
Record <record_uid> linked to folder <folder_uid>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `link_nsf_record_to_folder`

```python
    RECORD_UID_OR_TITLE = "My NSF Login"
    FOLDER_UID_OR_NAME = "Archive"

    result = nsf_folder_records.link_nsf_record_to_folder(
        vault, RECORD_UID_OR_TITLE, FOLDER_UID_OR_NAME
    )
    print(f"Record {result.record_uid} linked to folder {result.folder_uid}")
```

</details>

<details>

<summary>JavaScript CLI</summary>

**Function:** `Coming Soon`

```python
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `linkNestedShareRecord`

```python
export async function linkNestedShareRecord(
    storage: InMemoryStorage,
    auth: Auth,
    recordIdentifier: string,
    folderIdentifier: string
): Promise<LinkNsfRecordResult> {
    const recordUid = resolveNsfRecordIdentifier(storage, recordIdentifier)
    if (!recordUid) {
        throw new KeeperSdkError(`Record '${recordIdentifier}' not found`, ResultCodes.NSF_NOT_FOUND)
    }
```

</details>

### Remove/Unlink Record command

Removes one or more Keeper NSF records using the v3 remove API. Always runs a preview first, prints the impact, and asks for confirmation unless `-Force` is supplied.

<details>

<summary>DotNet CLI</summary>

**Command**: `nsf-rm`

**Parameters**:

| Parameter             | Description                                                      |
| --------------------- | ---------------------------------------------------------------- |
| `--folder`            | Folder UID or name that provides context (required for `unlink`) |
| `-o` or `--operation` | `owner-trash` (default), `folder-trash`, or `unlink`             |
| `-f` or `--force`     | Skip the confirmation prompt after preview                       |
| `--dry-run`           | Preview only; do not remove records                              |

**Examples**:

{% code expandable="true" %}

```bash
My Vault> nsf-rm NBPPHWMkzjss3z_WacXoIA

=== Keeper NSF Remove Preview ===

Record: NBPPHWMkzjss3z_WacXoIA
  Folder context: AAAAAAAAAAAAAAAAAALjjA
  Status: Success
  Impact:
    Folders:          0
    Records:          1
    Affected users:   1
    Affected teams:   0
    Other locations:  1
    Warning: Record will be removed from all folders and moved to owner's trash
Are you sure you want to move the record(s) above to your trash? (yes/No) yes

Removing records...

Keeper NSF record removal completed.
```

{% endcode %}

</details>

<details>

<summary>DotNet SDK</summary>

**Function:**

```csharp
var vault = new VaultOnline(auth);
await vault.SyncDown();

var removals = new List<KeeperNSFRecordRemoval>();
foreach (var name in recordUidsOrTitles)
{
    if (!vault.TryResolveKeeperNSFRecord(name, out var record)) continue;

    vault.TryResolveKeeperNSFRecordRemovalFolder(
        record.RecordUid,
        folderUidOrName,
        KeeperNSFRecordRemoveOperation.FolderTrash,
        out var folderUid);

    removals.Add(new KeeperNSFRecordRemoval
    {
        RecordUid = record.RecordUid,
        FolderUid = folderUid,
        Operation = KeeperNSFRecordRemoveOperation.FolderTrash,
    });
}

var preview = await vault.RemoveKeeperNSFRecords(removals, dryRun: true);
VaultOnline.ValidateRemoveResponse(preview.PreviewResponse, throwOnWarnings: false);

var confirm = await vault.RemoveKeeperNSFRecords(removals, dryRun: false);
if (!confirm.Confirmed)
{
    throw new InvalidOperationException("Record removal was not confirmed by the server.");
}

await vault.SyncDown(false);
```

#### Batch unlink records from folders command

{% code expandable="true" %}

```csharp
var unlinks = new List<KeeperNSFFolderRecordUnlinkRequest>
{
    new KeeperNSFFolderRecordUnlinkRequest { FolderUid = "<folderUid>", RecordUid = "<recordUid>" }
};

var results = await vault.UnlinkKeeperNSFRecordsFromFolders(unlinks);
```

{% endcode %}

</details>

<details>

<summary>Power Commander</summary>

**Command**: `Remove-KeeperNSFRecord`

**Alias**: `nsf-rm`

**Parameters**:

| Parameter    | Description                                                      |
| ------------ | ---------------------------------------------------------------- |
| `-Record`    | One or more record UIDs or titles. Accepts pipeline input        |
| `-Folder`    | Folder UID or name that provides context (required for `unlink`) |
| `-Operation` | `owner-trash` (default), `folder-trash`, or `unlink`             |
| `-Force`     | Skip the confirmation prompt after preview                       |
| `-DryRun`    | Preview only; do not remove records                              |

**Examples**:

{% code expandable="true" %}

```ps1
PS > Remove-KeeperNSFRecord -Record LXU5SAWkCZMTnqeqNBWJNyGw

=== Keeper NSF Remove Preview ===

Record: LXU5SkCZMTnqeqNBWJNyGw
  Folder context: AA123424ASSGREGGBJYAAAAALjjA
  Status: Success
  Impact:
    Folders:          0
    Records:          1
    Affected users:   1
    Affected teams:   0
    Other locations:  1
    Warning: Record will be removed from all folders and moved to owner's trash
Are you sure you want to move the record(s) above to your trash? (yes/No): y

Removing records...

Keeper NSF record removal completed.
```

{% endcode %}

#### Batch Support:

**Command**: `Unlink-KeeperNSFRecords`

**Alias**: `nsf-unln`

<table><thead><tr><th width="288">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>-FilePath</code> / <code>-Json</code></td><td>Batch payload</td></tr><tr><td><code>-DownloadSampleUnlinks</code></td><td>Write sample JSON (default: <code>nsf-folder-records-unlink-batch.sample.json</code>)</td></tr></tbody></table>

JSON schema — `unlinks` array; each item: `folder_uid`, `record_uid`.

**Examples:**

{% code expandable="true" %}

```ps1
PS > Unlink-KeeperNSFRecords -DownloadSampleUnlinks
PS > Unlink-KeeperNSFRecords -FilePath .\nsf-folder-records-unlink-batch.sample.json
```

{% endcode %}

</details>

<details>

<summary>Python CLI</summary>

**Command:** `nsf-rm`

**Parameters**:

`RECORD` Record UID(s) or title(s) to remove (max 500)\
`--folder` FOLDER Folder UID or name for operation context\
`--operation, -o` {owner-trash,folder-trash,unlink}\
Removal operation (default: owner-trash)\
`--force, -f` Skip confirmation after preview\
`--dry-run` Preview only; do not delete

**Example**:

```shellscript
My Vault> nsf-ln <record_uid> <folder_uid>
Record <record_uid> linked to folder <folder_uid>
```

</details>

<details>

<summary>Python SDK</summary>

**Function :** `remove_nsf_records`

```python
    RECORD_IDENTIFIERS = ["My NSF Login"]  # UIDs or titles
    OPERATION = "owner-trash"  # owner-trash, folder-trash, unlink
    FOLDER_UID_OR_NAME = None  # Required when OPERATION is unlink
    FORCE = True  # Skip confirmation after preview
    DRY_RUN = False  # Preview only

    if OPERATION == "unlink" and not FOLDER_UID_OR_NAME:
        raise ValueError('--folder is required when operation is "unlink"')

    removals = nsf_management.build_nsf_record_removals(
        vault,
        RECORD_IDENTIFIERS,
        operation_type=OPERATION,
        folder_uid=FOLDER_UID_OR_NAME,
    )
    preview = nsf_management.remove_nsf_records(vault, removals, dry_run=True)
    for pr in preview.preview_results:
        print(f"  {pr.item_uid}: {pr.error or 'ok to remove'}")
    if DRY_RUN:
        print("[Dry-run] No records were deleted.")
        return
    if not FORCE:
        answer = input("Proceed with deletion? [y/N]: ").strip().lower()
        if answer not in ("y", "yes"):
            print("Aborted.")
            return
    result = nsf_management.remove_nsf_records(vault, removals, dry_run=False)
    if result.confirmed:
        print("Record removal completed.")
    else:
        print("Record removal was not confirmed by the server.")
```

</details>

<details>

<summary>JavaScript SDK</summary>

**Function:** `removeNestedShareRecords`

```python
export async function removeNestedShareRecords(
    storage: InMemoryStorage,
    auth: Auth,
    input: RemoveNsfRecordInput
): Promise<RemoveNsfRecordResult> {
    const operation = normalizeOperation(input.operation)
    const dryRun = input.dryRun ?? false
    const removals = buildRemovals(storage, auth, input.records, input.folder, operation)
    try {
        const previewResponse = await executeRemove(auth, removals, RemoveAction.REMOVE_ACTION_PREVIEW)
        const preview = (previewResponse.results ?? []).map(mapPreviewItem)
        if (hasPreviewErrors(preview)) {
            throw new KeeperSdkError(
                formatRemoveNsfPreview(preview) || 'Removal preview failed.',
                ResultCodes.NSF_REMOVE_FAILED
            )
        }

```

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.keeper.io/keeperpam/commander-sdk/keeper-commander-sdks/sdk-command-reference/nested-shared-folder-commands/nsf-folders-commands.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
