Requirement: Sync Fileshare to SharePoint Online using PowerShell

sync file share to sharepoint online document library using powershell

If yous are using File Shares, yous may find the need to keep your file shares in sync with SharePoint Online or OneDrive for Business. Perhaps you want to keep data in both places upwardly to date or wish to take advantage of the additional storage and collaboration features that SharePoint Online offers. In either case, PowerShell provides a style to automate this process and go far less error-prone easily. This article volition evidence you how to use PowerShell to sync your file shares to SharePoint Online.

And so, How to sync a file server to SharePoint Online? While my other script, Drift File Share to SharePoint Online using PowerShell, imports files and folders from network file share to SharePoint Online, this script syncs file share to SharePoint Online document library.

Import-Module SharePointPnPPowerShellOnline  #Function to Import Files from Fileshare to SharePoint Online Function Import-FileShareToSPO {  param     (         [Parameter(Mandatory=$true)] [string] $SiteURL,         [Parameter(Mandatory=$true)] [string] $SourceFolderPath,         [Parameter(Mandatory=$truthful)] [string] $TargetLibraryName,                     [Parameter(Mandatory=$true)] [string] $LogFile     )      Endeavor {         Add-content $Logfile -value "`north---------------------- Import FileShare Script Started: $(Get-engagement -format 'dd/MM/yyy hh:mm:ss tt')-------------------"                 #Get Number of Source Items from the Source Folder         $SourceItemsCount =  (Get-ChildItem -Path $SourceFolderPath -Recurse).count          #Get the Target Library to Upload         $Spider web = Go-PnPWeb         $Library = Get-PnPList $TargetLibraryName -Includes RootFolder         $TargetFolder = $Library.RootFolder          #Get the site relative path of the target folder         If($web.ServerRelativeURL -eq "/")         {             $TargetFolderSiteRelativeURL = $TargetFolder.ServerRelativeUrl         }         Else         {                     $TargetFolderSiteRelativeURL = $TargetFolder.ServerRelativeURL.Replace($Web.ServerRelativeUrl,[string]::Empty)          }             #Go All Items from the Source         $SourceItems = Go-ChildItem -Path $SourceFolderPath -Recurse         $Source = @($SourceItems | Select FullName,  PSIsContainer,                                      @{Label='TargetItemURL';Expression={$_.FullName.Replace($SourceFolderPath,$TargetFolderSiteRelativeURL).Replace("\","/")}},                                              @{Label='LastUpdated';Expression={$_.LastWriteTimeUtc.ToString()}})          #Get All Files from the target document library - In batches of 2000         $TargetFiles = Go-PnPListItem -List $TargetLibraryName -PageSize 2000         $Target = @($TargetFiles | Select @{Label='FullName';Expression={$_.FieldValues.FileRef.Replace($TargetFolder.ServerRelativeURL,$SourceFolderPath).Supplant("/","\")}},                                                 @{Label='PSIsContainer';Expression={$_.FileSystemObjectType -eq "Folder"}},                                                     @{Label='TargetItemURL';Expression={$_.FieldValues.FileRef.Replace($Web.ServerRelativeUrl,[string]::Empty)}},                                                         @{Characterization='LastUpdated';Expression={$_.FieldValues.Modified.ToUniversalTime().ToString()}})          #Compare Source and Target and upload/update files that are non in the target         $Counter = 1         $FilesDiff = Compare-Object -ReferenceObject $Source -DifferenceObject $Target -Property FullName, PSIsContainer, TargetItemURL, LastUpdated         #$FilesDiff | Export-csv -path "C:\Temp\diff.csv" -NoTypeInformation         $SourceDelta = @($FilesDiff | Where {$_.SideIndicator -eq "<="})          $SourceDeltaCount = $SourceDelta.Count          #Check if Source Files are changed         If($SourceDeltaCount -gt 0)         {             Write-host "Found $SourceDeltaCount new differences in the Source!"              Add-content $Logfile -value "Institute $SourceDeltaCount new differences in the Source!"                     $SourceDelta | Sort-Object TargetItemURL | ForEach-Object {                 #Calculate Target Folder URL for the file                 $TargetFolderURL = (Split-Path $_.TargetItemURL -Parent).Replace("\","/")                 If($TargetFolderURL.StartsWith("/")) {$TargetFolderURL = $TargetFolderURL.Remove(0,1) }                 $ItemName = Separate-Path $_.FullName -leafage                 #Replace Invalid Characters                 $ItemName = [RegEx]::Replace($ItemName, "[{0}]" -f ([RegEx]::Escape([Cord]'\*:<>?/\|')), '_')                  #Brandish Progress bar                 $Condition  = "Importing $ItemName to $TargetFolderURL $($Counter) of $($SourceDeltaCount)"                 Write-Progress -Activeness "Importing Files from the Source..." -Status $Condition -PercentComplete (($Counter / $SourceDeltaCount) * 100)                  If($_.PSIsContainer)                 {                     #Ensure Folder                     $Folder  = Resolve-PnPFolder -SiteRelativePath ($TargetFolderURL+"/"+$ItemName) -Includes ListItemAllFields                                          Set-PnPListItem -List $TargetLibraryName -Identity $Binder.ListItemAllFields.Id -Values @{"Modified"=  ([DateTime]$_.LastUpdated).ToLocalTime()} | Out-nil                     Write-host "Ensured Folder '$($ItemName)' to Binder $TargetFolderURL"                     Add-content $Logfile -value "Ensured Folder '$($ItemName)' to Folder $TargetFolderURL"                 }                 Else                 {                     #Upload File                     $File  = Add-PnPFile -Path $_.FullName -Folder $TargetFolderURL -Values @{"Modified"=  ([DateTime]$_.LastUpdated).ToLocalTime()}                     Write-host "Ensured File '$($_.FullName)' to Folder $TargetFolderURL"                     Add together-content $Logfile -value "Ensured File '$($_.FullName)' to Folder $TargetFolderURL"                 }                 $Counter++             }         }         Else         {             Write-host "Found no new Items in the Source! Total Items in Source: $SourceItemsCount , Number Items in Target: $($Library.Itemcount)"              Add together-content $Logfile -value "Found no new Items in the Source! Items in Source: $SourceItemsCount ,  Number Items in Target: $($Library.Itemcount)"          }           }     Grab {         Write-host -f Crimson "Fault:" $_.Exception.Bulletin          Add-content $Logfile -value "Error:$($_.Exception.Message)"     }     Finally {        Add-content $Logfile -value "---------------------- Import File Share Script Completed: $(Get-appointment -format 'dd/MM/yyy hh:mm:ss tt')-----------------"     } }  #Function to Remove Files Delta in SharePoint Online (Files that are no longer exists in FileShare ) Function Remove-FileShareDeltaInSPO {  param     (         [Parameter(Mandatory=$true)] [string] $SiteURL,         [Parameter(Mandatory=$true)] [string] $SourceFolderPath,         [Parameter(Mandatory=$true)] [string] $TargetLibraryName,                     [Parameter(Mandatory=$truthful)] [string] $LogFile     )      Attempt {         Add-content $Logfile -value "`n---------------------- Remove FileShare Delta Script Started: $(Become-date -format 'dd/MM/yyy hh:mm:ss tt')-------------------"             #Go Number of Source Items from the Source Folder         $SourceItemsCount =  (Get-ChildItem -Path $SourceFolderPath -Recurse).count          #Go the Target Library         $Web = Go-PnPWeb         $Library = Get-PnPList $TargetLibraryName -Includes RootFolder         $TargetFolder = $Library.RootFolder          #Get the site relative path of the target folder         If($spider web.ServerRelativeURL -eq "/")         {             $TargetFolderSiteRelativeURL = $TargetFolder.ServerRelativeUrl         }         Else         {                     $TargetFolderSiteRelativeURL = $TargetFolder.ServerRelativeURL.Replace($Web.ServerRelativeUrl,[string]::Empty)          }                   #Get All Items from the Source         $SourceItems = Get-ChildItem -Path $SourceFolderPath -Recurse         $Source = @($SourceItems | Select FullName,  PSIsContainer,                                      @{Label='TargetItemURL';Expression={$_.FullName.Replace($SourceFolderPath,$TargetFolderSiteRelativeURL).Replace("\","/")}},                                              @{Label='LastUpdated';Expression={$_.LastWriteTimeUtc.ToString()}})          #Get All Files from the target document library - In batches of 2000         $TargetFiles = Become-PnPListItem -List $TargetLibraryName -PageSize 2000         $Target = @($TargetFiles | Select @{Characterization='FullName';Expression={$_.FieldValues.FileRef.Replace($TargetFolder.ServerRelativeURL,$SourceFolderPath).Replace("/","\")}},                                                 @{Label='PSIsContainer';Expression={$_.FileSystemObjectType -eq "Binder"}},                                                     @{Label='TargetItemURL';Expression={$_.FieldValues.FileRef.Supercede($Web.ServerRelativeUrl,[cord]::Empty)}},                                                         @{Label='LastUpdated';Expression={$_.FieldValues.Modified.ToUniversalTime().ToString()}})          #Compare Source and Target and remove files that are non in the Source         $Counter = one         $FilesDiff = Compare-Object -ReferenceObject $Source -DifferenceObject $Target -Property FullName, PSIsContainer, TargetItemURL, LastUpdated              $TargetDelta = @($FilesDiff | Where {$_.SideIndicator -eq "=>"})         $TargetDeltaCount = $TargetDelta.Count          #Check if Target Files Needs to be deleted         If($TargetDeltaCount -gt 0)         {             Write-host "Found $TargetDeltaCount differences in the Target!"              Add together-content $Logfile -value "Found $TargetDeltaCount differences in the Target!"                     $TargetDelta | Sort-Object TargetItemURL -Descending | ForEach-Object {                 #Display Progress bar                 $Status  = "Removing Item " + $_.TargetItemURL +" ($($Counter) of $($TargetDeltaCount))"                 Write-Progress -Activeness "Removing Items in the Target..." -Condition $Condition -PercentComplete (($Counter / $TargetDeltaCount) * 100)                  If($_.PSIsContainer)                 {                     #Empty and Remove the Folder                     $Folder  = Get-PnPFolder -Url $_.TargetItemURL -ErrorAction SilentlyContinue                     If($Folder -ne $Nil)                     {                         $Binder.Recycle() | Out-Zippo                         Invoke-PnPQuery                          Write-host "Removed Folder '$($_.TargetItemURL)'"                         Add-content $Logfile -value "Removed Folder '$($_.TargetItemURL)'"                     }                 }                 Else                 {                     $File = Get-PnPFile -Url $_.TargetItemURL -ErrorAction SilentlyContinue                     If($File -ne $Null)                     {                         #Remove the File                         Remove-PnPFile -SiteRelativeUrl $_.TargetItemURL -Force                         Write-host "Removed File '$($_.TargetItemURL)'"                         Add-content $Logfile -value "Removed File '$($_.TargetItemURL)'"                     }                 }                 $Counter++             }         }         Else         {             Write-host "Establish no differences in the Target! Full Items in Source: $SourceItemsCount , Number Items in Target: $($Library.Itemcount)"              Add-content $Logfile -value "Plant no differences in the Target! Items in Source: $SourceItemsCount ,  Number Items in Target: $($Library.Itemcount)"          }     }     Catch {         Write-host -f Red "Error:" $_.Exception.Message          Add together-content $Logfile -value "Error:$($_.Exception.Bulletin)"     }     Finally {        Add-content $Logfile -value "---------------------- Remove FileShare Delta Script Completed: $(Get-date -format 'dd/MM/yyy hh:mm:ss tt')-----------------"     } }  Function Sync-FileShareToSPO() {  param     (         [Parameter(Mandatory=$true)] [cord] $SiteURL,         [Parameter(Mandatory=$truthful)] [cord] $SourceFolderPath,         [Parameter(Mandatory=$true)] [string] $TargetLibraryName,                     [Parameter(Mandatory=$true)] [string] $LogFile     )      Try {         #Connect to PnP Online         Connect-PnPOnline -Url $SiteURL -Interactive          #Call the office to Import New Files from Fileshare to SPO         Import-FileShareToSPO -SiteURL $SiteURL -SourceFolderPath $SourceFolderPath -TargetLibraryName $TargetLibraryName -LogFile $LogFile          #Call the part to Remove Files in SPO that are moved/deleted in Fileshare         Remove-FileShareDeltaInSPO -SiteURL $SiteURL -SourceFolderPath $SourceFolderPath -TargetLibraryName $TargetLibraryName -LogFile $LogFile     }     Catch {         Write-host -f Red "Fault:" $_.Exception.Message     }     Finally {        DisConnect-PnPOnline     } }  #Call the Office to Sync Files from Fileshare to SharePoint Online Sync-FileShareToSPO -SiteURL "https://crescent.sharepoint.com/sites/Projects" -SourceFolderPath "\\FileServer\Reports" `                             -TargetLibraryName "Documents" -LogFile "C:\Temp\SyncFileShare-LOG.log"              

This script checks the timestamp of each file from the given file share and uploads information technology to SharePoint Online if they are updated in the File share. Similarly, whatsoever file deleted in Fileshare will exist deleted in SharePoint Online also. It generates a log file also every time it runs. Please note, this script does just one-style sync from Fileshare to SharePoint Online. You can Schedule PowerShell script in Windows Task scheduler to run on schedule. E.thou., for every 10 min.

You tin can too utilise this script to sync files from the local drive to SharePoint by irresolute the SourceFolderPath parameter to any folder on your estimator. Eastward.chiliad. "C:\Temp\Upload"

Salaudeen Rajack

Salaudeen Rajack is a SharePoint Builder with Ii decades of SharePoint Experience. He loves sharing his noesis and experiences with the SharePoint community, through his real-world manufactures!