Aug 15, 2017

PowerShell Script: List Files and Sub-Folders in a SharePoint Document Library

Just want to share to you guys for today, which I hope it will help you out when you need it. Here is the script to list all files and sub-folders in a SharePoint Document Library.

Syntax:
.\SPDocContent.ps1 [[-Credential] <PSCredential>] [-URL] <String> [-DocumentLibrary] <String> [[-BaseFolderPath] <String>] [[-CSVPath] <String>] [<CommonParameters>]



##############################################################################
#.SYNOPSIS
# Gets a list of files, folders and sub-folders in a SharePoint Online Document Library.
#
#.DESCRIPTION
# Gets a list of files, folders and sub-folders in a SharePoint Online Document Library.
#
#.PARAMETER Credential
# The credential to access with SharePoint Online.
#
#.PARAMETER URL
# The URL of the SharePoint site (can be a sub-site or root site).
#
#.PARAMETER Document Library
# The Document Library name to connect to.
#
#.PARAMETER BaseFolderPath
# Start from particular sub-folder (optional).
#
#.PARAMETER CSVPath
# The path of the CSV file to export the result.
#
#.EXAMPLE
# $Crd = Get-Credential
# .\SPDocContent.ps1 -URL "https://rdz.sharepoint.com" -DocumentLibrary "Documents" -CSVPath "D:\Documents.csv"
##############################################################################

[Cmdletbinding()]
param (
	[Parameter(Mandatory = $false)]
    [System.Management.Automation.PSCredential]$Credential = $null,
    [Parameter(Mandatory=$true)]
    [string]$URL,
    [Parameter(Mandatory=$true)]
    [string]$DocumentLibrary,
    [Parameter(Mandatory=$false)]
    [string]$BaseFolderPath,
	[Parameter(Mandatory = $false)]
    [string]$CSVPath = ""
)

Function ListContent(
    [Parameter(Mandatory=$true)]
    [Microsoft.SharePoint.Client.Folder]$BaseFolder,
    [Parameter(Mandatory=$false)]
    [switch]$Recursive = $false,
    [Parameter(Mandatory=$false)]
    [Microsoft.SharePoint.Client.Folder]$RootFolder,
    [Parameter(Mandatory=$false)]
    [int]$Level = 0
)
{
    $ContentInfo = @()

    $RootLevel = $false;
    $ctx.Load($BaseFolder.Folders)
    $ctx.Load($BaseFolder.Files)
    $ctx.Load($BaseFolder.ParentFolder)
    $ctx.ExecuteQuery()

    if ($RootFolder -eq $null) { $RootLevel = $true; $RootFolder = $BaseFolder; }
    $tabsRepeat = New-Object System.String("`t", ($Level + 1))

    if ($BaseFolder.Folders.Count -gt 0)
    {
        Write-Host "$($tabsRepeat)$($BaseFolder.Folders.Count) sub-folders for $($BaseFolder.ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))" -ForegroundColor Yellow
        for ($i = 0; $i -lt $BaseFolder.Folders.Count; $i++)
        {
            $ctx.Load($BaseFolder.Folders[$i])
            $ctx.ExecuteQuery()
            if ($BaseFolder.Folders[$i])
            {
                if (($RootLevel -and $BaseFolder.Folders[$i].Name -ne "Forms") -or -not $RootLevel)
                {
                    Write-Host "$($tabsRepeat)$($BaseFolder.Folders[$i].ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))"
                    $ContentInfo += [pscustomobject]@{
                        RelativePath = "$($BaseFolder.Folders[$i].ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))";
                        Type = "Folder";
                        Name = "$($BaseFolder.Folders[$i].Name)";
                        Level = $Level;
                    };

                    if ($Recursive -eq $true)
                    {
                        $ContentInfo += (ListContent -BaseFolder $BaseFolder.Folders[$i] -RootFolder $RootFolder -Recursive:$Recursive -Level ($Level + 1))
                    }
                }
            }
        }
    }
    if ($BaseFolder.Files.Count -gt 0)
    {
        Write-Host "$($tabsRepeat)$($BaseFolder.Files.Count) sub-files for $($BaseFolder.ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))" -ForegroundColor Yellow
        for ($i = 0; $i -lt $BaseFolder.Files.Count; $i++)
        {
            $ctx.Load($BaseFolder.Files[$i])
            $ctx.ExecuteQuery()
            if ($BaseFolder.Files[$i])
            {
                $ContentInfo += [pscustomobject]@{
                    RelativePath = "$($BaseFolder.Files[$i].ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))";
                    Type = "File";
                    Name = "$($BaseFolder.Files[$i].Name)";
                    Level = $Level;
                };
                Write-Host "$($tabsRepeat)$($BaseFolder.Files[$i].ServerRelativeUrl.Replace($RootFolder.ServerRelativeUrl + "/", [System.String]::Empty))"
            }
        }
    }
    return $ContentInfo;
}

