We all can Imagine the scenario. You create sites in sharepoint and now you want to edit multiple sites afterwards with PowerShell. In order to be safe, we have to check, wether an connection exists and if yes to disconnect the current connection to have a clean processing of the sites. In this article I want to show you how it might not work and how it works (state 25.06.2021). If you don’t know how to connect to SharePoint Online, check the article.

 

Symptoms – How I tried it first

sewing 2564557 1920

I tried to check the connection by a normal if query, but as you can see it throws everytime an error, so the script will be halted under normal circumstances. Changing the ErroActionPreference is something you could do for sure, but I would not recommend it, if you want to handle other upcomming potential errors of the API.


if ((Get-PnPConnection) )
{
    Write-Host "Connection found"
}
Get-PnPConnection : The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument to connect.
In Zeile:2 Zeichen:6
+ if ((Get-PnPConnection) )
+      ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-PnPConnection], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,PnP.PowerShell.Commands.Base.GetPnPConnection


PS H:>> 
if ((Get-PnPConnection) -ne $Null )
{
    Write-Host "Connection found"
}
Get-PnPConnection : The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument to connect.
In Zeile:2 Zeichen:6
+ if ((Get-PnPConnection) -ne $Null )
+      ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-PnPConnection], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,PnP.PowerShell.Commands.Base.GetPnPConnection
 

PS H:>> 
if ((Get-PnPConnection|out-null) -ne $Null )
{
    Write-Host "Connection found"
}
Get-PnPConnection : The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument to connect.
In Zeile:2 Zeichen:6
+ if ((Get-PnPConnection|out-null) -ne $Null )
+      ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-PnPConnection], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,PnP.PowerShell.Commands.Base.GetPnPConnection
 

PS H:>> 
if ((Get-PnPConnection -ErrorAction SilentlyContinue) -ne $Null )
{
    Write-Host "Connection found"
}
Get-PnPConnection : The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument to connect.
In Zeile:2 Zeichen:6
+ if ((Get-PnPConnection -ErrorAction SilentlyContinue) -ne $Null )
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-PnPConnection], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,PnP.PowerShell.Commands.Base.GetPnPConnection

Solutions

needle 106375 1920

Try Catch Solution

In order to handle this situation, you have to catchup the error.

The snippet tries to check wether there is an connection and if there is one, it will proceed and disconnect it. After disconnecting it I have set the variable $connection to $null, so I can process it later on.

try 
{
    Get-PnPConnection -ErrorAction Stop
    Disconnect-PnPOnline
    $Connection = $null
}
catch 
{
    $Connection = $null
}

BONUS 1: Invoke-PNPConnection with Credential object (No MFA enforcement)

I wrote a function which handles the whole procedure of cutting of the connection and reconnecting. In this case I have added an additional check of the contents of lists, because sometimes you do connect, but experience that the webserver is not ready yet – basically you get an 403 FORBIDDEN message in PowerShell.

NOTE: This will only work If your user has no MFA enforcement. If you have MFA enabled, I have another function for you.

Function Invoke-PNPConnection ($Url, $Cred)
{
    try 
    {
        Get-PnPConnection -ErrorAction Stop
        Disconnect-PnPOnline
        $Connection  = $null
    }
    catch
    {
        $Connection  = $null
    }

    $i = 1
    while ($null -eq $Connection -and $i -le 6 -and $null -eq $Lists)
    {
        Write-Verbose "Trying to connect to $Url for the $i time" 
        $Lists = $null
        Connect-PnPOnline -Url $Url -Credentials $Cred
        $Lists = Get-PnPList -ErrorAction SilentlyContinue
        $i++
        if ($i -ne 1 -and $null -eq $Lists)
        {
            Start-Sleep -Seconds 30
            Write-Verbose "Wait 30 Seconds"
        }
    }
    Write-Verbose "Connection to $Url established"

}

You can call the function like this

$Cred = get-credential
$Url = "https://contoso.sharepoint.com/sites/Sales"

Invoke-PNPConnection -Url $Url -Cred $Cred

Bonus 2: Invoke-PNPConnection interactively (MFA enforced)

So if you use the scripts interactively (with MFA enforced users), you can make use of this function

Function Invoke-PNPConnection ($Url)
{
    try 
    {
        Get-PnPConnection -ErrorAction Stop
        Disconnect-PnPOnline
        $Connection  = $null
    }
    catch
    {
        $Connection  = $null
    }

    $i = 1
    while ($null -eq $Connection -and $i -le 6 -and $null -eq $Lists)
    {
        Write-Verbose"Trying to connect to $Url for the $i time" 
        $Lists = $null
        Connect-PnPOnline -Url $Url -Interactive
        $Lists = Get-PnPList -ErrorAction SilentlyContinue
        $i++
        if ($i -ne 1 -and $null -eq $Lists)
        {
            Start-Sleep -Seconds 30
            Write-Verbose "Wait 30 Seconds"
        }
    }
    Write-Verbose "Connection to $Url established"

}

You can call the function like this

$Url = "https://contoso.sharepoint.com/sites/Sales"

Invoke-PNPConnection -Url $Url

Conclusio

There are ways to deal with the connections, you just have to think a bit OOTB 🙂

plush teddy bear 1082525 1280



Images:
Bild von Meine Reise geht hier leider zu Ende. Märchen beginnen mit auf Pixabay

Bild von vargazs auf Pixabay

Bild von Ina Hoekstra auf Pixabay

Bild von saulhm auf Pixabay