Nov 10, 2009

SharePoint 2010, PowerShell and Disposing

When you are already familiar with the SharePoint object model, you might know that SPSite and SPWeb allocate large amounts of memory and adequate memory management and disposing is essential. To make life easier the SharePoint team introduced two Cmdlets dealing with this in SharePoint 2010:
  • Start-SPAssignment
  • Stop-SPAssignment
By default, all Get commands dispose of these objects immediately after the pipeline finishes, but using SPAssignment, you can assign the list of objects to a variable and dispose of the objects after they are no longer needed. You can also ensure that the objects will remain as long as you need them, even throughout multiple iterations of commands
There are three levels of assignment:

No Assignment

The object is not assigned to a variable and is disposed after each iteration of the command.
Get-SPWeb http://server/sites/* |
     foreach { $_.Title | out-host } 

Simple Assignment

All objects are assigned to the global assignment store. This is done by using the Global parameter. When using this level, all objects are assigned to a global store and are disposed of when the Stop-SPAssignment command is called.

Start-SPAssignment -GlobalGlobal
$web = Get-SPWeb "http://server/sites/web"
$web.Title = "Greetings from PowerShell"
$web.Update()
Stop-SPAssignment -Global
# $web will be disposed

Note: Use global assignment with caution! For example, if you use Start-SPAssignment – Global with and then call Get-SPSite –Limit ALL, every site collection object will be loaded, every site collection object will be loaded into memory. In a live server farm, this is likely to cause to cause serious performance issues

Advanced Assignment

Objects are assigned to named stores for disposal. You can dispose of objects by using the -Identity parameter with the Stop-SPAssignment command.

$siteScope = Start-SPAssignment
foreach($site in ($siteScope | Get-SPSite "http://server/*"))
{
   $webScope = Start-SPAssignment
   $web = $webScope | Get-SPWeb $site.RootWeb.Url
   $web.Title = "Greetings from PowerShell"
   $web.Update()
   Stop-SPAssignment $webScope
}
Stop-SPAssignment $siteScope

Regardless of the level used, all objects are disposed of when the PowerShell runspace is closed.

Oct 26, 2009

Preview - Wikis in SharePoint 2010

Refers to build 14.0.4006.1010 (BETA 1)
Wiki functionality in SharePoint 2007 was kind of spartan. In this post I’ll have a look what will come with SharePoint 2010.

The Wiki Homepage Feature

When you create a blank site in SharePoint 2010 the homepage (default.aspx) will be a web part page as usual. But now there’s a new feature called “Wiki Page Home Page”.
image
When you activate the feature it creates a document library called “SitePages”, adds a wiki page named “default.aspx” and set it as the new homepage for the site.
image
The feature transforms your whole site to a wiki. Every time you create a new page it will create a new wiki page and store it in the “SitePages” lib (similar to the publishing features in 2007).
image
For sure you can tag Wiki pages as any other page as described in my previous post Managing Metadata in SharePoint 2010.

Content

While in SharePoint you could only write some rich text, you now could upload files (will be stored as a separate file) and add Web Parts.

No joke, you can now add Web Parts at any place within the wiki rich text!

image

[[Wiki Linking]]

In SharePoint 2010 you will get an intellisense like linking experience. That’s kind of cool :-) Just an enter [[ and press ctrl+space
image
image
You can now link easily pages, lists, items, documents and views.

Enterprise Wiki Layouts

Additionally there’s a new Site Collection feature called “Enterprise Wiki Layouts” for creating a large-scale wiki with categories and page layouts.
image
Seems to be correlated with the publishing infrastructure, because the feature add a new page layout content type. This means you can create wiki page layouts with SharePoint Designer 2010.
imageClick and see the beautiful new SharePoint 2010 error message. image
Never mind this a technical preview and lot of things already work great. Can’t await to continue with the beta in November…

Oct 22, 2009

Managing Metadata in SharePoint 2010

Obsolete: Refers to build 14.0.4006.1010 (beta 1)
SharePoint 2010 comes with a bunch of web 2.0 features, tags, tag clouds, rating, social bookmarking and enhanced blogs and wikis. What I really missed in SharePoint 2007 was tags and tag clouds. On the other hand this was a free space for developers like me, see Power Tag Cloud ;-) My experience with SharePoint 2003 already showed that text, dropdowns and lookup columns are to inflexible and people tend to over categorize in the conception stage.

Less is more!

This could lead to a confusing meta taxonomy. What we have learned from the web 2.0 wave in the last years is that tags and tag clouds are a great, simple and flexible way to organize information.
Now with SharePoint 2010 this and much, much more comes out of the box. Tagging becomes one of the most significant concepts for building enterprise taxonomies in SharePoint 2010.

What can be tagged?

  • List Items (Terms, Keywords, Social Tags)
  • Documents (Terms, Keywords, Social Tags)
  • Pages (Terms, Keywords, Social Tags)
  • External pages (Social Tags)

This means everything that has an URL can be social tagged. Do you know anything in the web that hasn’t one?

Talked enough, let’s play around with this stuff…

Tag a list item or a document:

image
Almost any built-in list has per default a “Managed Keywords” column. When you start to write you get a filtered list of suggestions. When you enter a tag that not exist it will be automatically added to the managed keywords list.

Tag and note a SharePoint page:

image
image
To tag a SharePoint page you can use the user’s context menu as shown above. Clicking “Tag or Note this Page” opens the following dialog.
imageYou can tag the page just like the list item before, but in addition you will get a list of suggested tags and you can mark them as private, so other user will not see them. At the bottom of the dialog you see a tag and note history. Furthermore you can add notes to the page (see in the second tab on the top).
image

How to tag an external page?

Since years I miss a tool from Microsoft to centrally manage bookmarks and I believe I’m not alone. To tag external pages you have first to add a link to the SharePoint tagging dialog to your browser’s favorites:
image
This adds the “Tags and Noteboard” bookmark (JavaScript) to your browsers favorites list. Now you tag an external page like this:
Tag external pageClicking to the “Tag and Noteboard” brings up the same dialog as in the previous example for a SharePoint page. You can tag and write notes as usual.
This looks similar to social bookmark tools like Diigo. But I miss some features like highlighting text, sticky notes, share bookmarks with a group, and a good browser plug-in. But hope this will come in later builds…

Tag Cloud Web Part

For sure you want to use your tags to navigate and filter content. For this reason there is now a tag cloud web part included in SharePoint 2010. I’m really a tag cloud fun :-)
image
image

My Tags and Notes

You can manage your tags globally as shown bellow.
image
image

Managing Enterprise Metadata

All you seen above is not enough for building an enterprise taxonomy. You don’t want let the users build your taxonomy on the fly with some tags, you want to predefine keywords and terms for your whole SharePoint farm. And what’s about multilingual terms and keywords? That’s why Microsoft added a something called “Term Store Management Tool”:
image
Here you can delete or create new tags and terms centrally for the whole farm. There is also support for multilingual terms! In my current build I’ve got the feeling this isn’t feature completed yet (there is already some documentation on MSDN), so I stop here and wait for further builds…

Although all this cool new web 2.0 features in SharePoint 2010, don’t forget that the most significant part is to get all this rocking is your company’s culture! Are you ready for culture 2.0?


UPDATE 26th Nov 09 (beta 2):
I've just seen in a screencast from Steffen Kraus (Microsoft Germany) some enhancements in newer builds:
  • support for hierachical tags (Taxonomy)
  • tag picker functionality
  • tag based hierachical navigation in a list (Metadata navigation)

There's a huge different between social tags (will be stored at the user profile) and Enterprise Keywords and Terms (will be stored in the item itself)


FAST Search can't use tag refinment for social tags - read more.

Oct 20, 2009

Built-in Features Overview in SharePoint 2010

Refers to build 14.0.4006.1010

Just an overview, I haven’t had time to check them all out yet, but want to share them with you…

Site Collection Features:

Advanced Web Analytics
This feature comprises advanced Web Analytics reports, data-driven workflows, workflow for scheduling reports, the What's Popular Web Part and customize reports functionality(for Enterprise SKU) at the site collection level.   

