# Enterprise Node Commands

#### Overview <a href="#usage-3" id="usage-3"></a>

A *node* is essentially an organisational unit used to structure users, roles, teams, and provisioning/authentication methods.

**Usage**

```bash
enterprise-node command [--options] OR en command [--options]
```

**Alias:** `en`

#### Commands <a href="#commands-1" id="commands-1"></a>

The following commands are supported by Enterprise Node commands

<table><thead><tr><th width="229.7890625">Command</th><th>Description</th></tr></thead><tbody><tr><td><a href="#enterprise-node-view"><code>view</code></a></td><td>View enterprise nodes</td></tr><tr><td><a href="#enterprise-info-tree"><code>add</code></a></td><td>Create enterprise nodes</td></tr><tr><td><a href="#enterprise-info-tree-1"><code>edit</code></a></td><td>Edit enterprise nodes</td></tr><tr><td><a href="#enterprise-info-tree-2"><code>delete</code></a></td><td>Delete enterprise nodes</td></tr><tr><td><a href="#enterprise-info-tree-3"><code>set-logo</code></a></td><td>Set node logo</td></tr><tr><td><a href="#enterprise-node-invite-email"><code>invite-email</code></a></td><td>Set invitation email</td></tr><tr><td><a href="#enterprise-node-invite-email-1"><code>wipe-out</code></a></td><td>Wipe out node content</td></tr></tbody></table>

### Enterprise Node View Command

View enterprise node.

<details>

<summary>DotNet CLI</summary>

**Command**: `enterprise-node <node name> --command=tree OR en tree -v`

**Example:**

```sh
My Vault> enterprise-node DEVOPS --command=tree
```

</details>

<details>

<summary>DotNet SDK</summary>

**Function:** `EnterpriseData.Nodes`

```csharp
var nodes = enterpriseData.Nodes
                            .Where(x => string.Equals(x.DisplayName, arguments.Node, StringComparison.InvariantCultureIgnoreCase))
                            .ToArray();
```

</details>

<details>

<summary>PowerCommander</summary>

**Command :** `Get-KeeperEnterpriseNode`

**Aliases:** `ken`

**Parameters:**

* `-Name` - User email.
* `-Filter` - Search filter.
* `-Format` - Output format.
* `-Output` - Output file name.

**Examples:**:

<pre class="language-powershell"><code class="lang-powershell"># List all nodes
<strong>PS> Get-KeeperEnterpriseNode
</strong><strong>----------------------------------------
</strong># Get specific node
PS> Get-KeeperEnterpriseNode -Name Test1

# Search nodes
PS> Get-KeeperEnterpriseNode -Filter Test
</code></pre>

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node view`

**Parameter**:

`node` - Node name or UID (required)

**Flag:**

* `-v`, `--verbose` - Print verbose information
* `--format` - Output format: `json`
* `--output` - Output filename

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
node = enterprise_data.nodes.get_entity(node_id) if isintance(node_id, int)
node = [node for node in enterprise_data.nodes.get_all_entities() if node.name.lower() == node_id]  if isintance(node_id, str)
```

</details>

### Enterprise Node Add Command <a href="#enterprise-info-tree" id="enterprise-info-tree"></a>

