Sunday, December 27, 2015

Find Your Azure Web App Deployment Credentials

If for any reason you forget your deployment credentials, and have trouble publishing without them, you can download the Publishing Profile from the manager website:

and grab the userPWD from the xml...

Tuesday, December 1, 2015

InfoPath Person/People Picker moving to top of page after it resolves

Having an issue where the Person/Group picker moves the page everytime it resolves the name?  Open the properties of the control, go to the Advanced Tab and set the Tab Index to be unique.  That's it!

Monday, September 28, 2015

"An unexpected error has occurred" when viewing a SharePoint task

I was getting the following message when some users were logging in to close their tasks:
An unexpected error has occurred.
The correlation ID associated to this error in the ULS logs was the following:
System.ArgumentNullException: Value cannot be null.  Parameter name: item    at Microsoft.Office.Workflow.ListPage.SimpleNameFromItem(SPListItem item)
Turns out in our environment we have users logging in from multiple domains, and the account trying to view the task didn't have access to the associated item to the task.  After giving that item permissions to the proper account, all was well.

Monday, June 29, 2015

Change the column width of a SharePoint List View web part

If you're looking to adjust the width of specific columns for a list view (aka XsltListViewWebPart), you can do this easily by adding a Content Editor webpart to the page (e.g. /Lists/MyList/AllItems.aspx), link it to a CSS file:

Then add the following into a stylesheet, and you can target either the DisplayName or the Name fields:

<style type='text/css'>
.ms-vh-div[DisplayName='Trial Column']

If you're not sure what to target take a look at the source of your web part and find the th column you want to target, which will look something like this:

<th nowrap scope="col" onmouseover="OnChildColumn(this)" class="ms-vh2"><div Sortable="FALSE" SortDisable="" FilterDisable="" Filterable="FALSE" FilterDisableMessage="" name="Trial_x0020_Column" CTXNum="3923" DisplayName="Trial Column" FieldType="Note" ResultType="" class="ms-vh-div">Trial Column</div></th>

Tuesday, June 23, 2015

Share Local Term Store Across Multiple Site Collections - PowerShell Script

I was migrating a site that used a Local Term Store for some of their metadata fields.  This caused all sorts of issues when trying to migrate content, since that data couldn't come along to the new site collection.  So when you tried and edit the properties the fields would appear red and you couldn't save anything.  I found some posts that mentioned how to reset it from a backup restore, including:

and an article resurrected from the wayback machine by Sergey Zelenov:

I expanded on this one a bit so that you can pass it the site collection url of the site with the local term store, and the site you want the "local" term store to appear in, and after you run this you'll be able to use the local term store across both site collections.