$ContentInfo = @()
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($URL)
Try
{
    if ($Credential)
    {
        if ($Credential.GetType().FullName -eq "Microsoft.SharePoint.Client.SharePointOnlineCredentials")
        {
            $ctx.Credentials = $Credential
        } elseif ($Credential.GetType().FullName -eq "System.Management.Automation.PSCredential")
        {
            $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Credential.Username,$Credential.Password)
        }
    }
    elseif ($PSCrd)
    {
        Write-Host "No credential set, retrieving from `$PSCrd." -ForegroundColor Yellow
        $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($PSCrd.Username,$PSCrd.Password)
    }
    elseif ($SPCrd)
    {
        Write-Host "No credential set, retrieving from `$SPCrd." -ForegroundColor Yellow
        $ctx.Credentials = $SPCrd
    }
    else
    {
        Write-Host "No credential set, none retrieved." -ForegroundColor Red -BackgroundColor Black
        exit
    }

    $Site = $ctx.Site
    $Web = $ctx.Web
    $ctx.Load($Site)
    $ctx.Load($Web)
    $ctx.Load($Web.Lists)
    $ctx.Load($Web.Webs)
    $ctx.ExecuteQuery()

    $DL = $Web.Lists.GetByTitle($DocumentLibrary)
    $ctx.ExecuteQuery()

    $ctx.Load($DL.RootFolder)
    $ctx.ExecuteQuery()

    if ($BaseFolderPath)
    {
        $RootFolderPath = "$($DL.RootFolder.ServerRelativeUrl)/$($BaseFolderPath)"
        $RootFolder = $DL.RootFolder.Folders.GetByUrl($BaseFolderPath)
        $ctx.Load($RootFolder)
        $ctx.ExecuteQuery()
        $ContentInfo += (ListContent -BaseFolder $RootFolder -Recursive)
    }
    else
    {
        $ContentInfo += (ListContent -BaseFolder $DL.RootFolder -Recursive)
    }

    if ($CSVPath)
    {
        if (Test-Path $CSVPath) { Remove-Item $CSVPath }
        $ContentInfo | Export-Csv $CSVPath -NoTypeInformation
    }
}
Catch
{
    Throw
}
Finally
{
    if ($ctx -ne $null) { $ctx.Dispose(); }
}

Note: this script is only meant for SharePoint Online.

Jun 13, 2017

PowerShell Script: Upload Large File to SharePoint in Chunks

Get back to the business again! Just wanted to share another great things in SharePoint (although to user is not fun at all).

According to MSDN, there are a few options to upload files to SharePoint.

Apr 3, 2017

SharePoint CAML Query through jQuery

I was just digging into my code snippet, and I thought this worth to share. I got the sample code where we can query using CAML in jQuery.

After a few tests, it’s still valid to be used. Here it is!


