Monthly Archives: November 2013

Detect if New Folders are allowed in SharePoint List/Library using Lists web service from remote application (works across SharePoint 2007, 2010, 2013)

Today I found myself tasked with finding a common method for detecting if a SharePoint list/library had been configured to allow new folders from a remote client application. The method also had to work across all versions of SharePoint (well at least 2007, 2010, 2013 on-premise and in the cloud). This ruled out using client side object model so my investigation turned to web services (yes they are deprecated in SP2013 so be careful using them going forward).

The Lists web service provides a few different ways to return the XML schema of a list(s) (e.g. GetList or GetListCollection)

Here’s a snippet of what the XML looks like that you get back from these web service methods.
05-sharepoint-new-folder-allowed-from-remote-app-list-schema-xml-cameron-dwyer

<List DocTemplateUrl="" DefaultViewUrl="/Lists/announce123/AllItems.aspx" MobileDefaultViewUrl="" ID="{F194025B-A0F2-4318-950A-9197AD8D2285}" Title="announce123" Description="" ImageUrl="/_layouts/15/images/itann.png?rev=23" Name="{F194025B-A0F2-4318-950A-9197AD8D2285}" BaseType="0" FeatureId="00bfea71-d1ce-42de-9c63-a44004ce0104" ServerTemplate="104" Created="20130510 01:18:39" Modified="20131015 03:57:05" LastDeleted="20130802 04:12:40" Version="3" Direction="none" ThumbnailSize="" WebImageWidth="" WebImageHeight="" Flags="603983880" ItemCount="6" AnonymousPermMask="0" RootFolder="" ReadSecurity="1" WriteSecurity="1" Author="9" EventSinkAssembly="" EventSinkClass="" EventSinkData="" EmailAlias="" WebFullUrl="/" WebId="8f69cd67-4cc9-42f4-b104-2fe1e2b7944e" SendToLocation="" ScopeId="fadcba6a-3b00-44b9-a813-db5dc5cf3858" MajorVersionLimit="0" MajorWithMinorVersionsLimit="0" WorkFlowId="" HasUniqueScopes="False" NoThrottleListOperations="False" HasRelatedLists="" Followable="False" AllowDeletion="True" AllowMultiResponses="False" EnableAttachments="True" EnableModeration="False" EnableVersioning="False" HasExternalDataSource="False" Hidden="False" MultipleDataList="False" Ordered="False" ShowUser="True" EnablePeopleSelector="False" EnableResourceSelector="False" EnableMinorVersion="False" RequireCheckout="False" ThrottleListOperations="False" ExcludeFromOfflineClient="False" CanOpenFileAsync="True" EnableFolderCreation="False" IrmEnabled="False" IsApplicationList="False" PreserveEmptyValues="False" StrictTypeCoercion="False" EnforceDataValidation="False" MaxItemsPerThrottledOperation="5000" xmlns="<a href="http://schemas.microsoft.com/sharepoint/soap/&quot;">http://schemas.microsoft.com/sharepoint/soap/"</a> />

After diligently looking through all of the attributes here it doesn’t seem like the “New Folders allowed” option is included. One attribute did catch my eye however… the “Flags” attribute. What was this for and could it hold the secret I was after?

I went into SharePoint toggled the Allow New Folders setting reran my code to call the Lists web service and grabbed the XML again to test if anything changed in the Flags attribute.

On my initial run through the Flags attribute had a value of “603983880” (no new folders allowed), on my second run through the Flags attribute had indeed changed to “67112968” (new folders allowed). Great, somehow this Flags attribute holds the key, but how do you make use of this?

My understanding of flags is that they work on an individual bit level, essentially every bit can have an on/off state. So this means a flag can hold the state of many different variables. So time to get binary! It’s been a few years since I last sat in a classroom and figured out binary/decimal conversions with a pencil and paper so let’s just cheat – or actually let’s use a much faster tool for the job.

I started up Windows Calc and put it into Programmer mode.

01-sharepoint-new-folder-allowed-from-remote-app-windows-calc-programmer-cameron-dwyer

Next set the calc to Dec(imal) mode and cut/paste the initial value of the flag in

02-sharepoint-new-folder-allowed-from-remote-app-paste-flag-decimal-cameron-dwyer

