Using PowerShell to connect to Project Online with CSOM under MFA
-
08-02-2021 - |
Question
I am trying to interact with a PWA on a tenant for which I have no choice but to use MFA. I'm trying to use the OfficeDev-PnP library which supports MFA, but can't get it to work with Project Online.
This works, but doesn't support MFA
$siteURL = "https://mytenant.sharepoint.com/sites/pwa"
$username = "my.name@mytenant.onmicrosoft.com"
$password = Read-Host -Prompt "Enter password" -AsSecureString
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
# Create & configure a client context connection
$pctx.Credentials = $credentials
# ...load stuff
$pctx.ExecuteQuery()
This uses Office Dev PnP to obtain a MFA-friendly auth context, but doesn't work (I get a 403 on the $pctx.ExecuteQuery()
)
$authmgr = new-object OfficeDevPnp.Core.AuthenticationManager
$pctx = New-Object Microsoft.ProjectServer.Client.ProjectContext($siteUrl)
$pctx.Credentials = $authmgr.GetWebLoginClientContext($siteURL).Credentials
# ...load stuff
$pctx.ExecuteQuery()
This latter method works fine for a plain vanilla SharePoint Online ClientContext. Maybe the problem is that $authmgr.GetWebLoginClientContext($siteURL)
returns a ClientContext, not a ProjectContext.
Edits:
- Per Gautam's suggestion, try to do
$pctx = $authmgr.GetWebLoginClientContext($siteURL)
: this fails when executing a query to load projects, with the Cannot find an overload for "Load" and the argument count: "1" message. Here, I believe $pctx doesn't know it's supposed to be a ProjectContext and is still a ClientContext (thus nothing has exercised the ProjectServer CSOM).
For completeness, here's the full code I've tried here:
# Load libraries
$PNPPath = "C:\Path\To\PnP"
Add-Type –Path "$PNPPath\Microsoft.SharePoint.Client.dll"
Add-Type –Path "$PNPPath\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "$PNPPath\Microsoft.ProjectServer.Client.dll"
Add-Type -Path "$PNPPath\OfficeDevPnP.Core.dll"
# do stuff
$siteURL = "https://mytenant.sharepoint.com/sites/pwa"
$authmgr = New-Object OfficeDevPnp.Core.AuthenticationManager
$pctx = $authmgr.GetWebLoginClientContext($siteURL)
$projects = $pctx.Projects
$pctx.Load($projects)
$pctx.ExecuteQuery()
- I also tried directly casting the ClientContext to a ProjectContext
$pctx = [Microsoft.ProjectServer.Client.ProjectContext]$authmgr.GetWebLoginClientContext($siteURL)
but this also fails, with a Cannot convert... error.
Solution
I don't know if there's another way to do this, but to get unstuck and do what I needed to do, I did the following:
- Forked the https://github.com/SharePoint/PnP-Sites-Core repo
- Created a new method in /Core/OfficeDevPnP/AuthenticationManager.cs based on
GetWebLoginClientContext()
that instead returns a ProjectContext instead of a ClientContext (obviously involved a couple of tweaks to the solution) - Built the solution and referenced the newly built
OfficeDevPnP.Core.dll
in my PowerShell code
$pctx = $authmgr.GetWebLoginProjectContext($siteURL)
Works like a charm.