Search code examples
powershell-3.0

Bulk upload the files from local path to SharePoint Online Allow Ampersand and Pound?


I am using PowerShell PnP v3 on Win 10 to bulk upload files and folders to SPO. I am using the script from this page: enter link description here, which works great. However, it will skip files and folders containing an ampersand (&) or a pound symbol (#). How can this code be updated to allow those characters? I am a Powershell newbie so any help is greatly appreciated.

$cred=Get-Credential  
$makeUrl ="https://sharepoint.com/" 
$sourcePath = "C:\foldername"; 
$topSPOFolder = "one\two"; 

# connect to spo online 
Connect-PnPOnline -Url $makeUrl -Credentials $cred

$fileNames = Get-ChildItem -Path $sourcePath -Recurse ;

foreach($aFileName in $fileNames) 
{ 
if($aFileName.GetType().Name -ne "DirectoryInfo")  
{ 
 $filepath= [System.IO.Path]::GetDirectoryName($aFileName.FullName)+"\" 
 $Urlpath= ($filepath.Replace($sourcePath, '')); 
 $foldername=$Urlpath.Replace("/","\"); 
 $fn=$topSPOFolder+"\"+$foldername; 
 Add-PnPFile -Path $aFileName.FullName -Folder $fn; 
 $fn=$null 
 } 
}

Solution

  • Indeed, in case if filename contains special symbols (such as #) the following exception occurs for Add-PnPFile cmdlet:

    The argument must be a single file name and cannot contain path characters.

    And seems the similar issue has been already reported here

    Further analysis of source code for Add-PnPFile cmdlet

      if (fileName.ContainsInvalidFileFolderChars())
                    throw new ArgumentException(CoreResources.FileFolderExtensions_UploadFile_The_argument_must_be_a_single_file_name_and_cannot_contain_path_characters_, nameof(fileName));
    

    confirms (at least in 3.2.1810.0 version) that:

    • # is not allowed
    • & is allowed

    But given the fact that support for # and % in SharePoint Online and OneDrive for Business has been introduced, not sure why # is still not allowed. So, i would consider it is a bug and recommend to report an issue in GitHub.

    Meanwhile you could consider the following solutions:

    Option 1

    Utilize the following function to upload a file which mimics to some extent Add-PnPFile cmdlet:

    Function UploadAFile() 
    {
    Param(
      [Parameter(Mandatory=$True)]
      [string]$PathName,
    
      [Parameter(Mandatory=$True)]
      [String]$FolderName,
    
      [Parameter(Mandatory=$False)]
      [String]$FileName
    )
    
       $ctx = Get-PnPContext
    
       if([string]::IsNullOrEmpty($FileName)){
          $FileName = [System.IO.Path]::GetFileName($PathName)
       }
    
       $folder = [Microsoft.SharePoint.Client.FileFolderExtensions]::EnsureFolder($ctx.Web,$ctx.Web.RootFolder, $FolderName)
       $fileUrl = [OfficeDevPnP.Core.Utilities.UrlUtility]::Combine($folder.ServerRelativeUrl, $FileName)
    
       $fci= New-Object Microsoft.SharePoint.Client.FileCreationInformation
       $fci.Overwrite = $true
       $fci.Content = [System.IO.File]::ReadAllBytes($PathName)
       $fci.Url = $FileName
       $uploadFile = $folder.Files.Add($fci)
       $ctx.ExecuteQuery()
       return $uploadFile
    }
    

    Example

    UploadAFile  -PathName "./Guide #123.docx" -FolderName "Shared Documents" 
    

    Option 2

    Replace all not supported special symbols using -NewFileName parameter of Add-PnPFile cmdlet, for example:

    Add-PnPFile -Path "./Guide #123.docx" -Folder "Shared Documents" -NewFileName "Guide 123.docx"