0

I am trying to automate the creation of some standard folders in a Team's SharePoint document library, using PowerShell and CSOM. In SharePoint on the web, the folder structure looks like this:

Documents -> General -> Customer A -> General Information, Legal Documents, Proposal Development, meta

Documents -> General -> Customer B -> General Information, Legal Documents, Proposal Development, meta

Documents -> General -> Customer C -> General Information, Legal Documents, Proposal Development, meta

.

.

.

etc.

I need to create the customer folder and its subfolders but when I try to create the customer folder, I get:

Exception calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error: (403) Forbidden."

...after this (line 91):

$ParentFolder.Context.ExecuteQuery()

I am using the same account to get the list of existing folders and that user has global admin rights. Any idea what the error is for?

Code:

$allCustomers = @('Customer A', 'Customer B', 'Customer C', 'Customer 4')
$cred = Get-Credential
$SiteURL = "https://site.sharepoint.com/sites/SalesDemo"
$LibraryName = "Documents"

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#region Get customer folders already in Team
#Function to get all folders
Function Get-AllFolders {
    param(
        [Microsoft.SharePoint.Client.Folder]$Folder
    )

    $ignoredNames = @(
        'Forms',
        'General'
        'Legal Documents'
        'Proposal Development'
        'General Information'
        'meta'
    )
    #Recursively Call the function to get all folders
    $Ctx.load($Folder.Folders)
    $Ctx.ExecuteQuery()

    $Folder.Folders | ForEach-Object {
        If ($_.Name -in $ignoredNames) {
            # Do not return the folder
        }
        Else {
            $_
        }
    }

    #Exclude "Forms" system folder and iterate through each folder
    ForEach ($SubFolder in $Folder.Folders | Where { $_.Name -notin $ignoredNames }) {
        Get-AllFolders -Folder $SubFolder
    }
}
#powershell list all documents in sharepoint online library
Function Get-SPODocumentLibraryFolders {
    param
    (
        [Parameter(Mandatory = $true)] [string] $SiteURL,
        [Parameter(Mandatory = $true)] [string] $LibraryName,
        [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $Credential
    )
    Try {
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName, $Cred.Password)

        #Get the Library and Its Root Folder
        $Library = $Ctx.web.Lists.GetByTitle($LibraryName)
        $Ctx.Load($Library)
        $Ctx.Load($Library.RootFolder)
        $Ctx.ExecuteQuery()

        #Call the function to get Files of the Root Folder
        Get-AllFolders -Folder $Library.RootFolder 
    }
    Catch {
        write-error "Error:" $_.Exception.Message
    }
}

#Call the function to Get All Files from a document library
$allCustomerFoldersInTeam = Get-SPODocumentLibraryFolders -SiteURL $SiteURL -LibraryName $LibraryName -Credential $Cred
#endregion Get customer folders already in Team

#region Find customers without folders in Team
$customersMissingTeamsFolder = Compare-Object -ReferenceObject $allCustomers -DifferenceObject $allCustomerFoldersInTeam.Name | Where-Object { $_.SideIndicator -eq '<=' } | Select-Object InputObject

$customersMissingTeamsFolder | ForEach-Object {
    $SiteUrl = "https://site.sharepoint.com/sites/SalesDemo"
    $ListURL = "/sites/SalesDemo/Shared Documents/General"
    $FolderName = "/$($_.InputObject)"

    Try {
        #Set up the context
        $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
        $Context.Credentials = $Cred

        #Get the List Root Folder
        $ParentFolder = $Context.web.GetFolderByServerRelativeUrl($ListURL)

        #sharepoint online powershell create folder
        $Folder = $ParentFolder.Folders.Add($FolderName)
        $ParentFolder.Context.ExecuteQuery()

        Write-host "New Folder Created Successfully!" -ForegroundColor Green
    }
    catch {
        write-error "Error: $($_.Exception.Message)"
    }
}
#endregion Find customers without folders in Team
0

Make sure the user have at least edit permission on the site/library. By default, Global admins and SharePoint admins don't have automatic access to all sites and each user's OneDrive, but they can give themselves access to any site or OneDrive.

Reference: https://docs.microsoft.com/en-us/sharepoint/sharepoint-admin-role

https://docs.microsoft.com/en-us/sharepoint/manage-site-collection-administrators

| improve this answer | |
  • I assume the account has the correct rights, since I am able to create folders and files through a browser login with the same credential (a service account). – StackExchangeGuy Jun 18 at 13:38
0

This issue could be due to many reasons, please look at the below:

  1. Open the PowerShell ISE in administrator mode.

  2. Add the user account to the particular site collection administrator.

  3. Make sure the internet is on and your site is up and running.

  4. Sometimes - if the VPN is on - we won't be able to connect to the site using the code, so try without a VPN connection.

  5. Try adding Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll explicitly in the PowerShell script like below:

    CLS

    #Load SharePoint CSOM Assemblies

    Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"

    Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

| improve this answer | |
  • 1. I am not using ISE and this is not a question of elevation. 2. The account has rights to create files and folders in the UI, I expect rights to be the same via code. 3 and 4. Yeah...I'm on the network. 5. Those .dll files are not Powershell modules and cannot be imported as such. – StackExchangeGuy Jun 18 at 13:58
  • Sorry it was a typo, it should be Add-Type -Path – Habibur Rahaman Jun 18 at 14:06
  • Check line 7 and 8 of the code sample. I am already doing that. Also, the .dll files are loaded because I was able to enumerate the existing folders. – StackExchangeGuy Jun 18 at 14:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.