Get-MsolServicePrincipalCredential - how to get the expiration date for a clientId

The fastest way to verify your Client Id and Client Secret are valid with PowerShell

This post was most recently updated on August 31st, 2022.

5 min read.

So, you have a Client Id and a Client Secret, but don’t know if they work anymore? Maybe they are expired? Maybe someone removed them? Maybe you copy-pasted them from the wrong Key Vault and they belong to another tenant?

No worries! We can use PowerShell to validate them.

This article explains a simple way to validate and debug your client id and client secret using PowerShell.

Solution

By using PowerShell, it’s fairly straightforward to verify, that your Client Id and Client Secret work. This article shows how to do that and explains a few different things that might go wrong. Well, quite a few different things that could go wrong, really :)

Time needed: 10 minutes

How to verify your Microsoft 365 / Office 365 Client Id and Client Secret are valid using PowerShell?

  1. First, we validate, that the values work.

    This can be done by running a simple PowerShell script, as shown here: https://www.koskila.net/fastest-way-to-verify-your-client-id-and-client-secret-are-valid-with-powershell/#validate

  2. If they’re invalid, validate the expiration

    If they don’t work, let’s run another script to see if the Client Id exists but has expired. A snippet for that is shown here:
    https://www.koskila.net/fastest-way-to-verify-your-client-id-and-client-secret-are-valid-with-powershell/#expired

  3. If you’re having issues in general, verify other configuration issues

    Of course, plenty of other things could go wrong as well! See this part of the article for some additional pointers:
    https://www.koskila.net/fastest-way-to-verify-your-client-id-and-client-secret-are-valid-with-powershell/#other

See the snippets below for the 2 different steps:

Validate your Client Id by trying to connect with it

We can validate the Client Id and Secret, by using Connect-PnPOnline to connect to SharePoint Online. 

In other words, in the example, I’m using the PnP PowerShell commandlets to authenticate against a SharePoint Online site, using a Client Id (called AppId) and a Client Secret (called App Secret).

# First, we install the PnP cmdlets in case we don't have them already
Install-Module -Name "PnP.PowerShell"

# If you have them, let's import the module!
Import-Module -Name "PnP.PowerShell"

# After this, we can run Connect-PnPOnline
Connect-PnPOnline -Url [your_sharepoint_site_url] -ClientId [clientId] -ClientSecret [clientSecret]

This shouldn’t return anything. That just means the AppId (or “Client id”) and AppSecret (“Client Secret”) are valid.

However, that doesn’t necessarily mean it works for your use case exactly. A good thing to try might be to try requesting the current SPWeb object to see if you have permission to access it. See an example below:

# Running the command below will return information about your context - pay attention to the "AuthenticationMode". It shouldn't be "Anonymous".

PS C:\> Get-PnPContext

RetryCount                   : 10
Delay                        : 1000
PropertyBag                  : {}
Web                          : Microsoft.SharePoint.Client.Web
Site                         : Microsoft.SharePoint.Client.Site
RequestResources             : Microsoft.SharePoint.Client.RequestResources
FormDigestHandlingEnabled    : True
ServerVersion                : 16.0.8720.1220
Url                          : https://contoso.sharepoint.com
ApplicationName              : SharePoint PnP PowerShell Library
ClientTag                    : 
DisableReturnValueCache      : True
ValidateOnClient             : True
AuthenticationMode           : Default
FormsAuthenticationLoginInfo :
Credentials                  : Microsoft.SharePoint.Client.SharePointOnlineCredentials
WebRequestExecutorFactory    : Microsoft.SharePoint.Client.DefaultWebRequestExecutorFactory
PendingRequest               : Microsoft.SharePoint.Client.ClientRequest
HasPendingRequest            : False
Tag                          :
RequestTimeout               : 1800000
StaticObjects                : {[Microsoft$SharePoint$SPContext$Current, Microsoft.SharePoint.Client.RequestContext], [
                               Microsoft$SharePoint$TenantSettings$Current, Microsoft.SharePoint.Client.TenantSettings]
                               }