Create enterprise node(s).

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=add <name> --parent "<main node>"`

**Alias :**`en --command=add <name>`

**Options**:

* `--parent <node>` - Parent node name or ID
* `--name <name>` - New node display name (for add/update)
* `-v, --verbose` - Show node IDs and additional info
* `--toggle-isolated` - Toggle node isolation (restrict visibility)

**Example:**

```shellscript
My Vault> enterprise-node --command=add "Engineering"
OR
My Vault> en --command=add "Isolated Team" --toggle-isolated
```

</details>

<details>

<summary>DotNet SDK</summary>

**Function:** `CreateNode`

```csharp
public static async Task<EnterpriseNode> CreateNode(this EnterpriseData enterpriseData, string nodeName, EnterpriseNode parentNode = null)
```

**Example:**

```csharp
var node = await enterpriseData.CreateNode(arguments.Node, parentNode);
```

</details>

<details>

<summary>PowerCommander</summary>

**Command:** `New-KeeperEnterpriseNode`

**Aliases:** `kena`

**Syntax:**

```powershell
New-KeeperEnterpriseNode [-NodeName] <string> [[-ParentNode] <string>] [<CommonParameters>]
```

**Parameters:**

* `-NodeName` - Node name
* `-ParentNode` - Parent node ID

**Example:**

```powershell
PS> New-KeeperEnterpriseNode -ParentNode "parent" -NodeName "MyNode"
OR 
kena "DevOps" -ParentNode 12345
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node add`

**Parameter**:

`node` - Node Name. Can be repeated. (required)

**Flag:**

* `--parent` - Parent node name or ID
* `--name`, `--displayname` - Set node display name
* `--set-isolated` - Set node isolated: `on` or `off`
* `-f`, `--force` - Do not prompt for confirmation

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
from keepersdk.enterprise import batch_management,  enterprise_management

node_names = list['names of nodes to be created']
nodes_to_add = [enterprise_management.NodeEdit(
    node_id=enterprise_loader.get_enterprise_id(), name=node_name, parent_id=parent_node_id,
    restrict_visibility=is_isolated)
    for node_name in node_names]
batch = batch_management.BatchManagement(loader=enterprise_loader, logger=enterprise_manager_logger)
batch.modify_nodes(to_add=nodes_to_add)
batch.apply()
```

</details>

### Enterprise Node Edit Command <a href="#enterprise-info-tree" id="enterprise-info-tree"></a>

Edit enterprise node(s).

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=update [--options]`

**Alias :** `en --command=update [--options]`

**Options**:

* `--parent <node>` - Parent node name or ID
* `--name <name>` - New node display name (for add/update)
* `-v, --verbose` - Show node IDs and additional info
* `--toggle-isolated` - Toggle node isolation (restrict visibility)

**Example:**

```sh
# Update node
enterprise-node --command=update "Engineering" --name "Engineering Dept"
enterprise-node update 12345 --parent "IT"
en update "Sales" --toggle-isolated  
```

</details>

<details>

<summary>DotNet SDK</summary>

**Function**: `UpdateNode`

```csharp
public static async Task UpdateNode(this EnterpriseData enterpriseData, EnterpriseNode node, EnterpriseNode newParentNode = null)
```

**Example:**

```csharp
await enterpriseData.UpdateNode(node, parentNode);
```

</details>

<details>

<summary>PowerCommander</summary>

**Command:** `Edit-KeeperEnterpriseNode`

**Aliases:** `kenu`

**Usage:**

```powershell
Edit-KeeperEnterpriseNode [-Node] <string> 
                          [-NewNodeName <string>] 
                          [-ParentNode <string>] 
                          [-RestrictVisibility] 
                          [<CommonParameters>]
```

**Parameters:**

| Parameter | Description                                                             |
| --------- | ----------------------------------------------------------------------- |
| `-Node`   | Node name or ID to update. This is a positional parameter (position 0). |

**Options:**

| Option                | Description                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------------------- |
| `-NewNodeName`        | New name for the node. Use this to rename an existing node.                                     |
| `-ParentNode`         | New parent Node name or ID. Use this to move the node to a different location in the hierarchy. |
| `-RestrictVisibility` | Enable node isolation. When enabled, restricts visibility to users outside the node.            |

**Example:**

```powershell
PS> Get-KeeperEnterpriseNode                                                                         

Id              DisplayName        ParentNodeName  RestrictVisibility Provisioning
--              -----------        --------------  ------------------ ------------
894448414228482 MS.                                False              
894448414228541 Test node                          False              

PS> Edit-KeeperEnterpriseNode -Node "Test node" -NodeName "test_node_updated2" -ParentNode "MS" -RestrictVisibility        
Node "test_node_updated2" updated.
Node Isolation: ON
PS> Get-KeeperEnterpriseNode                                                                                       
        
