Manage Team Drives

Much of the information you'll need to get started creating and managing Team Drives is detailed in the Team Drives reference. Here are a few more important considerations when working with Team Drives.

Creating Team Drives

Use the teamdrives.create to create a new Team Drive.

Java

TeamDrive teamDriveMetadata = new TeamDrive();
teamDriveMetadata.setName("Project Resources");
String requestId = UUID.randomUUID().toString();
TeamDrive teamDrive = driveService.teamdrives().create(requestId,
    teamDriveMetadata)
    .execute();
System.out.println("Team Drive ID: " + teamDrive.getId());

Python

team_drive_metadata = {'name': 'Project Resources'}
request_id = str(uuid.uuid4())
team_drive = drive_service.teamdrives().create(body=team_drive_metadata,
                                               requestId=request_id,
                                               fields='id').execute()
print 'Team Drive ID: %s' % team_drive.get('id')

PHP

$teamDriveMetadata = new Google_Service_Drive_TeamDrive(array(
    'name' => 'Project Resources'));
$requestId = Uuid::uuid4()->toString();
$teamDrive = $driveService->teamdrives->create($requestId, $teamDriveMetadata, array(
    'fields' => 'id'));
printf("Team Drive ID: %s\n", $teamDrive->id);

.NET

var teamDriveMetadata = new TeamDrive()
{
    Name = "Project Resources"
};
var requestId = System.Guid.NewGuid().ToString();
var request = driveService.Teamdrives.Create(teamDriveMetadata, requestId);
request.Fields = "id";
var teamDrive = request.Execute();
Console.WriteLine("Team Drive ID: " + teamDrive.Id);

Ruby

team_drive_metadata = {
    name: 'Project Resources'
}
request_id = SecureRandom.uuid
team_drive = drive_service.create_teamdrive(request_id,
                                            team_drive_metadata,
                                            fields: 'id')
puts "Team Drive Id: #{team_drive.id}"

Node.js

var teamDriveMetadata = {
  'name': 'Project resources'
};
var requestId = uuid.v4();
drive.teamdrives.create({
  resource: teamDriveMetadata,
  requestId: requestId,
  fields: 'id'
}, function (err, teamDrive) {
  if (err) {
    // Handle error
    console.error(err);
  } else {
    console.log('Team Drive Id: ', teamDrive.id);
  }
});

Calls to teamdrives.create are idempotent. The requestId parameter identifies the logical attempt to create the Team Drive. If the request times out or returns an indeterminant backend error, the same request may be repeated. The requestId and body of the request must remain the same.

If the Team Drive was successfully created on a previous request or as a result of a retry, the normal response is returned. In some cases, such as after a prolonged period of time or if the body of the request has changed, a 409 error may be returned indicating the requestId must be discarded.

Managing members and permissions

Add or remove Team Drive member using the permissions collection.

To add a member, create the permission on the Team Drive itself. Permission methods can also be used on individual files within a Team Drive to grant members additional privileges or allow non-members to collaborate on specific items.

See manage sharing for additional details and sample code.

Deleting Team Drives

Use the teamdrives.delete method to remove a Team Drive. All content in the Team Drive must be trashed or deleted prior to deleting the Team Drive.

Managing Team Drives for domain administrators

Use the useDomainAdminAccess parameter with the teamdrives and permissions resources to manage Team Drives across an organization.

Users calling these methods with useDomainAdminAccess=true must have the Drive and Docs administrator privilege. Administrators can search for Team Drives or update permissions for Team Drives owned by their organization, regardless of the admin's membership in any given Team Drive.

The following example demonstrates how to use these resources to recover Team Drives that no longer have an organizer.

Java

// Find all Team Drives without an organizer and add one.
// Note: This example does not capture all cases. Team Drives
// that have an empty group as the sole organizer, or an
// organizer outside the organization are not captured. A
// more exhaustive approach would evaluate each Team Drive
// and the associated permissions and groups to ensure an active
// organizer is assigned.
String pageToken = null;
Permission newOrganizerPermission = new Permission()
    .setType("user")
    .setRole("organizer")
    .setEmailAddress("user@example.com");