ServerSchemaVersion          : 15.0.0.0
ServerLibraryVersion         : 16.0.8720.1220
RequestSchemaVersion         : 15.0.0.0
TraceCorrelationId           : 

# The one below fetches the current web, and shouldn't throw an error either.
PS C:\> Get-PnPWeb

Title       ServerRelativeUrl  Id
-----       -----------------  --
Test /sites/test

In case that didn’t work, your principal might have expired, or your values are simply not valid. This should lead to an authentication error!

"connect-pnponline : Token request failed." when running Connect-PnpOnline with AppId and AppSecret.
“connect-pnponline : Token request failed.” when running Connect-PnpOnline with AppId and AppSecret.

Check your Client Id’s expiration date

To verify that the Client Id hasn’t expired, but rather is still valid, we’ll query the service principals in PowerShell using some of the available cmdlets. See below for different options…

Azure AD v1 (MSOnline)

You can run this in SharePoint Online Management Shell or Windows PowerShell:

# First, we install the cmdlets in case we don't have them already
Install-Module MSOnline

# If you have them already, let's import the module!
Import-Module MSOnline

# Then connect 
Connect-MSOLService
(Get-MsolServicePrincipalCredential -AppPrincipalId [clientId] -ReturnKeyValues $true).EndDate.ToShortDateString() | select -first 1

This (almost) one-liner will get all valid entries with your clientId (it’ll probably return 3 service principals), then fish out their end dates, and pick the first one.

You should get just a short date in the response.

But wait! What if you don’t have MSOnline (Azure AD v1 cmdlets) installed? What if you hate legacy technology, and want to only use the coolest new commandlets? I actually got a question about this on Twitter – how to query the end date with Azure AD v2 cmdlets?

Azure AD v2 (AzureAD)

It’s not that difficult, luckily! See below for a script sample:

# This is only needed, if you don't have AzureAD (v2) cmdlets installed already
Install-Module AzureAD

# If you have them already, we'll import the package
Import-Module AzureAD

# Then we connect, and query for the service principals
Connect-AzureAD
(Get-AzureADServicePrincipal -All $true -Filter "appId eq '[clientId]'").KeyCredentials.EndDate.ToShortDateString() | select -first 1

Not that complicated either! You should get just a short date in the response.

Note that you’ll need to use single quotes for the filter statement – otherwise PowerShell will fail miserably at parsing your filter!

Other configuration issues

This section contains some notes on what other things can go wrong. Because apparently, a lot of things could.

TLS deprecation 😬

If you’re getting errors somewhat like the ones below:

The underlying connection was closed: An unexpected error occurred on a send.

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Check out this blog post:

ClientId and ClientSecret are valid but authentication fails for all add-ins.

Your tenant might’ve been hit by the CustomAppAuthentication -issue, as Peter points out in the comments. I’ve posted about the solution here:

Note on ClientId and ClientSecret

If you ended up on this page looking for instructions on how to generate client id and client secrets in SharePoint Online, please note that nowadays you can either register them directly in SharePoint or simply create them in Azure AD like any app principal. The latter model is definitely the recommended way, as you can specify it to never expire (if you’re using PowerShell, or 2 years if you’re using the GUI) and have better control and transparency of your app anyway.

There are awesome articles online about this already, so I’m not going to explain it further – this blog post by Microsoft MVP Sergei Sergeev describes the steps really well, so check it out instead!

I’m getting an error about existing commandlet names!

If you’re getting an error like the below (sorry – it’s a bit long):