Id              DisplayName        ParentNodeName  RestrictVisibility Provisioning
--              -----------        --------------  ------------------ ------------
894448414228482 MS                                 False              
894448414228541 test_node_updated2 MS              True               

```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node edit`

**Parameter**:

`node` - Node Name or ID. Can be repeated. (required)

**Flag:**

* `--parent` - Parent node name or ID
* `--name`, `--displayname` - Set node display name
* `--set-isolated` - Set node isolated: `on` or `off`

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
from keepersdk.enterprise import batch_management,  enterprise_management

node = enterprise_data.nodes.get_entity(node_id)
node_list = [node]
nodes_to_update = [enterprise_management.NodeEdit(
    node_id=node.node_id, name=display_name, parent_id=node.parent_id, restrict_visibility=is_isolated)
    for node in node_list]
batch = batch_management.BatchManagement(loader=enterprise_loader, logger=enterprise_manager_logger)
batch.modify_nodes(to_update=nodes_to_update)
batch.apply()
```

</details>

### Enterprise Node Delete Command <a href="#enterprise-info-tree" id="enterprise-info-tree"></a>

Delete enterprise node(s).

<details>

<summary>DotNet CLI</summary>

**Command** : `enterprise-node --command=delete <node name>`

**Alias :** `en --command=delete <node name>`

**Options:**

* `-f, --force` - Force reload enterprise data

**Example**:

<pre><code># Delete node
<strong>My Vault> en --command=delete "Old Department" 
</strong>OR
enterprise-node --command=delete "Old Department"
enterprise-node --command=delete 12345
</code></pre>

</details>

<details>

<summary>DotNet SDK</summary>

**Function:** `DeleteNode`

<pre><code><strong>await enterpriseData.DeleteNode(node.Id);
</strong>public static async Task DeleteNode(this EnterpriseData enterpriseData, long nodeId)
</code></pre>

</details>

<details>

<summary>PowerCommander</summary>

**Command:** `Remove-KeeperEnterpriseNode`

**Aliases:** `kend`

**Parameters:**

<table><thead><tr><th width="159.015625">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>Node</code></td><td>Node name or ID to delete. Can be the node's display name or numeric node ID</td></tr><tr><td><code>Force</code></td><td>Skip confirmation prompt. When specified, deletes the node without asking for confirmation</td></tr></tbody></table>

**Usage:**

```powershell
PS > Remove-KeeperEnterpriseNode -Node "Old Department"
PS > kend "Old Department"
```

**Example:**

```powershell
PS> Remove-KeeperEnterpriseNode -Node "test_node_1"                 

Confirm
Are you sure you want to perform this action?
Performing the operation "Delete Enterprise Node" on target "test_node_1".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): a
Node "test_node_1" deleted successfully.
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node delete`

**Parameter**:

`node` - Node Name or ID (required)

**Flag:**

* `--logo-file` - Sets company logo using local image file (max size: 500 kB, min dimensions: 10x10, max dimensions: 320x320)

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
from keepersdk.enterprise import batch_management,  enterprise_management

node = enterprise_data.nodes.get_entity(node_id)
node_list = [node]
batch = batch_management.BatchManagement(loader=enterprise_loader, logger=enterprise_manager_logger)
batch.modify_nodes(to_remove=(enterprise_management.NodeEdit(node_id=node.node_id) for node in node_list))
batch.apply()
```

</details>

### Enterprise Node Set Logo Command <a href="#enterprise-info-tree" id="enterprise-info-tree"></a>

