Archive

Archive for the ‘SharePoint’ Category

Managing Quota Templates on SharePoint through PowerShell

August 10, 2013 3 comments

Quota templates are a seldom used but practically important feature in SharePoint. Important because it allows administrators to keep tabs on what sites can consume what level of storage without having to keep close watch on them. Defining a quota template with a high water mark (for warning when its reached) and a maximum level is the first step to this. Depending upon use, an administrator may have to define a large number of quota templates but doing this through the UI in SharePoint Central Administration is tedious.

clip_image001

One of these forms needs to be filled out for each template and it could get tiresome if there are tens of templates to create or edit. The easier way to do this? PowerShell.

The files in the archive posted here are PowerShell scripts that will allow an administrator to get a quick view of all available quota templates in XML and then allow the same XML file to accrue additions, modifications and changes pertaining to deletions that can be applied back to the set.

The following need to be ensured before running the scripts

  1. Run the scripts locally using the SharePoint Management Shell on a computer where SharePoint Server 2013 is installed and configured.
  2. Run the scripts as a farm administrator with permissions to alter quota templates. If the user is able to use the Central Administration UI to manage quota templates, then the user will be able to run these scripts.
  3. If there are permission issues with executing the script, ensure Add-SPShellAdmin is run for the user running the script.
  4. Use Set-ExecutionPolicy to temporarily tone the restrictions down if the shell complains about the script not being signed.

GetQuotaTemplates.ps1

##########################################
# Script:   GetQuotaTemplates.ps1
# Function: Retrieves all quota templates
#           defined on the farm in XML
# Author:   Lenny Ankireddi (2013)
##########################################

function Get-SPQuotaTemplates
{
    # Prepare XML structure
    $xmlText =
@"
<?xml version="1.0" encoding="UTF-8" ?>
<QuotaTemplates AsOn="">
    <QuotaTemplate Name="Sample" Action="None|Add|Edit|Delete" StorageMaxLevelInMB="0" StorageWarnLevelInMB="0" UserCodeMaxLevel="0" UserCodeWarnLevel="0" />
</QuotaTemplates>
"@

    # Read the XML string into an object
    $xmlDoc = [xml]$xmlText

    # Read the sample element
    $sampleQuotaTemplate = @($xmlDoc.QuotaTemplates.QuotaTemplate)[0]

    # Get a reference to the content web service
    $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

    # Iterate through the list of quota templates
    $service.QuotaTemplates | ForEach-Object {
        # Clone the sample element
        $newQuotaTemplate = $sampleQuotaTemplate.Clone()

        # Set the attributes of the element with the quota template properties
        $newQuotaTemplate.Name = $_.Name
        $newQuotaTemplate.Action = "None"
        $newQuotaTemplate.StorageMaxLevelInMB = [string]($_.StorageMaximumLevel / 1024 / 1024)
        $newQuotaTemplate.StorageWarnLevelInMB = [string]($_.StorageWarningLevel / 1024 / 1024)
        $newQuotaTemplate.UserCodeMaxLevel = [string]$_.UserCodeMaximumLevel
        $newQuotaTemplate.UserCodeWarnLevel = [string]$_.UserCodeWarningLevel

        # Add the element to the QuotaTemplates node as a new child
        $xmlDoc.QuotaTemplates.AppendChild($newQuotaTemplate)
    }

    # Remove Sample node
    $sample = $xmlDoc.QuotaTemplates.QuotaTemplate | Where-Object { $_.Name -eq "Sample" }
    $xmlDoc.QuotaTemplates.RemoveChild($sample)

    # Set date and time when generated
    $now = Get-Date
    $xmlDoc.QuotaTemplates.AsOn = [string]$now

    # Save the XML as a file to the current location
    $currentLocation = Get-Location
    $xmlDoc.Save("$currentLocation\QuotaTemplates.xml")

    # Report completion
    Write-Host -f Green "The quota template information has been saved to QuotaTemplates.xml."
}

Get-SPQuotaTemplates

This script fetches the quota templates currently specified on the local SharePoint farm and their related properties and places these details in an XML file in the same location as the script file.

clip_image002

The XML file will be named QuotaTemplates.xml and will be of the following format.

<?xml version="1.0" encoding="UTF-8"?>
<QuotaTemplates AsOn="04/24/2013 14:58:32">
    <QuotaTemplate Name="Personal Site" Action="None" StorageMaxLevelInMB="100" StorageWarnLevelInMB="80" UserCodeMaxLevel="300" UserCodeWarnLevel="200" />
    <QuotaTemplate Name="Sample 01" Action="None" StorageMaxLevelInMB="4096" StorageWarnLevelInMB="2048" UserCodeMaxLevel="0" UserCodeWarnLevel="0" />
    <QuotaTemplate Name="Sample 02" Action="None" StorageMaxLevelInMB="5120" StorageWarnLevelInMB="4096" UserCodeMaxLevel="0" UserCodeWarnLevel="0" />
</QuotaTemplates>

This file will serve as in input descriptor for the other script that manages the creation, edition and deletion of quota templates. Running the GetQuotaTemplates.ps1 script will overwrite any existing QuotaTemplates.xml file in the script file location. A file with the same name is expected as input by the ManageQuotaTemplates.ps1 script. Therefore if an input file is required for posterity, a copy of the file will need to be saved away manually.

