Web:Kemp's SharePoint Document Storage
| Purpose
This document walks an administrator through setting up SharePoint storage for Prime documents from the very beginning. It uses Microsoft Graph PowerShell device authentication for the administrative setup and site-permission grant because that approach avoids the browser-login problems that can occur on some servers and administrative workstations. |
|---|
| Document item | Value |
|---|---|
| Prepared for | Prime Web Application / Prime16 |
| Prepared on | May 6, 2026 |
| Authentication method used for setup | Microsoft Graph PowerShell device code authentication |
| Recommended permission model | Sites.Selected application permission + site-level write grant |
1. What this setup does
Prime can be configured to store uploaded documents in a SharePoint document library instead of keeping the document bytes only inside SQL Server. The setup has two separate parts:
- Prime runtime access: Prime uses an app registration in Microsoft Entra ID to get an app-only token and read/write documents in the selected SharePoint site.
- Administrator setup access: An administrator signs in with Microsoft Graph PowerShell using device authentication to find the SharePoint identifiers and grant the Prime app permission to the specific site.
| Important distinction
Device authentication is used only while setting up and granting access. Prime itself normally uses the Tenant ID, Client ID, and Client Secret or certificate stored in the Prime configuration table to run without an interactive user login. |
|---|
Recommended security model
- Create a dedicated SharePoint site for Prime document storage.
- Give the Prime app the Microsoft Graph Sites. Selected application permission, not broad all-sites access.
- Use the device-authenticated admin session to grant the app write access only to the selected SharePoint site.
- Store the client secret value securely in Prime and rotate it before it expires.
- Use a certificate instead of a client secret when the Prime code/configuration is ready for certificate-based authentication.
2. Before you begin
Accounts and roles
- A Microsoft 365 tenant with SharePoint Online.
- An account that can create or manage the SharePoint site. A SharePoint Administrator or Global Administrator is ideal.
- An account that can create Microsoft Entra app registrations, or an administrator who can create the app registration for you.
- Administrative approval to grant Microsoft Graph application permissions.
Workstation requirements
- Windows PowerShell 5.1 or PowerShell 7 installed on an administrative workstation.
- Internet access to Microsoft 365, Microsoft Graph, and the PowerShell Gallery.
- Ability to open a browser on any device for device-code sign-in. The browser does not have to be on the same computer running PowerShell.
Prime information you should know
- Which Prime organization/customer is being configured.
- Whether SharePoint should be enabled immediately or tested first.
- Where the Prime SharePoint configuration page is located in your installation, usually in an administrative setup area.
- Whether existing SQL-stored documents should be moved to SharePoint after the setup passes testing.
Use a dedicated site rather than mixing Prime documents with a general staff document library. That makes permissions, backups, retention, troubleshooting, and future migration much cleaner.
| Decision | Recommended value | Why it matters |
|---|---|---|
| Site type | Private Team site or other private dedicated SharePoint site | Keeps Prime documents isolated from unrelated files. |
| Site name | Prime Documents or Prime Case Documents | Makes the purpose clear to Microsoft 365 administrators. |
| Document library | Documents, Shared Documents, or a new library such as PrimeDocuments | Prime needs the drive ID for the library it will use. |
| Root folder | Prime or PrimeDocuments | Keeps Prime-created folders/files separated from other library content. |
| Permissions | Limit human access; let Prime app access the site through Graph | Reduces accidental file changes and privacy exposure. |
- Sign in to the Microsoft 365 admin center or SharePoint admin center with an administrator account.
- Open the SharePoint admin center.
- Go to Active sites and choose Create.
- Choose a Team site (use Standard team template) in your tenant. If Microsoft requires a group, create the group and keep membership limited.
- Name the site Prime Documents. The admin user may be made the Group owner.
- Set privacy to Private if the option is shown.
- Finish site creation.
- Open the new site in SharePoint.
- In the new site, create a new document library for Prime. Go to New and choose Document library. Choose a Blank library. Name the library Prime Library.
- Create a top-level folder. Go to Create or upload and choose Folder. Name this folder Client Documents. This folder name will be entered in Prime as the root folder.
| Record this URL
After the site is created, copy the site URL. Example: https://contoso.sharepoint.com/sites/PrimeDocuments. From this URL, the host name is contoso.sharepoint.com and the site path is /sites/PrimeDocuments. Also record the site name, document library name, and top-level folder name. These will all be entered in Prime. |
|---|
5. Register the Prime application in Microsoft Entra ID
Open the Microsoft Entra admin center.
Go to App registrations.
Select New registration.
Name the application Prime SharePoint Document Storage.
For supported account types, choose Single tenant only.
Leave Redirect URI blank. Prime document storage is an app-only/background integration and does not need a browser redirect for normal file storage.
Select Register.
On the app Overview page, copy the Application (client) ID and Directory (tenant) ID. You will enter both in Prime later.
| Do not confuse IDs
The Application (client) ID identifies the Prime app registration. The Directory (tenant) ID identifies the Microsoft 365 tenant. Prime needs both. |
|---|
6. Add the Microsoft Graph API permission
In the app registration, open API permissions.
Choose Add a permission.
Choose Microsoft Graph.
Choose Application permissions, not Delegated permissions.
Search for Sites.Selected.
Select Sites.Selected, then choose Add permissions.
Choose Grant admin consent for the tenant, then confirm.
Verify the permission status shows granted for the tenant.
| Why Sites.Selected
Sites.Selected allows the app to access only site collections that are separately granted to it. The site-specific grant is performed later with device-authenticated Microsoft Graph PowerShell. |
|---|
| Avoid broad permissions
Do not grant Sites.ReadWrite.All, Sites.FullControl.All, Files.ReadWrite.All, or other broad application permissions to the Prime app unless you intentionally want Prime to access much more than the single selected site. Sites.Selected plus the site grant is the safer pattern. |
|---|
7. Create the app credential used by Prime
In the same app registration, open Certificates & secrets.
For a first setup, choose Client secrets > New client secret.
Enter the description as Prime SharePoint Production Secret.
Choose an expiration period and record the expiration date in your maintenance calendar.
Select Add.
Immediately copy the secret Value. This is the only time Microsoft shows the value.
Store the value securely and enter it into Prime only through the Prime configuration page or other approved secure setup process.
| Production security note
Microsoft recommends certificates over client secrets for production confidential-client applications. If Prime is later updated to support certificate authentication for this integration, prefer a certificate and store/manage it securely. |
|---|
On a Windows machine, open Windows PowerShell ISE. Make sure you can see the Script Pane (View🡪Show Script Pane is checked). In the script pane—typically on the top with a blank line numbered one—copy and paste the following script and save this as a ps1 file:
Show PowerShell script
# ============================================================
# Prime SharePoint setup - clean Graph/device-auth version
# ============================================================
# Tenant/app/site values
$tenantId = "PASTE-DIRECTORY-TENANT-ID-HERE"
$appClientId = "PASTE-APPLICATION-CLIENT-ID-HERE"
$appClientSecret = "PASTE-CLIENT-SECRET-VALUE-HERE"
# SharePoint host and path
# IMPORTANT: no https:// in the host name
$sharePointHostName = "PASTE-SHAREPOINT-HOSTNAME-HERE" #Example: "contoso0.sharepoint.com"
$sitePath = "/sites/PrimeDocuments"
# Friendly display name for the app permission grant
$appDisplayName = "Prime SharePoint Documents"
Read-Host "Press Enter to start"
# ------------------------------------------------------------
# 1. Load Graph modules
# ------------------------------------------------------------
Write-Host "Installing and importing modules. Please be patient."
Install-Module Microsoft.Graph -Scope CurrentUser -Force -AllowClobber
Import-Module Microsoft.Graph.Authentication
Import-Module Microsoft.Graph.Sites
Write-Host “”
Write-Host “Finished installation and importing of modules.”
Write-Host “”
Write-Host “”
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 2. Fresh device-code admin login
# ------------------------------------------------------------
Write-Host "Starting administrative login. Use an account with administrative rights to Microsoft systems."
Disconnect-MgGraph -ErrorAction SilentlyContinue
Connect-MgGraph `
-TenantId $tenantId `
-Scopes "User.Read","Sites.Read.All","Sites.FullControl.All" `
-UseDeviceCode `
-ContextScope Process `
-NoWelcome
Write-Host ""
Write-Host "Graph context:"
Get-MgContext | Format-List
# Test delegated login
Write-Host ""
Write-Host "Testing delegated Graph login..."
Invoke-MgGraphRequest `
-Method GET `
-Uri "https://graph.microsoft.com/v1.0/me" | Out-Host
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 3. Get SharePoint site
# ------------------------------------------------------------
$siteUri = "https://graph.microsoft.com/v1.0/sites/{0}:{1}" -f $sharePointHostName, $sitePath
Write-Host ""
Write-Host "Looking up site:"
Write-Host $siteUri
$site = Invoke-MgGraphRequest `
-Method GET `
-Uri $siteUri
$siteId = $site["id"]
Write-Host ""
Write-Host "Site:"
[PSCustomObject]@{
Id = $site["id"]
DisplayName = $site["displayName"]
WebUrl = $site["webUrl"]
} | Format-List
Write-Host "Admin login section complete."
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 4. Get document library / drive
# ------------------------------------------------------------
Write-Host ""
Write-Host "Getting document libraries..."
$drives = Invoke-MgGraphRequest `
-Method GET `
-Uri "https://graph.microsoft.com/v1.0/sites/$siteId/drives"
$drives["value"] | ForEach-Object {
[PSCustomObject]@{
Name = $_["name"]
Id = $_["id"]
WebUrl = $_["webUrl"]
}
} | Format-Table -AutoSize
$drive = $drives["value"] | Where-Object { $_["name"] -eq "Documents" } | Select-Object -First 1
if ($null -eq $drive) {
throw "Could not find a document library named 'Documents'. Review the library list above and select the correct one manually."
}
$driveId = $drive["id"]
Write-Host ""
Write-Host "Selected drive:"
[PSCustomObject]@{
Name = $drive["name"]
Id = $drive["id"]
WebUrl = $drive["webUrl"]
} | Format-List
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 5. Grant Prime app write access to this site
# ------------------------------------------------------------
Write-Host ""
Write-Host "Granting app access to selected SharePoint site..."
$permissionBody = @{
roles = @(
"write"
)
grantedToIdentities = @(
@{
application = @{
id = $appClientId
displayName = $appDisplayName
}
}
)
}
$permission = Invoke-MgGraphRequest `
-Method POST `
-Uri "https://graph.microsoft.com/v1.0/sites/$siteId/permissions" `
-Body ($permissionBody | ConvertTo-Json -Depth 10) `
-ContentType "application/json"
Write-Host ""
Write-Host "Created permission:"
$permission | Out-Host
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 6. Verify permission grant
# ------------------------------------------------------------
Write-Host ""
Write-Host "Current site permission grants:"
$sitePermissions = Invoke-MgGraphRequest `
-Method GET `
-Uri "https://graph.microsoft.com/v1.0/sites/$siteId/permissions"
$sitePermissions["value"] | ForEach-Object {
$app = $null
if ($_["grantedToIdentitiesV2"]) {
$app = $_["grantedToIdentitiesV2"][0]["application"]
} elseif ($_["grantedToIdentities"]) {
$app = $_["grantedToIdentities"][0]["application"]
}
[PSCustomObject]@{
PermissionId = $_["id"]
Roles = ($_[ "roles" ] -join ", ")
AppId = if ($app) { $app["id"] } else { "" }
AppName = if ($app) { $app["displayName"] } else { "" }
}
} | Format-Table -AutoSize
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 7. Test app-only access with client secret
# ------------------------------------------------------------
Write-Host ""
Write-Host "Testing app-only access..."
$tokenResponse = Invoke-RestMethod `
-Method POST `
-Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" `
-ContentType "application/x-www-form-urlencoded" `
-Body @{
client_id = $appClientId
scope = "https://graph.microsoft.com/.default"
client_secret = $appClientSecret
grant_type = "client_credentials"
}
$appToken = $tokenResponse.access_token
$appDriveRoot = Invoke-RestMethod `
-Method GET `
-Uri "https://graph.microsoft.com/v1.0/drives/$driveId/root" `
-Headers @{
Authorization = "Bearer $appToken"
}
Write-Host ""
Write-Host "App-only drive root test succeeded:"
$appDriveRoot | Format-List
Read-Host "Press Enter to continue"
# ------------------------------------------------------------
# 8. Output values for Prime
# ------------------------------------------------------------
Write-Host ""
Write-Host "============================================================"
Write-Host "VALUES FOR PRIME"
Write-Host "============================================================"
Write-Host "Tenant ID:"
Write-Host $tenantId
Write-Host ""
Write-Host "Client ID:"
Write-Host $appClientId
Write-Host ""
Write-Host "SharePoint Host Name:"
Write-Host $sharePointHostName
Write-Host ""
Write-Host "Site Path:"
Write-Host $sitePath
Write-Host ""
Write-Host "Site ID:"
Write-Host $siteId
Write-Host ""
Write-Host "Drive ID:"
Write-Host $driveId
Write-Host "============================================================"
# Copy the two longest values to clipboard in a useful block
@"
Tenant ID: $tenantId
Client ID: $appClientId
SharePoint Host Name: $sharePointHostName
Site Path: $sitePath
Site ID: $siteId
Drive ID: $driveId
"@ | Set-Clipboard
Write-Host ""
Write-Host "Prime values copied to clipboard."
Replace the four values at the top, including $tenantId, $appClientId, $appClientSecret, and $sharePointHostName. The $tenantId and $appClientId entries come from the API registration. The $appClientSecret comes from the API client secret gathered before. The $sharePointHostName comes from the beginning of the URL to your new SharePoint site.
9. Enter the values into Prime
After the Microsoft 365 side is ready, open Prime and go to the SharePoint configuration/setup page for the organization. The exact menu label may vary by installation, but it should be in the administrator/system setup area.
| Prime setup field | Enter this value | Where to get it |
|---|---|---|
| Enable SharePoint / Use SharePoint | Checked / True | Prime setup page |
| Tenant ID / Directory ID | Directory (tenant) ID | Microsoft Entra app Overview page |
| Client ID / Application ID | Application (client) ID | Microsoft Entra app Overview page |
| Client Secret | Secret Value | Certificates & secrets page immediately after creating the secret |
| SharePoint Host Name | Example: contoso.sharepoint.com | From the SharePoint site URL or PowerShell output |
| Site Path | Example: /sites/PrimeDocuments | From the SharePoint site URL or PowerShell output |
| Site ID | Long ID containing host and GUIDs | PowerShell output from the site lookup |
| Drive ID | Long document-library drive ID | PowerShell output from the drive list |
| Document Library Name | Documents or your chosen library | PowerShell drive list |
| Root Folder | Prime, PrimeDocuments, or blank if not used | Your SharePoint design decision |
| Secret handling
Paste the client secret Value, not the Secret ID. The Secret ID is only an identifier for the credential. The Value is the password-like string Prime uses to authenticate. |
|---|
10. Test the setup
Recommended Prime test sequence
Save the SharePoint settings in Prime but leave broad rollout disabled if your setup page has a test mode.
Use the Prime test button, if available. A complete test should confirm token acquisition, site access, drive access, upload, download/read, and cleanup of a test file.
Upload a small harmless test PDF or text file to a test case in Prime.
Open the SharePoint library in a browser and confirm the file appeared in the expected folder.
Open or download the file from Prime and confirm it loads correctly.
Edit the document notes/category/metadata in Prime if those fields are part of your system and verify the file remains accessible.
Only after the test succeeds should you enable SharePoint for live staff use.
Manual Graph smoke test
If Prime says SharePoint is unavailable, use this PowerShell test to confirm the app can reach the site. This checks the administrative grant path; Prime may also have its own application-token test.
! # Confirm the permission exists on the target site. Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/sites/$siteId/permissions" | ConvertTo-Json -Depth 10 # Confirm the drive is visible to the admin session. Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/v1.0/drives/$driveId" | Select-Object id, name, webUrl
After SharePoint is working, Prime may show tools for moving documents that are still stored in SQL over to SharePoint. The exact button names may differ by page, but the safe migration approach is the same.
Move one test file first
Open a test case with at least one SQL-stored document.
Select one non-critical document.
Use the button that moves that file from SQL to SharePoint.
Confirm the file appears in SharePoint.
Confirm the file opens/downloads correctly from Prime.
Confirm the file review/details area now shows SharePoint storage instead of SQL storage.
Then use Move All for the case
Use Move All SQL Files to SharePoint only after the one-file test succeeds.
Run it on one case first, not the whole database.
Review the result list or error messages.
Open several moved files from Prime and directly in SharePoint.
After confidence is established, repeat case by case or according to your planned migration process.
| Expected button visibility
Migration buttons should appear only when SharePoint is enabled and available for the organization. If SharePoint is not configured or the test fails, staff should not be offered a move-to-SharePoint action. |
|---|
12. Ongoing maintenance
| Maintenance item | Recommended practice |
|---|---|
| Client secret expiration | Track the expiration date. Create a replacement secret before the old one expires, update Prime, test, then remove the old secret. |
| App permissions | Periodically confirm the app has Sites.Selected and only the needed site-level grant. |
| SharePoint site membership | Keep human site membership limited to administrators and approved staff. |
| Backups/retention | Ensure SharePoint retention, backup, and legal hold practices match your organization’s document requirements. |
| Prime testing | After Prime updates, run the SharePoint test and upload/download a small file before broad use. |
| Audit | Review SharePoint and Entra audit logs according to your organization’s security policy. |
13. Troubleshooting
| Problem | Likely cause | What to do |
|---|---|---|
| Connect-MgGraph appears to do nothing | Existing cached session, hidden prompt, embedded console, or suppressed welcome text | Run Get-MgContext. If no context exists, remove -NoWelcome, add -Verbose, use -UseDeviceAuthentication, and run from a normal PowerShell window. |
| Device code appears but sign-in fails | Wrong tenant or account lacks admin rights | Confirm the Directory tenant ID and sign in with a SharePoint Administrator or Global Administrator. |
| New-MgSitePermission returns access denied | Admin session lacks Sites.FullControl.All or user lacks required admin role | Reconnect with -Scopes Sites.FullControl.All and sign in as SharePoint Administrator or higher. |
| Prime test says invalid client secret | Secret ID was entered instead of secret Value, or the secret expired | Create a new client secret and paste the Value into Prime. |
| Prime test says unauthorized or access denied | Sites.Selected was not granted admin consent or site permission was not granted | Confirm API permission admin consent and rerun New-MgSitePermission for the correct site ID. |
| Wrong SharePoint site is used | Host/path copied incorrectly | Recheck the URL. Host is only the domain; site path starts with /sites/ or /teams/. |
| Wrong library is used | Drive ID from a different document library | Rerun the drive list command and copy the drive ID for the correct library. |
| Migration button does not work | SharePoint config unavailable, JavaScript/postback issue, or server-side error | First confirm the Prime SharePoint test succeeds; then check server logs and browser developer tools for the click/postback error. |
| Files upload but do not open | Path encoding, filename, or permission issue | Test with a simple filename first, then check special characters, folder path, and Graph response/error logs. |
Appendix A. Values worksheet
| Done | Task | Notes / value |
|---|---|---|
| ☐ | Create dedicated SharePoint site | Site name: ______________________________ |
| ☐ | Create/select document library | Library name: ___________________________ |
| ☐ | Record SharePoint URL | URL: ____________________________________ |
| ☐ | Record host name | Host: ___________________________________ |
| ☐ | Record site path | Path: ___________________________________ |
| ☐ | Create Entra app registration | App name: _______________________________ |
| ☐ | Record tenant ID | Tenant ID: ______________________________ |
| ☐ | Record client ID | Client ID: ______________________________ |
| ☐ | Add Sites.Selected application permission | Granted admin consent: Yes / No |
| ☐ | Create client secret | Expiration date: _________________________ |
| ☐ | Record site ID from PowerShell | Site ID: ________________________________ |
| ☐ | Record drive ID from PowerShell | Drive ID: _______________________________ |
| ☐ | Grant site permission with device auth | Role: read / write / other: _____________ |
| ☐ | Enter settings in Prime | Completed by: ___________________________ |
| ☐ | Run Prime SharePoint test | Result/date: ____________________________ |
| ☐ | Move one SQL-stored test file | Result/date: ____________________________ |
Appendix B. Source references
These references were used to align the setup steps with current Microsoft documentation:
- Microsoft Learn: Register an application in Microsoft Entra ID — https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app
- Microsoft Learn: Add and manage application credentials in Microsoft Entra ID — https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials
- Microsoft Learn: Connect-MgGraph — https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph
- Microsoft Learn: Get a SharePoint site resource by path — https://learn.microsoft.com/en-us/graph/api/site-getbypath
- Microsoft Learn: List drives — https://learn.microsoft.com/en-us/graph/api/drive-list
- Microsoft Learn: Create permission on a site — https://learn.microsoft.com/en-us/graph/api/site-post-permissions
- Microsoft Learn: Microsoft Graph permissions reference — https://learn.microsoft.com/en-us/graph/permissions-reference