Set enterprise node logo.

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=<action> <node_name> --logo-type=<logo_type> --logo-path=<upload_logo_path> OR en --command=<action> <node_name> --logo-type=<logo_type> --logo-path=<upload_logo_path>`

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr><tr><td><code>logo-type</code></td><td>Type of the logo Ex:- vault or email</td></tr><tr><td><code>logo-path</code></td><td>Upload file path</td></tr></tbody></table>

**Example:**

```sh
My Vault> en --command="upload-custom-logo" "Test" --logo-type="vault" --logo-path="<logo_path>" 
```

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>DotNet SDK</summary>

**Set Custom Invitation to Node:**

**Function:** `UploadEnterpriseCustomLogo`

**Usage:**

{% code overflow="wrap" %}

```csharp
public static async Task<CheckEnterpriseCustomLogoUploadResponse> UploadEnterpriseCustomLogo(this EnterpriseData enterpriseData, long nodeId, string logoType, string filePath)
```

{% endcode %}

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr><tr><td><code>logoType</code></td><td>Type of the logo Ex:- vault or email</td></tr><tr><td><code>filePath</code></td><td>Upload file path</td></tr></tbody></table>

**Example:**

{% code overflow="wrap" %}

```csharp
await EnterpriseManagementExamples.EnterpriseNodeExamples.SetEnterpriseCustomLogoExample.SetEnterpriseCustomLogoExample(70411693850884, "vault", "<file_path>");
```

{% endcode %}

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>PowerCommander</summary>

**Command:** `Set-KeeperEnterpriseNodeCustomLogo`

**Flags**:

<table><thead><tr><th width="198.5810546875">Flag</th><th>Description</th></tr></thead><tbody><tr><td><code>Node</code></td><td>Node name or ID</td></tr><tr><td><code>LogoType</code></td><td>Logo Type (eg: vault , email)</td></tr><tr><td><code>LogoPath</code></td><td>Path to the logo file</td></tr></tbody></table>

**Example:**

```
PS > Set-KeeperEnterpriseNodeCustomLogo -Node PCTNode -LogoType vault -LogoPath /Users/satish/Desktop/dotnet-reference/keeper-sdk-dotnet/download1.jpg
Custom logo uploaded for node "PCTNode"

LogoPath   : /vault/logo/nycE_9wCsOg
Status     : active
IsSuccess  : True
result     : success
resultCode : 
message    : 
command    : check_vault_logo_upload
```

</details>

<details>

<summary>Python CLI</summary>

**Command**: `enterprise-node set-logo`

**Parameters**:

* `node` : Node Name or ID
* `--logo-file` : Sets company logo using local image file (max size: 500 kB, min dimensions:

10x10, max dimensions: 320x320)

**Example:**

```sh
My Vault> enterprise-node set-logo <node_uid> --logo-file="logo.jpg"
```

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
from keepersdk.vault import attachment

upload_task = attachment.FileUploadTask(logo_filepath)
upload_task.prepare()
# Check file MIME-type and size
if upload_task.mime_type not in {'image/jpeg', 'image/png', 'image/gif'}:
    raise Exception('File must be a JPEG, PNG, or GIF image')
if upload_task.size > 500000:
    raise Exception('Filesize must be less than 500 kB')
rq_logo = {
    'command': f'request_{logo_type}_logo_upload',
    'node_id': node_id,
}
rs_logo = KeeperAuth_obj.execute_auth_command(rq_logo)
# Construct POST request for upload
upload_id = rs_logo.get('upload_id')
upload_url = rs_logo.get('url')
assert isinstance(upload_url, str)
success_status_code = rs_logo.get('success_status_code')
file_param: Optional[str] = rs_logo.get('file_parameter')
assert file_param is not None
form_data = rs_logo.get('parameters')
assert isinstance(form_data, dict)
form_data['Content-Type'] = upload_task.mime_type
with upload_task.open() as task_stream:
    files = {file_param: (None, task_stream, upload_task.mime_type)}
    upload_rs = requests.post(upload_url, files=files, data=form_data)
    if upload_rs.status_code == success_status_code:
        # Verify file upload
        check_rq = {
            'command': f'check_{logo_type}_logo_upload',
            'node_id': node_id,
            'upload_id': upload_id
        }
        while True:
            check_rs = KeeperAuth_obj.execute_auth_command(check_rq)
            check_status = check_rs.get('status')
            if check_status == 'pending':
                time.sleep(2)
            else:
                if check_status != 'active':
                    if check_status == 'invalid_dimensions':
                        raise Exception('Image dimensions must be between 10x10 and 320x320')
                    else:
                        raise Exception(f'Upload status = {check_status}')
                else:
                    get_logger().info('File "%s" set as %s logo.', logo_fp, logo_type)
                    break
    else:
        raise Exception(f'HTTP status code: {upload_rs.status_code}, expected {success_status_code}')
```