ManageQuotaTemplates.ps1

###############################################
# Script:   ManageQuotaTemplates.ps1
# Function: Applies changes to quota templates
#           based on definition in XML
# Author:   Lenny Ankireddi (2013)
###############################################

function ManageQuotaTemplates
{
    # Get a reference to the content service
    $service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

    # Read XML input file
    $currentLocation = Get-Location
    $xmlDoc = New-Object XML
    $xmlDoc.Load("$currentLocation\QuotaTemplates.xml");
    $xmlDoc.QuotaTemplates.QuotaTemplate | Foreach-Object {

        $Name = $_.Name
        $StorageMaxLevel = $_.StorageMaxLevelInMB
        $StorageWarnLevel = $_.StorageWarnLevelInMB
        $UserCodeMaxLevel = $_.UserCodeMaxLevelInMB
        $UserCodeWarnLevel = $_.UserCodeWarnLevelInMB

        switch ($_.Action)
        {
            "Add"
            {
                Write-Host "Attempting to add new quota template $name..."
                # Check if quota template already exists
                if ($service.QuotaTemplates[$Name] -ne $null)
                {
                    Write-Host -f Red "Quota Template $Name already exists. Cannot add a new one with the same name. Use the Edit action to alter the existing template."
                    Write-Host ""
                }
                else
                {
                    # Get a reference to a quota template object
                    Write-Host "    Getting a reference to a new quota template object..."
                    $quotaTemplate = New-Object Microsoft.SharePoint.Administration.SPQuotaTemplate

                    # Set mandatory properties on the quota template
                    Write-Host "    Setting quota template properties..."
                    $quotaTemplate.Name = $Name
                    $quotaTemplate.StorageMaximumLevel = [int]$StorageMaxLevel * 1024 * 1024
                    $quotaTemplate.StorageWarningLevel = [int]$StorageWarnLevel * 1024 * 1024
                    $quotaTemplate.UserCodeMaximumLevel = [double]$UserCodeMaxLevel
                    $quotaTemplate.UserCodeWarningLevel = [double]$UserCodeWarnLevel

                    # Add the new quota template to the list of quota templates
                    Write-Host "    Adding the quota template $Name..."
                    $service.QuotaTemplates.Add($quotaTemplate)

                    # Update the service
                    $service.Update()

                    Write-Host -f Green "Quota Template $Name has been added."
                    Write-Host ""
                }
            }

            "Edit"
            {
                Write-Host "Attempting to edit quota template $name..."
                # Check if quota template already exists
                if ($service.QuotaTemplates[$Name] -ne $null)
                {
                    # If found, edit the template with new property values
                    Write-Host "    Quota template was located; editing it..."
                    $service.QuotaTemplates[$Name].Name = $Name
                    $service.QuotaTemplates[$Name].StorageMaximumLevel = [int]$StorageMaxLevel * 1024 * 1024
                    $service.QuotaTemplates[$Name].StorageWarningLevel = [int]$StorageWarnLevel * 1024 * 1024
                    $service.QuotaTemplates[$Name].UserCodeMaximumLevel = [double]$UserCodeMaxLevel
                    $service.QuotaTemplates[$Name].UserCodeWarningLevel = [double]$UserCodeWarnLevel

                    # Update the service
                    $service.Update()

                    Write-Host -f Green "Quota Template $Name has been edited."
                    Write-Host ""
                }
                else
                {
                    Write-Host -f Red "Quota Template $Name was not found. Verify that it exists and name has been correctly typed in XML input. Use the Add action to add a new template by this name."
                    Write-Host ""
                }
            }

            "Delete"
            {
                Write-Host "Attempting to delete quota template $name..."
                # Check if quota template can be found
                if ($service.QuotaTemplates[$Name] -ne $null)
                {
                    # If found, delete it
                    Write-Host "    Quota template was located; deleting it..."
                    $service.QuotaTemplates.Delete($Name)

                    # Update the service
                    $service.Update()

                    #Report completion
                    Write-Host -f Green "Quota template $Name has been deleted."
                    Write-Host ""
                }
                else
                {
                    Write-Host -f Red "Quota template by name $Name was not found. Verify that it exists and name has been correctly typed in XML input."
                    Write-Host ""
                }
            }
        }
    }
}

ManageQuotaTemplates

This script is used to make changes to the quota templates currently defined within the system. This can be done by altering the XML file output generated by GetQuotaTemplates.ps1 shown above.

clip_image003

The Action attribute of the QuotaTemplate element can be altered to one of the following values.

 

Action Result
Add The script will attempt to create a new quota template. However if one already exists by the name used in the XML, no action is taken.
Edit The script will attempt to find an existing quota template by the given name and edit its properties. If one is not found, no action is taken.
Delete The script will attempt to find an existing quota template by the given name and delete it. If one is not found, script reports failure to find it.
None The quota template is left untouched.

Altering the XML