do {
  TeamDriveList result = driveService.teamdrives().list()
      .setQ("organizerCount = 0")
      .setFields("nextPageToken, teamDrives(id, name)")
      .setUseDomainAdminAccess(true)
      .setPageToken(pageToken)
      .execute();
  for (TeamDrive teamDrive : result.getTeamDrives()) {
    System.out.printf("Found Team Drive without organizer: %s (%s)\n",
        teamDrive.getName(), teamDrive.getId());
    // Note: For improved efficiency, consider batching
    // permission insert requests
    Permission permissionResult = driveService.permissions()
        .create(teamDrive.getId(), newOrganizerPermission)
        .setUseDomainAdminAccess(true)
        .setSupportsTeamDrives(true)
        .setFields("id")
        .execute();
    System.out.printf("Added organizer permission: %s\n",
        permissionResult.getId());

  }
  pageToken = result.getNextPageToken();
} while (pageToken != null);

Python

# Find all Team Drives without an organizer and add one.
# Note: This example does not capture all cases. Team Drives
# that have an empty group as the sole organizer, or an
# organizer outside the organization are not captured. A
# more exhaustive approach would evaluate each Team Drive
# and the associated permissions and groups to ensure an active
# organizer is assigned.
page_token = None
new_organizer_permission = {
    'type': 'user',
    'role': 'organizer',
    'emailAddress': 'user@example.com'
}

while True:
    response = drive_service.teamdrives().list(
            q='organizerCount = 0',
            fields='nextPageToken, teamDrives(id, name)',
            useDomainAdminAccess = True,
            pageToken=page_token).execute()
    for team_drive in response.get('teamDrives', []):
        print 'Found Team Drive without organizer: %s (%s)' % (
            team_drive.get('title'), team_drive.get('id'))
        permission = drive_service.permissions().create(
                fileId=team_drive.get('id'),
                body=new_organizer_permission,
                useDomainAdminAccess = True,
                supportsTeamDrives = True,
                fields='id').execute()
        print 'Added organizer permission: %s ' % (permission.get('id'))

    page_token = response.get('nextPageToken', None)
    if page_token is None:
        break

PHP

// Find all Team Drives without an organizer and add one.
// Note: This example does not capture all cases. Team Drives
// that have an empty group as the sole organizer, or an
// organizer outside the organization are not captured. A
// more exhaustive approach would evaluate each Team Drive
// and the associated permissions and groups to ensure an active
// organizer is assigned.
$pageToken = null;
$newOrganizerPermission = new Google_Service_Drive_Permission(array(
    'type' => 'user',
    'role' => 'organizer',
    'emailAddress' => 'user@example.com'
));

do {
    $response = $driveService->teamdrives->listTeamdrives(array(
        'q' => 'organizerCount = 0',
        'fields' => 'nextPageToken, teamDrives(id, name)',
        'useDomainAdminAccess' => true,
        'pageToken' => $pageToken
    ));
    foreach ($response->teamDrives as $teamDrive) {
        printf("Found Team Drive without organizer: %s (%s)\n",
            $teamDrive->name, $teamDrive->id);
        $permission = $driveService->permissions->create($teamDrive->id,
            $newOrganizerPermission,
            array(
                'fields' => 'id',
                'useDomainAdminAccess' => true,
                'supportsTeamDrives' => true
            ));
        printf("Added organizer permission: %s\n", $permission->id);
    }
    $pageToken = $repsonse->pageToken;
} while ($pageToken != null);

.NET

// Find all Team Drives without an organizer and add one.
// Note: This example does not capture all cases. Team Drives
// that have an empty group as the sole organizer, or an
// organizer outside the organization are not captured. A
// more exhaustive approach would evaluate each Team Drive
// and the associated permissions and groups to ensure an active
// organizer is assigned.
string pageToken = null;
var newOrganizerPermission = new Permission()
{
    Type = "user",
    Role = "organizer",
    EmailAddress = "user@example.com"
};