</details>

### Enterprise Node Set Custom Invite Email Command <a href="#enterprise-node-invite-email" id="enterprise-node-invite-email"></a>

Set invitation email.

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=<action> <node_name> --json-file-path="<file_path>" OR en --command=<action> <node_name> --json-file-path="<file_path>"`

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr><tr><td><code>jsonFilePath</code></td><td>create a json file with <code>subject</code> , <code>header</code>, <code>body</code>, <code>buttonLabel</code> and give path here.</td></tr></tbody></table>

**Examples:**

```sh
My Vault> enterprise-node --command="set-custom-invitation" "Test" --json-file-path="<file_path>"
```

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>DotNet SDK</summary>

**Set Custom Invitation to Node:**

**Function:** `SetEnterpriseCustomInvitation`

**Usage:**

{% code overflow="wrap" %}

```csharp
public static async Task SetEnterpriseCustomInvitation(this EnterpriseData enterpriseData, long nodeId, string jsonFilePath)
```

{% endcode %}

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr><tr><td><code>jsonFilePath</code></td><td>create a json file with <code>subject</code> , <code>header</code>, <code>body</code>, <code>buttonLabel</code> and give path here.</td></tr></tbody></table>

**Example:**

{% code overflow="wrap" %}

```csharp
await EnterpriseManagementExamples.EnterpriseNodeExamples.SetEnterpriseCustomInvitationExample.SetEnterpriseCustomInvitationExample(70411693850884, "<Path_to_jsonFile>");
```

{% endcode %}

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>PowerCommander</summary>

**Command**: `Set-KeeperEnterpriseNodeCustomInvitation`

**Flags:**

<table><thead><tr><th width="227.8876953125"></th><th></th></tr></thead><tbody><tr><td><code>Node</code></td><td>Node Name or ID</td></tr><tr><td><code>JsonFilePath</code></td><td>Path to JSON file containing invitation template (subject, header, body, buttonLabel)</td></tr></tbody></table>

**Example:**

```
PS> Set-KeeperEnterpriseNodeCustomInvitation -Node PCTNode -JsonFilePath "/Users/xxaaeafd/Desktop/dotnet-reference/keeper-sdk-dotnet/testfile.json"
Custom invitation set for node "PCTNode"
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node invite-email`

**Parameter**:

`node` - Node Name or ID (required)

**Flag:**

* `-f`, `--force` - Do not prompt for confirmation
* `--invite-email` - Sets invite email template from file. Saves current template if file does not exist. Use dash (-) for stdout

</details>

<details>

<summary>Python SDK</summary>

**Function**: Not supported

</details>

### Enterprise Node Wipe Out Command <a href="#enterprise-node-invite-email" id="enterprise-node-invite-email"></a>

**Wipe-out** removes all content under a given enterprise node:

<table><thead><tr><th width="237.9990234375">What is removed</th><th>Description</th></tr></thead><tbody><tr><td><strong>Role–user links</strong></td><td>All users are removed from every role that belongs to the node or its descendants.</td></tr><tr><td><strong>Role–managed-node links</strong></td><td>All managed-node associations for those roles are removed.</td></tr><tr><td><strong>Roles</strong></td><td>All roles whose parent node is the target or a descendant are deleted.</td></tr><tr><td><strong>Users</strong></td><td>All users whose parent node is the target or a descendant are deleted.</td></tr><tr><td><strong>Teams</strong></td><td>All teams (and in .NET CLI, queued teams) under the node are deleted.</td></tr><tr><td><strong>Subnodes</strong></td><td>All child nodes under the target node are deleted.</td></tr></tbody></table>

The **target node itself is not deleted**; it is left empty. The **root node cannot be wiped out**.

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=wipe-out <node>`