var DocLibName = "Shared Documents";
var camlQry = 
	"<View Scope='RecursiveAll'>" +
		"<Query>" +
			"<Where>" +
				"<And>" +
					"<Leq>" +
						"<FieldRef Name='Created'/>" +
						"<Value Type='DateTime'><Today /></Value>" +
					"</Leq>" +
					"<Eq>" +
						"<FieldRef Name='FSObjType'/>" +
						"<Value Type='Integer'>0</Value>" +
					"</Eq>" +
				"</And>" + 
			"</Where>" +
		"</Query>" +
	"</View>";
var requestData = { "query" :
	{ "__metadata" :
		{ "type" : "SP.CamlQuery" },
		"ViewXml" : camlQry
	}
};
$.ajax({
	url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('" + DocLibName + "')/GetItems?$expand=FieldValuesAsText",
	method: "POST",
	async: false,
	data: JSON.stringify(requestData),
	headers: {
		"X-RequestDigest": $("#__REQUESTDIGEST").val(),
		"Accept": "application/json; odata=verbose",
		"Content-Type": "application/json; odata=verbose"
	},
	success : function(d) {
		$.each(d.d.results, function (iRow, vRow) {
			//do your own processing here
		});
	}, error : function(a, b, c) {
		console.log(a);
		console.log(b);
		console.log(c);
	}
});

Enjoy!

Mar 29, 2017

PowerShell: Remove Site Collection Administrator Account

This time, I’m going to share you on the script to remove Site Collection Administrator of ALL site collections at one go.

12_13_47-000117


[Cmdletbinding()]
param (
    [string]$UserName = "",
    [string]$Tenant = "",
	[Parameter(Mandatory=$true)]
    [string]$AccountToRemove = "",
    [string]$RelativeSiteUrl = ""
)

Connect-SPOService -Url "https://$($Tenant)-admin.sharepoint.com" -Credential $UserName

if ($RelativeSiteUrl)
{
    $siteUrl = "https://$($Tenant).sharepoint.com$($RelativeSiteUrl)"
    Write-Host "Removing $AccountToRemove from $siteUrl..." -Fore Yellow -NoNewline
    Set-SPOUser -Site $site.Url -LoginName $AccountToRemove -IsSiteCollectionAdmin $false
    Write-Host "REMOVED" -Fore Green
}
else
{
    $SiteColl = Get-SPOSite
    Write-Host "Removing $AccountToRemove from:" -Fore Green
    foreach ($site in $SiteColl)
    {
        Write-Host "`t$($site.Url)..." -Fore Yellow -NoNewline
        Set-SPOUser -Site $site.Url -LoginName $AccountToRemove -IsSiteCollectionAdmin $false
        Write-Host "REMOVED" -Fore Green
    }
}

Disconnect-SPOService

Enjoy!

Mar 22, 2017

PowerShell Script to Iterate All Documents (including sub-folders)

Seems like I want to dump again an old script to you. This PowerShell Script is commonly used to list down all documents in the Document Library regardless of their location, whether it’s in the root or sub-folders.

No need to explain in detail again, here’s the script.

Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll"
$Siteurl = "https://consotoayam.com/sites/EPRG" #you can replace this url with your own
$ListName = "Shared Documents" #replace this with your own Document Library name
$credential = Get-Credential #to prompt for credential

if ($SiteUrl -ne $null)
{
    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
    if ($ctx -ne $null)
    {
        $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($credential.UserName, $credential.Password)

        $st = $ctx.Site
        $wb = $ctx.Web
        $DocsLib = $wb.Lists.GetByTitle($ListName)

        $q = New-Object Microsoft.SharePoint.Client.CamlQuery
        $q.ViewXml = '0'

        $items = $DocsLib.GetItems($q)
        $ctx.Load($st)
        $ctx.Load($wb)
        $ctx.Load($DocsLib)
        $ctx.Load($items)
        $ctx.ExecuteQuery()
        foreach($item in $items)
        {
	    #if necessary, you can load the item
            $ctx.Load($item)
            $ctx.ExecuteQuery()
        }
    }
}

Enjoy!