Wednesday, October 7, 2015

SPBasePermissions enumeration - values in Int64, Hexadecimal, and Name

$t = [type]'Microsoft.SharePoint.SPBasePermissions'
[enum]::GetValues($t) | ForEach-Object {Write-Host "$($_): $([int64]$_) (0x$([Convert]::ToString([int64]$_,16)))"}

Haven't figured out a way to use Format-Table for this, but good enough for now.

Thursday, July 30, 2015

Solutions, features, and CompatibilityLevel

I recently came across an issue where certain feature definitions were not available in 2010 mode sites in one farm, but they were in another. It turned out that the parameters supplied to Install-SPSolution are the reason. Essentially, the difference was specifying -CompatibilityLevel {14,15} vs specifying nothing. I found this article to be very helpful: Planning Deployment of Farm Solutions for SharePoint 2013

Monday, July 20, 2015

Error codes

Just some notes to myself on some resources to help decipher error codes that I often come across. These are sometimes mentioned in the ULS logs with something like hresult= or hr=

Saturday, July 4, 2015

A potentially dangerous Request.Path value was detected from the client (%)

Recently came across an issue with an error like the following:
Application error when access {some-url}, Error=A potentially dangerous Request.Path value was detected from the client (%).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

Looking more carefully at the URL, it turned out there was a %2520 in it. That is there was a space in the URL which was encoded into a %20, but then some errant code encoded it again into %2520.

What was tricky about this issue that I never saw my endpoint request actually get logged in ULS. Instead, it looked like this was caught by .NET. 

Tuesday, May 5, 2015

Hacking SPRoleDefinition SPRoleType in the database

If you are a Site Collection Administrator, SharePoint allows you to go to a Site Collection, Site Actions->Site Permissions->Permission Levels, then edit a permission level and delete it.

Some predefined Permission Levels (SPRoleDefinition) have a Type (SPRoleType) defined. This is not visible via the UI. However you can get this via Powershell as follows:

$web = Get-SPWeb your-web-url
$web.RoleDefinitions | Format-Table Id, Name, Type, Hidden -AutoSize

This gives output like the following:

        Id Name                       Type Hidden
        -- ----                       ---- ------
1073741829 Full Control      Administrator  False
1073741828 Design              WebDesigner  False
1073741827 Contribute          Contributor  False
1073741826 Read                     Reader  False
1073741825 Limited Access            Guest   True

Now, if you delete one of these such as the Contribute and then decide to recreate it, the type is now "None". There is no way to make the Type "Contributor".

This is all fine, but if you have some code that calls Microsoft.SharePoint.SPRoleDefinitionCollection.GetByType then your code is now broken.

To "resolve" (using the term very loosely as I do not know if there are any implications), I was able to restore this by hacking the database directly.

Essentially, I looked into the Roles table in the WSS_Content database, filtered on the WebId and RoleId and set the Type column directly in the database. Is it a good idea? Who knows? It seemed to work for me, but I do not know what I may have broken as a result of this.

Friday, April 10, 2015

Automatically capturing matching Failed Request Trace Logs

I was trying to troubleshoot a particularly challenging user identity issue with SharePoint and thought about using Failed Request Tracing which I will write about some other time.

While doing so, I wanted a way to grab the relevant fr*.xml files. I thought that it would streamline things if I could watch for these log files as they are created, run some filter against them and, if matched, copy the file to another folder (hopefully before the log rolls over).

Then I came across this post regarding "check folder for new files":
I adapted it to my purpose:

$destination = 'c:\Inetpub\Logs\FailedReqLogFiles\Temp'
$folder = 'C:\Inetpub\logs\FailedReqLogFiles\W3SVC2'

$filter = 'fr*.xml'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{
  IncludeSubdirectories = $false
  NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'

$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
  $path = $Event.SourceEventArgs.FullPath
  $name = $Event.SourceEventArgs.Name
  $changeType = $Event.SourceEventArgs.ChangeType
  $timeStamp = $Event.TimeGenerated
  $frlogfile = Get-Content $path
  $xml = [xml]$frlogfile
  $url = $xml.failedRequest.url
  Write-Host "The file $($name) was $($changeType) at $($timeStamp) with URL $($url)"
  if (***my matching conditions***) {
    Copy-Item $path -Destination $destination -Force -Verbose

I definitely need to read up more on Get-Event, Get-EventSubscriber, Register-*Event cmdlets as well as the IO.FileSystemWatcher class. I think I could do some pretty cool stuff with them.

Friday, March 13, 2015

Amazon AWS value cannot be null, parameter name awsAccessKeyId

Today, none of my AWS Powershell scripts would work any more. They were all returning
... : Value cannot be null.
Parameter name: awsAccessKeyId

Coincidentally, my Visual Studio would keep on crashing upon startup. I eventually dug into the crash logs and realized that it had to do with the Amazon plugin as well.

Initially I thought it had to do with expired credentials or even the Windows Patch Tuesday.

However, I ended up reinstalling AWS Powershell (and with a much newer version) and the problem went away.