Download all files from a document library using client object model

For this to work, you will need to obtain a copy of the SharePoint Client DLL (microsoft.sharepoint.client.dll).

On a server with SharePoint intalled:
SharePoint 2010: 14 hive
SharePoint 2013: 15 hive
SharePoint 2016: 16 hive
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\

In Visual Studio, create a console application and name it Download_All_Files. Copy all the code below and paste it into your code window. Update site URLs and list name (Taco Storage).

Using this process, I was able to download 10,000 documents from a library. Took around 30 minutes to complete.

using System;
using System.IO;
using Microsoft.SharePoint.Client;

namespace Download_All_Files
    class Program
        static void Main(string[] args)
            // input YOUR URL below
            var site = new ClientContext("http://sharepoint/sites/somesite");
            var web = site.Web;
            // CHANGE THIS to your library name, get this from the Library Settings page
            List list = web.Lists.GetByTitle("Taco Storage");
            foreach (Folder folder in list.RootFolder.Folders)
        public static void processFolderClientobj(string folderURL)
            // folder on your computer where all the files will be downloaded to
            string Destination = @"C:\\yourFolder";
            // input YOUR URL below
            var site = new ClientContext("http://sharepoint/sites/somesite");
            var web = site.Web;
            Folder folder = web.GetFolderByServerRelativeUrl(folderURL);
            foreach (Microsoft.SharePoint.Client.File file in folder.Files)
                string destinationfolder = Destination + "/" + folder.ServerRelativeUrl;
                Stream fs = Microsoft.SharePoint.Client.File.OpenBinaryDirect(site, file.ServerRelativeUrl).Stream;
                byte[] binary = ReadFully(fs);
                if (!Directory.Exists(destinationfolder))
                FileStream stream = new FileStream(destinationfolder + "/" + file.Name, FileMode.Create);
                BinaryWriter writer = new BinaryWriter(stream);
        public static byte[] ReadFully(Stream input)
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                    ms.Write(buffer, 0, read);
                return ms.ToArray();

Add and Remove Shell Access in SharePoint Using PowerShell

How do you add or remove shell access to a web apps content databases?

This script will grant shell access to a user on all the content databases associated with a content database.

$contentDbs = Get-SPContentDatabase -WebApplication ""

foreach($db in $contentDbs)
	Add-SPShellAdmin -UserName "domain\user"  -database $db

Remove shell access

$contentDbs = Get-SPContentDatabase -WebApplication ""

foreach($db in $contentDbs)
	Remove-SPShellAdmin -UserName "domain\user"  -database $db

After running the remove script, make sure you check the WSS_Admin_WPG and WSS_WPG groups on the servers in your farm.

Error Microsoft.Office.RecordsManagement.RecordsRepository.Record

One one my testers was receiving this error when testing a PowerShell script that was doing records management in SharePoint.

System.Management.Automation.RuntimeException: Unable to find type [Microsoft.Office.RecordsManagement.RecordsRepository.Records]: make sure that the assembly containing this type is loaded.
at System.Management.Automation.TypeLiteral.resolveType()
at System.Management.Automation.TypeNode.ResolveType()
at System.Management.Automation.TypeNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.AssignmentStatementNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)

User was remoted into a SharePoint server, but did not have the right permissions on the server. I tried adding the user to Power Users group, but that didn’t help. Ended up adding the users to the local server Administrators group and the error went away.

Specify a Search Scope When Using search.asmx Service

This article will outline how to setup your code:  link

For my app, I needed to leverage a search scope as part of my query.  Note: when setting up the XML packet, pay close attention to your spacing and closing tags.  If not, you will run into endless error’s that have little to no relevant description.


<ResponsePacket xmlns="urn:Microsoft.Search.Response"><Response domain="QDomain"><Status>ERROR_BAD_REQUEST</Status><DebugErrorMessage>Name cannot begin with the ' ' character, hexadecimal value 0x20. Line 1, position 442.</DebugErrorMessage></Response></ResponsePacket>