do
{
    var request = driveService.Teamdrives.List();
    request.UseDomainAdminAccess = true;
    request.Q = "organizerCount = 0";
    request.Fields = "nextPageToken, teamDrives(id, name)";
    request.PageToken = pageToken;
    var result = request.Execute();
    foreach (var teamDrive in result.TeamDrives)
    {
        Console.WriteLine(string.Format(
               "Found abandoned Team Drive: {0} ({1})",
               teamDrive.Name, teamDrive.Id));
        // Note: For improved efficiency, consider batching
        // permission insert requests
        var permissionRequest = driveService.Permissions.Create(
          newOrganizerPermission,
          teamDrive.Id
        );
        permissionRequest.UseDomainAdminAccess = true;
        permissionRequest.SupportsTeamDrives = true;
        permissionRequest.Fields = "id";
        var permissionResult = permissionRequest.Execute();
        Console.WriteLine(string.Format(
               "Added organizer permission: {0}", permissionResult.Id));

    }
    pageToken = result.NextPageToken;
} while (pageToken != null);

Ruby

# Find all Team Drives without an organizer and add one.
# Note: This example does not capture all cases. Team Drives
# that have an empty group as the sole organizer, or an
# organizer outside the organization are not captured. A
# more exhaustive approach would evaluate each Team Drive
# and the associated permissions and groups to ensure an active
# organizer is assigned.
new_organizer_permission = {
    type: 'user',
    role: 'organizer',
    email_address: 'user@example.com'
}

team_drives = drive_service.fetch_all(items: :team_drives) do |page_token|
  drive_service.list_teamdrives(
      q: 'organizerCount = 0',
      fields: 'nextPageToken, teamDrives(id, name)',
      use_domain_admin_access: true,
      page_token: page_token)
end

for team_drive in team_drives
  puts "Found Team Drive without organizer: #{team_drive.name} #{team_drive.id}"
  permission = drive_service.create_permission(team_drive.id,
                                               new_organizer_permission,
                                               use_domain_admin_access: true,
                                               supports_team_drives: true,
                                               fields: 'id')
  puts "Added organizer permission: {permission.id}"
end

Node.js

var newOrganizerPermission = {
  type: 'user',
  role: 'organizer',
  emailAddress: 'user@example.com'
};

var pageToken;
// Using the npm module 'async'
async.doWhilst(function (callback) {
  drive.teamdrives.list({
    q: "organizerCount = 0",
    fields: 'nextPageToken, teamDrives(id, name)',
    useDomainAdminAccess: true,
    pageToken: pageToken
  }, function (err, res) {
    if (err) {
      // Handle error
      console.error(err);
      callback(err)
    } else {
      async.eachSeries(res.teamDrives, function (teamDrive, callback) {
        console.log('Found Team Drive without organizer:',
            teamDrive.name, teamDrive.id);
        drive.permissions.create({
          resource: newOrganizerPermission,
          fileId: teamDrive.id,
          useDomainAdminAccess: true,
          supportsTeamDrives: true,
          fields: 'id'
        }, callback);
      }, callback);
      pageToken = res.nextPageToken;
    }
  });
}, function () {
  return !!pageToken;
}, function (err) {
  if (err) {
    // Handle error
    console.error(err);
  } else {
    // All pages fetched
  }
});

Additional considerations when listing and managing Team Drives

When searching for Team Drives with the teamdrives.list to audit Team Drives, consider the following statements.

  1. A Team Drive with an organizerCount of zero can only be managed by an administrator.
  2. The Team Drive resource for a Team Drive with a memberCount of zero can only be accessed by an administrator.
  3. A Team Drive with an organizerCount or memberCount greater than zero may still only be accessed by an administrator if the remaining permissions are for empty groups, or external users that were added prior to disabling sharing outside the domain.
  4. The organizerCount and memberCount fields do not distinguish between members of the organization and external members.
  5. Files inside a Team Drive with a memberCount of zero can still be accessed by entities written on the file permission.

Send feedback about...

Drive REST API
Drive REST API