function Add-SPSiteLocalTermSetAccess

    param (
        if (-not (Get-PSSnapin | Where-Object {$_.Name -eq "Microsoft.SharePoint.PowerShell"}))
            Add-PSSnapin Microsoft.SharePoint.PowerShell;
        ## Force the script to terminate on errors that would by default be treated as non-terminating
        $ErrorActionPreference = "Stop";        
        if ($originalSite -isnot [Microsoft.SharePoint.SPSite])
            $originalSite = Get-SPSite -Identity $originalSite;
            Write-Verbose -Message ("Bound to site collection {0} at {1}" -f $originalSite.Id, $originalSite.Url);

        $ts = Get-SPTaxonomySession -Site $originalSite;
        ## Obtain the ID of the term set group from the root site property bag
        $sgroupid = $originalSite.RootWeb.AllProperties.Keys | 
            Where-Object `
                $_ -like "SiteCollectionGroupId*"
            } | 
                Select-Object -Property @{n="GroupID";e={$originalSite.RootWeb.AllProperties[$_]}} |
                    Select-Object -ExpandProperty GroupID;
Write-Verbose -Message ("sgroupid: '{0}'" -f $sgroupid)

        $sgroup = $ts.TermStores[0].Groups[$sgroupid];
        if ($sgroup -eq $null)
            throw "Target term store group could not be found!"
        Write-Verbose -Message ("Found term set group: '{0}'" -f $sgroup.Name)

Write-Verbose -Message ("Group Access IDs: '{0}'" -f $sgroup.SiteCollectionAccessIds)
        ## Remove the 'old' (prior to backup/delete/restore) site collection ID from the group access list
        ## We don't want to lose the originalSite's association in this case
        #$sgroup.SiteCollectionAccessIds | 
        #    Foreach-Object `
        #    {
        #        $sgroup.DeleteSiteCollectionAccess($_);
        #        Write-Verbose -Message ("Removed ID '{0}' from the Site Collection Access List" -f $_);
        #    }
if ($siteToAdd -isnot [Microsoft.SharePoint.SPSite])
            $siteToAdd = Get-SPSite -Identity $siteToAdd;
            Write-Verbose -Message ("Bound to site collection {0} at {1}" -f $siteToAdd.Id, $siteToAdd.Url);

        ## Add the new site collection ID to the group access list
        Write-Verbose -Message ("Added new site ID ('{0}') to the Site Collection Access List" -f $siteToAdd.Id);

        ## Persist the changes in the database - very important!!
        Write-Verbose -Message ("Commited all changes to term store '{0}'" -f $sgroup.TermStore.Name);

## Get the siteToAdd SiteCollectionGroupId
## Obtain the ID of the term set group from the root site property bag
        $siteToAddGroupId = $siteToAdd.RootWeb.AllProperties.Keys | 
            Where-Object `
                $_ -like "SiteCollectionGroupId*"

Write-Verbose -Message ("SiteToAddGroupID: ('{0}')" -f $siteToAddGroupId)

# Get the first of the collection (if multiple)
  # NOTE:  This targets the first one -- might need to loop through
  # this if multiple, or target the specific one.  
$siteToAddGroupId = $siteToAddGroupId[0]

$webProp = $web.GetProperty($siteToAddGroupId)

# cast to string
$stringGroupId = $sgroupid.ToString()

Write-Verbose "siteToAddGroupId: $siteToAddGroupId"
Write-Verbose "stringGroupId: $stringGroupId"
Write-Verbose "WebProp: $webProp"

If ($webProp -eq $null)
  # Add property
  Write-Verbose "Property is null..."
  $web.AddProperty($siteToAddGroupId, $stringGroupId)
  # Property exists – remove/re-add the property   
  Write-Verbose "Property already exists, in else..."
  $web.AddProperty($siteToAddGroupId, $stringGroupId)

        Write-Output -InputObject ("Site collection's access to term store group '{0}' added successfully" -f $sgroup.Name);

Add-SPSiteLocalTermSetAccess -Verbose

Note that afterwards I had to re-inherit permissions at the hidden taxonomy list here:

before users could see the data in the columns.

Thursday, January 29, 2015

Remove the grayed out columns created by InfoPath that are not mapped to SharePoint columns

Sometimes when you map InfoPath columns to SharePoint columns, if you switch environments and the column IDs don't match up you'll get grayed out columns in addition to your SharePoint columns:

You can go back into InfoPath and under Form Options -> Property Promotion, go through and map each column to the proper SharePoint content type and column that you created, and re-publish the InfoPath form.  Then run the following:

$web = Get-SPWeb -identity http://webapp/site
$list = $web.Lists["LISTNAME"]
foreach($column in $list.Fields)
if ($column.Group -eq "Microsoft Office InfoPath")
if ($column.ReadOnlyField -eq $true)
Write-Host $column.Title
$column.Hidden = $false
$column.ReadOnlyField = $false

and you'll remove the extra columns and your InfoPath data should be mapped to your SharePoint columns properly.

Thursday, January 15, 2015

InfoPath: Some external data was not retrieved. The form will load without the requested data.

When moving your InfoPath form through Dev/Test/Prod, if you have an InfoPath data connection that is referencing a list (and querying that data connection like populating a dropdown), InfoPath winds up storing the GUID of that list in some of it's queries.  So if the list GUIDs don't match then you might get a message like this:

If you just recreate the data connection in InfoPath, then this message should go away.