<table><thead><tr><th width="227.8046875">Argument</th><th>Description</th></tr></thead><tbody><tr><td><code>--command=wipe-out</code></td><td>Subcommand that selects the wipe-out action.</td></tr><tr><td><code>&#x3C;node></code></td><td>Node name or node ID to wipe out. Required for <code>wipe-out</code>.</td></tr></tbody></table>

**Examples:**

```shellscript
enterprise-node --command=wipe-out "Sales"
# or using alias
en --command=wipe-out "Sales"
```

</details>

<details>

<summary>DotNet SDK</summary>

Coming Soon

</details>

<details>

<summary>PowerCommander</summary>

**Command :** `Invoke-KeeperEnterpriseNodeWipeOut`

**Alias :** `kenwipe`

**Parameters**

<table><thead><tr><th width="117.08203125">Parameter</th><th width="135.357421875">Mandatory</th><th>Description</th></tr></thead><tbody><tr><td><code>Node</code></td><td>Yes</td><td>Node name or node ID to wipe out.</td></tr><tr><td><code>Force</code></td><td>No</td><td>Skip the confirmation prompt. Use with caution.</td></tr></tbody></table>

**Examples**

```powershell
PowerCommander> Invoke-KeeperEnterpriseNodeWipeOut -Node Test1

Confirm
Are you sure you want to perform this action?
Performing the operation "Wipe out" on target "Node "Test1" and all its content".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): a
WARNING: This action cannot be undone.
Node "Test1" and its content have been wiped out.
```

</details>

<details>

<summary>Python CLI</summary>

**Command:** `enterprise-node wipe-out`

**Parameter:**

* `node` - Node Name or ID (required)

**Warning:** This action cannot be undone and will remove all users, roles, teams, and subnodes.

</details>

<details>

<summary>Python SDK</summary>

**Function:**

```python
from keepersdk.enterprise import batch_management,  enterprise_management

node = enterprise_data.nodes.get_entity(node_id)
if node.node_id == enterprise_data.root_node.node_id:
    raise ValueError('Cannot wipe out root node')

subnode_lookup: Dict[int, List[int]] = {}
for n in enterprise_data.nodes.get_all_entities():
    parent_id = n.parent_id or 0
    if parent_id not in subnode_lookup:
        subnode_lookup[parent_id] = []
    subnode_lookup[parent_id].append(n.node_id)

sub_nodes = [node.node_id]
pos = 0
while pos < len(sub_nodes):
    if sub_nodes[pos] in subnode_lookup:
        sub_nodes.extend(subnode_lookup[sub_nodes[pos]])
    pos += 1
nodes = set(sub_nodes)

batch = batch_management.BatchManagement(loader=enterprise_loader, logger=enterprise_manager_logger)

roles = {x.role_id for x in enterprise_data.roles.get_all_entities() if x.node_id in nodes}
users = {x.enterprise_user_id for x in enterprise_data.users.get_all_entities() if x.node_id in nodes}

role_users = [enterprise_management.RoleUserEdit(role_id=x.role_id, enterprise_user_id=x.enterprise_user_id)
                for x in enterprise_data.role_users.get_all_links() if
                x.role_id in roles or x.enterprise_user_id in users]
if len(role_users) > 0:
    batch.modify_role_users(to_remove=role_users)

managed_nodes = [enterprise_management.ManagedNodeEdit(role_id=x.role_id, managed_node_id=x.managed_node_id)
                    for x in enterprise_data.managed_nodes.get_all_links() if
                    x.managed_node_id in nodes or x.role_id in roles]
if len(managed_nodes) > 0:
    batch.modify_managed_nodes(to_remove=managed_nodes)

roles_to_remove = [enterprise_management.RoleEdit(role_id=x) for x in roles]
if len(roles) > 0:
    batch.modify_roles(to_remove=roles_to_remove)

users_to_remove = [enterprise_management.UserEdit(enterprise_user_id=x) for x in users]
if len(users_to_remove) > 0:
    batch.modify_users(to_remove=users_to_remove)

queued_teams = [enterprise_management.TeamEdit(team_uid=x.team_uid)
                for x in enterprise_data.queued_teams.get_all_entities() if x.node_id in nodes]
if len(queued_teams) > 0:
    batch.modify_teams(to_remove=queued_teams)

teams = [enterprise_management.TeamEdit(team_uid=x.team_uid)
            for x in enterprise_data.teams.get_all_entities() if x.node_id in nodes]
if len(teams) > 0:
    batch.modify_teams(to_remove=teams)

sub_nodes.pop(0)
sub_nodes.reverse()
nodes_to_remove = [enterprise_management.NodeEdit(node_id=x) for x in sub_nodes]
if len(nodes_to_remove) > 0:
    batch.modify_nodes(to_remove=nodes_to_remove)

batch.apply()
```

