powershell script to Check if a folder exist in SharePoint with CSOM - powershell

I have a powershell script which i got somewhere from the internet that creates a folder in SharePoint. It works as it can create a folder when i tested it but, i would like like to know how can i modify this script to check if the folder that i am creating does not exist yet? can someone please help?
function CreateFolder {
param
(
$SPSite,
$SiteUrl,
$FolderName,
$User,
$Password
)
$ErrorActionPreference = "Stop"
$DocLibName = "Documents"
$FullSPPath = $SPSite+ $SiteUrl
#Connect Office 365 SharePoint Online Site
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SPSite)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds
$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List)
#Get the List Root Folder
$ParentFolder=$Context.web.GetFolderByServerRelativeUrl($FullSPPath)
#Create New Folder
$Folder = $ParentFolder.Folders.Add($FolderName)
$ParentFolder.Context.Load($Folder)
$ParentFolder.Context.ExecuteQuery()
Write-host "New Folder Created Successfully!"
}

You can do pretty much the same as what you are doing to get the rootfolder. So if the new folder is called NewFolder in the root of your library it would look like:
$newFolder = $Context.Web.GetFolderByServerRelativeUrl("/sites/site/library/NewFolder")
$context.Load($newFolder)
$context.ExecuteQuery()
Now all you need to do is check the exists property on the Folder object:
if (!$newFolder.Exists) {
#do stuff here
}

Related

How to download two different files in powershell