The following precautions need to be taken while altering the input file for the quota template management script

  1. Only edit the Action attribute on QuotaTemplate elements that need to be changed. It is None by default and these quota templates are not altered by the script.
  2. To add a new quota template, copy one of the existing elements over and change its attributes. Do not forget to set the Action attribute to Add.
  3. To edit an existing quota template, select the QuotaTemplate element with the corresponding Name attribute and change its attributes. Do not forget to set the Action attribute to Edit.
  4. To delete an existing quota template, select the QuotaTemplate element with the corresponding Name attribute and set its Action attribute to Delete.
  5. Add, Edit and Delete values on the Action attribute are case sensitive. Type exactly as shown here.
  6. Change the values of the attributes of the QuotaTemplate elements as necessary. Do NOT change any of the other XML constructs.
  7. Values for StorageMaxLevelInMB and StorageWarnLevelInMB are to be provided in integer megabytes. If you do not want to specify these, set them to zero.
  8. Values for UserCodeMaxLevel and UserCodeWarnLevel are to be provided in numerical points. If you do not want to specify these, set them to zero. If you want to set them to SharePoint standard values, specify 300 and 100 respectively.

Recommended approach

Run the GetQuotaTemplates.ps1 script first always to get a fresh updated XML from the server. Alter the XML as required and run ManageQuotaTemplates.ps1. The scripts have been written to avoid providing input parameters on the command line. Hope this helps.

PowerShell script to install SharePoint Root certificate to Trusted Root store

June 18, 2013 3 comments

Now this post is not really about why and how certificates are used by SharePoint. But in order to understand why we are doing what we are going to do shortly, let me start with a brief 2-minute (hopefully) primer on what this is about.

The public key infrastructure allows messages between users, applications and servers that host the applications to happen in a secure manner using digital certificates. The same happens within SharePoint when a message between entities needs to be secured. Now in order for the sender and receiver of messages secured through certificates to work, a trust needs to be established between the parties. The way this works is that both parties trust a third party which is the issuer of the certificate using which the message is signed. Bear in mind that this is a very high level overview of how this works and there are several variations that we shall not get into here. Having said the above, now in order for the receiver of a message to trust the certificate that is presented with it, it will need to be verified. Not only that certificate but its issuer’s certificate and that certificate’s issuer and so forth until we can trace back to a trusted root certificate. This is referred to as certificate chaining.

Within SharePoint, one instance where this happens is when the Security Token Service issues a token and signs it with a certificate. This certificate will need to be verified as mentioned above through building a chain back to a trusted root certificate. Also, a Certificate Revocation List (CRL) needs to be verified to ensure the certificate has not been revoked. This last is yet another topic requiring much detailed explanation that I shall try to address in a future post. But the idea here is that each certificate in the chain needs to be verified and one needs to lead to a trusted root CA store. If this doesn’t happen, certificate validation errors will occur and cause delays in response time to the users. To avoid this, we need to ensure that the SharePoint Root Authority certificate is installed to the Trusted Root Certification Authorities certificate store on each server in the SharePoint farm. The link above provides steps to do this but involves several manual steps. What I have included below, is a PowerShell script that does it all end to end.

The following are prerequisites to running the script.

  • To be run locally on each machine.
  • To be run as a user with Shell_Admin_Access role on the farm databases [If this is not available run Add-SPShellAdmin before proceeding].
  • To be run as a user with local administrator privileges on the server.

Another thing worth verifying before executing the script is the execution policy on the server. You can determine this by running the Get-ExecutionPolicy cmdlet. This typically shouldn’t be a problem unless you are running the script from a remote share. If you do have a problem though, you can work around it by using the Set-ExecutionPolicy cmdlet.

function CopySharePointRootCertToLocalTrustedCertStore {

    # Add the SharePoint PowerShell snap-in
    if (-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) {
	    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
    }

    # Get the SharePoint root certificate
    $rootCert = (Get-SPCertificateAuthority).RootCertificate

    # Store current location
    $location = Get-Location

    # Go to trusted root certificate store on local machine
    cd Cert:\LocalMachine\Root

    # Check if the certificate already exists
    # If it does, report and end
    if ((dir | ? { $_.Thumbprint -eq $rootCert.Thumbprint })) {
        Write-Host -f Green "SharePoint Root Authority already exists in local machine trusted root certificate store."
        cd $location
        return
    }

    # Get the certificate store for "Trusted Root Certification Authorities" (Cert:\LocalMachine\Root)
    $certStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store Root, LocalMachine

    # Open the store with maximum allowed privileges
    $certStore.Open("MaxAllowed")

    # Add the certificate to the store
    $certStore.Add($rootCert)

    # Close the store
    $certStore.Close()

    # Get the certificate if it exists
    if ((dir | ? { $_.Thumbprint -eq $rootCert.Thumbprint })) {
	    Write-Host -f Green "Certificate was successfully added to the Trusted Root store."
    }
    else {
	    Write-Host -f Red "The certificate could not be added to the Trusted Root store."
    }

    # Set location back to where it was
    cd $location
}

CopySharePointRootCertToLocalTrustedCertStore

You can save the script as a .ps1 file and run on each of the servers where the SharePoint root certificate needs to be copied. The way to verify that this has actually worked is to pull up a management console and add the Certificates snap-in as described in the Microsoft Support KB Article referenced above. If however, your objective is to just export the certificate from SharePoint, you may want to use the script provided below. Just make sure you set the $certPath to where you would actually like to export the certificate and by what name.

# Set the certificate file path
$certPath = "C:\SharePointRootAuthority.cer"