Collect Signatures Workflow
Gathers signatures needed to complete a Microsoft Office document.

Collect Signatures Workflow - SharePoint 14
Gathers signatures needed to complete a Microsoft Office document. This workflow can be edited in SharePoint Designer. 

Disposition Approval Workflow
Manages document expiration and retention by allowing participants to decide whether to retain or delete expired documents.

Document ID Service
Assigns IDs to documents in the Site Collection, which can be used to retrieve items independent of their current location.

Document Sets
Provides the content types required for creating and using document sets. Create a document set when you want to manage multiple documents as a single work product. 

Enterprise Wiki Layouts
Create a large-scale wiki with categories and page layouts. 

In Place Records Management
Enable the definition and declaration of records in place.  

Library and Folder Based Retention
Allows list administrators to override content type retention schedules and set schedules on libraries and folders. 
  
Microsoft Search Server Web Parts
This feature uploads all web parts required for Search Center.

Office SharePoint Server Enterprise Site Collection features
Features such as the business data catalog, forms services, and Excel Services, included in the Office SharePoint Server Enterprise License.

Office SharePoint Server Publishing Infrastructure
Provides centralized libraries, content types, master pages and page layouts and enables page scheduling and other publishing functionality for a site collection.

Office SharePoint Server Standard Site Collection features
Features such as user profiles and search, included in the Office SharePoint Server Standard License.

Reporting
Creates reports about information in Windows SharePoint Services. 
  
Routing Workflows
Workflows that send a document for feedback or approval.

Routing Workflows - SharePoint 14
Workflows that send a document for feedback or approval. These workflows can be edited in SharePoint Designer. 

Site Help
Create Help content for this site collection.

Three-state workflow
Use this workflow to track items in a list.

Translation Management Workflow
Manages document translation by creating copies of the document to be translated and assigning translation tasks to translators.

Visio Web Access
View Visio Drawing in Web Browser

Site Features:

Access Services System Tables
Access Services System Tables

Content Organizer
Create metadata based rules that move content submitted to this site to the correct library or folder.

E-mail Router
This enables a site's document router to accept and route email messages. This feature should be used only in a highly managed store, like a Records Center.

Entity Collaboration Configuration
Creates the infrastructure necessary to enable users to create entity collaboration sites.

Entity Collaboration Instance Configuration
Creates the infrastructure necessary to enable users to create entity collaboration instance sites.

GroupBoard Lists
Provides Calendar lists with added functionality for team and resource scheduling.

Hold and eDiscovery
This feature is used to track external actions like litigations, investigations, or audits that require you to suspend the disposition of documents.

Metadata Navigation and Filtering
Provides each list in the site with a settings pages for configuring that list to use metadata tree view hierarchies and filter controls to improve navigation and filtering of the contained items.

Office Business Application Design Tools
Document libraries, lists, content types and pages required to build an Office Business Application solution. 

Office SharePoint Server Enterprise Site features
Features such as the business data catalog, forms services, and Excel Services, included in the Office SharePoint Server Enterprise License.

Office SharePoint Server Publishing
Create a Web page library as well as supporting libraries to create and publish pages based on page layouts.

Office SharePoint Server Standard Site features
Features such as user profiles and search, included in the Office SharePoint Server Standard License.

Take list offline
Take a virtual list offline into Outlook or Groove. 

Team Collaboration Lists
Provides team collaboration capabilities for a site by making standard lists, such as document libraries and issues, available.

Translation Management Library
Create a translation management library when you want to create documents in multiple languages and manage translation tasks. Translation management libraries include a workflow to manage the translation process and provide sub-folders, file versioning, and check-in/check-out.

Wiki Page Home Page
This site feature will create a wiki page and set it as your site home page.

Oct 19, 2009

Early look at LINQ to SharePoint

This post is preliminary and is subject to change, but should give you at least an idea. It refers to build 14.0.4006.1010.

In SharePoint 2007 you have to user CAML to query SharePoint lists. Anybody who have already written CAML queries knows that this can be tedious with complex queries. To make life easier the community had developed various helper tools like the U2U CAML Query Builder, YACAMLQT (Yet Another CAML Query Tool), CAML.NET… Meanwhile .NET 3.5 has been released with a cool new feature called LINQ (Language Integrated Queries). LINQ allows you to query in an object-oriented way, supports compile-time check, gives you intellisense support in Visual Studio and defines a unified, SQL like syntax to query any data source.
var result = from c in Contacts 
where c.FirstName == "Christian"
select c
The abstraction to allow querying any data source has been implemented through an interface called IQueryable(T), but don’t want to go deep in LINQ. Since now Microsoft has been delivered four LINQ providers:
  • LINQ to Object
  • LINQ to XML
  • LINQ to SQL
  • LINQ to Entity
With SharePoint 2010 the fifth LINQ Provider will be available:

LINQ to SharePoint

To don’t overlook the community efforts, there is already a LINQ provider for SharePoint on CodePlex, but since now it is in an alpha stadium.
LINQ to SharePoint works similar to LINQ to SQL or LINQ to Entity. You write business objects (or maybe a DAOs) and decorate them with mapping attributes. When the query will be executed the LINQ statements will be translated to CAML.image
The example class Contact maps to a custom Content Type with the name MyContact and the columns ID and FirstName. Writing this manual is cumbersome, therefore there’s a command line tool called SPMetal, which generates this classes for a whole site. E.g: 
SPMetal /web:http://localhost/anysite /namespace:iLoveSharePoint /code:SPDataContext.cs


image
Now we want to query our SharePoint list with LINQ. This is done by a class called Microsoft.SharePoint.Linq.DataContext. The DataContext represents a whole web site. SPMetal additionally generates a derived DataContext containing all lists as Properties.
image













Adding, editing and deleting Items with LINQ to SharePoint

Certainly you can add, edit and delete items with LINQ to SharePoint. To enable change tracking you must (not really all) implement some interfaces in your class:

  • Microsoft.SharePoint.Linq.ITrackEntityState
  • Microsoft.SharePoint.Linq.ITrackOriginalValues
  • System.ComponentModel.INotifyPropertyChanged
  • System.ComponentModel.INotifyPropertyChanging
Don’t panic, SPMetal does the job for you. I recommend to use SPMetal to generate the classes.

Let’s add new contact:
image









The method SumbitChanges of the DataContext persist all changes (add, edit, delete) to the SharePoint Content DB.

Relations in LINQ to SharePoint 

Another hot topic in SharePoint are relations between lists. In SharePoint 2007 CAML hasn’t any support for joins! This have made it almost impossible to build data centric applications for SharePoint 2007 (among other restrictions). But many, many customer want do that! Now with LINQ to SharePoint comes support for relational queries – Yippee!
Now we extend our sample Content Type with a lookup column to another Content Type called MyCountry and map the relation.

image

To map a multi Lookup you have to use EntitySet<T> instead of EntityRef<T> and set the MultivalueType property of the Association attribute to Multi. The loading of the relation is deferred. The Country object of the Contact will be loaded from the DB when the property will accessed and not before.
Get all contacts from Germany:
image

Yet I haven’t verified that this relational query really ends up in a SQL joins If not, this would really be bad. I will verify that as soon as possible…

I think I stop here, because things could change in further builds…

Early look at SharePoint 2010 & PowerShell

This post is preliminary and is subject to change. It refers to build 14.0.4006.1010.

In the community the combination of SharePoint and PowerShell is already a best practice for SharePoint 2007. Thanks to guys like Zach Rosenfield, Eric Kraus and hopefully myself.

I’m glad to announce that SharePoint 2010 comes with built-in PowerShell support. What a surprise ;-)

You have two options to use PowerShell with SharePoint 2010, either you can launch the built-in SharePoint 2010 Management Console

image

or import the SharePoint PowerShell snap in manually (Add-PSSnapin Microsoft.SharePoint.PowerShell).

image

Out of the box there are 492 SharePoint PowerShell commands!

You don’t believe, check it out yourself:
get-command -Noun SP* | measure-object

As expected the naming convention for the commands is

[Verb]-SP[Noun]

