Export (0) Print
Expand All
Add a Recycle Bin to Windows SharePoint Services for Easy Document Recovery
Use Windows SharePoint Services as a Platform for Building Collaborative Applications
Use Windows SharePoint Services as a Platform for Building Collaborative Apps, Part 2
Expand Minimize

How to Write a Back Up and Restore Application for SharePoint Portal Server 2003

SharePoint 2003
 

Michael Washam
Microsoft Corporation

January 2005

Applies to:
    Microsoft Office SharePoint Portal Server 2003

Summary: Learn how to programmatically write a complete disaster recovery application for a SharePoint Portal Server 2003 farm, including the backup and restoration of all SharePoint Portal Server 2003 and Windows SharePoint Services sites in the farm. (20 printed pages)

Download SPSBackupSample.EXE.

Contents

Introduction
Backing Up and Restoring Sites Programmatically
Sample Application: Walking Through the Code
Conclusion
Additional Resources

Introduction

Microsoft Office SharePoint Portal Server 2003 uses a group of products and technologies—Microsoft Office 2003, Microsoft SQL Server 2000 SP3, and Microsoft Windows SharePoint Services—to enable you to create a unified portal site that connects the entire organization. SharePoint Portal Server 2003 builds on top of Windows SharePoint Services architecture to provide additional functionality, such as enterprise integration, content management, organization, publication, and connected collaboration. However, because of differences in functionality between Windows SharePoint Services and SharePoint Portal Server 2003, you should use only SharePoint Portal Server tools to back up and restore sites created with SharePoint Portal Server.

The SharePoint Portal Server Data Backup and Restore utility is the SharePoint Portal Server tool you use to back up and restore sites created with SharePoint Portal Server 2003. You can access this utility from the SharePoint Portal Server group on the All Programs menu, on the server running SharePoint Portal Server. For information about backing up and restoring sites created with SharePoint Portal Server 2003, see the Microsoft Office SharePoint Portal Server 2003 Administrator's Guide.

Backing Up and Restoring Sites Programmatically

SharePoint Portal Server 2003 also offers a Backup and Restore API to enable customers and third parties to develop custom backup-and-restore applications. This API is contained in the mssctlbm.dll and mssitlbm.dll that are provided as private assemblies in SharePoint Portal Server 2003. You can find the Backup and Restore API in the following path on the SharePoint Portal Server 2003 CD:

\Products\Applications\Server\SharePoint Portal Server 2003\RTM\SPS\Files\PFiles\SPS\Bin 

Note   In spsbackup.dll, SharePoint Portal Server 2003 also offers other unmanaged code APIs that provide an IStream interface to back up and restore the computers running Indexing Service (formerly called Index Server). In addition, the SharePoint Portal Server object model contains support for backing up and restoring using the PrepareSiteForBackup() and Restore() methods of the PortalSite object.

The Backup and Restore sample application (SPSBackupSample.exe) that accompanies this article shows you how to use the Backup and Restore API to back up and restore SharePoint Portal Server sites and any Windows SharePoint Services sites, if they are installed on the SharePoint Portal Server Web servers. The Backup and Restore API has the same basic functionality as SPSBackupSample.exe. The sample is written using Microsoft Visual C++ 7.1.

Note   Because the SharePoint Portal Server 2003 documentation in the Microsoft SharePoint Products and Technologies 2003 SDK does not address the Backup and Restore API, you can use this article to help you write your own backup and restore applications using the API. However, you should use the sample that accompanies this article (download link provided at start of the article) only as a prototype application; the sample is not designed to be used in a production environment.

Running the Backup and Restore Sample

Before we delve into the code, you should run the sample application and see how it works. Download SPSBackupSample.EXE and build the application (SPSBackupSample) on a computer running SharePoint Portal Server 2003 and the Platform SDK. You should use this sample only on a front-end Web server running SharePoint Portal Server 2003.

To run the sample

  1. Start the backup process: In a Command Prompt window, type <SampleLocation>\SPSBackupSample –b, and then press Enter.
  2. Restore the sites when backup is complete: Type <SampleLocation>\SPSBackupSample –r, and then press Enter.
    Note   You are prompted to enter the backup and restore locations and a few other details while the application backs up and restores the sites.

Backing Up Document Libraries (Web Storage System–based)