# Add the SharePoint PowerShell snap-in
if (-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) {
	Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
}

# Get the SharePoint root certificate
$rootCert = (Get-SPCertificateAuthority).RootCertificate

# Export the certificate to disk as a certificate file
$rootCert.Export("Cert") | Set-Content $certPath -Encoding byte

Once you have exported the certificate, you can manually add it to the certificate store by using the Management Console or by using the second half of the first script presented above. The only difference is that you will need to construct an X509 certificate object from the certificate file as shown in the script snippet below.

# Set the certificate file path
$certPath = "C:\SharePointRootAuthority.cer"

# Get the certificate store for "Trusted Root Certification Authorities" (Cert:\LocalMachine\Root)
$certStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store Root, LocalMachine

# Get the certificate from the location where it was placed by the export process
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 $certPath

# Open the store with maximum allowed privileges
$certStore.Open("MaxAllowed")

# Add the certificate to the store
$certStore.Add($cert)

# Close the store
$certStore.Close()

That’s it for now. Hopefully, I will find some time to write up more about troubleshooting certificates in SharePoint soon. In the meanwhile, happy scripting!

Video Renditions in SharePoint 2013

October 19, 2012 Leave a comment

During my explorations of new web content management and publishing features in SharePoint 2013 through the guidance published here, I came upon the idea of image renditions. I tried them out in different ways and posted some findings here on their workings. One thing I did not find any mention of in the article is of renditions applicable to videos. I chanced on video renditions as I was experimenting with uploading and embedding video in SharePoint 2013 which I talk about here. Although I initially wondered why, trying the feature out showed me that renditions as applicable to video are a different concept than Image Renditions. Here’s a quick comparison.

Image Renditions Video Renditions

Asset and Rendition are separate
There is one image that any of a set of predefined renditions available to all images in the site can be applied upon or even customized.

Each rendition is a new asset
If a given video file will need to be played back in different modes, formats, dimensions or bitrates, a new video file meeting those criteria needs to be created and uploaded.

Defined for each instance of embedded image
Content authors or designers can use renditions provided with SharePoint 2013 or add their own. They can define the various ways in which a given image can be displayed in several different locations on the site using different renditions.

One default picked for a video
One of the available renditions of the video can be picked as the default for display on any page where it is embedded. Different renditions cannot be placed on different pages.

Viewers get to see, not change renditions
Content consumers can see the effect of the rendition applied to the image but cannot change them or apply other renditions to a given instance of an image.

Viewers get to apply desired rendition
The default rendition is what is loaded with the page each time but the consumer of the page can select another rendition to apply.

To illustrate the above, let’s take a quick look at how we can do renditions of video. First, I go to my asset library where I keep videos for my site, pick the video I want and open the actions popup (click the ellipsis). When there, since what I want to do right now is not play or download the video, I can bring up a menu of additional actions by clicking on the ellipsis again [for the uninitiated, the ellipsis is the 3 dots you see on the tile indicating that "there’s more"]. I chose to "Edit Properties".

clip_image001

On the "Edit Properties" page, you get a little section that speaks about "This video’s renditions" – it is typically collapsed. When I expanded it, here’s what I saw.

clip_image002

Clicking on "Manage Renditions" takes you to the following slightly weird page with text flowing off the screen and flush to the right edge of the browser (but it works). As you can see here, in order to create alternate renditions of this video, you will actually have to upload other video(s).

clip_image003

I clicked on "Upload Video Rendition" and saw the following dialog; nothing fancy here, just pick a video file and upload. I uploaded a low bitrate version of the video I already had, that is more suited for playback on small form factor mobile devices.

clip_image004

When I click "OK", I am presented with a dialog where I can put in some metadata relating to the video file I uploaded. Note that I did NOT type in the "183 KB/sec" value in the Label field. That is something that SharePoint inferred based on the properties of the video. There are certain other properties that are not even presented on this dialog such as bit rate, frame width and height. You see these in the rendition listing above. Obviously, these are also auto-captured from the video asset uploaded.

clip_image005

Once I clicked on "Save" here, the video is uploaded to SharePoint. After upload, I now see there are two renditions available each with a different bitrate and frame size. The little green star (I like this a lot better than the word "New" that used to hang on a new item) shows the new video file that was added and as you can see, its metadata properties were correctly inferred.

clip_image006

As you can see above, you can also pick which rendition of a video is the default when you put it on a page. Notice how this setting is "global" for a given video? If you select the rendition that is default here, that is the rendition that will apply to the video on any page where it is embedded when the page loads. You cannot choose to do a different rendition on each page. The content consumers do have the opportunity to choose a different rendition to play back but it will always load with the default specified here. This is different from how image renditions work.

I left the default selection (to use the lowest bitrate available) for the default video rendition and clicked on "Save". This took me back to the "Edit Properties" page for the video.

clip_image007

As you can see under "This video’s renditions", the default rendition is now the low-res version. Since I did not change any of the actual video properties, I reckoned it shouldn’t matter if I hit "Save" or "Cancel" on this page but I hit "Cancel" just to check if it caused any kooky rollback of changes made to renditions. It did not – so everything’s good here. Oh, by the way, notice the new icon in the controls section of the play that looks like the signal bars on your cellphone? That is what indicates that there are multiple renditions of this video available. The same icon can be used to switch renditions.