like Eric and I have done before in SPoshMod or myself in the PowerShell profile script for SharePoint. This is great because you are already familiar with the usage and it minimizes script migration efforts. The example in my SharePoint & PowerShell Quick Start post works without any changes with the SharePoint 2010 PowerShell Snap In.

$web = get-spweb “http://localhost”
$web.Title = "Hello PowerShell"
$web.Update()

You can also provide a wildcard (*) in the URL to return a collection of sub sites. See all options with “get-help get-spweb”

Appendix - List of SharePoint 2010 PowerShell Commands

Add-SPClaimMapping
Add-SPFeatureSetMember
Add-SPInfoPathUserAgent
Add-SPProfileServiceApplicationTenant
Add-SPServiceApplicationProxyGroupMember
Add-SPSolution
Add-SPUserSolution
Backup-SPConfigurationDatabase
Backup-SPFarm
Backup-SPSite
Check-SPContentDatabase
Clear-SPBusinessDataCatalogPartitionData
Clear-SPLogLevel
Clear-SPMetadataWebServicePartitionData
Clear-SPSecureStoreCredentialMapping
Connect-SPConfigurationDatabase
Copy-SPBusinessDataCatalogAclToChildren
Disable-SPBusinessDataCatalogEntity
Disable-SPFeature
Disable-SPInfoPathFormTemplate
Disable-SPSessionStateService
Disable-SPSingleSignOn
Disable-SPTimerJob
Disable-SPWebApplicationHttpThrottling
Disconnect-SPConfigurationDatabase
Dismount-SPContentDatabase
Dismount-SPStateServiceDatabase
Enable-SPBusinessDataCatalogEntity
Enable-SPFeature
Enable-SPInfoPathFormTemplate
Enable-SPSessionStateService
Enable-SPTimerJob
Enable-SPWebApplicationHttpThrottling
Export-SPBusinessDataCatalogModel
Export-SPBusinessDataCatalogPartitionData
Export-SPEnterpriseSearchTopology
Export-SPInfoPathAdministrationFiles
Export-SPMetadataWebServicePartitionData
Export-SPProfileServiceApplicationTenant
Export-SPSiteSubscriptionSettings
Export-SPWeb
Get-SPAccessServiceApplication
Get-SPAlternateURL
Get-SPBackupHistory
Get-SPBrowserCustomerExperienceImprovementProgram
Get-SPBusinessDataCatalogMetadataObject
Get-SPBusinessDataCatalogThrottleConfig
Get-SPCertificate
Get-SPCertificateStore
Get-SPClaimProviderManager
Get-SPContentDatabase
Get-SPContentDeploymentJob
Get-SPContentDeploymentPath
Get-SPCustomLayoutsPage
Get-SPDatabase
Get-SPDataConnectionFile
Get-SPDataConnectionFileDependent
Get-SPDesignerSettings
Get-SPDiagnosticConfig
Get-SPDiagnosticsProvider
Get-SPEdiscoveryHubSearchScope
Get-SPediscoveryHubSite
Get-SPEnterpriseSearchAdministrationComponent
Get-SPEnterpriseSearchCrawlComponent
Get-SPEnterpriseSearchCrawlContentSource
Get-SPEnterpriseSearchCrawlCustomConnector
Get-SPEnterpriseSearchCrawlDatabase
Get-SPEnterpriseSearchCrawlExtension
Get-SPEnterpriseSearchCrawlMapping
Get-SPEnterpriseSearchCrawlRule
Get-SPEnterpriseSearchCrawlTopology
Get-SPEnterpriseSearchExtendedClickThroughExtractorJobDefinition
Get-SPEnterpriseSearchExtendedConnectorProperty
Get-SPEnterpriseSearchExtendedQueryProperty
Get-SPEnterpriseSearchIndexPartition
Get-SPEnterpriseSearchLanguageResourcePhrase
Get-SPEnterpriseSearchManagerService
Get-SPEnterpriseSearchManagerServiceInstance
Get-SPEnterpriseSearchManagerServiceProxy
Get-SPEnterpriseSearchMetadataCategory
Get-SPEnterpriseSearchMetadataCrawledProperty
Get-SPEnterpriseSearchMetadataManagedProperty
Get-SPEnterpriseSearchMetadataMapping
Get-SPEnterpriseSearchPropertyDatabase
Get-SPEnterpriseSearchQueryAuthority
Get-SPEnterpriseSearchQueryComponent
Get-SPEnterpriseSearchQueryDemoted
Get-SPEnterpriseSearchQueryKeyword
Get-SPEnterpriseSearchQueryScope
Get-SPEnterpriseSearchQueryScopeRule
Get-SPEnterpriseSearchQuerySuggestionCandidates
Get-SPEnterpriseSearchQueryTopology
Get-SPEnterpriseSearchRankingModel
Get-SPEnterpriseSearchSecurityTrimmer
Get-SPEnterpriseSearchService
Get-SPEnterpriseSearchServiceApplication
Get-SPEnterpriseSearchServiceApplicationProxy
Get-SPEnterpriseSearchServiceInstance
Get-SPEnterpriseSearchSiteHitRule
Get-SPExcelBlockedFileType
Get-SPExcelDataConnectionLibrary
Get-SPExcelDataProvider
Get-SPExcelFileLocation
Get-SPExcelServiceApplication
Get-SPExcelUserDefinedFunction
Get-SPFarm
Get-SPFarmConfig
Get-SPFeature
Get-SPFeatureSet
Get-SPHelpCollection
Get-SPIdentityProvider
Get-SPIisWebServiceApplicationPool
Get-SPIisWebServiceSettings
Get-SPInfoPathFormsService
Get-SPInfoPathFormTemplate
Get-SPInfoPathUserAgent
Get-SPInfoPathWebServiceProxy
Get-SPLogEvent
Get-SPLogLevel
Get-SPManagedAccount
Get-SPManagedPath
Get-SPMetadataServiceApplication
Get-SPMetadataServiceApplicationProxy
Get-SPMobileMessagingAccount
Get-SPObjectSecurity
Get-SPParentFarmTrust
Get-SPProcessAccount
Get-SPProduct
Get-SPSearchService
Get-SPSearchServiceInstance
Get-SPSecureStoreApplication
Get-SPSecurityTokenService
Get-SPServer
Get-SPServiceApplication
Get-SPServiceApplicationProxy
Get-SPServiceApplicationProxyGroup
Get-SPServiceContext
Get-SPServiceEndpoint
Get-SPServiceInstance
Get-SPSessionStateService
Get-SPSite
Get-SPSiteAdministration
Get-SPSiteSubscription
Get-SPSiteSubscriptionConfig
Get-SPSiteSubscriptionMetadataConfig
Get-SPSolution
Get-SPStateServiceApplication
Get-SPStateServiceApplicationProxy
Get-SPStateServiceDatabase
Get-SPTaxonomySession
Get-SPTimerJob
Get-SPTopologyWebServiceApplication
Get-SPTopologyWebServiceProxy
Get-SPUsageApplication
Get-SPUsageDefinition
Get-SPUsageService
Get-SPUser
Get-SPUserSolution
Get-SPVisioExternalData
Get-SPVisioPerformance
Get-SPVisioSafeDataProvider
Get-SPVisioServiceApplication
Get-SPVisioServiceApplicationProxy
Get-SPWeb
Get-SPWebAnalyticsServiceApplication
Get-SPWebApplication
Get-SPWebApplicationHttpThrottlingMonitors
Get-SPWebPartPack
Get-SPWebTemplate
Get-SPWorkflowConfig
Grant-SPBusinessDataCatalogMetadataObject
Grant-SPServiceApplication
Import-SPBusinessDataCatalogModel
Import-SPBusinessDataCatalogPartitionData
Import-SPEnterpriseSearchTopology
Import-SPInfoPathAdministrationFiles
Import-SPMetadataWebServicePartitionData
Import-SPProfileServiceApplicationTenant
Import-SPSiteSubscriptionSettings
Import-SPWeb
Initialize-SPContentDatabase
Initialize-SPResourceSecurity
Initialize-SPStateServiceDatabase
Install-SPApplicationContent
Install-SPDataConnectionFile
Install-SPFeature
Install-SPHelpCollection
Install-SPInfoPathFormTemplate
Install-SPSolution
Install-SPUserSolution
Install-SPWebPartPack
Install-SPWebTemplate
Merge-SPLogFile
Mount-SPContentDatabase
Mount-SPStateServiceDatabase
Move-SPBlobStorageLocation
Move-SPUser
New-SPAccessServiceApplication
New-SPAlternateURL
New-SPBusinessDataCatalogServiceApplication
New-SPBusinessDataCatalogServiceApplicationProxy
New-SPCentralAdministration
New-SPCertificate
New-SPClaimMapping
New-SPClaimsObject
New-SPClaimsPrincipal
New-SPConfigurationDatabase
New-SPContentDatabase
New-SPContentDeploymentJob
New-SPContentDeploymentPath
New-SPEnterpriseSearchCrawlComponent
New-SPEnterpriseSearchCrawlContentSource
New-SPEnterpriseSearchCrawlCustomConnector
New-SPEnterpriseSearchCrawlDatabase
New-SPEnterpriseSearchCrawlExtension
New-SPEnterpriseSearchCrawlMapping
New-SPEnterpriseSearchCrawlRule
New-SPEnterpriseSearchCrawlTopology
New-SPEnterpriseSearchLanguageResourcePhrase
New-SPEnterpriseSearchMetadataCategory
New-SPEnterpriseSearchMetadataCrawledProperty
New-SPEnterpriseSearchMetadataManagedProperty
New-SPEnterpriseSearchMetadataMapping
New-SPEnterpriseSearchPropertyDatabase
New-SPEnterpriseSearchQueryAuthority
New-SPEnterpriseSearchQueryComponent
New-SPEnterpriseSearchQueryDemoted
New-SPEnterpriseSearchQueryKeyword
New-SPEnterpriseSearchQueryScope
New-SPEnterpriseSearchQueryScopeRule
New-SPEnterpriseSearchQueryTopology
New-SPEnterpriseSearchRankingModel
New-SPEnterpriseSearchSecurityTrimmer
New-SPEnterpriseSearchServiceApplication
New-SPEnterpriseSearchServiceApplicationProxy
New-SPEnterpriseSearchSiteHitRule
New-SPExcelBlockedFileType
New-SPExcelDataConnectionLibrary
New-SPExcelDataProvider
New-SPExcelFileLocation
New-SPExcelServiceApplication
New-SPExcelUserDefinedFunction
New-SPFeatureSet
New-SPIdentityProvider
New-SPIisWebServiceApplicationPool
New-SPLogFile
New-SPManagedAccount
New-SPManagedPath
New-SPMetadataServiceApplication
New-SPMetadataServiceApplicationProxy
New-SPObaSolutionPackage
New-SPParentFarmTrust
New-SPProfileServiceApplication
New-SPProfileServiceApplicationProxy
New-SPSecureStoreApplication
New-SPSecureStoreApplicationField
New-SPSecureStoreServiceApplication
New-SPSecureStoreServiceApplicationProxy
New-SPSecureStoreTargetApplication
New-SPServiceApplicationProxyGroup
New-SPSite
New-SPSiteSubscription
New-SPStateServiceApplication
New-SPStateServiceApplicationProxy
New-SPStateServiceDatabase
New-SPSubscriptionSettingsServiceApplication
New-SPSubscriptionSettingsServiceApplicationProxy
New-SPUsageApplication
New-SPUsageLogFile
New-SPUser
New-SPVisioSafeDataProvider
New-SPVisioServiceApplication
New-SPVisioServiceApplicationProxy
New-SPWeb
New-SPWebAnalyticsServiceApplication
New-SPWebAnalyticsServiceApplicationProxy
New-SPWebApplication
New-SPWebApplicationExtension
New-SPWordConversionServiceApplication
New-SPWordConversionServiceApplicationProxy
Publish-SPServiceApplication
Receive-SPSharedServiceApplicationInfo
Remove-SPAlternateURL
Remove-SPBusinessDataCatalogModel
Remove-SPBusinessDataCatalogPartition
Remove-SPBusinessDataCatalogThrottleConfig
Remove-SPCertificate
Remove-SPClaimMapping
Remove-SPConfigurationDatabase
Remove-SPContentDatabase
Remove-SPContentDeploymentJob
Remove-SPContentDeploymentPath
Remove-SPEnterpriseSearchCrawlComponent
Remove-SPEnterpriseSearchCrawlContentSource
Remove-SPEnterpriseSearchCrawlCustomConnector
Remove-SPEnterpriseSearchCrawlDatabase
Remove-SPEnterpriseSearchCrawlExtension
Remove-SPEnterpriseSearchCrawlMapping
Remove-SPEnterpriseSearchCrawlRule
Remove-SPEnterpriseSearchCrawlTopology
Remove-SPEnterpriseSearchLanguageResourcePhrase
Remove-SPEnterpriseSearchMetadataCategory
Remove-SPEnterpriseSearchMetadataManagedProperty
Remove-SPEnterpriseSearchMetadataMapping
Remove-SPEnterpriseSearchPropertyDatabase
Remove-SPEnterpriseSearchQueryAuthority
Remove-SPEnterpriseSearchQueryComponent
Remove-SPEnterpriseSearchQueryDemoted
Remove-SPEnterpriseSearchQueryKeyword
Remove-SPEnterpriseSearchQueryScope
Remove-SPEnterpriseSearchQueryScopeRule
Remove-SPEnterpriseSearchQueryTopology
Remove-SPEnterpriseSearchRankingModel
Remove-SPEnterpriseSearchSecurityTrimmer
Remove-SPEnterpriseSearchServiceApplication
Remove-SPEnterpriseSearchServiceApplicationProxy
Remove-SPEnterpriseSearchSiteHitRule
Remove-SPExcelBlockedFileType
Remove-SPExcelDataConnectionLibrary
Remove-SPExcelDataProvider
Remove-SPExcelFileLocation
Remove-SPExcelUserDefinedFunction
Remove-SPFeatureSet
Remove-SPFeatureSetMember
Remove-SPIdentityProvider
Remove-SPIisWebServiceApplicationPool
Remove-SPInfoPathUserAgent
Remove-SPManagedAccount
Remove-SPManagedPath
Remove-SPParentFarmTrust
Remove-SPProfileServiceApplicationTenant
Remove-SPSecureStoreApplication
Remove-SPServiceApplication
Remove-SPServiceApplicationProxy
Remove-SPServiceApplicationProxyGroup
Remove-SPServiceApplicationProxyGroupMember
Remove-SPSite
Remove-SPSiteSubscription
Remove-SPSiteSubscriptionMetadataConfig
Remove-SPSiteSubscriptionSettings
Remove-SPSolution
Remove-SPSolutionDeploymentLock
Remove-SPStateServiceDatabase
Remove-SPUsageApplication
Remove-SPUser
Remove-SPUserSolution
Remove-SPVisioSafeDataProvider
Remove-SPVisioServiceApplication
Remove-SPVisioServiceApplicationProxy
Remove-SPWeb
Remove-SPWebApplication
Rename-SPServer
Restart-SPEnterpriseSearchQueryComponent
Restore-SPEnterpriseSearchServiceApplication
Restore-SPFarm
Restore-SPSite
Resume-SPStateServiceDatabase
Revoke-SPBusinessDataCatalogMetadataObject
Revoke-SPServiceApplication
Set-SPAccessServiceApplication
Set-SPAlternateURL
Set-SPBrowserCustomerExperienceImprovementProgram
Set-SPBusinessDataCatalogMetadataObject
Set-SPBusinessDataCatalogServiceApplication
Set-SPBusinessDataCatalogThrottleConfig
Set-SPCentralAdministration
Set-SPContentDatabase
Set-SPContentDeploymentJob
Set-SPContentDeploymentPath
Set-SPCustomLayoutsPage
Set-SPDataConnectionFile
Set-SPDesignerSettings
Set-SPDiagnosticConfig
Set-SPDiagnosticsProvider
Set-SPediscoveryHub
Set-SPEnterpriseSearchAdministrationComponent
Set-SPEnterpriseSearchCrawlContentSource
Set-SPEnterpriseSearchCrawlDatabase
Set-SPEnterpriseSearchCrawlRule
Set-SPEnterpriseSearchCrawlTopology
Set-SPEnterpriseSearchExtendedConnectorProperty
Set-SPEnterpriseSearchExtendedQueryProperty
Set-SPEnterpriseSearchIndexPartition
Set-SPEnterpriseSearchMetadataCategory
Set-SPEnterpriseSearchMetadataCrawledProperty
Set-SPEnterpriseSearchMetadataManagedProperty
Set-SPEnterpriseSearchMetadataMapping
Set-SPEnterpriseSearchPropertyDatabase
Set-SPEnterpriseSearchQueryAuthority
Set-SPEnterpriseSearchQueryComponent
Set-SPEnterpriseSearchQueryKeyword
Set-SPEnterpriseSearchQueryScope
Set-SPEnterpriseSearchQueryScopeRule
Set-SPEnterpriseSearchQueryTopology
Set-SPEnterpriseSearchRankingModel
Set-SPEnterpriseSearchService
Set-SPEnterpriseSearchServiceApplication
Set-SPEnterpriseSearchServiceApplicationProxy
Set-SPEnterpriseSearchServiceInstance
Set-SPExcelDataConnectionLibrary
Set-SPExcelDataProvider
Set-SPExcelFileLocation
Set-SPExcelServiceApplication
Set-SPExcelUserDefinedFunction
Set-SPFarmConfig
Set-SPIdentityProvider
Set-SPIisWebServiceApplicationPool
Set-SPIisWebServiceSettings
Set-SPInfoPathFormsService
Set-SPInfoPathFormTemplate
Set-SPInfoPathWebServiceProxy
Set-SPLogLevel
Set-SPManagedAccount
Set-SPMetadataServiceApplication
Set-SPMetadataServiceApplicationProxy
Set-SPMobileMessagingAccount
Set-SPParentFarmTrust
Set-SPPassPhrase
Set-SPProfileServiceApplication
Set-SPProfileServiceApplicationProxy
Set-SPProfileServiceApplicationTenant
Set-SPSearchService
Set-SPSearchServiceInstance
Set-SPSecureStoreApplication
Set-SPSecureStoreServiceApplication
Set-SPServiceApplication
Set-SPServiceEndpoint
Set-SPSessionStateService
Set-SPSite
Set-SPSiteAdministration
Set-SPSiteSubscriptionConfig
Set-SPSiteSubscriptionMetadataConfig
Set-SPStateServiceApplication
Set-SPStateServiceApplicationProxy
Set-SPStateServiceDatabase
Set-SPSubscriptionSettingsServiceApplication
Set-SPTimerJob
Set-SPTopologyWebServiceApplication
Set-SPTopologyWebServiceProxy
Set-SPUsageApplication
Set-SPUsageDefinition
Set-SPUsageService
Set-SPUser
Set-SPVisioExternalData
Set-SPVisioPerformance
Set-SPVisioSafeDataProvider
Set-SPVisioServiceApplication
Set-SPWeb
Set-SPWebAnalyticsServiceApplication
Set-SPWebApplication
Set-SPWebApplicationHttpThrottlingMonitor
Set-SPWebApplicationSiginRedirectUrl
Set-SPWebTemplate
Set-SPWordConversionServiceApplication
Set-SPWorkflowConfig
Start-SPAdminJob
Start-SPAssignment
Start-SPContentDeploymentJob
Start-SPEnterpriseSearchManagerServiceInstance
Start-SPEnterpriseSearchServiceInstance
Start-SPInfoPathFormTemplate
Start-SPServiceInstance
Start-SPTimerJob
Stop-SPAssignment
Stop-SPEnterpriseSearchManagerServiceInstance
Stop-SPEnterpriseSearchServiceInstance
Stop-SPInfoPathFormTemplate
Stop-SPServiceInstance
Suspend-SPStateServiceDatabase
Test-SPInfoPathFormTemplate
Uninstall-SPDataConnectionFile
Uninstall-SPFeature
Uninstall-SPHelpCollection
Uninstall-SPInfoPathFormTemplate
Uninstall-SPSolution
Uninstall-SPUserSolution
Uninstall-SPWebPartPack
Uninstall-SPWebTemplate
Unpublish-SPServiceApplication
Update-SPFarmEncryptionKey
Update-SPInfoPathFormTemplate
Update-SPInfoPathUrl
Update-SPSecureStoreApplicationServerKey
Update-SPSecureStoreCredentialMapping
Update-SPSecureStoreGroupCredentialMapping
Update-SPSecureStoreMasterKey
Update-SPSolution
Update-SPUserProfilePhotoStore
Update-SPUserSolution
Upgrade-SPContentDatabase
Upgrade-SPEnterpriseSearchServiceApplication
Upgrade-SPSingleSignOnDatabase

