Search Results for

    Show / Hide Table of Contents

    Apps

    The Core SDK Admin library provides SharePoint Apps related APIs for configuring app prerequisites for managing apps.

    Creating Context

    In this article, you'll see a lot of context use: in this case this is a PnPContext which was obtained via the PnPContextFactory as explained in the overview article and shown below:

    using (var context = await pnpContextFactory.CreateAsync("SiteToWorkWith"))
    {
        // See next chapter on how to use the PnPContext for doing SharePoint admin operations
    }
    

    PnP.Core.Admin dependency

    The functionality shown in this article depends on the PnP.Core.Admin nuget package. Once the PnP.Core.Admin nuget package has been installed you can get to the SharePoint admin features via using the GetSharePointAdmin, GetSiteCollectionAppManager, GetTenantAppManager and GetSiteCollectionManager extension methods:

    using (var context = await pnpContextFactory.CreateAsync("SiteToWorkWith"))
    {
        // Use the GetSharePointAdmin extension method on any PnPContext 
        // to tap into the SharePoint admin features
        var url = context.GetSharePointAdmin().GetTenantAdminCenterUri();
    }
    

    Two types of app catalogs

    There are two types of app catalogs available in SharePoint Online. One is global at the tenant level called tenant app catalog. It hosts all the apps that are available for all sites in your tenant. The other app catalog type is a site collection app catalog. It's aimed to host apps for the specific site collection only.

    PnP.Core.Admin package provides an explicit way of managing either tenant or site collection scoped apps. To do so, you should create an instance of the corresponding app manager using one of the extension methods GetTenantAppManager or GetSiteCollectionAppManager:

    // instantiate a class to work with various tenant app catalog related operations
    var tenantAppManager = context.GetTenantAppManager();
    
    // instantiate a class to work with various site collection app catalog related operations
    var siteCollectionAppManager = context.GetSiteCollectionAppManager();
    
    Important

    If you're willing to work with the site collection app catalog, you should call the GetSiteCollectionAppManager extension method using the site collection's app catalog context.

    Depending on your requirements you will create any of the above objects to work with apps in your app catalog sites.

    Common app operations

    Tenant and site collection app managers provide some common app operations like GetAvailable, Add, Deploy, Install, etc. These operations are available for both tenant and site collection app managers and are listed below.

    In the samples below you will see a lot of appManager usages. appManager can be either tenant or site collection app catalog manager (depending on which extension method you use). As mentioned above, all the below methods apply to any of the app catalog managers.

    Get available app(s)

    You can use the method GetAvailable to get either all or specific apps by their id or title. The app's id corresponds to the UniqueId field value inside the out-of-the-box AppCatalog list where all the apps are located.

    // gets all available apps for the app catalog
    var allApps = await appManager.GetAvailableAsync();
    
    // gets the app instance by it's unique id
    var app = await appManager.GetAvailableAsync(new Guid("34427a18-486d-45d2-b4e5-9fd5324ede53"));
    
    // get the app instance by it's title
    var app = await appManager.GetAvailableAsync("title of my app");
    

    Add an app

    To add an app to the app catalog you should use the Add method. It accepts a file path or a binary file as a bytes array:

    // adds app package to the app catalog and overwrites if there is an existing one
    var app = await appManager.AddAsync("path/to/file.sppkg", true);
    
    // adds app package using bytes array and app name
    var bytes = System.IO.File.ReadAllBytes("path/to/file.sppkg");
    var app = await appManager.AddAsync(bytes, "My App", true);
    

    Add method returns an instance of the App object, which you can use to perform further operations.

    Deploy an app

    When your app is added to the app catalog, it's not yet available to the sites. To make it available you should first deploy it using the corresponding method:

    var app = await appManager.AddAsync(packagePath, true);
    
    // deploy the app using the app's unique id
    var result = await appManager.DeployAsync(app.Id, false);
    

    Upon deployment, you can specify whether to perform global deployment (when your app immediately becomes available for all the sites). In SharePoint Framework this feature is called "Skip feature deployment". When you provide skipFeatureDeployment=true for the Deploy method, the app will be deployed globally.

    To deploy the app you can also use the app instance itself:

    var app = await appManager.AddAsync(packagePath, true);
    // deploys app globally using app instance
    await app.DeployAsync(true);
    

    Under the hood, the app instance calls the Deploy method from the appManager.

    Install an app

    To install the app into the specific site you need to call the Install method:

    // install the app to the site
    await appManager.InstallAsync(app.Id);
    
    // or use app instance
    await app.InstallAsync();
    
    Important

    Install operation is context-specific. It means that you should use the PnPContext instance from the corresponding site to install the app to that site.

    Approve Permissions

    Some apps can request permissions to call additional APIs by adding a webApiPermissionRequests element in their package-solution.json file. Below snippet shows a part of such a file:

    {
        "solution": {
        "name": "apicalltest-client-side-solution",
        "id": "da4e941c-a64e-401a-b63d-664e5bf62bdc",
        "version": "1.0.0.0",
        "includeClientSideAssets": true,
        "skipFeatureDeployment": true,
        "isDomainIsolated": false,
        "webApiPermissionRequests": [
          {
            "resource": "Microsoft Graph",
            "scope": "Calendars.Read"
          },
          {
            "resource": "Microsoft Graph",
            "scope": "User.ReadBasic.All"
          }
        ]
    }
    

    Permissions requested this way can be approved by using the ApprovePermissionRequests method.

    var app = await appManager.AddAsync(packagePath, true);
    var result = await appManager.DeployAsync(app.Id, false);
    
    // approve permissions requested from the app
    IPermissionGrant2[] approvedPermissionGrants = app.ApprovePermissionRequests();
    

    The result is an array of IPermissionGrant2 containing the effective permissions including those previously granted for other apps on this resource.

    Upgrade an app

    To upgrade the app on the specific site you need to call the Upgrade method:

    // upgrades the app on the site
    await appManager.UpgradeAsync(app.Id);
    
    // or use app instance
    await app.UpgradeAsync();
    
    Important

    Upgrade operation is context-specific. It means that you should use the PnPContext instance from the corresponding site to upgrade the app on that site.

    Uninstall an app

    To uninstall the app from the specific site you need to call the Uninstall method:

    // uninstalls the app from the site
    await appManager.UninstallAsync(app.Id);
    
    // or use app instance
    await app.UninstallAsync();
    
    Important

    Uninstall operation is context-specific. It means that you should use the PnPContext instance from the corresponding site to uninstall the app from that site.

    Retract an app

    Retract operation is the opposite to Deploy. If you don't want your app to be available for sites, you should call Retract. Retract command does not delete the app from the app catalog.

    // retracts app
    await appManager.RetractAsync(app.Id);
    
    // or use app instance
    await app.RetractAsync();
    

    Remove an app

    To completely remove the app from the app catalog you should call the Remove method:

    // removes the app from the corresponding app catalog
    await appManager.RemoveAsync(app.Id);
    
    // or use app instance
    await app.RemoveAsync();
    

    List, add, revoke or delete the permission grants

    Some apps can request permissions to call additional APIs by adding a webApiPermissionRequests element in their package-solution.json file. Below snippet shows a part of such a file:

    {
        "solution": {
        "name": "apicalltest-client-side-solution",
        "id": "da4e941c-a64e-401a-b63d-664e5bf62bdc",
        "version": "1.0.0.0",
        "includeClientSideAssets": true,
        "skipFeatureDeployment": true,
        "isDomainIsolated": false,
        "webApiPermissionRequests": [
          {
            "resource": "Microsoft Graph",
            "scope": "Calendars.Read"
          },
          {
            "resource": "Microsoft Graph",
            "scope": "User.ReadBasic.All"
          }
        ]
    }
    

    After adding and deploying an app to the app catalog these API permissions need to be approved by an admin (e.g. via https://contoso-admin.sharepoint.com/_layouts/15/online/AdminHome.aspx#/webApiPermissionManagement) or via code. The code approach can be implemented using the IApp class and the ApprovePermissionRequests method (see Approve Permissions).

    Additional API permissions are granted on the ServicePrincipal object. These permission grants can be listed, added, revoked, and deleted using these methods:

    // instantiate the TenantAppManager
    var appManager = context.GetTenantAppManager();
    
    // list permissions granted to ServicePrincipal
    IPermissionGrant2[] grants = appManager.ServisePrincipal.ListGrants2();
    
    // add a grant, e.g. scope "Calendars.ReadWrite.Shared" for "Microsoft Graph"
    IPermissionGrant2 addedGrant 
        = appManager.ServisePrincipal.AddGrant2("Microsoft Graph", "Calendars.ReadWrite.Shared");
    
    // revoke the scope "Calendars.ReadWrite.Shared" for "Microsoft Graph" from 'addedGrant'
    IPermissionGrant2 revokedGrant 
        = appManager.ServisePrincipal.RevokeGrant2(addedGrant.Id, "Calendars.ReadWrite.Shared");
    
    // delete all permissions for 'addedGrant', all of "Microsoft Graph" in this example
    appManager.ServisePrincipal.DeleteGrant2(addedGrant.Id);
    
    Important

    Please not that the previous implemenations of the GetPermissionRequests, ApprovePermissionRequest, DenyPermissionRequest, RevokeGrant, and ListGrants operations were based on the SharePoint Client Side Object Model (CSOM). These operations are considered for internal use only. Therefore these operations are now marked obsolete and will be removed in the next major release.

    Enable or disable the SharePoint app service principal

    The SharePoint app service principal can be enabled or disabled using the Azure Active Directory portal or via code. The Enable2 and Disable2 operations can be found on the ServicePrincipal object:

    // Enable the ServicePrincipal
    var appManager = context.GetTenantAppManager();
    IServicePrincipalProperties result = await appManager.ServicePrincipal.Enable2();
    
    // Disable the ServicePrincipal
    var appManager = context.GetTenantAppManager();
    IServicePrincipalProperties result = await appManager.ServicePrincipal.Disable2();
    
    Important

    Please not that the previous implemenations of the Enable and Disable operations were based on the SharePoint Client Side Object Model (CSOM). These oprations are considered for internal use only. Therefore these operations are now marked obsolete and will be removed in the next major release.

    Tenant app catalog specific operations

    Some methods are available only for the tenant app catalog. They are listed below.

    Getting the url for the tenant app catalog site

    When you're running setup tasks you need to ensure there's an app catalog site setup, using the GetTenantAppCatalogUri methods you can get the current tenant app catalog site url:

    // Get the tenant app catalog url, returns null if there's none setup
    var url = await context.GetTenantAppManager().GetTenantAppCatalogUriAsync();
    

    Ensuring there's a tenant app catalog

    If you want to ensure there's a tenant app catalog because you need to deploy an app to it, you can use the EnsureTenantAppCatalog methods. If the tenant app catalog site exists the methods return false, if there was no app catalog it will be setup using the default path of sites/appcatalog and the method returns true.

    // Get the tenant app catalog url, returns null if there's none setup
    if (await context.GetTenantAppManager().EnsureTenantAppCatalogAsync())
    {
        // App catalog site was missing, but now added as /sites/appcatalog
    }
    else
    {
        // The app catalog site was already available
    }
    

    Note that you have to use the GetTenantAppCatalogUri to get the actual app catalog site url, even when there was no app catalog site and it was created by calling EnsureTenantAppCatalog it's still recommended to get the actual url.

    List all site collection app catalogs

    Using the GetSiteCollectionAppCatalogs you can get all site collection app catalogs from the whole tenant:

    var tenantAppManager = context.GetTenantAppManager();
    var siteAppCatalogList = await tenantAppManager.GetSiteCollectionAppCatalogsAsync();
    

    The result includes site collection app catalog metadata like absolute url and unique id.

    Ensuring there's a site collection app catalog

    To ensure a site collection app catalog does exist you can use the EnsureSiteCollectionAppCatalog methods, they check if there's an app catalog and if not one is created by calling the AddSiteCollectionAppCatalog methods.

    var tenantAppManager = context.GetTenantAppManager();
    await tenantAppManager.EnsureSiteCollectionAppCatalogAsync("https://contoso.sharepoint.com/sites/sitethatneedsacatalog");
    

    Removing a site collection app catalog

    If the app catalog of a site is not needed anymore then it can be removed using the RemoveSiteCollectionAppCatalog methods:

    var tenantAppManager = context.GetTenantAppManager();
    await tenantAppManager.RemoveSiteCollectionAppCatalogAsync("https://contoso.sharepoint.com/sites/sitethatneedsacatalog");
    

    Check whether the solution contains MS Teams component

    SharePoint Framework solutions might extend MS Teams as well. You can check, whether a particular SPFx app extends MS Teams or not:

    // get tenant app manager 
    var tenantAppManager = context.GetTenantAppManager();
    
    // get app
    var app = await tenantAppManager.GetAvailableAsync("My App Title");
    
    // check it
    var containsTeams = await tenantAppManager.SolutionContainsTeamsComponentAsync(app.Id);
    

    For example, If your SPFx solution lists any webpart with TeamsPersonalApp or TeamsTab as supported hosts, the method above will return true.

    Get all apps, acquired from SharePoint Store

    Your tenant app catalog hosts not only custom apps, but also apps installed from the SharePoint store. To easily get all third-party apps from the SharePoint Store, use the method below:

    var tenantAppManager = context.GetTenantAppManager();
    var storeApps = await tenantAppManager.GetStoreAppsAsync();
    

    storeApps is a collection of App instances, where you can do all common operations like Install, UnInstall, etc.

    Automate SharePoint Store apps deployment and installation

    With tenant app manager you can also automate the process of installing apps from the SharePoint Store. To deploy an app from SharePoint Store you should know the unique store asset id. You can easily find it in the query string on the app home page. Usually the url has a format https://appsource.microsoft.com/en-us/product/office/WA200001111 or <your tenant>sites/appcatalog/_layouts/15/appStore.aspx/appDetail/WA200001111. The last part of the url is your asset id, i.e. WA200001111. Then you can use the below code to add the app:

    var tenantAppManager = context.GetTenantAppManager();
    var app = tenantAppManager.AddAndDeployStoreApp("WA200001111", CultureInfo.GetCultureInfo(1033).Name, false, true);
    

    The method returns an App instance so that you can further install it to any SharePoint site using apps API.

    Check if an upgrade for an app is available

    Use below API to check whether the upgrade is available for the specific app on a site:

    var tenantAppManager = context.GetTenantAppManager();
    var app = await tenantAppManager.GetAvailableAsync("My App Title");
    var result = await tenantAppManager.IsAppUpgradeAvailableAsync(app.Id);
    

    The method returns true if the app can be upgraded from the app catalog using the most recent version.

    Download MS Teams solution from SharePoint Framework app

    SharePoint Framework solutions might extend MS Teams as well. If you want to download Teams specific component from SharePoint Framework solution, you should use DownloadTeamsSolution method:

    var tenantAppManager = context.GetTenantAppManager();
    var app = await tenantAppManager.GetAvailableAsync("My App Title");
    
    // download MS Teams's solution stream
    using (var stream = await tenantAppManager.DownloadTeamsSolutionAsync(app.Id))
    using (var outputFileStream = new FileStream("teams app.zip", FileMode.Create))
    {
        // save stream to a file
        stream.CopyTo(outputFileStream);
    }
    
    Back to top PnP Core SDK
    Generated by DocFX with Material UI
    spacer