</details>

### Enterprise Node Get Custom Email Invitation Data Command

This command/function helps to get the custom invitation template of a node.

<details>

<summary>DotNet CLI</summary>

**Command:** `enterprise-node --command=<action> <node_name> OR en --command=<action> <node_name>`

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr></tbody></table>

**Examples:**

```sh
My Vault> enterprise-node --command="get-custom-invitation" "Test"   
```

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>DotNet SDK</summary>

**Set Custom Invitation to Node:**

**Function:** `GetEnterpriseCustomInvitation`

**Usage:**

{% code overflow="wrap" %}

```csharp
public static async Task<GetEnterpriseCustomInvitationResponse> GetEnterpriseCustomInvitation(this EnterpriseData enterpriseData, long nodeId)
```

{% endcode %}

**Parameters:**

<table><thead><tr><th width="227.4921875"></th><th>Description</th></tr></thead><tbody><tr><td><code>nodeId</code></td><td>EnterpriseNode ID representing the node</td></tr></tbody></table>

**Example:**

{% code overflow="wrap" %}

```csharp
await EnterpriseManagementExamples.EnterpriseNodeExamples.GetEnterpriseCustomInvitationExample.GetEnterpriseCustomInvitationExample(70411693850884);
```

{% endcode %}

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>PowerCommander</summary>

**Command**: `Get-KeeperEnterpriseNodeCustomInvitation`

**Flags:**

<table><thead><tr><th width="227.8876953125"></th><th></th></tr></thead><tbody><tr><td><code>Node</code></td><td>Node Name or ID</td></tr><tr><td><code>JsonFilePath</code></td><td>Path to JSON file containing invitation template (subject, header, body, buttonLabel)</td></tr></tbody></table>

**Example:**

```
PS> Get-KeeperEnterpriseNodeCustomInvitation -Node PCTNode                                                                                       
Custom invitation for node "PCTNode":
Subject: You're Invited to Join
Header: Welcome to Our Portal
Body: Click the button below to create your Keeper account and start protecting your passwords.
Button Label: Create Account

Subject     : You're Invited to Join
Header      : Welcome to Our Portal
Body        : Click the button below to create your Keeper account and start protecting your passwords.
ButtonLabel : Create Account
LogoPath    : 
IsSuccess   : True
result      : success
resultCode  : 
message     : 
command     : get_enterprise_custom_invitation
```

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>Python CLI</summary>

Comming Soon

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>

<details>

<summary>Python SDK</summary>

Comming Soon

**Reference:**

[Commander Reference](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/enterprise-management-commands#changing-role-enforcements-and-privileges)

</details>