Next stop, the page on which I had embedded this video. This is where I was disappointed. Just loading the page did not show the presence of the renditions available on the page. I cleared the browser cache and reloaded the page. That didn’t work either. Next, I recycled the app pool on the server to see if that would help but had no luck. I then went to the last resort which was to check out and edit the page, update the video and publish. When I edited the page, it worked. The renditions now showed up and worked. I republished the page and had everything going. The problem though, is that the change to the asset didn’t work directly on the page using it. The page had to be republished.

This behavior is in pattern with a similar observation I made relating to the Preview image that I documented in my notes from playing with video embedding. In general the behavior I am consistently noticing is that if you make changes to the properties of a video asset that you embedded on a publishing page in SharePoint, the change doesn’t reflect on an instance of that asset that you placed on a publishing page unless the page is edited and republished. This is rather inconvenient – so I am hoping this is something that is either only happening to me or is a bug in SharePoint 2013 Preview that will be fixed by release.

clip_image008

Another observation here is that the preview image I saw was for the high-res version. Clicking on the renditions icons showed me that the current rendition being applied is the low-res version but that is not the impression you get from seeing the preview image. You have to remember that you don’t get to associate a preview image with each rendition file that you upload for an asset. There is one image that is associated to the asset as a whole – one that was either auto-generated during asset upload or one that we change and apply to the asset.

There is a way to work around this last problem, though. After you have placed the video on the page, you can specify, through the ribbon, the preview image that you would like to apply to it. To do this, you would have to have already gone and taken a key frame shot from your video in the default rendition and stored it. You can also adjust the Horizontal and Vertical sizes through the ribbon to avoid too much of the black offsets. A little more work but hey, you can get it done.

clip_image009

Now once you’ve done all that and published the page, the switching of the renditions is pretty smooth. You can switch renditions even as you are playing back and the video would switch to the other bitrate or format specified in flight. This rendition selection is available to all users that are able to view the video on the page although they cannot change the default rendition. There you are – video renditions in SharePoint 2013.

Improvements with embedding video in SharePoint 2013

October 18, 2012 Leave a comment

In reading through the list of content authoring improvements made within SharePoint 2013, I found here the following text which sounded very encouraging from a video asset upload and metadata management perspective:

"A new video content type is added, and the video upload process is improved for content authors. Thumbnail preview images are created automatically when a video is uploaded to an asset library, and content authors can choose a frame from the video and use that as the thumbnail preview image".

So I went ahead and tried to do some testing with adding video to a publishing page on an installation of SharePoint 2013 Preview to see what the new experience is like. Here’s how you do it.

clip_image001

When you choose the upload "From Computer" option, here’s what you get to do:

clip_image002

The "Images" library – an "Asset Library" by definition seems to be the default destination library. I uploaded to "Videos" – an asset library I added to my site to keep videos separated from other publishing images. After upload, you get to edit metadata relating to your video.

clip_image003

In addition to keywords, author and comments, the preview image, copyright and label can be set.

clip_image004

I set everything except the preview image. On publishing, the page looks like this – rendered using the Silverlight web part and a random key frame chosen for the preview image.

clip_image005

Now all of this was for when you have your own video asset that you want to store on local infrastructure or on SharePoint and reference on your page in SharePoint. There is also an easy way to embed video from the popular video services such as YouTube and Vimeo.

Among the options presented above on where you want to select the video you insert from, you see "Embed" which allows you to paste an HTML code snippet in, to reference the video like you would do when you are trying to embed video from YouTube, for instance. Since inserting iframes in HTML field controls in SharePoint 2013 is possible, it should be a breeze to achieve something like the below… What? I love Coldplay.

clip_image006

NOTE: In order for an iframe to be able to display content from another site, the domain for the site will need to be cleared through HTML Field Security in site settings. This is also something that was newly introduced with SharePoint 2013 and is mentioned among the content authoring improvements that I referred to above.

I did play around with this feature too and posted some findings here. The reason I was able to quickly embed video from YouTube is because the domains for YouTube and Vimeo are already placed in the list of secure domains for display in HTML fields. So you can just borrow the video embedding code snippets from those sites and just paste them into the source of an HTML field in SharePoint 2013 and it would work.

Thumbnail / Preview Images

As mentioned in the list of improvements on the TechNet site, there is a way to pick a thumbnail image by playing back the video and using a "Capture Thumbnail" button (which is referred to as the "Camera button" in the options – likely to change by release?).

clip_image007

The other ways to set a thumbnail image is to use a picture saved to disk or one that can be obtained from a web address.

When the thumbnail image corresponding a video uploaded to an asset library is changed, the behavior observed on a publishing page where the video is embedded is slightly off – the video no longer has a preview image – it is blacked out as shown below. Not sure if this is a "preview" bug that will be fixed by release. Refreshing the page didn’t help restore the preview image. The playback wasn’t affected, though. Checked after playback if the preview image would be restored. That didn’t work either.

clip_image008

Checking out and editing the page seem to have the desired effect of refreshing the thumbnail image corresponding to the video.

clip_image009

This may be painful if there are a large number of pages with embedded video whose thumbnail previews are being changed. The behavior seems to suggest that they would all be blacked out and will need to be republished.