Now click on Bin(ary) to convert the number and we get:

100100000000000001000000001000

This on it’s own gives us nothing, but if we repeat the steps with the second value of the flag (after we toggled the allow New Folders setting) we get the binary value:

000100000000000001000000001000

Now we have something to work with, if you align these 2 values under each other you can see that just a single bit has changed.

03-sharepoint-new-folder-allowed-from-remote-app-bitwise-flag-comparison-cameron-dwyer

That’s the bit that represents the “Allow New Folder” setting.

Before we dive into the code for the solution I’ll explain why the values you see in the code don’t look like the binary numbers above. Binary is damn hard to read, very long to type, and prone to typing errors. I’ve converted these binary numbers to Hex in order to do the comparisons. When you convert these 2 numbers to Hex (using calc again) you get

04-sharepoint-new-folder-allowed-from-remote-app-hex-flag-comparison-cameron-dwyer

As you can see, we still have our difference of a single number in the sequence but it’s a lot less digits.

So now all that’s left is the code that checks if this bit has been set or not.

// Detect if folders are allowed in this list/library - it's hidden in the Flags attribute.
UInt64 flags = 0;
bool foldersAllowed = false;
string flagsStr = listNode.Attributes.GetNamedItem("Flags").InnerText;
if (UInt64.TryParse(flagsStr, out flags))
{
    foldersAllowed = ((flags & ((ulong)0x20000000L)) == 0L);
}

SharePoint PowerShell How To: Create SharePoint Library Folders for Load/Performance Testing

SharePoint PowerShell How To Series – Foreword

I often find myself scratching around the local drive of my development machines for remnants of PowerShell scripts to generate list & libraries in SharePoint with all sorts of different folder hierarchies to test the performance of code I’m working on to ensure it scales well once the folder & item counts start getting up to high numbers. So rather than keep scratching I’m going to start posting my scripts as I create and use them so I can find/reuse them later on and someone else might find them useful as well. I’m sure they won’t work under all scenarios and situations (and they are not designed to). They are just quick scripts that serve a specific purpose to me at the time and you may be able to tweak to fit your needs.

Create folders in the root of a document library

Script description: Create 4000 subfolders within the “Folder Performance Test 01” library on the SharePoint Server “vs-server38”

#Script settings
$webUrl = "http://vs-server38"
$listName = "Folder Performance Test 01"
$numberFoldersToCreate = 4000;
$folderNamePrefix = "folder";

# Open web and library
$web = Get-SPWeb $webUrl
$list = $web.Lists[$listName]

# Create desired number of subfolders
for($i=1; $i -le $numberFoldersToCreate; $i++)
{
$folder = $list.AddItem("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, "$folderNamePrefix$i")
$folder.Update()
write-host $i
}

#Dispose web
$web.Dispose()

Create folders within an existing folder in a document library

Script description: Create 4000 subfolders within a folder called “C” within the “Folder Performance Test 02” library on the SharePoint Server “vs-server38”

# Script settings
$webUrl = "http://vs-server38"
$listName = "Folder Performance Test 02"
$subFolderName = "C"
$numberFoldersToCreate = 4000;
$folderNamePrefix = "folder";

# Open web and library
$web = Get-SPWeb $webUrl
$list = $web.Lists[$listName]

# Get handle on the subfolder
$subFolder = $list.RootFolder.SubFolders.Item($subFolderName);
Write-Host $subFolder

# Create desired number of subfolders
for($i=1; $i -le $numberFoldersToCreate; $i++)
{
$folder = $list.AddItem($subFolder.ServerRelativeUrl, [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, "$folderNamePrefix$i")
$folder.Update()
write-host $i
}

#Dispose web
$web.Dispose()

Related articles

How to find the Version, Culture and PublicKeyToken of an Assembly (DLL) using PowerShell

In response to a question on my article How to install a DLL to the GAC on Windows Server 2012 using only PowerShell (without having to install SDK or Visual Studio) here’s how you can find the PublicKeyToken for a DLL using only PowerShell.

([system.reflection.assembly]::loadfile("c:\temp\MyDLL.dll")).FullName

The output of this PowerShell statement will provide the Version, Culture and PublicKeyToken as shown below.
MyDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=630d986a50055aa6

%d bloggers like this: