# Migrate

{% hint style="warning" %}
You will need to [install](https://documentation.grax.com/reuse-data/managed-package/second-generation/install) the second-generation GRAX Managed Package, and [uninstall](https://documentation.grax.com/reuse-data/managed-package/first-generation/uninstall) the first-generation Managed Package during the migration process.
{% endhint %}

The primary blocker when switching between generations of the Managed Package is managing the access that users have to GRAX features and components. The first-generation package includes legacy permission sets that can be used to control user access, but the second-generation relies on permission sets created by the GRAX application during Auto Config. When removing the first-generation package, users assigned the legacy permission sets need to be updated to the equivalent set to avoid interruptions.

For more details on GRAX's permissions model, see our [Roles for End Users](/other/permissions-and-access/roles-for-end-users.md) documentation.

For migration purposes, the non-defunct legacy permission sets map as follows:

| Old Permission Set Name  | New Permission Set Name          |
| ------------------------ | -------------------------------- |
| GRAX Configuration Admin | GRAX Console Admin Permission    |
| GRAX Advanced User       | GRAX Console Power Permission    |
| GRAX User                | GRAX Console Standard Permission |

All other legacy permission sets have no equivalent and are defunct. They can be dropped from users without consequence.

### Automatically Migrating Permission Sets

The following steps and script can be used to automatically perform the mapping shown above for all users in your org.

{% stepper %}
{% step %}

### Open the Developer Console

Documentation on how to open the console is available [here](https://help.salesforce.com/s/articleView?id=platform.code_dev_console_opening.htm\&type=5).

Once the console is open, expand the "Debug" menu and click "Open Execute Anonymous Window."
{% endstep %}

{% step %}

### Run the Script

Copy the following script into the "Enter Apex Code" dialog box.

```apex
private class GRAXLegacyPerm {
  Map<String, Id> psIDs;
  Map<String, Set<Id>> existingConsole;

  public GRAXLegacyPerm() {
    List<PermissionSet>lps=[
        SELECT Id, Name
        FROM PermissionSet
        WHERE name in ('GRAX_Configuration_Admin', 'GRAX_Advanced_User', 'GRAX_User', 'GRAX_Console_Admin_User', 'GRAX_Console_Power_User', 'GRAX_Console_Standard_User')
    ];

    psIDs = new Map<String, Id>();
    for(PermissionSet ps : lps){
        System.debug('PermissionSet '+ps.Name +' Id: ' + ps.Id);
        psIDs.put(ps.Name, ps.Id);
    }

    existingConsole = new Map<String, Set<Id>>();
    for (String name : new String[]{'GRAX_Console_Admin_User', 'GRAX_Console_Power_User', 'GRAX_Console_Standard_User'}) {
         List<PermissionSetAssignment> ecpsa = [
            SELECT AssigneeId
            FROM PermissionSetAssignment
            WHERE IsActive=true
              AND PermissionSetId = :psIDs.get(name)
        ];

        Set<Id> ecpsuID = new Set<Id>();

        for (PermissionSetAssignment a : ecpsa) {
            ecpsuID.add(a.AssigneeId);
        }
        existingConsole.put(name, ecpsuID);
        System.debug('Existing '+name +' User Ids: ' + ecpsa);

    }
  }

  public String migratePermSet(String oldPS, String newPS) {
    List<PermissionSetAssignment> migratePS  = new List<PermissionSetAssignment>();
    List<PermissionSetAssignment> lpsuID = [
        SELECT AssigneeId
        FROM PermissionSetAssignment
        WHERE IsActive=true
          AND PermissionSetId = :psIDs.get(oldPS)
          AND AssigneeId NOT IN :existingConsole.get(newPS)
    ];

    for(PermissionSetAssignment a : lpsuID){
        System.debug('Migrate '+oldPS+' User: ' + a.AssigneeId + ' to '+newPS);

        migratePS.add( new PermissionSetAssignment (
            PermissionSetId = psIDs.get(newPS),
            AssigneeId =  a.AssigneeId
        ));

        if( migratePS.size() > 200) {
            upsert migratePS;
            migratePS.clear();
        }
    }
    if( migratePS.size() > 0) {
        try {
            insert migratePS;
        } catch(DmlException e) {
            System.debug('error: ' + e);
        }
      migratePS.clear();

    }
    return 'done';
  }
}


GRAXLegacyPerm glp = new GRAXLegacyPerm();

glp.migratePermSet('GRAX_Configuration_Admin', 'GRAX_Console_Admin_User');
glp.migratePermSet('GRAX_Advanced_User', 'GRAX_Console_Power_User');
glp.migratePermSet('GRAX_User', 'GRAX_Console_Standard_User');
```

Click "Execute."
{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.grax.com/reuse-data/managed-package/first-generation/migrate.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