rip

Oct 7, 2009

My Impressions from the Azure World Tour 2009

I’m just travelling home from the Azure Worldtour in Munich. I really was the only guy who worn a shirt! But…

Steve Ballmer and Me

…this mustn’t necessarily be something bad.

Seems Steve loves SharePoint too :-)

Back to Azure: I really like the cloud strategy from Microsoft, the .NET Services, .NET Service Bus and SQL Services and all the Azure stuff. Gartner says the market will grow from $46 billion to $150 billion in 2013. And one is “azure” Microsoft want to have a big chunk of the cake! And they are on a good way…

There is one thing frightening me when I think of cloud computing. When in the near future almost anybody would make use of cloud computing and there are only a few data centers around the world, they would obviously be a good target for terrorism. A destroyed data center could seriously harm the global economy.

Will this be Terrorism 2.0?! 

One of the base ideas of the Internet, the ARPANET was to create a distributed network which will survive an nuclear attack (semi-myth). What would be in case of a war, maybe between the USA and Europe? Would Microsoft sill provide their cloud services? Would this really be a risk? Maybe this wouldn’t matter in case of a nuclear war anymore. But luckily we have freedom and are friends (see pic above:), so I stop this “mindmare” here.

Additionally cloud computing always remembers me at Skynet in Terminator, iRobot and Matrix – great movies :-)