Here is my code example. Keep in mind that I’ve already setup my web reference (_vti_bin/Search.asmx).

                var webServ = "http://rootSiteUrl/mysitecolleciton/_vti_bin/Search.asmx";

                QueryService qService = new QueryService();
                qService.Credentials = System.Net.CredentialCache.DefaultCredentials;
                qService.Url = webServ;

                SearchQuery sQuery = new SearchQuery();
                var querySetup = sQuery.SearchString("my search value");
                var queryResults = qService.QueryEx(querySetup);

    class SearchQuery
        public string SearchString (string entityId )
            StringBuilder queryXml = new StringBuilder();
            queryXml.Append("<QueryPacket xmlns=\"urn:Microsoft.Search.Query\" Revision=\"1000\">");
            queryXml.Append("<Query domain=\"QDomain\">");
            queryXml.Append("<QueryText language='en-US' type='MSSQLFT'>");
            queryXml.Append("SELECT Title, Path, Description, Write, Rank, Size FROM Scope() WHERE \"Scope\" = 'Big - Scope' AND CONTAINS(owsOrderx0020Number,'" + entityId +"')");

            return queryXml.ToString();

Error When Using PowerShell to Call SharePoint Web Service

New-WebServiceProxy : The HTML document does not contain Web service discovery information.
At C:\myScript.ps1:91 char:17
+ ...    $Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
+                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (http://mySharePoint....bin/Search.asmx:Uri) [New-WebServiceProxy], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.NewWebServiceProxy

First attempt at calling the search.asmx service.

$webServ = ""
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
$Results = $Service.Query($QueryPacket.OuterXml)

After adding ?wsdl to the uri string, it worked.

$webServ = ""
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ
$Results = $Service.Query($QueryPacket.OuterXml)

Use UserGroup.asmx to get all the users in a SharePoint site

This is a little tricky. I was looking for a way to list all the users that you see in Site Settings –> People and Groups, but I found more info than I needed. This post will be updated once I can track down the actual site users.

The script uses the Users and Groups web service to pull all the users in the site collection.

In my case, the LoginName is setup like this: domain\username

First try:

$webServ = "http://sharepointed/sites/MySiteCollection/_vti_bin/UserGroup.asmx"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ 
$Users = $Service.GetUserCollectionFromSite().Users 
$UserNames = New-Object System.Collections.Generic.List[System.Object]

$Users.User | ForEach-Object {
	$spUser = $_.LoginName.Split('\')[1]

Found the answer to my question. Using the Lists.asmx service, I was able to query the UserInfo list for all the site users.

$webServ = "http://sharepointed/sites/MySiteCollection/_vti_bin/Lists.asmx"
$Service = New-WebServiceProxy -UseDefaultCredential -uri $webServ 

$UserNames = New-Object System.Collections.Generic.List[System.Object]

$listname = 'UserInfo'
$listItems = $Service.GetListItems($listname, $null, $null, $null, $null, $null, $null)

for ($counter = 0;$counter -lt $;$counter++)
	$UserNames += $[$counter].ows_Name

Using c# to get at the information. Here I output the LoginName (domain\userName).

            #create a Web Reference to http://yoursiteURL/_vti_bin/usergroup.asmx?wsdl
            #in my case, i named the reference wsUsersGroups
            wsUsersGroups.UserGroup _WSUsersGroups = new wsUsersGroups.UserGroup();
            _WSUsersGroups.Url = "http://sharepointSite/sites/SiteCollectionName/_vti_bin/usergroup.asmx";
            _WSUsersGroups.Credentials = System.Net.CredentialCache.DefaultCredentials;
            XmlNode ndUsers = _WSUsersGroups.GetAllUserCollectionFromWeb();

            StringReader rdrGroups = new StringReader(ndUsers.OuterXml);
            DataSet dsGroups = new DataSet();

            StringBuilder sb = new StringBuilder();

            foreach (DataRow item in dsGroups.Tables[1].Rows)

            File.WriteAllText("C:\\Users\\myname\\Desktop\\siteUSers.csv", sb.ToString());

SOLVED: Exception calling “StartWorkflow” with “X” argument(s)

Trying to start a SharePoint workflow using PowerShell and I couldn’t get past this error:

Exception calling “StartWorkflow” with “4” argument(s): “Object reference not set to an instance of an object.”
Exception calling “StartWorkflow” with “3” argument(s): “Object reference not set to an instance of an object.”
NO clue if there is a bug in my farm, but the script below works.  Ended up having to re-get the item when running the workflow. $manager.StartWorkflow($list.GetItemById($item.ID),$assoc,$data,$true)

$web = Get-SPWeb ""
$list = $web.Lists["Shared Documents"]

$assoc = $list.WorkFlowAssociations |Where { $_.Name -eq "tacoWF"}
$data = $assoc.AssociationData
$manager = $web.Site.WorkflowManager

$sQuery = New-Object Microsoft.SharePoint.SPQuery 

#Get all items with an ID greater than 5 
$caml = '<Where><Gt><FieldRef Name="ID" /><Value Type="Counter">5</Value></Gt></Where>'
$sQuery.Query = $caml
$fItems = $list.GetItems($sQuery)

Foreach($item in $fItems)

Ran into this again on a SharePoint 2016 farm.
The following commands fixed the problem:
$webapp = Get-SPWebApplication -identity http://

SharePoint OfficialFile.asmx NotFound

When using the SubmitFile method of the OfficialFile.asmx service, I was returned this value: NotFound


Simple fix was to add my account to the Records Center Web Service Submitters group on the site.

Healthy return message from the service:

Good example on how to upload load files to the Drop Off Library using OfficialFile.asmx service.

The post outlines setting up routing rules and submitting files.

More info on the web service can be found here:[MS-OFFICIALFILE].pdf

Value                                                   Meaning
Success                                                    The operation is successful.
MoreInformation                                  The operation is successful but further action is needed.
InvalidRouterConfiguration               The operation failed because the repository was not configured for routing.
InvalidArgument                                   The operation failed because of an invalid argument.
InvalidUser                                             The operation failed because of an invalid user.
NotFound                                                The operation failed because the user was not authorized to submit files.
FileRejected                                            The operation failed because of a rejected file.
UnknownError                                       The operation failed because of an unknown error.

SharePoint 2016 new-spconfigurationdatabase the user does not exist

When installing SharePoint 2016 from PowerShell, make sure you use the machineName\userName when prompted.



New-SPConfigurationDatabase –DatabaseName SharePoint_Config –DatabaseServer machineName\sqlInstance –AdministrationContentDatabaseName SharePoint_Content –Passphrase (ConvertTo-SecureString BigTaco@12345 –AsPlaintext –Force) –FarmCredentials (Get-Credential) -localserverrole SingleServerFarm

A login prompt will appear.

for the username: enter your machine name \ username (WIN-SP16\spUser).

Error I received when I tried to use spUser without the machine name.

new-spconfigurationdatabase the user does not exist

Are SharePoint Designer Workflows Using Custom Features or Solutions (iLoveSharePoint)

Needed to audit a farm to see if a CodePlex solution was being used in SharePoint Designer workflows.  In my case, I needed to see where the iLove SharePoint  solution was being used. The script below is only targeted at one web and is looking for word “ILoveSharePoint” in the XML.


if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) 
	Add-PSSnapin "Microsoft.SharePoint.PowerShell"


		$resultsarray =@()
		#output file name
		$fileName = "C:\ilsp-" + $(Get-Date -Format "yyyyMMddHHmmss") + ".csv"
		#name of the feature we are looking for
		$wFeatureName = "ILoveSharePoint"

		Function GetFiles($folder)
			foreach($file in $folder.Files)
				if($file.Name.Split('.')[-1] -eq "xoml")
					$web2 = Get-SPWeb $file.Web.Url
					$wFile = $web2.GetFileOrFolderObject($web2.URL +"/"+ $file.URL)

					if ($wFile.Exists -eq "True")
						$wXml = (New-Object System.Text.UTF8Encoding).GetString($wFile.OpenBinary());
						$nsDetail = $wXml.OuterXml.ToLower()
						$wFeatureName = $wFeatureName.ToLower()
						if($nsDetail -Like "*$wFeatureName*")
							$outFolder = $folder -replace "Workflows/",""

							$outObject = new-object PSObject
							$outObject | add-member -membertype NoteProperty -name "URL" -Value $web2.Url
							$outObject | add-member -membertype NoteProperty -name "Workflow" -Value $outFolder
							$outObject | add-member -membertype NoteProperty -name "Created By" -Value $wFile.Author
							$outObject | add-member -membertype NoteProperty -name "Created Date" -Value $wFile.TimeCreated
							$outObject | add-member -membertype NoteProperty -name "Modified By" -Value $wFile.ModifiedBy
							$outObject | add-member -membertype NoteProperty -name "Modified Date" -Value $wFile.TimeLastModified

							$global:resultsarray += $outObject

			# Use recursion to loop through all subfolders.
			foreach ($subFolder in $folder.SubFolders)

		$WebApplications = Get-SPWebApplication

		foreach($webApp in $WebApplications)
			foreach($site in $webApp.Sites)
				if ((Get-SPSite $site.url -ErrorAction SilentlyContinue) -ne $null) 
					foreach($web in $site.AllWebs)
						if ((Get-SPWeb $web.url -ErrorAction SilentlyContinue) -ne $null) 
							$list1 = $web.Lists.TryGetList("Workflows")
							if($list1 -ne $null)

		#output file
		$resultsarray | Export-csv $fileName -notypeinformation