To configure the backup component for this sample to back up document libraries (Web Storage System–based), you need to create a new COM+ package and register the WSSBackup.dll on the server where the Document Library component is installed in your farm's topology. You can find WSSBackup.dll included with the SPSBackupSample code in the download.

To configure the backup component using COM+

  1. In Windows Explorer, under Administrative Tools, point to Component Services, point to Computers, and then click the name of the computer that the Document Library component is running on. Right-click COM+ Applications, click New, and then click Application.
  2. Create the new application with the following details:

    Name: WSSBackup

    Activation Type: Server Application

    Identity: A domain account that has appropriate permissions to back up Microsoft Exchange Server.

  3. After you create the application, expand it, right-click Components, point to New Component, and then click Install New Component(s). Browse to the WSSBackup.dll.

Sample Application: Walking Through the Code

The following sections provide a walkthrough of the code written for the Backup and Restore sample (SPSBackupSample.exe) to demonstrate the function and usage of the Backup and Restore API.

You can use this article and the code sample as a reference or starting point for creating your own backup and restore applications.

As you read the following instructions, in Microsoft Visual Studio .NET, open the C++ solution file SPSBackupSample.sln and refer to its code.

Back Up a Server Farm

The BackupMode() method is the main path of execution for backup in the Backup and Restore sample application (SPSBackupSample.exe). In a Command Prompt window, when you type <SampleLocation>\SPSBackupSample –b and press Enter, you invoke this method.

This section describes the operation of the BackupMode() method. In the .cpp file, search for void BackupMode() to locate this method.

The following procedure shows the process that the BackupMode() method follows to back up a server farm.