Oct 1, 2009

Using the SharePoint Object Model with IronPython

Same with IronPython, download IronPython and go!
# import CLR
import clr

# add a reference to the SharePoint assembly
clr.AddReference(‚Microsoft.SharePoint‘)

# import all types from the Microsoft.SharePoint namespace
from Microsoft.SharePoint import *

# instantiate SPSite at http://localhost/mysite
site = SPSite("http://localhost/mysite")

# open the web
web = site.OpenWeb()

# set the title of the web - just trivial example
web.Title = "Greetings from IronPython"

# persist changes to content DB
web.Update()

# clean up
web.Dispose()
site.Dispose()

# the end


01.10

Using the SharePoint Object Model with IronRuby

Install the latest version from IronRuby and let's script!
# load the SharePoint Assembly
require "Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

# import SPSite
SPSite = Microsoft::SharePoint::SPSite

# instantiate the SPSite at http://localhost/anysite
site = SPSite.new("http://localhost/anysite")

# open the corresponding web
web = site.OpenWeb

#Set the title -> just a trivial Demo!
web.Title = "Greetings from IronRuby"

# persist the changes to the Content DB
web.Update

# clean up. Don't forget as I did ;-)
web.Dispose
site.Dispose

# have a cup of coffee and enjoy to be a developer :-)


image Thanks @ Thorsten Hans for the IronRuby crash course.

Sep 26, 2009

jQuery Test Panel for SharePoint

I don’t think I’ve to told anybody how cool jQuery is, you know already, nor how to integrate in SharePoint. Let’s start with a screenshot:

image

The idea is to have a Webpart on your SharePoint site that simply executes jQuery statements.

Just great to experiment with jQuery and SharePoint or to learn jQuery.

All you need is a standard Content Editor Webpart with the following with the following content (source).













Works great with IE Developer Toolbar together.

Examples:

$(“.ms-sitetitle”) // selects the site title