PackageManagement\Install-Package : The following commands are already available on this system:'Export-PnPClientSidePa
ge,Export-PnPClientSidePageMapping,Get-PnPAvailableClientSideComponents,Get-PnPClientSideComponent,Get-PnPClientSidePag
e,Get-PnPMicrosoft365GroupMembers,Get-PnPMicrosoft365GroupOwners,Invoke-PnPSearchQuery,Move-PnPClientSideComponent,Remo
ve-PnPClientSideComponent,Remove-PnPClientSidePage,Save-PnPClientSidePageConversionLog,Set-PnPClientSidePage,Set-PnPCli
entSideText,Set-PnPClientSideWebPart,Add-PnPAlert,Add-PnPApp,Add-PnPApplicationCustomizer,Add-PnPContentType,Add-PnPCon
tentTypeToDocumentSet,Add-PnPContentTypeToList,Add-PnPCustomAction,Add-PnPDocumentSet,Add-PnPEventReceiver,Add-PnPField
,Add-PnPFieldFromXml,Add-PnPFieldToContentType,Add-PnPFile,Add-PnPFolder,Add-PnPHtmlPublishingPageLayout,Add-PnPHubSite
Association,Add-PnPIndexedProperty,Add-PnPJavaScriptBlock,Add-PnPJavaScriptLink,Add-PnPListItem,Add-PnPMasterPage,Add-P
nPMicrosoft365GroupMember,Add-PnPMicrosoft365GroupOwner,Add-PnPMicrosoft365GroupToSite,Add-PnPNavigationNode,Add-PnPOrg
AssetsLibrary,Add-PnPOrgNewsSite,Add-PnPPublishingImageRendition,Add-PnPPublishingPage,Add-PnPPublishingPageLayout,Add-
PnPRoleDefinition,Add-PnPSiteClassification,Add-PnPSiteCollectionAdmin,Add-PnPSiteCollectionAppCatalog,Add-PnPSiteDesig
n,Add-PnPSiteDesignTask,Add-PnPSiteScript,Add-PnPStoredCredential,Add-PnPTaxonomyField,Add-PnPTeamsChannel,Add-PnPTeams
Tab,Add-PnPTeamsTeam,Add-PnPTeamsUser,Add-PnPTenantCdnOrigin,Add-PnPTenantSequence,Add-PnPTenantSequenceSite,Add-PnPTen
antSequenceSubSite,Add-PnPTenantTheme,Add-PnPView,Add-PnPWebhookSubscription,Add-PnPWebPartToWebPartPage,Add-PnPWebPart
ToWikiPage,Add-PnPWikiPage,Approve-PnPTenantServicePrincipalPermissionRequest,Clear-PnPDefaultColumnValues,Clear-PnPLis
tItemAsRecord,Clear-PnPMicrosoft365GroupMember,Clear-PnPMicrosoft365GroupOwner,Clear-PnPRecycleBinItem,Clear-PnPTenantA
ppCatalogUrl,Clear-PnPTenantRecycleBinItem,Connect-PnPOnline,Copy-PnPFile,Deny-PnPTenantServicePrincipalPermissionReque
st,Disable-PnPFeature,Disable-PnPSharingForNonOwnersOfSite,Disable-PnPSiteClassification,Disable-PnPTenantServicePrinci
pal,Disconnect-PnPOnline,Enable-PnPCommSite,Enable-PnPFeature,Enable-PnPSiteClassification,Enable-PnPTenantServicePrinc
ipal,Export-PnPTaxonomy,Export-PnPTermGroupToXml,Find-PnPFile,Get-PnPAccessToken,Get-PnPAlert,Get-PnPApp,Get-PnPAppAuth
AccessToken,Get-PnPApplicationCustomizer,Get-PnPAuditing,Get-PnPAuthenticationRealm,Get-PnPAvailableLanguage,Get-PnPAzu
reCertificate,Get-PnPConnection,Get-PnPContentType,Get-PnPContentTypePublishingHubUrl,Get-PnPContext,Get-PnPCustomActio
n,Get-PnPDefaultColumnValues,Get-PnPDeletedMicrosoft365Group,Get-PnPDocumentSetTemplate,Get-PnPEventReceiver,Get-PnPExc
eption,Get-PnPFeature,Get-PnPField,Get-PnPFile,Get-PnPFileVersion,Get-PnPFolder,Get-PnPFolderItem,Get-PnPFooter,Get-PnP
GraphAccessToken,Get-PnPGraphSubscription,Get-PnPGroup,Get-PnPGroupPermissions,Get-PnPHideDefaultThemes,Get-PnPHomePage
,Get-PnPHomeSite,Get-PnPHubSite,Get-PnPHubSiteChild,Get-PnPIndexedPropertyKeys,Get-PnPInPlaceRecordsManagement,Get-PnPI
sSiteAliasAvailable,Get-PnPJavaScriptLink,Get-PnPKnowledgeHubSite,Get-PnPLabel,Get-PnPList,Get-PnPListInformationRights
Management,Get-PnPListItem,Get-PnPListRecordDeclaration,Get-PnPMasterPage,Get-PnPMicrosoft365Group,Get-PnPNavigationNod
e,Get-PnPOrgAssetsLibrary,Get-PnPOrgNewsSite,Get-PnPPowerShellTelemetryEnabled,Get-PnPProperty,Get-PnPPropertyBag,Get-P
nPPublishingImageRendition,Get-PnPRecycleBinItem,Get-PnPRequestAccessEmails,Get-PnPRoleDefinition,Get-PnPSearchConfigur
ation,Get-PnPSearchCrawlLog,Get-PnPSearchSettings,Get-PnPSharingForNonOwnersOfSite,Get-PnPSite,Get-PnPSiteClassificatio
n,Get-PnPSiteClosure,Get-PnPSiteCollectionAdmin,Get-PnPSiteCollectionTermStore,Get-PnPSiteDesign,Get-PnPSiteDesignRight
s,Get-PnPSiteDesignRun,Get-PnPSiteDesignRunStatus,Get-PnPSiteDesignTask,Get-PnPSitePolicy,Get-PnPSiteScript,Get-PnPSite
ScriptFromList,Get-PnPSiteScriptFromWeb,Get-PnPSiteSearchQueryResults,Get-PnPStorageEntity,Get-PnPStoredCredential,Get-
PnPTaxonomyItem,Get-PnPTaxonomySession,Get-PnPTeamsApp,Get-PnPTeamsChannel,Get-PnPTeamsChannelMessage,Get-PnPTeamsTab,G
et-PnPTeamsTeam,Get-PnPTeamsUser,Get-PnPTenant,Get-PnPTenantAppCatalogUrl,Get-PnPTenantCdnEnabled,Get-PnPTenantCdnOrigi
n,Get-PnPTenantCdnPolicies,Get-PnPTenantId,Get-PnPTenantRecycleBinItem,Get-PnPTenantSequence,Get-PnPTenantSequenceSite,
Get-PnPTenantServicePrincipal,Get-PnPTenantServicePrincipalPermissionGrants,Get-PnPTenantServicePrincipalPermissionRequ
ests,Get-PnPTenantSite,Get-PnPTenantSyncClientRestriction,Get-PnPTenantTemplate,Get-PnPTenantTheme,Get-PnPTerm,Get-PnPT
ermGroup,Get-PnPTermSet,Get-PnPTheme,Get-PnPTimeZoneId,Get-PnPUnifiedAuditLog,Get-PnPUPABulkImportStatus,Get-PnPUser,Ge
t-PnPUserOneDriveQuota,Get-PnPUserProfileProperty,Get-PnPView,Get-PnPWeb,Get-PnPWebhookSubscriptions,Get-PnPWebPart,Get
-PnPWebPartProperty,Get-PnPWebPartXml,Get-PnPWebTemplates,Get-PnPWikiPageContent,Grant-PnPHubSiteRights,Grant-PnPSiteDe
signRights,Grant-PnPTenantServicePrincipalPermission,Import-PnPTaxonomy,Import-PnPTermGroupFromXml,Import-PnPTermSet,In
stall-PnPApp,Invoke-PnPQuery,Invoke-PnPSiteDesign,Invoke-PnPSPRestMethod,Invoke-PnPWebAction,Measure-PnPList,Measure-Pn
PWeb,Move-PnPFile,Move-PnPFolder,Move-PnPListItemToRecycleBin,Move-PnPRecycleBinItem,New-PnPAzureCertificate,New-PnPExt
ensibilityHandlerObject,New-PnPGraphSubscription,New-PnPGroup,New-PnPList,New-PnPMicrosoft365Group,New-PnPPersonalSite,
New-PnPSite,New-PnPTeamsApp,New-PnPTeamsTeam,New-PnPTenantSequence,New-PnPTenantSequenceCommunicationSite,New-PnPTenant
SequenceTeamNoGroupSite,New-PnPTenantSequenceTeamNoGroupSubSite,New-PnPTenantSequenceTeamSite,New-PnPTenantSite,New-PnP
TenantTemplate,New-PnPTerm,New-PnPTermGroup,New-PnPTermLabel,New-PnPTermSet,New-PnPUPABulkImportJob,New-PnPUser,New-PnP
Web,Publish-PnPApp,Read-PnPTenantTemplate,Register-PnPAppCatalogSite,Register-PnPHubSite,Register-PnPManagementShellAcc
ess,Remove-PnPAlert,Remove-PnPApp,Remove-PnPApplicationCustomizer,Remove-PnPContentType,Remove-PnPContentTypeFromDocume
ntSet,Remove-PnPContentTypeFromList,Remove-PnPCustomAction,Remove-PnPDeletedMicrosoft365Group,Remove-PnPEventReceiver,R
emove-PnPField,Remove-PnPFieldFromContentType,Remove-PnPFile,Remove-PnPFileVersion,Remove-PnPFolder,Remove-PnPGraphSubs
cription,Remove-PnPGroup,Remove-PnPHomeSite,Remove-PnPHubSiteAssociation,Remove-PnPIndexedProperty,Remove-PnPJavaScript
Link,Remove-PnPKnowledgeHubSite,Remove-PnPList,Remove-PnPListItem,Remove-PnPMicrosoft365Group,Remove-PnPMicrosoft365Gro
upMember,Remove-PnPMicrosoft365GroupOwner,Remove-PnPNavigationNode,Remove-PnPOrgAssetsLibrary,Remove-PnPOrgNewsSite,Rem
ove-PnPPropertyBagValue,Remove-PnPPublishingImageRendition,Remove-PnPRoleDefinition,Remove-PnPSearchConfiguration,Remov
e-PnPSiteClassification,Remove-PnPSiteCollectionAdmin,Remove-PnPSiteCollectionAppCatalog,Remove-PnPSiteDesign,Remove-Pn
PSiteDesignTask,Remove-PnPSiteScript,Remove-PnPStorageEntity,Remove-PnPStoredCredential,Remove-PnPTaxonomyItem,Remove-P
nPTeamsApp,Remove-PnPTeamsChannel,Remove-PnPTeamsTab,Remove-PnPTeamsTeam,Remove-PnPTeamsUser,Remove-PnPTenantCdnOrigin,
Remove-PnPTenantSite,Remove-PnPTenantTheme,Remove-PnPTermGroup,Remove-PnPUser,Remove-PnPView,Remove-PnPWeb,Remove-PnPWe
nPReIndexList,Request-PnPReIndexWeb,Reset-PnPFileVersion,Reset-PnPLabel,Reset-PnPMicrosoft365GroupExpiration,Reset-PnPU
serOneDriveQuotaToDefault,Resolve-PnPFolder,Restore-PnPDeletedMicrosoft365Group,Restore-PnPFileVersion,Restore-PnPRecyc
leBinItem,Restore-PnPTenantRecycleBinItem,Revoke-PnPHubSiteRights,Revoke-PnPSiteDesignRights,Revoke-PnPTenantServicePri
ncipalPermission,Save-PnPTenantTemplate,Send-PnPMail,Set-PnPApplicationCustomizer,Set-PnPAppSideLoading,Set-PnPAuditing
,Set-PnPAvailablePageLayouts,Set-PnPContext,Set-PnPDefaultColumnValues,Set-PnPDefaultContentTypeToList,Set-PnPDefaultPa
geLayout,Set-PnPDocumentSetField,Set-PnPField,Set-PnPFileCheckedIn,Set-PnPFileCheckedOut,Set-PnPFolderPermission,Set-Pn
PFooter,Set-PnPGraphSubscription,Set-PnPGroup,Set-PnPGroupPermissions,Set-PnPHideDefaultThemes,Set-PnPHomePage,Set-PnPH
omeSite,Set-PnPHubSite,Set-PnPIndexedProperties,Set-PnPInPlaceRecordsManagement,Set-PnPKnowledgeHubSite,Set-PnPLabel,Se
t-PnPList,Set-PnPListInformationRightsManagement,Set-PnPListItem,Set-PnPListItemAsRecord,Set-PnPListItemPermission,Set-
PnPListPermission,Set-PnPListRecordDeclaration,Set-PnPMasterPage,Set-PnPMicrosoft365Group,Set-PnPMinimalDownloadStrateg
y,Set-PnPPropertyBagValue,Set-PnPRequestAccessEmails,Set-PnPSearchConfiguration,Set-PnPSearchSettings,Set-PnPSite,Set-P
nPSiteClosure,Set-PnPSiteDesign,Set-PnPSitePolicy,Set-PnPSiteScript,Set-PnPStorageEntity,Set-PnPTaxonomyFieldValue,Set-
PnPTeamifyPromptHidden,Set-PnPTeamsChannel,Set-PnPTeamsTab,Set-PnPTeamsTeam,Set-PnPTeamsTeamArchivedState,Set-PnPTeamsT
eamPicture,Set-PnPTenant,Set-PnPTenantAppCatalogUrl,Set-PnPTenantCdnEnabled,Set-PnPTenantCdnPolicy,Set-PnPTenantSite,Se
t-PnPTenantSyncClientRestriction,Set-PnPTermGroup,Set-PnPTermSet,Set-PnPTheme,Set-PnPTraceLog,Set-PnPUserOneDriveQuota,
Set-PnPUserProfileProperty,Set-PnPView,Set-PnPWeb,Set-PnPWebhookSubscription,Set-PnPWebPartProperty,Set-PnPWebPermissio
n,Set-PnPWebTheme,Set-PnPWikiPageContent,Submit-PnPSearchQuery,Submit-PnPTeamsChannelMessage,Sync-PnPAppToTeams,Test-Pn
PListItemIsRecord,Test-PnPTenantTemplate,Uninstall-PnPApp,Unpublish-PnPApp,Unregister-PnPHubSite,Update-PnPApp,Update-P
nPSiteClassification,Update-PnPTeamsApp'. This module 'SharePointPnPPowerShellOnline' may override the existing
commands. If you still want to install this module 'SharePointPnPPowerShellOnline', use -AllowClobber parameter.

It might mean you’ve got the legacy version of the commandlets (SharePointPnPPowerShellOnline) installed instead of the current one (PnP.PowerShell), and installing or importing the new version might cause you to encounter this issue.

You can get rid of it by running this:

Uninstall-Module -Name "SharePointPnPPowerShellOnline" -AllVersions -Force

After which the installation of PnP.PowerShell should work just fine!

References

  • See the documentation for Connect-PnPOnline here.
  • Check out the docs for
    • AADv1 command Get-MsolServicePrincipalCredential here
    • AADv2 command Get-AzureADServicePrincipal here
  • See more information about SharePoint PnP commandlets here.
mm
5 1 vote
Article Rating
Subscribe
Notify of
guest

8 Comments
most voted
newest oldest
Inline Feedbacks
View all comments