Create PDF Documents with PowerShell

Niklas Goude rules.  He posted nice article on how to create PDF documents with PowerShell…

The code snippet from the site is below (slightly modified)

[System.Reflection.Assembly]::LoadFrom(“C:\util\textsharp\itextsharp.dll”)

Function MakePDF($path, $data)
{
$Doc = New-Object iTextSharp.text.Document
[void][iTextSharp.text.pdf.PdfWriter]::GetInstance($Doc, [System.IO.File]::Create($path)  )
$Doc.Open()
$Chunk = New-Object iTextSharp.text.Chunk
[void]$Chunk.Append($data)
$Doc.Add($Chunk)
$Doc.AddAuthor(“User”)
$Doc.Close()
}

 

BinarySecurityToken not being returned when authenticating to SharePoint Online…

Recently, I have been trying to create a C# application for SharePoint Online to import some data.  After some digging on how to create the appropriate requests to the appropriate URLs for the appropriate tokens (phew!) discovered that the response back from https://login.microsoftonline.com/extSTS.srf was not what it was supposed to be (BinarySecurityToken was nowhere to be found).

After more digging, found this helpful post basically saying that you won’t/can’t get a BinarySecurityToken from an SPO site that was upgraded from BPOS.  That kinda sucks.

STS responses differ between new SharePoint site and site migrated from BPOS

http://community.office365.com/en-us/forums/154/t/46946.aspx

Here is the clip from the article for the sake of others:

=========================================================

Author: Cirrus6
Post replied on 6/25/2012 3:47 PM
UPDATE 6/25/2012…… I have spent a significant amount of time working with both the SharePoint Tech Support and business folks at Microsoft to achieve a positive outcome to this issue. A few things for you all to know.

First, currently there are two scenarios where you CANNOT export/import Office 365 SharePoint site templates because the SharePoint/site features do not match up properly.

1) Sites migrated from BPOS becuase they contain features in order for older BPOS sites to operate on Office 365

2) Sites exported using a higher plan (ie E3) to a lower plan (ie E1). You can only export/import from a lower plan (ie E10) to a higher plan (E3).

Second, There are two methods to connect to Office 365 SharePoint sites programatically:

1) Remote Client Object Model – This requires that a pop-up browser window appears where the user id and password are entered manually in order to connect to SharePoint. We have tested this code and it supports both Office 365 SharePoint sites orginally created in Office 365 and sites transitioned from BPOS. This works well if you are trying to create a utility to migrate your SharePoint data from an old site to a new site in the absence of being able to export/import site templates.

Example

code.msdn.microsoft.com/…/Remote-Authentication-in-b7b6f43c

2) Headerless Authentication – This does NOT require a pop-up windows and you can only connect to Office 365 sites that were NOT migrated from BPOS otherwise you encounter the invalid security token error. There are a number examples on the internet that explain how to code this. We have tested them and confirm that it works. But, here is the kicker…. its is NOT SUPPORTED by Microsoft. According to what we’ve learned, support for this method is being decided upon internally but it isn’t looking like they want to do it for whatever reasons. I am in the process of escalating this via multiple channels. I would suggest you all do the same. Otherwise, developers will not have the ability to achieve SSO (without using ADFS) and you won’t be able to create automated applications that push data from external systems to Office 365 SharePoint by simply passing credentials. You should avoid incorporating this method into retail, production applications as it could stop working at anytime.

Examples:

allthatjs.com/…/remote-authentication-in-sharepoint-online

The problem is in step 2, we receive the improper response from the E1 Plan migrated from BPOS. While we get the appropriate result from my E3 account.

Note that in the conversation another person pointed out an issue with SharePoint sites migrated from BPOS.

www.wictorwilen.se/…/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx

(The developer is not getting the binary security token. Most likely a SharePoint site migrated from BPOS)

social.technet.microsoft.com/…/4e304493-7ddd-4721-8f46-cb7875078f8b

(Similar approach.)

I hope that this gives you all some insight into a very frustrating issue.