To back up a server farm

  1. Create an instance of the TopologyManager object.
    TopologyManager * tm = new TopologyManager();
    
    
  2. Check for supported topology.
    • Ensure that the topology of the farm is supported using the IsSupportedTopology flag of the TopologyManager object.
         if(false == tm->IsSupportedTopology)
      
      
    • Ensure that the backup application is running on a front-end Web server.
         bool IsFEW(TopologyManager *tm) 
      
      
  3. (For related example code, see the CheckAndAcquireLock() function.) Lock the Topology Manager. Acquire an exclusive lock so that no other administrative operations can be performed on the farm.
    Note   Even with an exclusive lock, users are able to access any sites or portal sites in the farm. If you do not acquire an exclusive lock, the farm is fully functional during the backup process and other users could create new portal sites and Document Workspace sites. This can result in a backup image that is not a full replica of the farm.
    tm ->Lock->Acquire())
    
    
    

    Check the Boolean value returned by this method to ensure that the lock was given. If the lock was not given, ask the user to force the lock. However, be very cautious here and make sure that the process for which you are releasing the lock is completed.

    (tm ->Lock->Acquire(true))
    
    
  4. To ensure that the portal site's data is consistent before backing up any data from the portal site, call ps->PrepareForBackup().
  5. To back up the databases for each portal site in the server farm, enumerate through the tm ->PortalSites collection.
               iEnum = static_cast<SqlCollectionBase::SqlEnumerator 
    *>(psc->GetEnumerator());
               while(iEnum->MoveNext())
    
    

    Each PortalSite object in the collection has three properties that represent the three databases. These properties are: SiteDatabase, ServiceDatabase, and UserProfileDatabase. Each PortalSite object also has three other properties of interest to us: IsFederated, IsCentral, and ID.

    (bool) ps->IsFederated 
       Indicates whether the portal site consumes shared services
    
    (bool) ps->IsCentral
       Indicates whether the portal site provides shared services
    
    (Guid) ps->ID
       ID of the PortalSite object. We check the ID during restore. 
       A portal site cannot be restored if it already exists.
    
    
  6. For each PortalSite object that you back up, store the IsFederated, IsCentral, and ID properties in the backup metadata.
           * Sample XML Metadata
          <Site PortalURL="http://somePortalServer/" IsFederated="False" 
    IsCentral="False" PortalID="4de04d81-ab32-4308-bc5f-0f93eb709fc4">
          <SITEDB DatabaseName="testPort1_SITE" 
             ImageName="testPort1_SITE.bak" />
          <SERVICEDB DatabaseName="testPort1_SERV" 
             ImageName="testPort1_SERV.bak" />
          <PROFILESDB DatabaseName="testPort1_PROF" 
             ImageName="testPort1_PROF.bak" />
    
    
  7. Using the SQL backup method you choose, back up the SharePoint Portal Server databases using the connection string and the database name.
  8. For performance reasons, cache the IDs for later retrieval. Iterations through the various collections can result in numerous roundtrips to the database. The code sample uses an instance of the Hashtable object for caching these IDs.
  9. Back up any additional content databases on the virtual server as follows.
    1. Obtain a reference to the portal site's SPVirtualServer object.
         SPVirtualServer * spPSVS = ps->VirtualServer->GetSPVirtualServer();
      
      
    2. Iterate through the SPVirtualServer->ContentDatabases collection and save the state of the following properties.
      (string)   Name
      (int)   WarningSiteCount
      (int)   MaximumSiteCount 
      
      
    3. Back up the physical database.
      * Sample metadata for content databases.
      <CONTENTDATABASES>
         <CONTENTDB NAME="NewContentDB" ImageName="NewContentDB.bak" 
         WarningSiteCount="300" MaximumSiteCount="500" />
      </CONTENTDATABASES>
      
      
  10. Back up search databases and servers running Indexing Service.
    1. Back up search only when the portal site is not shared.
      if(false == ps->IsFederated)
      
      
    2. Identify the active index management servers on the farm.
      // Collect all of the Indexing Service information for the farm 
               while(iIndexEnum->MoveNext())
               {
               IndexService *is = static_cast<IndexService *>(iIndexEnum->Current);
            // Only back up if the Indexing Service is active
               if(is->IsActive())
      
      
    3. Provide the following metadata.

      Index management server name:

         (string) IndexService->Server->Name
      
      

      Whether it is the job server or not:

         (bool)is->Server->IsJobServer
      
      

      The GUID/string ID of the actual search application:

         (string) ps->SearchApplicationName
      
      
  11. (For related example code, see the BackupSearchApplication() function.) Lock the active servers running Indexing Service to prevent other backups from taking place at the same time. Call the AcquireBackupPermission() method of the SearchAdminClass class. If the lock fails, release the computers running Indexing Service and do not back up.

    For more information, see the LockIndexServers function in the C++ solution file, as follows:

    bool LockIndexServers(SearchAdminClass * sAdmin, ArrayList * al)
    
    
  12. For every portal site you back up, you must iterate through each of the active Indexing Services and call the BackupToStream() method of the CSPSBackupClass class.
    1. To create an instance of CSPSBackup, set a reference to mssctlbm.dll.
      spsBackup = new CSPSBackupClass(); 
      
      
    2. Call BackupToStream for each index management server that is backed up.
         spsBackup->BackupToStream(ServerName, objPStream , "", 
         SearchApplicationName);
               
      (string) ServerName   Name of server running Indexing Service to
                            back up the search application from.
      IStream *) objPStream   An Implementation of IStream to write the 
                              data. Pass an empty string. 
      (string) SearchApplicationName   The GUID/String ID for the 
                                       server running Indexing Service.
      
      
  13. BackupToStream is an asynchronous method. While it is executing, call spsBackup->GetBackupStatus() to retrieve the current status of the backup and update your user interface accordingly.
    GetBackupStatus(ActiveIndexServerName,ps->SearchApplicationName, 
    &nBackupState, &nLastError, &dLastTime, &nPercentCompleted);  
    
    

    The following enumeration has a value of nBackupState that you must define in your application.

    // Enum for the various states from GetBackupStatus()
    typedef enum tagSPSBackupState
    {   
          SPSBACKUPSTATE_IDLE   = 0,
          SPSBACKUPSTATE_BACKUP   = 1,
          SPSBACKUPSTATE_RESTORE   = 2
    }SPSBackupState;
    
    
  14. Back up the search schedules configuration from each index management server. This is an XML BLOB that you do not need to parse.
           SearchFarmConfig *sfc = new SearchFarmConfig();
      String * sBackupSchedules = sfc->BackupSchedules(IndexServerName,
         portalSiteObject);
    
    
  15. Call ReleaseBackupPermission on each of the Indexing Services that you previously locked.
    Warning   If you fail to perform this step, Microsoft SharePoint Portal Server Search (SharePointPSSearch) service on each server running Indexing Service does not allow you to back up or restore until the search service is restarted.

    For reference, see the following function in the C++ solution file.

       void ReleaseIndexServers(SearchAdminClass * sAdmin, ArrayList * al)
    
    *Sample backup metadata for indexes:
        <INDEXES>
     <INDEX ServerName="IndexServerA" SearchApplicationName="4de04d81-
    ab32-4308-bc5f-0f93eb709fc4" 
    ImageName="testing123IndexServerA4de04d81-ab32-4308-bc5f-
    0f93eb709fc4.stream" IsJobServer="True">
    <![CDATA[<?xml version='1.0' ?>
     ** Scheduled Tasks XML BLOB goes here – left out for clarity.
    <IScheduledTasks>
    </IScheduledTasks>]]>
     </INDEX>
         </INDEXES>
    
    
  16. (For related example code, see the BackupWSS() function.) Back up any Windows SharePoint Services virtual server information that is not SharePoint Portal Server 2003 information.
    1. Create an instance of the SPGlobalAdmin object.
         SPGlobalAdmin * spGA = new SPGlobalAdmin();
      
      
    2. Iterate through the SPGlobalAdmin->VirtualServers collection.
    3. Compare the VirtualServerID for each VirtualServer in the collection against the VirtualServerID of the TopologyManager->PortalSites collection. If it is not part of a portal site and its state is not equal to SPVirtualServerState::NotAdministrable, then back up its state (htCachedVSIds is a previously used hash table in which to cache the portal site's virtual server IDs).
      if(!htCachedVSIds->ContainsKey(spVS->VirtualServerId.ToString()) 
      && SPVirtualServerState::NotAdministrable != spVS->State && 
      SPVirtualServerState::NeedExtend != spVS->State)
      
      
    4. Save the metadata from the current SPVirtualServer object. The code sample uses this for backup identification; you can modify this data when you restore.
      (string)   Description
      (string)   Url 
      
      
    5. Iterate through the SPVirtualServer->Prefixes collection and save the state of each prefix (exclusions/inclusions).
      (string)   Name
      (int)   Type
      
      
    6. Iterate through the SPVirtualServer->ContentDatabases collection and save the state of the following properties.
      (string)   Name
      (int)   WarningSiteCount
      (int)   MaximumSiteCount 
      
      
    7. Back up the physical database.
      * Sample metadata for stand-alone Windows SharePoint Services virtual servers.
        <TEAMSITES>
          <VIRTUALSERVER DESCRIPTION="portal" URL="http://mw2003virt2/" 
          ID="4f68ef73-4606-48bd-9a2e-a943a19e44e3">
            <PREFIXES>
              <PREFIX NAME="" TYPE="0" />
              <PREFIX NAME="sites" TYPE="1" />
              <PREFIX NAME="uddi" TYPE="2" />
              <PREFIX NAME="uddipublic" TYPE="2" />
            </PREFIXES>
            <CONTENTDATABASES>
              <CONTENTDB NAME="STS_someServer_770673706" 
              ImageName="STS_someServer_770673706.bak" 
              WarningSiteCount="9000" MaximumSiteCount="15000" />
            </CONTENTDATABASES>
          </VIRTUALSERVER>
        </TEAMSITES>
      
      
  17. (For related example code, see the BackupSSO() function.) Back up the Microsoft Single Sign-On service database.
    1. To identify the Single Sign-On database, use the tm ->GlobalProperties->SSODatabaseConnectionString property. This string is null if no database is configured.
    2. If there is a connection string, back up the Single Sign-On database.
    3. To determine if an encryption key is set, check the SingleSignon::Configuration::DoesMasterSecretExist (bool) property.
    4. To obtain the encryption key for backup, use the SingleSignon::Configuration::MasterSecret (static unsigned char __gc[]) property.
      * Sample metadata for Single Sign-On
        <SSODB DatabaseName="SSO" ImageName="SSO.bak" 
        TicketTimeoutMin="2" PurgeAuditDays="10" />
        <SSOSecretKey ImageName="myBackup_ssoKey.txt" />
      
      
  18. (For related example code, see the BackupLegacyDocLib() function.) Back up legacy document libraries.

    The Exchange Streaming APIs are used to back up the document libraries (Web Storage System–based). For more information, see Backup and Restore in the Microsoft Exchange Server SDK.

    1. If the farm is not shared, determine if tm->GlobalProperties->DefaultDocumentService is not null. If it is not null, check its active status using the IsActive property. Only one Web Storage System–based DocumentService is in the farm, so logging in your metadata that one exists should let you know whether to restore it or not.
           if(false == IsFarmFederated && NULL != tm->GlobalProperties-
           >DefaultDocumentService)
      
            DocumentService * ds = static_cast<DocumentService *>(tm-
           >GlobalProperties-   >DefaultDocumentService);
         if(ds->IsActive())
      
      
    2. If DocumentService is active, back up the storage group "SharePoint Portal Server Group". Also, look at the code sample WSSBackup (provided in the download), which uses the HrESE APIs. (For more information, see Backup and Restore in the Microsoft Exchange Server SDK).

      After restoring Exchange Server, call the OnRestoreComplete() method to tell SharePoint Portal Server 2003 that the Exchange Server database is restored and to create the Internet Information Services (IIS) virtual directories needed for the document libraries.

      Import the component that contains the CTahoeBackupManager interface.

      #import "C:\Program Files\SharePoint Portal Server\BIN\pkmpi.dll" 
          no_namespace raw_interfaces_only
      
      IDMRestorePtr pDMRestore;
      
      // Tell SharePoint Portal Server we are through with Restore
      pDMRestore.CreateInstance(__uuidof(CTahoeBackupManager));
      hr = pDMRestore->OnRestoreComplete();
      
      
    3. Iterate through the TopologyManager->DocumentWorkspaces collection and save each Name property of the Document Workspace site to your backup's metadata for performing a restore operation.
      Metadata
      (string)   Name
      
      * Sample XML metadata
         <DOCLIB>
             <WORKSPACES>
                 <WORKSPACE NAME="testdoclib1" />
                 <WORKSPACE NAME="testdoclib2" />
             </WORKSPACES>
         </DOCLIB>
      
      
  19. After the backup is complete, release the lock.
              
       tm->Lock->Release(true);
    
    

You have now completed the steps you need to perform to back up the sites in a farm. The following section describes how to restore a farm.

Restore a Farm

The RestoreMode() method is the main path of execution for restoration in the sample application. When you type <SampleLocation>\SPSBackupSample –r and press Enter in the Command Prompt window, you invoke this method.

This section describes the operation of the RestoreMode() method. To locate this method, search for void RestoreMode() in the .cpp file.

The following steps show the process of the RestoreMode() method to restore a server farm.

To restore a server farm

  1. Create an instance of the TopologyManager object.
    TopologyManager * tm = new TopologyManager();
    
    
  2. Check for supported topology.
    1. Ensure that the topology of the farm is supported using the IsSupportedTopology flag of the TopologyManager object.
            if(false == tm->IsSupportedTopology)
      
      
    2. Ensure that the backup application is running on a front-end Web server.
            bool IsFEW(TopologyManager *tm) 
      
      
  3. Lock the TopologyManager. Acquire an exclusive lock so that no other administrative operations can be performed on the farm.
    Note   Despite the exclusive lock, users are able to access any sites or portal site in the farm.
    tm ->Lock->Acquire())
    
    

    Check the Boolean value returned by this method to ensure the lock was given. If the lock was not given, ask the user to force the lock. However, be very cautious and make sure that the process for which you are releasing the lock is completed.

    (tm ->Lock->Acquire(true))
    
    
  4. Get the farm shared services configuration. Get the values for TopologyManager->GlobalProperties->IsCentral and TopologyManager->GlobalProperties->IsFederated.
          IsFarmCentral = tm->GlobalProperties->IsCentral;
          IsFarmFederated = tm->GlobalProperties->IsFederated;
    
    
  5. Cache topology. Enumerate the tm->DatabaseServices and tm->IndexServices collections and cache the information.
    Note   This step is not required but it can help to reduce roundtrips to the database. Refer to the following comments in the code sample.
       // Enumerate and cache servers running Indexing Service in the farm
       // Enumerate and cache the database servers in the farm
    
    
  6. Lock the servers running Indexing Service.
    Warning   You must lock the servers running Indexing Service before calling the Restore() method. Locking the servers after calling Restore() can result in a race condition between your application and the SPSAdmin service trying to acquire the lock. Lock the active index management servers so no other restore operation can take place at the same time using the AcquireBackupPermission() method of the SearchAdminClass class. If the lock fails after a reasonable number of retries, then release the servers and do not proceed with the portal site restoration.
    bool LockIndexServers(SearchAdminClass * sAdmin, ArrayList * al)
    
    
  7. Determine if you can restore the portal site. You can use the following pseudocode logic to restore a portal site. Whether the portal site was providing or consuming shared services greatly affects whether and how it is restored. For more information, see the following comment in the code sample.
    /* Start Of Restore Matrix */ 
    
    

    Use the following restore matrix to determine when and if you can restore the portal site.

    Table 1. Restore matrix

    Backup/destinationIndependentIntra-farm shared childInter-farm shared childMaster
    IndependentYesYesYesYes
    ChildNoYesYesNo
    ParentYesNo**YesYes***

    ** When it is already the parent portal site of that farm. If there is an existing parent, it can be restored as a child portal site.

    *** Should automatically set itself to be the parent portal site.

    MasterPortalExists = 
    TopologyManager.GlobalProperties.MasterPortalSite <> NULL
    IsFarmCentral = TopologyManager->GlobalProperties->IsCentral
    IsFarmFederated = TopologyManager->GlobalProperties->IsFederated
    IsPortalCentral = PortalSite->IsCentral
    IsPortalFederated = PortalSite->IsFederated
    
    ' A farm that is NOT using shared services
    If IsFarmCentral = false and IsFarmFederated = false Then
        If IsPortalFederated = True Then
             ' Cannot restore without being in a farm 
             ' configured for shared services
        Else 
             ' Restore normally
        End If
    End if
    
    ' A farm that provides shared services 
    
    If IsFarmCentral = true Then
         'If the portal site was a parent portal site
        If IsPortalCentral = True Then
         'Call restore and set 
         'TopologyManager.GlobalProperties.MasterPortalSite 
         ' = NewPortalSite if the portal site was
         'If the portal site was a child portal site   
        Else If IsPortalFederated = True Then
                If MasterPortalExists Then
                      'Restore and skip search Restore
               Else
                      'Cannot Restore unless parent portal site exists
               End If
         ' A portal site that was formerly independent 
       Else If IsPortalCentral = false AND IsPortalFederated = false Then
               If MasterPortalExists = false Then
                  If No Portal in backup is Marked IsPortalCentral then 
                        'Offer to promote to parent
                  End If
                  If PromoteToMaster = true Then
                        'Call Restore and set 
                        'TopologyManager.GlobalProperties.MasterPortalSite 
                        '= NewPortalSite
                  Else
                        'Cannot Restore unless parent portal exists
                  End If
               End If
       End If
    End If 
    
    ' A farm that consumes shared services from another farm – 
    ' Inter Federated 
    If IsFarmFederated = true Then
          If MasterFarmConnectionString <> NULL and MasterConfigurationDatabase <> NULL Then 
             'Call Restore – in this Restore case all portal sites will. 
             'be child portal sites so skip search Restore
         End If
    End If
    
    
  8. (For related example code, see the RestorePortal() function.) Check for an existing portal site. Ensure that the portal site does not exist before calling the Restore() method. If you attempt to restore over an existing portal site, Restore() throws an exception. For an example of how to check for an existing portal site, see the following code.
    PortalSite * GetPortalByID(TopologyManager *tm, String *ID). 
    
    * To delete the portal site, call the Delete method of the 
      TopologyManager object's PortalSites collection object.
         ps = PortalSite to delete
         fDeleteDatabases = bool whether to delete the 
         underlying databases or not. 
         tm->PortalSites->Delete(ps, fDeleteDatabases);
    
    
    Note   If you set the second argument of the Delete() method to true and the content databases are inaccessible (for example, the server is down), everything does not get cleaned up. To work around this, you can unextend the virtual server in the exception handler that cleans up the configuration database. For an example, see the following function in the sample.
          void DeletePortal(TopologyManager *tm, PortalSite *ps, bool fDeleteDatabases)
    
    
  9. Cache existing portal site IDs. Iterate and cache the ID property of each PortalSite tm->PortalSites. The code sample uses a hash table called htVSIDs to store the existing IDs.
  10. Get valid target virtual servers.
    1. Iterate through the existing virtual servers on the target computer.
        (SPGlobalAdmin) spGA
      
            spGA->VirtualServers – collection of VirtualServers
      
      
    2. Test each server to see if it is extendable and that it is not part of an existing PortalSite.
          if(SPVirtualServerState::NeedExtend == spVS->State && 
            !htVSIDs->ContainsKey(spVS->VirtualServerId.ToString()))
      
      
    3. Save the available servers for potential restore targets.
      ArrayList) alIISVServers
          alIISVServers->Add(spVS);
      
      
  11. Collect restore information from the user.
    • PortalURL. The URL of the virtual server this portal site should be restored on. If this is a migration, this URL may be different from what was backed up. You should only allow one of the virtual servers from step 8 to be selected from this list.
      Note   If the user selected to delete the target databases in step 8, proceed with step 12.
    • VirtualServerURL. Selected from step 10.
    • Target database server for the service database and the database name. Target database server should be restricted to SQL Server computers cached in step 5.
    • Target database server for the profiles database and the database name. Target database server should be restricted to the SQL Server computers cached in step 5.
    • Target database server for the site database and the database name. Restrict target database server to the SQL Server computers cached in step 5.
  12. If the user selected to delete the target databases, restore the databases to the selected database servers.
  13. Restore the portal site. Call the static Restore method of the PortalSite object.
    1. The Restore method takes the following input parameters:

      PortalUrl = The URL of your portal site.

      VSUrl = The virtual server to extend to host the site.

      SiteDBServer = Server name where the Site database was restored (or already resides).

      SiteDBName = Database name for the Site database.

      ServiceDBServer = Server name where the Service database was restored (or already resides).

      ServiceDBName = Database name for the Service database.

      ProfilesDBServer = Server name where the User Profile database was restored (or already resides).

      ProfilesDBName = Database name for the User Profile database.

      PortalSite * newPS = PortalSite::Restore(PortalUrl, new Uri(VSUrl), 
      SiteDBServer, SiteDBName, ProfilesDBServer, ProfilesDBName, 
      ServiceDBServer, ServiceDBName);
      
      
    2. If portal site creation succeeds, set the new portal site's Status property to TopologyStatus::Online and call the Commit() method, passing true.
                newPS->Status = TopologyStatus::Online;
                newPS->Commit(true);
      
      
  14. Restore content databases. Collect the target database server for each individual content database and the database name.
    Warning   Restrict the target database server to the SQL Server computers cached in step 5.
    1. Restore the database.
    2. Add the content database information to the portal site's SPVirtualServer object's ContentDatabases collection using its Add method; nWarningSiteCount and nMaximumSiteCount are from the metadata saved in your backup.
      spVS->ContentDatabases->Add(dbServer, dbName, "", "", 
         nWarningSiteCount, nMaximumSiteCount, 0);
      
      
  15. (For related example code, see the RestoreSearchApplication() function.) Restore search database and servers running Indexing Service.

    Only restore search if the portal site is NOT shared and the indexes are locked (from step 6).

       if(false == tp->_isPortalFederated && true == 
          fIndexServersLocked)
    
    
    1. For every independent or parent portal site that is backed up, iterate through each of the active Indexing Services and call the RestoreFromStream() method of the CSPSBackup class.

      If you want to change the restore path on the search server, change sRestorePath to a user-selected location.

      ActiveIndexServerName = String containing the name of the index management server that the application will be backed up from.

         pStream = IStream = your IStream implementation 
         backedUpSearchApplicationName = SearchApplicationName for 
           search application you previously backed up.
         spsBackup->RestoreFromStream(ActiveIndexServerName, 
           Marshal::GetObjectForIUnknown(pStream), "", true, sRestorePath, 
         backedUpSearchApplicationName);
      
      

      Restore rules for indexes:

      1. The target Indexing Service has to be Active (use IsActive).

      2. If the image you are restoring came from a server running Indexing Service that was also the job server, that image must be restored to the job server in the target farm.

      3. If you are restoring a regular index (not a job server), make sure that you don't restore the two images of the same SearchApplication to the index management server. For example, if you backed up from IndexA and IndexB, you cannot restore both to IndexC (merging of indexes is not allowed).

    2. Restore any custom search schedules that were backed up.
      SearchFarmConfig *sfc = new SearchFarmConfig();
      sfc->RestoreSchedules(IndexServerName, PortalSiteObject,
       ScheduleXMLThatWasBackedUp);
      
      
    3. RestoreFromStream is an asynchronous method. While it is executing, call the following to retrieve the current status of the restore operation.
      spsBackup->GetBackupStatus()
      GetBackupStatus(ActiveIndexServerName,ps->SearchApplicationName,
       &nBackupState, &nLastError, &dLastTime, &nPercentCompleted); 
      
      
    4. If, during the restore operation, the portal site's URL has NOT changed, then propagate the indexes. If it has changed, skip this step because the SPSAdmin service has to recrawl and propagate the indexes.
    5. After all of the portal sites are restored, release each of the locked index management servers by using a call to ReleaseBackupPermission().
  16. For related example code, see the RestoreSSO() function.) If the farm does not have shared services enabled, restore the Single Sign-On database.
    1. Call the ConfigureSecretServer method with the correct information.
      SingleSignon::Configuration::ConfigureSecretServer(SSOAdminAccount,
      SSOApplicationAdminAccount, SSODBServer, SSODBName, 
      nTicketTimeout, nAuditPurge);
      
      
    2. To restore the encryption key, call the following to determine whether to re-encrypt the data.
      SingleSignon::Configuration::RestoreMasterSecret(sKey, fReEncrypt);
      fReEncrypt = boolean 
      
      
  17. (For related example code, see the RestoreWSS() function.) Restore any stand-alone Windows SharePoint Services virtual servers that were backed up.
    1. Get a list of all the virtual servers available on the server to restore to. To do this, iterate through the SPGlobalAdmin->VirtualServers collection. Any virtual server with the state of SPVirtualServerState::NeedExtend can be used as a restore target.
    2. Give the user a choice of virtual servers to restore to.
    3. After the user selects the virtual servers, call OpenVirtualServer(new Uri(newUrl)) passing the URL the user selected.
    4. If the call succeeds, extend the virtual server.
      spGA->ExtendVirtualServer(new Uri(newUrl), false, 
      TopologyManager::DefaultApplicationPoolName, false, NULL, NULL);
      
      
    5. Clear any existing prefixes from the SPVirtualServer object.
         // Clear any existing prefixes
         int nPrefixCount=0;
         String *strPrefixes[] = __gc new String*[spVS->Config->Prefixes->Count];
         for(nPrefixCount=0;nPrefixCount < spVS->Config->Prefixes->Count; nPrefixCount++)
         {
            strPrefixes[nPrefixCount] = spVS->Config->Prefixes->Item[nPrefixCount]->Name;
         }
         spVS->Config->Prefixes->Delete(strPrefixes);
      
      
    6. Add the prefix (exclusions and inclusions) information that was backed up to the new SPVirtualServer object's Prefix collection using its Add method.
    7. Restore the backed-up content databases to the SQL Server computer.
    8. Add the content database information to the SPVirtualServer object's ContentDatabases collection using its Add method.
  18. (For related example code, see the RestoreLegacyDocLib() function.) Check the metadata for backed-up legacy document libraries. If there are any, proceed to restore them using the HrESE APIs documented in Backup and Restore in the Microsoft Exchange Server SDK.
  19. After you restore the legacy document library, enumerate through your metadata to check for backed-up Document Workspace sites. For each Document Workspace site that is backed up, check to see if it already exists in the configuration database by enumerating the current farm's TopologyManager->DocumentWorkspaces collection. If it does not exist, create a new DocumentWorkspace object using the following code, which adds the Document Workspace site to the farm's configuration database.
    // Url = http://newDocumentServer/doclibName    ds = tm-
    >DefaultDocumentService
    DocumentWorkspace * dw = new DocumentWorkspace(backedUPName, 
    Url, ds); 
       Then call 
       tm->DocumentWorkspaces->Add(dw); 
    
    
  20. Iterate through the servers running Indexing Service locked previously, and call ReleaseBackupPermission().
  21. Call tm->Lock->Release() when the restore operation is complete.

Conclusion

The backup and restore sample in this article demonstrated how to develop a disaster recovery or migration solution programmatically for SharePoint Portal Server 2003. You should not use this sample as a replacement for a production-quality backup solution. However, it is well suited to use as a prototype for a custom or third-party ISV solution.

Additional Resources

Microsoft SharePoint Products and Technologies 2003 SDK
Microsoft Office SharePoint Portal Server 2003 Administrator's Guide
Backup and Restore in the Microsoft Exchange Server SDK

Show:
© 2014 Microsoft