The article mentions that automatic thumbnail generation is possible but will require Windows Desktop Experience to be enabled. I did this using the method I published here. That didn’t change the overall behavior much. The thumbnail generation and the refresh on update behavior was pretty much the same. Although it didn’t black out this time (which may be due to the difference in media format – WMV before vs. MP4 this time), it did not apply the updated thumbnail image (even after republishing the page).

I wonder if this is behavior that I am experiencing exclusively but I doubt it given the number of times I have tried it and am constantly able to reproduce it. Given I am doing all this on SharePoint 2013 Preview, I do hope it is fixed by release.

Image Renditions

October 18, 2012 Leave a comment

Image Renditions are a new feature in SharePoint 2013 that allow you to create multiple views of a given image uploaded to SharePoint. This allows for the same image to be displayed differently in different parts of the site through the application of different renditions. The following are findings from my playing around with the feature on SharePoint 2013 Preview.

You will find Image Renditions in Site Settings under the "Look and Feel" section

clip_image001

In order to use Image Renditions, the blob cache will need to be configured for the web application that is hosting your SharePoint site. If you have not already done this, the following is what you’ll see when you try to configure Image Renditions.

clip_image002

To set the blob cache, the web.config file for the web application containing the SharePoint site in question needs to be edited. This should be found typically at <OSDrive>:\inetpub\wwwroot\wss\Virtual Directories\<portnumber>. You can open the file using notepad or something similar and find the following line:

<BlobCache location="C:\BlobCache\14" path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|ico|png|wdp|hdp
|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm
|rmvb|wma|wmv|ogg|ogv|oga|webm|xap)$" maxSize="10" enabled="false" />

I have not changed the location although it is recommended that you set the blob cache location to a disk that does not have the OS installed for the server and is not the one where the server log files are written. The list of available file types seemed fine for my testing purposes. The only thing I really needed to change was set enabled="true", save web.config and exit.

Here is a reference for different cache settings you can make for a SharePoint web application on TechNet.

When done, you should be able to go back to the Image Rendition listing page. You should be able to add a new rendition, edit an existing one or delete one from the list. Here’s what you can edit with a rendition – the same set of attributes you can control when you create a new one:

clip_image003

Any rendition that you place here is available to all images that are added to this site. To test this out, I headed next to the "Images" asset library that comes by default with the Publishing site template and uploaded an image. Now I am not going to get into exactly how I uploaded an image to an asset library because that is pretty standard experience. The only thing I will remark about is metadata relating to the picture that when available is auto-captured by the image property dialog.

clip_image004

When done uploading, I headed back to the publishing page where I was experimenting with all content authoring features, checked out and edited it and embedded the image on the page using the Insert > Picture > From SharePoint option shown below.

clip_image005

Then of course you get to navigate to the asset library of your choice and pick an image that has been uploaded there.

clip_image006

Once you have picked and inserted your image, the image tab on the ribbon is where you see the new option to pick a rendition – this will list all renditions in the list of renditions available centrally to the site. The first option – "Full size image" is not a rendition option – it is the default selection for the image. Note that you can also "Edit Renditions" from here.

clip_image007

If you click on "Edit Renditions", you will see the several renditions available applied to the selected image in the dialog that pops up as shown below. Note that there is a "Click to Change" link on each. It is also interesting to note that there are four URLs here for each rendition. Each of these basically shows you the image with the rendition applied.

clip_image008

If you click on the "Click to Change" link, the following message asking you to check out the image to be altered is shown

clip_image009

When you click on "Cancel", nothing happens and you are thrown back on to the prior dialog, which is fine. When you click on "OK" though, again, nothing happens except that the message disappears. The image has been checked out but you don’t know that because you are not told so. The only way you know is by clicking on one of the "Click to Change" links again. If you don’t see the above message this time, you know that check out worked. When you do, you end up on the following dialog.

clip_image010

So what is this? It essentially draws a rectangle on your image – or you can draw your own – of the same aspect ratio as the width and height specified on the chosen rendition. You can adjust the boundaries of that rectangle while not disturbing that aspect ratio to focus on the part of the image that you would like to show in the width and height you’ve been provided which in the above example is 120 pixels wide and 68 pixels high. For illustration, refer to the rectangle I drew below to change what part of the image is enclosed in the rendition. You can see what your image will look like in the preview provided below.

clip_image011

So what did we do? When we add a rendition or use one that’s available with SharePoint 2013, we get to define only the width and height of the bounding box that will be used upon the image to which the rendition will be applied. We do not get to specify the coordinates of where that box should start – like the left and top settings you would make in CSS for example. This is because those settings are very image specific and should be made when applying the rendition on an image. Therefore, we applied that through the image cropping function on the combination of an image and a specific rendition. We end up with the following.

clip_image012

I edited the one that is called "Display Template Video". All others are as SharePoint would normally crop them. The default cropping scheme essentially tries to fit in the largest bounding box with the specified aspect ratio that can fit into the dimensions of the image provided. Where this results in one dimension being accommodated but the image having available real estate along the other dimension, the box is centered (vertically or horizontally as the case may be). This is what results in the decapitated penguins you see above.