Another person on Stackoverflow had the answer (http://stackoverflow.com/questions/9626539/saml-token-format) — just need to figure out how to implement it:

answered Mar 12 ’12 at 14:23
codebrane

It’s an encrypted response using a KEK (Key Encryption Key). You’ll need the public key of the sender to decrypt the EncryptedKey. That lets you use that key to decrypt the CipherData which is what you’re after I would think.

convert an XML document into a C# dynamic object.

http://www.itdevspace.com/2012/07/parse-xml-to-dynamic-object-in-c.html

This guy has a great class to convert an XML document into a C# dynamic object. very useful

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Dynamic;

namespace LinkedInAggregator.Core
{
/// <summary>
/// Converts XML data into a C# Dynamic Object
/// http://www.itdevspace.com/2012/07/parse-xml-to-dynamic-object-in-c.html
/// </summary>
public class XmlToDynamic
{
public static void Parse(dynamic parent, XElement node)
{
if (node.HasElements)
{
if (node.Elements(node.Elements().First().Name.LocalName).Count() > 1)
{
//list
var item = new ExpandoObject();
var list = new List<dynamic>();
foreach (var element in node.Elements())
{
Parse(list, element);
}

AddProperty(item, node.Elements().First().Name.LocalName, list);
AddProperty(parent, node.Name.ToString(), item);
}
else
{
var item = new ExpandoObject();

foreach (var attribute in node.Attributes())
{
AddProperty(item, attribute.Name.ToString(), attribute.Value.Trim());
}

//element
foreach (var element in node.Elements())
{
Parse(item, element);
}

AddProperty(parent, node.Name.ToString(), item);
}
}
else
{
AddProperty(parent, node.Name.ToString(), node.Value.Trim());
}
}

private static void AddProperty(dynamic parent, string name, object value)
{
if (parent is List<dynamic>)
{
(parent as List<dynamic>).Add(value);
}
else
{
(parent as IDictionary<String, object>)[name] = value;
}
}
}
}

DDWRT FormatDate XSL Date Formatting…

Recently I had to change the format of a Blog Post in a SharePoint blog site.  After some muddling, came across this link:

http://panvega.wordpress.com/2008/12/08/ddwrtformatdate-with-different-formatflags/

After I updated the XSL of the webpart to include the following:

<xsl:value-of select=”ddwrt:FormatDate($thisNode/@PublishedDate, 1033, 3)”/>

Everything worked like a charm 🙂 XSL is growing on me…

 

SharePoint Workflow Variables —

Goldmine!  This nice person posted all variables from a Workflow…

Thanks!

REPOST:
http://community.corasworks.net/blogs.aspx?CWFrameSource=http://community.corasworks.net/blogs/AdamMacaulay/archive/2012/01/14/workflow-context-and-current-item-fields.aspx

Workflow Context and Current Item Fields

Tags:

In working with developing some workflows I needed to understand what are all the possible default elements I can access. Since the workflow itself is a reusable workflow I cannot associate it with a specific list and as such can only access certain pieces of information. Using a Item Event won’t work for me so workflow is the only choice. So given that I have the information and I couldn’t find it on the web, I am sharing it with you as well so you don’t have to get it manually yourself.

Task List

Workflow Context Association Name: Test
Workflow Context Manual Start: True
Workflow Context Workflow Context Manual Start Requires Permissions: True

Workflow Context Start on Item Change: True
Workflow Context Start on Item Creation: True
Workflow Context Start to Approve Major Versions: False
Workflow Context Associator: domain\user

Workflow Context Current Item URL: http://[web app]/sites/site/Lists/Tasks/DispForm.aspx?ID=1
Workflow Context Current Site URL: http://[web app]/sites/[site]
Workflow Context Current User: domain\user

Workflow Context Date and Time Last Run: 1/14/2012 11:47:55 AM
Workflow Context Date and Time Started: 1/14/2012 11:47:55 AM
Workflow Context Initiator: domain\user

Workflow Context Instance ID: 8cc41170-2253-4466-aecc-d9f4a046616f
Workflow Context Item Name: Item Added
Workflow Context Workflow Status URL: http://[web app]/sites/[site]/_layouts/WrkStat.aspx?List=ed681468%2D4791%2D49cd%2Db2fa%2D462b70ea8fee&WorkflowInstanceID=8cc41170%2D2253%2D4466%2Daecc%2Dd9f4a046616f

Current Item Content Type: Task
Current Item Created: 1/14/2012 11:47:55 AM
Current Item Created By: domain\user
Current Item ID: 1
Current Item Modified: 1/14/2012 11:47:55 AM
Current Item Modified By: domain\user

Current Item Title: Item Added

Document List

Workflow Context Association Name: Test
Workflow Context Manual Start: True
Workflow Context Workflow Context Manual Start Requires Permissions: True

Workflow Context Start on Item Change: True
Workflow Context Start on Item Creation: True
Workflow Context Start to Approve Major Versions: False
Workflow Context Associator: domain\user
Workflow Context Current Item URL: http://[web app]/sites/[site]/Shared Documents/ImplementUser (1)_C.xml
Workflow Context Current Site URL: http://[web app]//sites/[site]
Workflow Context Current User: domain\user
Workflow Context Date and Time Last Run: 1/14/2012 11:49:12 AM
Workflow Context Date and Time Started: 1/14/2012 11:49:12 AM
Workflow Context Initiator: domain\user
Workflow Context Instance ID: 925b5612-af61-4538-ba0b-db684665a4d1
Workflow Context Item Name: ImplementUser (1)_C
Workflow Context Workflow Status URL: http://[web app]//sites/[site]/_layouts/WrkStat.aspx?List=9cc7dc27%2D1e4a%2D475c%2D9959%2D0fe34f859667&WorkflowInstanceID=925b5612%2Daf61%2D4538%2Dba0b%2Ddb684665a4d1

Current Item Content Type: Document
Current Item Created: 1/14/2012 11:48:55 AM
Current Item Created By: domain\user
Current Item ID: 1
Current Item Modified: 1/14/2012 11:49:12 AM
Current Item Modified By: domain\user
Current Item Title: ImplementUser (1).xml

Event Receiver ItemDeleting with CancelWithRedirectUrl “Event Receiver has canceled the request” – SOLVED

After much troubleshooting on an odd error “Event Receiver has canceled the request” when trying to redirect a user to a custom error page, I discovered that SharePoint is picky about the RedirectUrl you pass in.  When using properties.RelativeUrl on a root web application it returns “/” when using it on a non-root site collection it returns something like “sites/mysite” (with no ending slash).  So – if you are developing on a non-root site collection and deploy to a root site collection, your redirect URL may contain a double slash.  This double slash was the problem for me.

Checking for an ending slash fixed the issue.

SPList list = properties.List;

SPListItem item = list.GetItemById(properties.ListItemId);

string itemName = item[“Title”].ToString();

string itemId = item[“ID”].ToString();

string relativeUrl = properties.RelativeWebUrl;

if (relativeUrl.EndsWith(“/”) == false) { relativeUrl = relativeUrl + “/”; }

properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;

properties.RedirectUrl = relativeUrl + “Lists/Foo/CustomDelete.aspx?ItemName=” + itemName + “&itemId=” + itemId;

DisableLoopbackCheck – FTW (SharePoint Alternate Access Mapping, Access Denied – Solved)

While configuring my local alternate access mappings in my local SharePoint workspace, I was unable to connect to the newly created site through the AAM url (i.e. http://foo.bar.com).  The solution is to create a DWORD registry key called “DisableLoopbackCheck” with a value of “1” here:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

This will allow you to create AAMs based on host names to the local server.

http://www.harbar.net/archive/2009/07/02/disableloopbackcheck-amp-sharepoint-what-every-admin-and-developer-should-know.aspx

Boom.  Now on to solve the actual problem I’m working on 🙂

Symptoms:
Alternate Access Mapping – 401.1, unable to authenticate to new AAM site, Access Denied on new AAM configuration

SharePoint_Config database marked as suspect — Solution

Recently, my SharePoint_Config database was marked as suspect.  Yikes!  Had to run the following to fix it:

Use Master
EXEC sp_resetstatus ‘SharePoint_Config’

ALTER DATABASE SharePoint_Config SET EMERGENCY DBCC checkdb(‘SharePoint_Config’)

ALTER DATABASE SharePoint_Config SET SINGLE_USER WITH ROLLBACK IMMEDIATE DBCC CheckDB (‘SharePoint_Config’, REPAIR_ALLOW_DATA_LOSS)

ALTER DATABASE SharePoint_Config SET MULTI_USER EXEC sp_resetstatus ‘SharePoint_Config’
GO

Phew!

Also, I knew something was up when I saw the error “Cannot connect to configuration database” and “The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.” when logging into SharePoint PowerShell.