I have this simple script that is working and I'm able to download a csv file From my SharePoint site but I'm just wondering how can I modify it so that I can download another file that is located in another path and save it in the same local folder as soon as the first one is complete downloading?.
Basically this is what I'm trying to do
Download this first
$SourceFile="/sites/msteams/ReportsFull/OneDrive.csv"
Download this second, save in the same folder with the first one
$SourceFile="/sites/msteams/Shared%20Documents/OneDriveInventory/ActiveLitHoldWithOneDrive.csv"
\#Set parameter values
$SiteURL="https://companyName.sharepoint.com"
$SourceFile="/sites/msteams/ReportsFull/OneDrive.csv"
$TargetFile="C:\\Users\\AS\\Downloads\\New folder\\LegalDoc.docx"
Function Download-FileFromLibrary()
{
param
(
\[Parameter(Mandatory=$true)\] \[string\] $SiteURL,
\[Parameter(Mandatory=$true)\] \[string\] $SourceFile,
\[Parameter(Mandatory=$true)\] \[string\] $TargetFile
)
Try {
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Global:adminUPN, $Global:adminPwd)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
#sharepoint online powershell download file from library
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$SourceFile)
$WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
$FileInfo.Stream.CopyTo($WriteStream)
$WriteStream.Close()
Write-host -f Green "File '$SourceFile' Downloaded to '$TargetFile' Successfully!" $_.Exception.Message
}
Catch {
write-host -f Red "Error Downloading File!" $\_.Exception.Message
}
}
\#Call the function to download file
Download-FileFromLibrary -SiteURL $SiteURL -SourceFile $SourceFile -TargetFile $TargetFile
You've got the right code, just need to call the function twice
$sourceFile1 = '/sites/msteams/ReportsFull/OneDrive.csv'
$targetFile1 = 'C:\\Users\\AS\\Downloads\\New folder\\LegalDoc.docx'
Download-FileFromLibrary -SiteURL $SiteURL -SourceFile $SourceFile1 -TargetFile $TargetFile1
$sourceFile2 = '/sites/msteams/Shared%20Documents/OneDriveInventory/ActiveLitHoldWithOneDrive.csv'
$targetFile2 = 'C:\\Users\\AS\\Downloads\\New Folder\\NewFile2.docx'
Download-FileFromLibrary -SiteURL $siteUrl -SourceFile $sourceFile2 -TargetFile $targetFile2```

Azure Automation - Copy Files from one Sharepoint site to another

I would like to create a workflow that automatically copies files which were uploaded to a Sharepoint-Site onto another SharePoint-Site (for file exchange with customers). Therefore I created a Logic App that triggers a Runbook with following content:
param(
[Parameter (Mandatory = $true)][string]$FilePath,
[Parameter (Mandatory = $true)][string]$FileName
)
$Client = "C:\Modules\User\Microsoft.SharePoint.Client\Microsoft.SharePoint.Client.dll"
$ClientRT = "C:\Modules\User\Microsoft.SharePoint.Client\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path $Client
Add-Type -Path $ClientRT
Creds = Get-AutomationPSCredential -Name "SharepointCreds"
#Set parameter values
$TargetSiteURL="https://domain.SharePoint.com/sites/site1"
$SourceSiteURL="https://domain.Sharepoint.com/sites/site2"
#Set Source and Destination File URL
$SourceFileURL="/sites/Sitename1/$Filepath/$FileName"
$TargetFileURL="/sites/Sitename2/$Filepath/$FileName"
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Creds.UserName, $Creds.Password)
#Setup the contexts
$SourceCtx = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteURL)
$SourceCtx.Credentials = $Credentials
$TargetCtx = New-Object Microsoft.SharePoint.Client.ClientContext($TargetSiteURL)
$TargetCtx.Credentials = $Credentials
#Get the Source File
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($SourceCtx, $SourceFileURL)
#Copy File to the Target location
[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($TargetCtx, $TargetFileURL, $FileInfo.Stream,$True)
Anyways I keep receiving following error: Cannot send a content-body with this verb-type
How can I resolve this issue? Is there a better approach?
In sharepoint, we could use the MoveCopyUtil Class to copy file between sites
For example:
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SourceSiteURL)
$Ctx.Credentials = $Credentials
#Copy the File
$MoveCopyOpt = New-Object Microsoft.SharePoint.Client.MoveCopyOptions
$Overwrite = $True
[Microsoft.SharePoint.Client.MoveCopyUtil]::CopyFile($Ctx, $SourceFileURL, $TargetFileURL, $Overwrite, $MoveCopyOpt)
$Ctx.ExecuteQuery()
Reference: https://www.sharepointdiary.com/2017/02/sharepoint-online-copy-file-between-document-libraries-using-powershell.html#ixzz7CSvEyjEc

How to use Get-PnPFolder to show SharePoint folder perm

I am using PowerShell PNP to try and read the permissions of a folder but the command Get-PnPFolder does not appear to include the permissions.
I tried the code listed here but the permissions collection are empty. https://sharepoint.stackexchange.com/questions/221118/retrieve-permissions-at-folder-and-file-level-in-powershell/221513 . This small sample below is what I used for testing.
$spserver = 'https://myportal.sharepoint.com/sites/mysite/'
Connect-PnPOnline –Url $spserver –UseWebLogin
$foldername = 'myFormLibraryName'
$folderObj = Get-PnPFolder -Url $foldername -Includes ListItemAllFields.RoleAssignments, ListItemAllFields.HasUniqueRoleAssignments
$folderObj.ListItemAllFields.HasUniqueRoleAssignments
$folderObj.ListItemAllFields.RoleAssignments
The results of the code will return "collection has not been initialized". How do I get a list of the permissions for a SharePoint folder?
I was not able to get the code to work with Get-PnPFolder and used the code below as an alternative.
$spserver = 'https://myportal.sharepoint.com/sites/mysite/'
Connect-PnPOnline –Url $spserver –UseWebLogin
$ctx=Get-PnPContext
$foldername = 'Documents'
$web = $ctx.Web
$list = $ctx.Site.RootWeb.Lists.GetByTitle($foldername)
$ctx.Load($list)
$ctx.ExecuteQuery()
Write-Host 'count is ' $list.ItemCount
$roleass = $list.RoleAssignments
$ctx.Load($roleass)
$ctx.ExecuteQuery()
Write-Host 'loaded'
foreach($rol in $roleass) {
$ctx.Load($rol.Member)
$ctx.ExecuteQuery()
Write-Host $rol.Member.Title
}

How to use PowerShell to download files from SharePoint?

I've used the following sites to help me get this far and to troubleshoot.
Download file from SharePoint
How to download newest file from SharePoint using PowerShell
Mike Smith's Tech Training Notes SharePoint, PowerShell and .Net!
Upload file to a SharePoint doc library via PowerShell
Download latest file from SharePoint Document Library
How to iterate each folders in each of the SharePoint websites using PowerShell
PowerShell's Get-ChildItem on SharePoint Library
I am trying to download random files from SharePoint folder, and I have it working for when I actually know the file name and extension.
Working code with name and extension:
$SharePoint = "https://Share.MyCompany.com/MyCustomer/WorkLoad.docx"
$Path = "$ScriptPath\$($CustomerName)_WorkLoad.docx"
#Get User Information
$user = Read-Host "Enter your username"
$username = "$user#MyCompany"
$password = Read-Host "Enter your password" -AsSecureString
#Download Files
$WebClient = New-Object System.Net.WebClient
$WebClient.Credentials = New-Object System.Net.Networkcredential($UserName, $Password)
$WebClient.DownloadFile($SharePoint, $Path)
However, I don't seem to be able to figure out how to do it with multiple files of unknown names or extensions.
I have tried mapping a drive, only to end up with "drive mapping failed" & "The network path was not found." errors:
$SharePoint = Read-Host 'Enter the full path to Delivery Site'
$LocalDrive = 'P:'
$Credentials = Get-Credential
if (!(Test-Path $LocalDrive -PathType Container)) {
$retrycount = 0; $completed = $false
while (-not $completed) {
Try {
if (!(Test-Path $LocalDrive -PathType Container)) {
(New-Object -ComObject WScript.Network).MapNetworkDrive($LocalDrive,$SharePoint,$false,$($Credentials.username),$($Credentials.GetNetworkCredential().password))
}
$Completed = $true
}
Catch {
if ($retrycount -ge '5') {
Write-Verbose "Mapping SharePoint drive failed the maximum number of times"
throw "SharePoint drive mapping failed for '$($SharePoint)': $($Global:Error[0].Exception.Message)"
} else {
Write-Verbose "Mapping SharePoint drive failed, retrying in 5 seconds."
Start-Sleep '5'
$retrycount++
}
}
}
}
I've also used the following code with similar results or no results at all.
#Get User Information
$user = Read-Host "Enter your username"
$username = "$user#MyCompany"
$password = Read-Host "Enter your password" -AsSecureString
#Gathering the location of the Card Formats and Destination folder
$Customer = "$SharePoint\MyCustomer"
$Products = "$Path\$($CustomerName)\Products\"
#Get Documents from SharePoint
$credential = New-Object System.Management.Automation.PSCredential($UserName, $Password)
New-PSDrive -Credential $credential -Name "A" -PSProvider "FileSystem" -Root "$SharePoint"
net use $spPath #$password /USER:$user#corporate
#Get PMDeliverables file objects recursively
Get-ChildItem -Path "$Customer" | Where-Object { $_.name -like 'MS*' } | Copy-Item -Destination $Products -Force -Verbose
Without defined "input parameters", it's not exactly clear the full solution you need so I'll provide a few snippets of PowerShell that should be of use based on what you've described.
I'll spare you the basics of the various OOTB functions (i.e. Get-SPWeb, etc) though can provide those details as well if needed. I've also been overly explicit in the scripting, though know some of these lines could be chained, piped, etc to be made shorter & more efficient.
This example will iterate over the contents of a SharePoint Library and download them to your local machine:
$Destination = "C:\YourDestinationFolder\ForFilesFromSP"
$Web = Get-SPWeb "https://YourServerRoot/sites/YourSiteCollection/YourSPWebURL"
$DocLib = $Web.Lists["Your Doc Library Name"]
$DocLibItems = $DocLib.Items
foreach ($DocLibItem in $DocLibItems) {
if($DocLibItem.Url -Like "*.docx") {
$File = $Web.GetFile($DocLibItem.Url)
$Binary = $File.OpenBinary()
$Stream = New-Object System.IO.FileStream($Destination + "\" + $File.Name), Create
$Writer = New-Object System.IO.BinaryWriter($Stream)
$Writer.write($Binary)
$Writer.Close()
}
}
This is pretty basic; the variables up top are where on your local machine you wish to store the download files ($Destination), the URL of your SharePoint Site/Web ($Web) and the name of the Document Library (Your Doc Library Name).
The script then iterates through the items in the Library (foreach ($DocLibItem in $DocLibItems) {}), optionally filters for say items with a .docx file extension and downloads each to your local machine.
You could customize this further by targeting a specific sub-folder within the Doc Library, filter by metadata or properties of the Docs or even iterate over multiple Sites, Webs and/or Libraries in one script, optionally filtering those based on similar properties.

Create Folder in DocLib of a Teamsite - Office 365 - Sharepoint Online

I want to create an example folder in a Document Library of a created Teamsite on Sharepoint Online using Powershell but am running into an error.
After I have created the Teamsite I use the following script:
#Retrieve list
$DocLibName = "Dokumente"
$FolderTitle = "Beispiel"
$List = $ctx.Web.Lists.GetByTitle($DocLibName)
$folder = $list.AddItem("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder)
$folder["Title"] = $FolderTitle
$folder.Update();
$ctx.Load($List)
$ctx.ExecuteQuery()
Error Message
The type [Microsoft.SharePoint.SPFileSystemObjectType] was not found : Make sure that the assembly that contains this type is loaded.
Line:79 Char:1
+ $ Folder = $ List.addItem ("" [Microsoft.SharePoint.SPFileSystemObjectType ] :: Folde ...
It is not possible to use an index to a null array.
Line:80 Char:1
+ $ Folder ["Title"] = $FolderTitle
It is not possible to call a method for an expression of the NULL .
Line:81 Char:1
+ $Folder.Update();
How can this be resolved?
You are getting this error since Microsoft.SharePoint.SPFileSystemObjectTypetype belongs to SharePoint Server Side API which is not compatible with Office 365.
Below is demonstrated how to create a folder in SharePoint Online site via PowerShell (utilizes SharePoint CSOM API)
Function Create-Folder()
{
Param(
[Parameter(Mandatory=$True)]
[Microsoft.SharePoint.Client.Folder]$ParentFolder,
[Parameter(Mandatory=$True)]
[String]$FolderName
)
$folder = $ParentFolder.Folders.Add($folderName)
$ParentFolder.Context.Load($folder)
$ParentFolder.Context.ExecuteQuery()
return $folder
}
Function Get-Context($Url,$Username,$Password){
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$ctx.Credentials = $credentials
return $ctx
}
Usage
$Url = "https://contoso.sharepoint.com/"
$UserName = "jdoe#contoso.onmicrosoft.com"
$Password = ""
$TargetFolderName = "Archive2016"
$ctx = Get-Context -Url $Url -Username $Username -Password $Password
$parentFolder = $ctx.Web.Lists.GetByTitle("Documents").RootFolder
$folder = Create-Folder -ParentFolder $parentFolder -FolderName $TargetFolderName
Write-Host "Folder [$TargetFolderName] has been created succesfully. Url: $($folder.ServerRelativeUrl)"
For creating a folder hierarchy the following script could be utilized:
Function Create-FolderHierarchy()
{
Param(
[Parameter(Mandatory=$True)]
[Microsoft.SharePoint.Client.Folder]$ParentFolder,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$folderNames = $FolderUrl.Trim().Split("/",[System.StringSplitOptions]::RemoveEmptyEntries)
$folderName = $folderNames[0]
$curFolder = $ParentFolder.Folders.Add($folderName)
$ParentFolder.Context.Load($curFolder)
$ParentFolder.Context.ExecuteQuery()
if ($folderNames.Length -gt 1)
{
$curFolderUrl = [System.String]::Join("/", $folderNames, 1, $folderNames.Length - 1)
return Create-FolderHierarchy -ParentFolder $curFolder -FolderUrl $curFolderUrl
}
return $curFolder
}
If you are interested in scenario for uploading files while preserving a folder structure, take a look at How to: Upload files into Office 365 via PowerShell post, it contains ready made script for that purpose.