The bounding box drawn on the image may be larger (or smaller) than the dimensions of the rendition specified. As long as the aspect ratio is maintained, as in this case it is forced to, the actual image placed on a publishing page will be scaled up or down to show the contents specified by the bounding box in the size specified by the rendition. So for instance, I could have drawn a box on my image as I was customizing the rendition for it that was 240×136. The contents of that box would scale down by 50% when displayed on the page to fit the 120×68 rendition.

Now it stands to reason that the information relating to the rendition customization for the image was stored with the image itself – especially since we had to check the image out before we made the changes. So how do we get to that information?

If you head back to the asset library where you uploaded the image, you should be able to place your cursor on the image, click on the ellipsis and pull up the menu where you can "Edit Renditions".

clip_image013

When you click on "Edit Renditions" here, you are brought back to the "Edit Renditions" screen with all the different renditions applied to the current image as seen before and you can go back to changing the renditions again.

clip_image014

Incidentally, you can use the URL provided against the rendition for the image as a way to directly reference a specific rendition for the image. So for instance, you could use an image tag and set the source directly to the URL with the RenditionID and the specific rendition of the image would load.

clip_image015

The above source edit on the HTML field on the publishing page would have the following effect.

clip_image016

So how else are these useful? You can use the one image with several renditions to display several images on your publishing page without actually using several cropped images. This way, only one image loads during your page load and this could have significant impact on the amount of time it takes for your page to render.

I added a few new renditions to the list on the site as shown below

clip_image017

The 3 new items I added are seen now in the list below – each starts with the word ‘Headshot’.

clip_image018

Now I go back to my image and specify the rendition settings for these three new ones I just created to focus on the faces of each of the chipmunks as shown below.

clip_image019

After having done the same for the other two and saved, this is what I end up with. One thing to note is that since the bounding box scales to be exactly 100×100, I didn’t have to spend much time worrying about resizing cropped images as I would have had to do to fit Theodore’s rather large (and adorable) head.

clip_image020

Now that I have these available, I can put the following code on a page. As you can see, I have used just the one image several times over with different renditions applied. As a side note: there is still no respite for people using the HTML field source editor with doing indentations and so forth with HTML. The control now does a very good job with formatting HTML after you hit the "OK" button, to be XHTML compliant. In fact, I forgot to place my <th> tag in the code below inside of its own <tr> and the editor went ahead and corrected that. Pretty impressive. I still wish I was able to indent code as I was putting it in.

clip_image021

The effect of doing this is the following publishing page on SharePoint.

clip_image022

Now to see how this works. In order to check what the page is loading as it is being rendered, I used fiddler to trace the page load after having cleared the cache.

clip_image023

To see how this compares to loading a page that has the full image (without renditions) loaded with any compression accounted for, I also traced the load on a page that has the full size image embedded:

clip_image024

From what we see, the following observations can be made:

  1. The image we uploaded is 320 KB in size but since we always only get a portion of it through a rendition, the cumulative size of all image downloads is only around 25 KB.
  2. You see the actual JPEG file download happen four times where highlighted in the first image of Fiddler. So each rendition, has its own image downloaded separately.
  3. Each of the 3 smaller renditions were around 3KB in size but they were not all the same size. This is because of the slight differences in the sizes of the bounding boxes we drew as we framed the faces of the characters in the larger picture.

So how does all this help?

  1. Saves a graphic designer the trouble of slicing up images to create different bits that can be used on different pages or the same page. Remember that the scaling of images to fit specific sized boxes is handled by the rendition definition.
  2. Since we are effectively only storing one image in the content database, it saves the additional space used up by different size versions of the image that a designer may have to create.

NOTE: We do not save anything with the number of images that are downloaded during the page load. Therefore, this is not to be confused with concepts such as CSS sprites and other techniques that are used to reduce either the number of HTTP requests made for individual images or the sizes of images downloaded.

One last thing to check before we close this topic – what happens if you apply a rendition on an image that is larger than the image itself? As expected the image size would be scaled up to match the rendition and could make it look rather ugly depending on the how large the ratio of rendition size to image size is. That said, this is probably something no one would ever do so it should be fine.

clip_image001[4]

Overall, it is a very useful feature to have to quickly produce scaled and alternate views of an image very quickly instead of slicing images or using tricky CSS.

Just another SharePoint VM–Part 4–Installing SharePoint 2013 Preview

October 10, 2012 Leave a comment

To this point I have installed Windows Server 2012 and configured it (published in Part 1), setup the service accounts required by SQL Server and SharePoint (published in Part 2), installed SQL Server 2012 and configured it (published in Part 3) and now am ready to go ahead and install SharePoint 2013 Preview. What I have in terms of media is the .img file from Microsoft downloads which I will not be able to use in Oracle VM VirtualBox. So I went ahead and extracted the contents to a folder on my host machine that I shared with the virtual machine. Having done this, when I browse the contents of the folder, I see the following:

clip_image001

Though setup.exe immediately caught my eye, I paused to check if there was a prerequisite installer like in SharePoint 2010. Sure enough, there it was. I decided to run this first to ensure everything SharePoint 2013 required was in place. The followings is the list of items, the prerequisite installer professes to install. As you can see, the IIS role is one of the items on the list. This is why we did not have to add the IIS role during Windows Server 2012 configuration. Moved on by clicking "Next".

clip_image002

On the following screen is the EULA. Read and accepted the terms to move on:

clip_image003