$(“a[href^=’http://’]”).attr(“target”,”_blank”) // open all absolute links in a new window

$("*").click(function(event){
  $(this).hide("slow"); return false;
});
//just fun ;-)

Sep 10, 2009

Customize the My Site Portal Link

I’m waiting for two buttons from our designer, so I’ve got 10 minutes for trivial post…

One of our customers has already created hundreds of My Sites, but unfortunately all this sites are missing the portal link to the intranet. Two simple requirements: all new sites should have the portal link automatically and all existing sites should get the portal link too.

image

  1. Customizing the portal link of the root My Site site takes care that the portal link will automatically added to new my sites. You have to enter the url to the setting page directly (e.g. http://localhost:8020/_layouts/portal.aspx), otherwise you get routed to your My Site.
  2. To migrate all existing My Sites I’ve written a simple PowerShell script – what else ;-)
# Set-SPPortalLink.ps1
# e.g. . .\Set-SPPortalLink "http://localhost:81/" "Intranet" "http://intranet"

param($webAppUrl, $portalName, $portalUrl)

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$webApp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($webAppUrl)

foreach($site in $webApp.Sites)
{
$site.Url | Out-Host
#impersonate site to system user
$impSite = new-object Microsoft.SharePoint.SPSite($site.ID, $site.SystemAccount.UserToken)
$impSite.PortalName = $portalName
$impsite.PortalUrl = $portalUrl

$impSite.Dispose()
$site.Dispose()
}

Aug 2, 2009

WebPart Connections With Power WebPart 3.0

Web Part connections in SharePoint allows you to connect different Web Parts and to exchange data between them, even if they are from different suppliers. This is possible through the ASP.NET WebPart Connection Framework and some interfaces. For sure Power WebPart supports Web Part connections. It can act either as a row and table provider or as a consumer.

image

The example shows on the left a Power WebPart using a SPGridView to display current processes and acts as a row provider. It uses a DataTable as data source and sends the selected DataRow to the consumers. Theoretically you can send any object, but PowerShell dynamic types/properties (add-member) behave different and can not be reflected by the Web Part Connection Framework, so I recommend using DataTables and DataRows for WebPart connections ( in PowerShell 2.0 you can alternatively use add-type to generate C# types on the fly). On the right you see two consumers, a Power WebPart and a SharePoint List View WebPart. Both consume the DataRow from the provider on the left. The Power WebPart consumer simply shows the first column and the SharePoint List View uses the “Name” column of the provided row to filter the list items.

A script says more than thousand words.

The row provider web part:

# SPGridView to display the result 
$gridView = New-Object Microsoft.SharePoint.WebControls.SPGridView

# DataTable is used as data container
$table = New-Object System.Data.DataTable("Container")

function CreateChildControls($controls)
{ 
# add columns to the table
$table.Columns.Add($(New-Object System.Data.DataColumn("ID",[Int32])))
$table.Columns.Add($(New-Object System.Data.DataColumn("Name",[String])))
$table.Columns.Add($(New-Object System.Data.DataColumn("CPU",[double])))

# fill the table with processes
foreach($p in $(get-process))
{
$row = $table.NewRow()
$row.ID = $p.ID
$row.Name = $p.Name
$row.CPU = [double]$p.CPU

$table.Rows.Add($row)
}

# add columns to the SPGridView
$colSelectButton = New-Object System.Web.UI.WebControls.CommandField
$colSelectButton.HeaderText = "Action"
$colSelectButton.SelectText = "select"
$colSelectButton.ShowSelectButton = $true
$gridView.Columns.Add($colSelectButton)


$colId = New-Object Microsoft.SharePoint.WebControls.SPBoundField
$colId.HeaderText = "ID"
$colId.DataField = "ID"
$gridView.Columns.Add($colId)

$colName = New-Object Microsoft.SharePoint.WebControls.SPBoundField
$colName.HeaderText = "Name"
$colName.DataField = "Name"
$gridView.Columns.Add($colName)

$colCPU = New-Object Microsoft.SharePoint.WebControls.SPBoundField
$colCPU.HeaderText = "CPU"
$colCPU.DataField = "CPU"
$gridView.Columns.Add($colCPU);

# configure SPGridView
$gridView.AutoGenerateColumns=$false
$gridView.DataSource = $table
$gridView.DataBind()

$controls.Add($gridView)
}

# returns the schema to the WP Connection Framework
function GetSchema
{  
# return an empty row (or type, used for reflection)
return $table.NewRow()
}

# sends the selected row to the WP Connection Framework
function SendRow
{ 
if($gridView.SelectedIndex -gt -1) 
{
return $table.Rows[$gridView.SelectedIndex]
}
else
{
# return $null when nothing is selected
return $null
}
}

The row consumer web part:

$label = New-Object System.Web.UI.WebControls.Label

function OnReceiveRow($row, $schema)
{
if ($row -ne $null){$label.Text= $row[0]}
}

function OnPreRender
{ 
# request the row from the web part connection
# will fire "OnReceiveRow" 
Query-Connections 
}

function Render($writer)
{
$writer.Write("

") $label.RenderControl($writer) $writer.Write("

") }

WebPart Connections work with Power WebPart 3.0 build 0908020651 or greater.

Jun 11, 2009

Charts with Power WebPart ( Management-Eye-Catchers )

In this post I’ll give you some ideas how you can script charts in SharePoint with Power WebPart featuring Microsoft Chart Controls.

Visualizing a SharePoint list as a pie

image

image

Setup and Configuration:

  1. 1. Download and install Microsoft Chart Controls (ensure that System.Web.DataVisualization.dll is either in the GAC or in the web app’s bin folder)
  2. 2. Download and install Power WebPart (follow the instructions in the readme.txt)
  3. 3. To use the Chart Controls in ASP.NET or SharePoint you have to modify the web.config:

Add this line to appSettings section:

<add key="ChartImageHandler" value="Storage=session;Timeout=20;" />

Add this line to the httpHandlers section:

<add path="ChartImg.axd" verb="GET,HEAD" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />

The Script

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.DataVisualization")

$chart = New-Object System.Web.UI.DataVisualization.Charting.Chart
$series = new-object System.Web.UI.DataVisualization.Charting.Series
$chartArea = New-Object System.Web.UI.DataVisualization.Charting.ChartArea
$legend = New-Object System.Web.UI.DataVisualization.Charting.Legend

function createchildcontrols($controls)
{
$data = $web.Lists["Chart"].Items.GetDataTable()

$chart.DataSource = $data
$chart.Width=500

$series.ChartType = [System.Web.UI.DataVisualization.Charting.SeriesChartType]::Pie
$series.XValueMember ="Title"
$series.YValueMembers ="Value"
$series.ShadowOffset = 2
$series.IsValueShownAsLabel = $true

$chart.Series.Add($series)

$chartArea.Area3DStyle.Enable3D = $true
$chart.ChartAreas.Add($chartArea)

$chart.Legends.Add($legend)

$controls.Add($chart)

$chart.DataBind()

$series.Points.FindMaxByValue()["Exploded"] = $true
}

This just one example! The Chart Control is really mighty! Download the chart control examples from Microsoft to get an impression:


ChartImgCACU0PM6 ChartImgCAEO5EDD Bollinger2



The limitation is your imagination!

Jun 10, 2009

SPoshMod v1.0 Released!

I'm glad to annouce that SPoshMod V1.0 has been released today. SPoshMod is a PowerShell 2.0 Module for SharePoint wrapping the most common SharePoint object model calls (e.g. Get-SPWeb, Get-SPSite...).

SPoshMod is a joint project from Eric Kraus (founder) and me. If you have written a helpful script or function and think it would be useful in the module, please send them to sposhmod@live.com we will give credit to you in the module.

More coming soon...

Jun 8, 2009

Using SharePoint Controls with Power WebPart

SharePoint comes with a bunch of custom ASP.NET Controls. For sure you can use them with Power WebPart.
This example shows how you can search for list items by title containing a specified search string and display the result in a SharePoint list view, featuring the SharePoint ListViewByQuery control.
image

The Script

$textBox = New-Object System.Web.UI.WebControls.TextBox;
$button = New-Object System.Web.UI.WebControls.Button;
$button.Text = "Search"
$listView = New-Object Microsoft.SharePoint.WebControls.ListViewByQuery;
$br = New-Object System.Web.UI.WebControls.WebControl([System.Web.UI.HtmlTextWriterTag]::Br)

function createchildcontrols($controls)
{
$controls.Add($textBox)
$controls.Add($button)
$controls.Add($br)
$controls.Add($listView)
}

function onprerender()
{
# Parameter 1 can be configured in the webpart editor
$listTitle = $webpart.Parameter1

$list = $web.Lists[$listTitle]
$listView.List = $list;
$query = New-Object Microsoft.SharePoint.SPQuery -ArgumentList $list.DefaultView;

$query.Query = "
                                 


$($textBox.Text)

"

$listView.Query = $query
$listView.DisableFilter = $true
$listView.DisableSort = $true 
}

function onerror($writer)
{
$writer.Write("List title is not configured or the list does not exist.")
}

May 31, 2009

IronPython In Action

For about six years I felt in love with .NET and SharePoint. In the last year I’ve also learned to love PowerShell. I was really impressed of the dynamic and power you can gain with a scripting language in combination with the .NET Framework. So I’ve started to combine SharePoint and PowerShell through embedding PowerShell and developed SharePoint PowerActivity, Power EventReceiver and Power WebPart. It was really amazing to see how fast you can develop small SharePoint apps with this stuff. But as a C# developer you sometime miss the object orientation in PowerShell. On the BASTA! Spring I first meet Michael J Foord after his talk about the DLR and embedding IronPython. The talk was similar to my talk about embedding PowerShell. Embedding IronPython seemed to be almost as simple as embedding PowerShell, but with a dynamic and object oriented language. I was really excited - for sure I’ve to learn IronPython. Unfortunately resources about IronPython are very limited. Luckily Michael and Christian Muirhead has just written IronPython In Action.

IronPython In Action covers all you need to getting started with IronPython for an .NET or Python developer. It is written coherent without needless ballast, well suited to the philosophy of the language itself. My favorite chapters are “Sliverlight: IronPython in the browser”, “Agile testing where dynamic typing shines” and “Embedding the IronPython engine”. The book has inspired me to found the CodePlex project IronSharePoint (coming soon) showing how you can develop SharePoint apps with IronPython. I’m convinced that in the near future dynamic languages will get more attention again, just think at the “dynamic” keyword in C# 4.0. Absolutely worth to keep an eye on it!

The power of combining statically and dynamically typed languages are really incredible!

May 10, 2009

Power WebPart 3.0 – Runas-System

In general code in SharePoint runs with the privileges of the current user, but sometimes you need to run code with elevated privileges. The SharePoint object model covers this scenario with the SPSecurity.RunWithElevatedPrivileges. In Power WebPart you can use the “Runas-System” function to run script with elevated privileges. Usage: Runas-System –script
Example 1: Output Current Identity
function render($writer)
{
   $identiy1 = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
   $identiy2 = Runas-System "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"

   $writer.Write($identiy1)
   $writer.Write($identiy2)
}
Example 2: Call a Function with Parameters
function Render-Identity($writer)
{
    $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    $writer.Write($identity)
}  
function render($writer)
{
   Render-Identity $writer
   Runas-System "Render-Identity `$writer"
}
Example 3: Call a Function with Return Value
function Get-Identity
{
    return [System.Security.Principal.WindowsIdentity]::GetCurrent().Name 
}

function render($writer)
{
   $identity1 = Get-Identity
   $identity2 = Runas-System "Get-Identity"

   $writer.Write($identity1)
   $writer.Write($identity2)
}
Example 4: Impersonate SPWeb
function render($writer)
{
   $writer.Write($web.CurrentUser.LoginName)

    $impersonatedWeb = Runas-System "Get-SPWeb $($web.Url)"
    $writer.Write($impersonatedWeb.CurrentUser.LoginName)
    $impersonatedWeb.Dispose()
}

May 2, 2009

Power Tag Cloud - SharePoint Tag Cloud written in PowerShell

I'm a tag cloud fan but unfortunately there isn’t any in SharePoint 2007 out of the box. So let’s write a reusable tag cloud as an example for PowerWebPart. The Power Tag Cloud consists of two web parts, the tag cloud itself and the tag browser.

Tag an item. You can either use a text field with a semicolon as separator or any lookup field. Maybe I show in following post how you can pimp the tag field with a jQuery AJAX auto completion script and PowerWebPart.

image

Configure how your cloud should looks like and behaves. The editor panel is written in PowerShell too!

image

The tag cloud

image

When you click on a tag the tag browser shows all items tagged with this tag within the chosen scope.

image

All this stuff is written in PowerShell!

To get a feeling how PowerWebPart scripts look like:

Power Tag Cloud Script

#init parameters
$scope = Init-Parameter "Parameter1" [String]::Empty
$tagField = Init-Parameter "Parameter2" "Tags" -defaultOnEmpty
$maxFontSize = Init-Parameter "Parameter3" "40" -defaultOnEmpty
$minFontSize = Init-Parameter "Parameter4" "6" -defaultOnEmpty
$color1 = Init-Parameter "Parameter5" "#003399" -defaultOnEmpty
$color2 = Init-Parameter "Parameter6" "#CCCCCC" -defaultOnEmpty
$listType = Init-Parameter "Parameter7" "0" -defaultOnEmpty
$tagBrowser = Init-Parameter "Parameter8" [String]::Empty

# calculate gradient
$r1 = [Convert]::ToInt32($color1.Substring(1,2),16)
$g1 = [Convert]::ToInt32($color1.Substring(3,2),16)
$b1 = [Convert]::ToInt32($color1.Substring(5,2),16)

$r2 = [Convert]::ToInt32($color2.Substring(1,2),16)
$g2 = [Convert]::ToInt32($color2.Substring(3,2),16)
$b2 = [Convert]::ToInt32($color2.Substring(5,2),16)

$diff_r = $r2-$r1
$diff_g = $g2-$g1
$diff_b = $b2-$b1

# css
$defaultCss =@"
.power-cloud A {
TEXT-DECORATION: none
}
.power-cloud A:hover {
TEXT-DECORATION: underline
}
.power-cloud UL {
PADDING-RIGHT: 0px;
PADDING-LEFT: 0px;
PADDING-BOTTOM: 0px;
MARGIN: 0px;
PADDING-TOP: 0px;
LIST-STYLE-TYPE: none;
TEXT-ALIGN: center
}
.power-cloud LI
{
PADDING-RIGHT: 0px;
DISPLAY: inline;
PADDING-LEFT: 0px;
BACKGROUND-IMAGE: none !important;
PADDING-BOTTOM: 0px;
MARGIN: 0px;
PADDING-TOP: 0px;
TEXT-ALIGN: justify
}
"@

$css = Init-Parameter "Parameter9" $defaultCss -defaultOnEmpty

Register-CSSBlock $css

function CreateChildControls($controls)
{
#find all tagged list items
$query = New-Object "Microsoft.SharePoint.SPSiteDataQuery"
$query.Query = @"





"@
$query.ViewFields = ""
#set query scope
if([String]::IsNullOrEmpty($scope) -eq $false){ $query.Webs=""}

#set list type
$query.Lists = ""

$dataTable = $web.GetSiteData($query)

# extract all tags in a list
$global:tags = New-Object System.Collections.ArrayList
$dataTable | Select-Object Tags | %{$_.Tags.Split(';')} | %{$tags.Add($_.Trim().TrimStart('#'))}

# group tags
$global:tagGroups = $tags | Group-Object | Sort-Object Count -Descending
}

function Render($writer)
{
$gradientSteps = $tagGroups.Count

#begin cloud
$writer.Write("
    ")

    for($i=0; $i -lt $tagGroups.Count; $i++ )
    {
    # calculate font size
    $size = [Math]::Round(($tagGroups[$i].Count * $maxFontSize) / $tagGroups[0].Count)
    if($size -lt $minFontSize){$size = $minFontSize}

    # calculate color
    $gradientFactor = $i / $gradientSteps
    $r = $r1 + $diff_r * $gradientFactor
    $g = $g1 + $diff_g * $gradientFactor
    $b = $b1 + $diff_b * $gradientFactor
    $color = "rgb($r, $g, $b)"

    $tagName = $tagGroups[$i].Name
    $tagUrl = "{0}?tag={1}&listType={2}&scope={3}&tagField={4}" -f $tagBrowser, $tagName, $listType ,$scope, $tagField

    #render tag
    $writer.Write("
  • `n$tagName`n")
    }

    # end cloud
    $writer.Write("
")
}


Power Tag Cloud Editor Script
$txtMaxFontSize = New-Object System.Web.UI.WebControls.TextBox
$txtMaxFontSize = New-Object System.Web.UI.WebControls.TextBox
$txtMinFontSize = New-Object System.Web.UI.WebControls.TextBox
$txtMaxColor = New-Object System.Web.UI.WebControls.TextBox
$txtMinColor = New-Object System.Web.UI.WebControls.TextBox
$txtTagField = New-Object System.Web.UI.WebControls.TextBox
$txtTagBrowser = New-Object System.Web.UI.WebControls.TextBox
$drpdScope = New-Object System.Web.UI.WebControls.DropDownList
$drpdLists = New-Object System.Web.UI.WebControls.DropDownList
$txtCss = New-Object iLoveSharePoint.WebControls.SimpleTextEditor

function CreateChildControls($controls)
{
$drpdScope.Items.Add([String]::Empty)
$drpdScope.Items.Add("Recursive")
$drpdScope.Items.Add("SiteCollection")


$drpdLists.Items.Add($(New-Object System.Web.UI.WebControls.ListItem("Generic list","0")))
$drpdLists.Items.Add($(New-Object System.Web.UI.WebControls.ListItem("Document Library","1")))
$drpdLists.Items.Add($(New-Object System.Web.UI.WebControls.ListItem("Discussion forum","3")))
$drpdLists.Items.Add($(New-Object System.Web.UI.WebControls.ListItem("Vote or Survey","4")))
$drpdLists.Items.Add($(New-Object System.Web.UI.WebControls.ListItem("Issues List","5")))

$controls.Add($drpdScope)
$controls.Add($drpdLists)
$controls.Add($txtTagField)
$controls.Add($txtMaxFontSize)
$controls.Add($txtMinFontSize)
$controls.Add($txtMaxColor)
$controls.Add($txtMinColor)
$controls.Add($txtTagBrowser)

$txtCss.DisplayText = "Edit CSS"
$controls.Add($txtCss)
}


function OnSyncChanges()
{
$this.EnsureChildControls()

$drpdScope.SelectedValue = $webpart.Parameter1
$txtTagField.Text = $webpart.Parameter2
$txtMaxFontSize.Text = $webpart.Parameter3
$txtMinFontSize.Text = $webpart.Parameter4
$txtMaxColor.Text = $webpart.Parameter5
$txtMinColor.Text = $webpart.Parameter6
$drpdLists.SelectedValue = $webpart.Parameter7
$txtTagBrowser.Text = $webpart.Parameter8
$txtCss.Text = $webpart.Parameter9
}

function OnApplyChanges()
{
$this.EnsureChildControls()

$webpart.Parameter1 = $drpdScope.SelectedValue
$webpart.Parameter2 = $txtTagField.Text
$webpart.Parameter3 = $txtMaxFontSize.Text
$webpart.Parameter4 = $txtMinFontSize.Text
$webpart.Parameter5 = $txtMaxColor.Text
$webpart.Parameter6 = $txtMinColor.Text
$webpart.Parameter7 = $drpdLists.SelectedValue
$webpart.Parameter8 = $txtTagBrowser.Text
$webpart.Parameter9 = $txtCss.Text

return $true
}

function Render($writer)
{
$writer.Write("")

Render-Row "Scope" $drpdScope $writer
Render-Row "List Type" $drpdLists $writer
Render-Row "Tag Column Name" $txtTagField $writer
Render-Row "Tag Browser Url" $txtTagBrowser $writer
Render-Row "Max font size" $txtMaxFontSize $writer
Render-Row "Min font size" $txtMinFontSize $writer
Render-Row "Max color (hex)" $txtMaxColor $writer
Render-Row "Min color (hex)" $txtMinColor $writer
Render-Row "Style" $txtCss $writer

$writer.Write("
")

}

function Render-Row($text, $control, $writer)
{
$writer.Write("")
$writer.Write("")
$writer.Write("
$text
")
$control.RenderControl($writer)
$writer.Write("")
$writer.Write("")
}

Power Tag Cloud Browser Script
function CreateChildControls($controls)
{
$global:tag = $page.Request["tag"].ToString()
$global:scope = $page.Request["scope"]
$global:listType = $page.Request["listType"].ToString()
$global:tagField = $page.Request["tagField"].ToString()

$query = New-Object "Microsoft.SharePoint.SPSiteDataQuery"

#set query scope
if([String]::IsNullOrEmpty($scope) -eq $false){ $query.Webs=""}

$query.Lists = ""

$query.Query = @"


$tag


"@
$query.ViewFields = ""
if($listType -ne "1"){$query.ViewFields +=""}

$global:table = $web.GetSiteData($query)
}

function Render($writer)
{
$writer.Write("

Tag: $tag

")
foreach($row in $table)
{
$writer.Write("
")
$writer.Write($(Build-Headline $row))
$writer.Write($(Build-Body $row))
$writer.Write("

")
}
}

function Build-Headline($row)
{
$siteId = $site.ID
$href = "/_layouts/CopyUtil.aspx?Use=id&Action=dispform&ItemId={0}&ListId={1}&WebId={2}&SiteId=$siteId" -f $row["Id"],$row["ListId"],$row["WebId"]
if($global:table.Columns.Contains('Title') -eq $false -or [String]::IsNullOrEmpty($row["Title"]))
{
$title = $row["FileLeafRef"].Split('#')[1]
}
else
{
$title = $row["Title"]
}

$html = "" -f $href, $title

return $html
}

function Build-Body($row)
{
$tags = $row[$tagField].Split(';')

$html = "Tags: "

foreach($tag in $tags)
{
$tag = $tag.Trim().TrimStart('#')
$html += "$tag "
}

$html += "

"

return $html
}

function OnError($ex, $writer)
{
$writer.Write("Please ensure that tag, listType, tagField and scope url parameters are provided.")
}

You can download the two wepart files on the PowerWebPart 3.0 release homepage and then import them into the web part gallery or just copy and paste the scripts. An exported PowerWebPart .webart file self contains it script and digital signature, so you can simply export and import PowerWebParts. An end user will never notice if the web part is written in PowerShell or C#. Only farm admins can see and change the scripts. Note that when you import a PowerWebPart from a foreign SharePoint farm the signature will be invalid. A farm admin can simply resign the script through a click on “Apply” in the web part’s editor panel.

Apr 25, 2009

Getting Started with SharePoint PowerWebPart 3.0

I’ve just released PowerWebPart 3.0 on my iLove SharePoint project at CodePlex. What can you do with PowerWebPart?

Write reusable SharePoint WebParts with PowerShell

Features:

  • Simple HTML Rendering
  • ASP.NET and SharePoint WebControls
  • Supports WebPart Connections (Row Provider/Consumer, Table Provider/Consumer)
  • AJAX enabled
  • jQuery enabled
  • Configurable parameters
  • SharePoint Object Model
  • NEW: PowerGUI Script Editor Integration
  • NEW: Script Signing
  • NEW: Custom Editor Parts written in PowerShell
  • NEW: Central Script Repository
  • NEW: Import and Export
  • NEW: Error Handling
  • NEW: Debugging
  • No compile, no packaging, no deploy, no iis reset deployment
  • Copy & Paste deployment
  • Anything PowerShell can do :-)

One of the major improvements is the automatically script signing. Only farm administrators are allowed to edit scripts in the UI. But what is when you export a web part, change the script and import it to a web part gallery again? The signature will be broken and the script will not run anymore. So exporting and importing is now secure. The script will automatically be signed when a farm administrator clicks on ‘Apply’ in the web part's editor panel. The signing key will generated randomly on installation, but can be changed anytime later. 

For installation and configuration see documentation.

Getting Started Screen Cast:

Soon I will post a PowerWebPart Tag Cloud example…