Forum Discussion

Jurgen Wiersema's avatar
Jurgen Wiersema
Copper Contributor
Nov 30, 2016
Solved

OfficeDevPNP Add-PnPFile error folder already exists while looping through directories

I'm getting the following error while looping through a local directory structure and trying to upload all files to a SPO library. The first file in each directory succeeds but the following files in the same direcotry give an error. It seems to me the context is outdated (OfficeDevPNP doesn't seem to know that the folder was already created in the previous iteration of the loop. How do I fix this?

 

Add-PnPFile : Er bestaat al een bestand of map met de naam https://mytenant.sharepoint.com/sites/mysite/mylibrary/myfolder/mysubfolder/
subsubfolder. ("A File or Folder already exists with the name")

 

(Part of) the code:

$fileNames = Get-ChildItem -Path $scriptPath -Recurse -Include *.json,*.xml;

foreach($aFileName in $fileNames)
{
# create folder structure leading to file in SPO
$fileLocalSourcePath = $aFileName.FullName;
$fileSPOTargetPath = $topSPOFolder + ($fileLocalSourcePath.Replace($sourcePath, ' ').TrimStart(' ') -replace '\\', '/');
$fileSPOTargetPath = $fileSPOTargetPath.Replace('/' + $aFileName.Name, ' ');
# upload file to SPO
Add-PnPFile -Path $fileLocalSourcePath -Folder $fileSPOTargetPath -Web $aWeb -Publish;
}

  • Made few corrections in your script to work. Below is the updated script.

     

    $sourcePath = $PSScriptRoot; # 1.Don't forget to add  "\" at end of $PSScriptRoot String value 
    #$topSPOFolder = "SiteConfigurations/_PSI_Gestapeld";
    $topSPOFolder = "Bieb1/_PSI_Gestapeld";
    # install pnp powershell..?
    #Install-Module SharePointPnPPowerShellOnline;
    # connect to spo online; TODO: use appid and appsecret
    Connect-PnPOnline -Url $makeUrl -UseWebLogin;
    # foreach (updated or new?) file in git project
    $fileNames = Get-ChildItem -Path $sourcePath -Recurse -Include *.json,*.xml;
    $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("/","\");  # 2."\","/" was changed
         $fn=$topSPOFolder+"\"+$foldername; # 3. "\" Added 
         Add-PnPFile -Path $aFileName.FullName -Folder $fn;
         $fn=$null
       }
    
    } 
    
    

5 Replies

  • Check the below script, which will loop through the directories and add the required folder and upload the files to SPO. While modifying "$folder", don't forget to have "\" at the end.

     

    $cred=Get-Credential
    Connect-PnPOnline -Url https://tenantname.sharepoint.com/sites/contosobeta -Credentials $cred
    $Folder =  "C:\Desktop\Userfolder2\"
    $rootfolder=$folder.Replace("\","\\")
    $ParentFolder ="Shared Documents\testing" 
    
    Function UploadFiles($path)
    {
    
    	$files = Get-ChildItem $path
    	foreach ($file in $files) 
    	{  
    		if($file.GetType().Name -eq "DirectoryInfo") 
    		{
    			$foldername=$file.Name
    			$parent=$file.Parent.FullName
    			$parent1=$parent+"\"
    			If($parent1 -eq $Folder)
    			{
    				Add-PnPFolder -Name $foldername -folder $ParentFolder
    			}
    			Else
    			{
    				$Urlpath1= ($parent -split "$rootfolder" )[1]
    				$foldernames1=$Urlpath1
    				if($foldernames1 -like "*\*")
    				{
    					$foldername1=$foldernames1.Replace("\","/")
    				}
    				Else
    				{
    					$foldername1=$foldernames1
    				}
    				$fnPath=$ParentFolder+"/"+$foldername1
    				Add-PnPFolder -Name $foldername -folder $fnPath
    			}
    
    			$Folderpath1=$file.FullName
    
    			UploadFiles  $Folderpath1
    		}
    		Else
    		{
    			$filepath= [System.IO.Path]::GetDirectoryName($file.FullName)
    			$Urlpath= ($filepath -split "$rootfolder" )[1]
    			$foldernames=$Urlpath
    			if($foldernames -like "*\*")
    			{
    				$foldername=$foldernames.Replace("\","/")
    			}
    			Else
    			{
    				$foldername=$foldernames
    			}   
    			$fn=$ParentFolder+"/"+$foldername
    
    			Add-PnPFile -Path $File.FullName -Folder $fn ;   
    			$fn=$null
    		}
    	}
    }
    UploadFiles -path $Folder
    
    
    
    • Jurgen Wiersema's avatar
      Jurgen Wiersema
      Copper Contributor

       Thank you NarasimaPerumal! You script works perfectly although I don't understand yet why mine doesn't. I combined both our scripts to make the below script. Add-PnpFile creates the required folders itself so it isnt necessary to use Add-PnPFolder separately.

       

       

      $sourcePath = $PSScriptRoot;
      #$topSPOFolder = "SiteConfigurations/_PSI_Gestapeld";
      $topSPOFolder = "Bieb1/_PSI_Gestapeld";

      # install pnp powershell..?
      #Install-Module SharePointPnPPowerShellOnline;

      # connect to spo online; TODO: use appid and appsecret
      Connect-PnPOnline -Url $makeUrl -UseWebLogin;

      # foreach (updated or new?) file in git project
      $fileNames = Get-ChildItem -Path $sourcePath -Recurse -Include *.json,*.xml;

      foreach($aFileName in $fileNames)
      {
      $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
      }

      • Made few corrections in your script to work. Below is the updated script.

         

        $sourcePath = $PSScriptRoot; # 1.Don't forget to add  "\" at end of $PSScriptRoot String value 
        #$topSPOFolder = "SiteConfigurations/_PSI_Gestapeld";
        $topSPOFolder = "Bieb1/_PSI_Gestapeld";
        # install pnp powershell..?
        #Install-Module SharePointPnPPowerShellOnline;
        # connect to spo online; TODO: use appid and appsecret
        Connect-PnPOnline -Url $makeUrl -UseWebLogin;
        # foreach (updated or new?) file in git project
        $fileNames = Get-ChildItem -Path $sourcePath -Recurse -Include *.json,*.xml;
        $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("/","\");  # 2."\","/" was changed
             $fn=$topSPOFolder+"\"+$foldername; # 3. "\" Added 
             Add-PnPFile -Path $aFileName.FullName -Folder $fn;
             $fn=$null
           }
        
        } 
        
        
  • Maybe you should groep the files to each folder... and for each folder iterate through the array instead of for each file. That makes it easier to debug if something is not working. (je mag me ook een mailtje sturen, dan kan ik verder meedenken :)

Resources