At this point, the prerequisite installation starts and could take a few minutes to go through and install all items listed above. For items that are already installed or for items where later versions are already available on the target environment, the prerequisite installer is clever enough to take no action.

The installation of the web server role requires a restart. I went ahead and clicked on "Finish" to restart the VM.

clip_image004

Again, I have to mention here how fast the restart operation is for a server operating system compared to what I have been used to. Including update configurations resulting from pre-restart changes, it took just over a minute to get back to the login screen. Logged in again as the administrator and the prerequisite installer continued with the configuration of IIS role, installation of the Windows Server AppFabric, WIF and other items on the list.

clip_image005

Here’s the report after completion of all installations – except for those that were skipped intentionally, everything else installed correctly.

clip_image006

The installation report urges you to look at the following list of optional software prerequisites that you may want to install.

clip_image007

In order to figure out what makes this list of items optional (or what I will not be able to do without them), I decided to ignore these for now and clicked on "Finish" to exit the prerequisite installer. Restarted the VM for good measure to flush out any residual updates or configuration before moving on.

When the system restarted, I did a couple of things

1. Took a snapshot of the VM to this point that I can restore to in case something went wrong with the installation.

2. Logged in as the SP Setup account we created before – this is the account we want to use to install SharePoint.

Having dallied enough, it was now time to go on to the installation of SharePoint 2013 itself. So launched my shared location with the bits extract again and launched setup.exe this time.

clip_image008

After a short prep screen display, you are asked for the product key. Entered and selected "Continue".

clip_image009

Again, read and accepted the license terms

clip_image010

Next, we have the file location selection. There was no real reason to change any of these – so moved on by clicking on "Install Now".

clip_image011

Next the installation progress screen goes through and tracks the installation of the product. This takes a few minutes – especially during the finalization of installation – the overall process took about 5 minutes for me.

clip_image012

When done, this is what you see. Evidently, the easiest part of the installation so far was the actual installation of SharePoint products. Now for the tricky part – the configuration of SharePoint products. As you can see below, the installer checks the box that will launch the configuration wizard. If you want to go ahead and configure now, just click "Close". If not, you could uncheck the box and launch the Configuration Wizard later. I chose to run the wizard.

clip_image013

The Configuration Wizard runs and tells you to have certain things on hand to complete configuration. The name of the database server and the username and password for the farm account which we already created in a previous step – known as SP Service.

clip_image014

Next, the warning about the services that will need to be reset during configuration is shown. There is no way to escape this if I want to complete configuration so I select "Yes" to move on.

clip_image015

On the next screen, I choose to create a new server farm

clip_image016

On the following screen, specified the server name and the username and password of the farm account. The username should be entered in DOMAIN\username format – this is important. Did not change the database name here and clicked "Next" to proceed.

clip_image017

On the next screen, chose and confirmed a passphrase that will be used by all servers in the farm to secure configuration data. The passphrase needs to be 8 characters long, have uppercase and lowercase characters, numerals and special characters to meet complexity criteria.

clip_image018

Next, you get to specify the port on which the Central Administration application will be installed. I usually choose the year (version) of the product for this – makes it easy to remember. Also, the authentication provider can be selected here. I chose "NTLM".

clip_image019

Next, the configuration wizard shows a quick summary of the selections and settings made so far before configuration is applied. When you click "Next" here is when all of the real SharePoint setup is happening and you need this part to work well – ergo, fingers crossed.

clip_image020

Follow the progress very closely – it is important to know where and what fails here to be able to troubleshoot. Somewhat easier than reading logs later.

clip_image021

Some tense moments (about 5 minutes) and several shortened nails later

clip_image022

A little happy dance and then clicked on "Finish" to bring up the Central Administration application in a new browser window.

clip_image023

In past versions, after installation, there were a set of tasks added somewhere for the administrator to "go do" – such as "Servers on the farm", "Services on the Server" and so forth, to complete the configuration of the farm. SharePoint 2013 provides you a wizard.

Now I would have preferred to configure the farm myself but I wanted to see what the wizard would do. So I clicked on "Start the Wizard". On the next screen you get to manage the service applications you want to run on the server and the account using which to run them. It is recommended that a different account than the farm account be used. I specified a the "SP Services" account already created for this.

clip_image024

A slightly different message asking you to wait while changes are made. I like it for now (because it is shiny and new) although soon, I may not like it as much. It took quite a while here (over 12 minutes – likely due to the limited RAM allocation I could make… *sigh*)

clip_image025

When done, here’s where we end up as the next step in the wizard. Creating a site collection. I am in the habit of creating a site collection at the root of the server. Therefore, I go ahead and do that while applying the "Publishing Portal" template to the site – Why? No particular reason – happens to be the set of features I want to explore first.

clip_image026

clip_image027

Again, the already irksome "Sorry to keep you waiting" message for about 3 minutes and then

clip_image028

Clicked "Finish" and done. We end up on the familiar Central Administration view.

clip_image029

So how about that root site collection we created? Navigating to the root site brings up the following. Note – no fancy images, logos or web parts just a plain site with placeholders for content to come.

clip_image030

And a list of things to do for an Information Architect and a Visual Designer. Kind of different than earlier versions. But more on that later. For now, we have successfully installed and verified the SharePoint Server 2013 Preview.

%d bloggers like this: