Spam comments were deleted

17. February 2011

I have noticed that while I was not posting new posts the blog was filled with spam comments. I have deleted most of the comments. In the future I will monitor the comments more carefully. I have also added reCaptcha and I hope it will block some of the spam comments.


New job and updated blog engine

17. February 2011

I haven’t posted anything new on this blog for over one and half years. During that time I have switched job. I am currently working in Windows organization in Windows Update team. I am working on Windows Update and other technologies and components built on top of Windows Update infrastructure.

Recently I have also updated the blog engine on this blog to BlogEngine.NET version 2.

Expect more news and some posts soon.

Blog ,

“Mastering” branding of SharePoint

16. April 2009

Ok, I am exaggerating here. This post will not be about “mastering” the branding but rather about branding through master pages. This post is another post in a series of posts where I try to learn SharePoint. When I found out that SharePoint is based on ASP.NET master pages I immediately thought it would be fun to create a SharePoint that would look exactly like my web pages. So, here is my target visual.



Creating new master page

By looking at the default.master page (located at C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\GLOBAL\default.master) I got scared. This page is not simple, let me say it this way. I tried to come up with a clean minimal page. I found a minimal master page on MSDN. Unfortunately that page didn’t work and I had no clue why (I guess it’s because I don’t have MOSS but just WSS installed on my machine). I then tried to come up with my own minimal master page. Here is the result.


<%@Master language="C#"%>
<%@ Import Namespace="Microsoft.SharePoint" %> 
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" 
  Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" 
  Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" 
  Assembly="Microsoft.SharePoint, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="wssuc" TagName="Welcome" src="~/_controltemplates/Welcome.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="DesignModeConsole" 
  src="~/_controltemplates/DesignModeConsole.ascx" %>

<html id="HTML1" dir="<%$Resources:wss,multipages_direction_dir_value%>" runat="server" 

<head id="HEAD1" runat="server">
    <META Name="progid" Content="SharePoint.WebPartPage.Document">
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    <META HTTP-EQUIV="Expires" content="0">
    <SharePoint:RobotsMetaTag ID="RobotsMetaTag1" runat="server"/>
    <Title ID="onetidTitle">
        <asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server"/>
    <SharePoint:CssLink ID="CssLink1" runat="server"/>
    <!-- remove support for themes <SharePoint:Theme ID="Theme1" runat="server"/> -->
    <SharePoint:ScriptLink ID="ScriptLink1" language="javascript" name="core.js" Defer="true" runat="server" />
    <SharePoint:CustomJSUrl ID="CustomJSUrl1" runat="server" />
    <SharePoint:SoapDiscoveryLink ID="SoapDiscoveryLink1" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderAdditionalPageHead" runat="server"/>
    <SharePoint:DelegateControl ID="DelegateControl1" runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>
<body scroll="yes" onload="javascript:if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();">

    <form id="Form1" runat="server" onsubmit="return _spFormOnSubmitWrapper();">
        <WebPartPages:SPWebPartManager id="m" runat="Server" />

        <!-- MAIN CONTENT -->
        <div id="main">
            <asp:ContentPlaceHolder id="PlaceHolderMain" runat="server"/>

<asp:Panel ID="HiddenPlaceholders" visible="false" runat="server">
    <asp:ContentPlaceHolder id="PlaceHolderBodyLeftBorder" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderBodyRightMargin" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderCalendarNavigator" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderFormDigest" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderGlobalNavigation" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderGlobalNavigationSiteMap" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderHorizontalNav" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderLeftActions" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBarBorder" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBarDataSource" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBarTop" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderMiniConsole" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderNavSpacer" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderPageDescription" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderPageImage" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderPageTitleInTitleArea" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderSiteName" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderTitleAreaSeparator" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderTitleBreadcrumb" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderTitleLeftBorder" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderTitleRightMargin" runat="server" />
    <asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server"/>
    <asp:ContentPlaceHolder ID="SPNavigation" runat="server" />
    <asp:ContentPlaceHolder ID="WSSDesignConsole" runat="server" />
        <input type="text" name="__spDummyText1" style="display:none;" size=1/>
        <input type="text" name="__spDummyText2" style="display:none;" size=1/>
    <asp:ContentPlaceHolder id="PlaceHolderUtilityContent" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderBodyAreaClass" runat="server"/>
    <asp:ContentPlaceHolder id="PlaceHolderTitleAreaClass" runat="server"/>

This minimal master page leads to the following visual.



At this point I took master page from my web server and put it in my minimal SharePoint master page. The trick is to play with SharePoint ContentPlaceHolders. These are all the available placeholders:


Placeholder Description
PlaceHolderAdditionalPageHead Additional content that needs to be within the tag of the page, for example, references to script in style sheets
PlaceHolderBodyAreaClass Additional body styles in the page header
PlaceHolderBodyLeftBorder Border element for the main page body
PlaceHolderBodyRightMargin Right margin of the main page body
PlaceHolderCalendarNavigator Shows a date picker for navigating in a calendar when a calendar is visible on the page
PlaceHolderFormDigest The "form digest" security control
PlaceHolderGlobalNavigation The global navigation breadcrumb
PlaceHolderHorizontalNav Top navigation menu for the page
PlaceHolderLeftActions Bottom of the left navigation area
PlaceHolderLeftNavBar Left navigation area
PlaceHolderLeftNavBarBorder Border element on the left navigation bar
PlaceHolderLeftNavBarDataSource Data source for the left navigation menu
PlaceHolderLeftNavBarTop Top of the left navigation area
PlaceHolderMain Page's main content
PlaceHolderMiniConsole A place to show page-level commands, for example, WIKI commands such as Edit Page, History, and Incoming Links
PlaceHolderNavSpacer The width of the left navigation area
PlaceHolderPageDescription Description of the page contents
PlaceHolderPageImage Page icon in the upper left area of the page
PlaceHolderPageTitle The page


With this information I have updated the “logo” element:

<!-- LOGO -->
<div id="logo" class="logo">
    <asp:ContentPlaceHolder id="PlaceHolderSiteName" runat="server">
        <SharePoint:SPLinkButton runat="server" NavigateUrl="~site/" id="onetidProjectPropertyTitle" CssClass="whiteLink" >
            David Pokluda's <SharePoint:ProjectProperty ID="ProjectProperty1" Property="Title" runat="server" />


Here is my “main content” element:

<!-- MAIN TEXT -->
<div id="main">
    <asp:ContentPlaceHolder id="PlaceHolderMain" runat="server" />


I have also added the simple “search” element:

<div id="sn1" class="sidenote">
    <div id="sn1header" class="sidenoteheader">
        Quick Search
    <div id="sn1text" class="sidenotetext">
        <asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server">
          <SharePoint:DelegateControl ID="DelegateControl5" runat="server" ControlId="SmallSearchInputBox" />


After updating the CSS file (with styles from my web server) I saw the following visual:



I think it is pretty good when you consider that it was a simple modification of the master page. (Ok, it is not as simple as I am trying to say here but it is not a rocket science.)


Applying the new master page

In the previous section I skipped the part of applying the new master page to the site. You have multiple options for that. The easiest is probably to use SharePoint Designer for that – see Apply the new master page. Another option is to do that programmatically. To do so use the following code:


public void ApplyCustomBrand() 
    SPWeb site = SPContext.Current.Web;

    string MasterUrlPath = site.ServerRelativeUrl;
    if (!MasterUrlPath.EndsWith(@"/"))
        MasterUrlPath += @"/";
    MasterUrlPath += @"_catalogs/masterpage/Pokluda.master";
    ApplyCustomBrandToWebs(MasterUrlPath, site);


public void ApplyCustomBrandToWebs(string MasterUrlPath, SPWeb site) 
    site.MasterUrl = MasterUrlPath;
    site.AlternateCssUrl = "/_layouts/1033/STYLES/Pokluda/PokludaWebStyle.css";
    site.SiteLogoUrl = "";

    foreach (SPWeb child in site.Webs) 
        ApplyCustomBrandToWebs(MasterUrlPath, child);


The above mentioned code is based on CustomBranding project from Chapter 3 of Inside Microsoft Windows SharePoint Services 3.0 book from Ted Pattison and Daniel Larson.

More information:


Pulse virtual machines programmatically

8. April 2009

I use Hyper-V frequently for testing purposes. Virtualization has a lot of advantages. There is one thing (ok, there is more but let’s concentrate on a particular one today) that bothers me. All my machines joined our company Active Directory. The problem is that if a machine doesn’t run for a certain time (I guess something like 2 weeks) the machine account will be removed from Active Directory. It’s not a huge deal, you just have to:

  • login as administrator
  • remove your computer from the domain
  • restart
  • join the domain again
  • restart

Even thought it’s not such a big deal it annoys me every time I need to do that. I thought that if I would be able to automatically start each machine (let’s say at night when I’m not using the computer) it would solve this problem. Since I use PowerShell I wanted to be able to leverage PowerShell for this.

Retrieve all available VMs

To retrieve all available VMs we need to execute a WMI query. The trick with this query is that it will retrieve all machines including your host machine. That’s why you need to add additional filter where you ask to retrieve only machines which caption starts with “Virtual”.


function get-vms
    $query = "SELECT * FROM MsVM_ComputerSystem WHERE Caption Like 'Virtual%' "
    get-wmiobject -query $query -namespace "root\virtualization" -computername "." 


Retrieve a particular VM

Once we have a collection of all available VMs, we will execute some actions on them. As a helper I will also create a function that will retrieve VM object when provided a machine name:


function get-vm([string] $name)
    #Get the VM Object
    $query = "SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" + $name + "'"
    get-wmiobject -query $query -namespace "root\virtualization" -computername "."


Starting VM

To start a VM, we just need to set RequestStateChange to value 2. The code to do so is very simple.


function start-vm([string] $name)
    $VM = get-vm $name
    #Request a state change on the VM
    $result = $VM.RequestStateChange(2)


Shutting down VM

To shutdown a VM, we need to get a special ShutdownComponent and call InitiateShutdown method. The code might seem complex but it isn’t. Most of the code bellow is just error handling code.


function shutdown-vm([string] $name)
    #Get the Shutdown Component for the VM
    $vm = get-vm $name
    $query = "SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='" + $ + "'"
    $Shutdown = get-wmiobject -query $query -namespace "root\virtualization" -computername "." 
    if ($Shutdown -ne $null)
        #Request a forced shutdown
        $result = $Shutdown.InitiateShutdown($true,"Shutdown initiated from PowerShell script")
        if ($result.returnValue -eq 0) 
            write-host "Shutdown of '$name' started."
            write-host "Attempt to shutdown 'name' failed with code $($result.returnValue)."
        write-host "Could not get shutdown component for '$name'."


Final script

To put it all together we need to retrieve all VMs and call start and shutdown in a loop for each of the retrieved VMs.


$VMs = get-vms
foreach ($VM in $VMs)
    $name = $VM.ElementName
    write-host $name
    write-host "`tStarting...."
    start-vm $name
    write-host "`tWaiting to fully load for 7 minutes..."
    start-sleep -seconds 420
    write-host "`tShutdown..."
    shutdown-vm $name

write-host "Finished."


Let me note that in the previous script I added a sleep for 7 minutes. Why do I do that? I want to give the VM enough time to completely start all the services.



Let me add that I found that shutdown can also be done using “associators”. In the above code we use the following query:

    $vm = get-vm $name
    $query = "SELECT * FROM Msvm_ShutdownComponent WHERE SystemName='" + $ + "'"
    $Shutdown = get-wmiobject -query $query -namespace "root\virtualization" -computername "." 

The same can be done using “associators”.


    $vm = get-vm $name
    $query = "Associators of {$vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_ShutdownComponent"
    $Shutdown = get-wmiobject -query $query -namespace "root\virtualization" -computername "." 

I don’t know which one is better but both of them seems to work just fine on my machine. If you do know the difference then please let me know.


More information

More information can be found at:




Windows Live Writer Source Code plug-in

2. April 2009

I use Windows Live Writer for authoring my blog posts. It is very user friendly application that allows you to forget about the ugly web interface your blog engine has for authoring posts. As a developer I wanted to be able to paste source code samples into my posts and be able to format them accordingly. Fortunately Alex Gorbatchev wrote a simple JavaScript application that will format source code according to parameters in the PRE element in which the code is placed. All we need to do is:

  • add support for Alex Gorbatchev’s SyntaxHighlighter to your blog (server)
  • teach Windows Live Writer to enter the right parameters whenever you insert a source code snippet in one of your posts

There are solutions for all of these but none of them suited my needs (I will try to cover the reasons for that later). Rather than complain I thought I would try to solve my problems.

Source Code Plug-in on CodePlex

I have created SourceCodePlugin project on CodePlex to include my solution to the above mentioned needs. The project has two parts: SyntaxHighligher for BlogEngine.NET and SourceCode plug-in for Windows Live Writer.

SyntaxHighligter for BlogEngine.NET

This part of the project allows you to integrate an updated SyntaxHighlighter with the BlogEngine.NET system. The highlighter is based on Alex Gorbatchev's code with a couple of updates:


Product: SyntaxHighlighter 
Author: Alex Gorbatchev 
Version: 2.0.296 


Updates from Alex's code:

  • added PowerShell script
  • added FSharp script


Why did I have to code it myself? I had to update SyntaxHighlighter to add support for PowerShell and F# because I am used them frequently. Support for other my languages is already part of the product (C#, C++, SQL, XML, JavaScript, etc.). I found an integration into BlogEngine.NET but the extension was not compatible with the latest release of SyntaxHighlighter.

I have decided to update SyntaxHightlighter scripts library and create a new extension component for BlogEngine.NET compatible with the latest release of SyntaxHighlighter.



Sample F# code (this is a snippet from Tutorial.fs):

// Types: records
// ---------------------------------------------------------------

type Card = { Name  : string;
              Phone : string;
              Ok    : bool }
let cardA = { Name = "Alf" ; Phone = "(206) 555-8257" ; Ok = false }
let cardB = { cardA with Phone = "(206) 555-4112"; Ok = true }
let ShowCard c = 
  c.Name + " Phone: " + c.Phone + (if not c.Ok then " (unchecked)" else "")


Sample PowerShell code (this is a function I use for my nightly job):

#This method starts Windows service. It doesn't throw in case of an error.
function Start-ServiceNotThrowing($service, [bool]$displayWarning = $true)
    start-service $service -ErrorVariable errs 2&gt;$null
    if (($errs -ne $null) -and ($displayWarning))
        set-color "yellow"
        write-host "Warning: Service $service is not installed."

SourceCode plug-in for Windows Live Writer

This part of the project adds a SourceCode plug-in into Windows Live Writer to enable inserting code into your blog posts in a form compatible with SyntaxHighlighter.

To insert a code, click on Source code... item in Insert section (right side of the Windows Live Writer). The plug-in will use the currently selected text or (when configured accordingly) take the text from the clipboard.



You can tweak the behavior of the plug-in by clicking Options button to update plug-in options. All values that you enter in this options dialog will be saved for future use (you don’t have to enter the same configuration over and over again).





Why did I have to code it myself? I found several plug-ins for SyntaxHighlighter. One of them was not able to keep option values between invocations that led to a situation where you had to update your options every time you wanted to touch your source code. Another one saved the options but when I was editing source code that was already inserted into a post, the plug-in wouldn’t display the currently selected text. Instead I had to select the text, press Ctrl+C, open the plug-in and press Ctrl+V.

I have decided I will create a simple plug-in that behave the way I expected.


As I mentioned above the whole project is now available at CodePlex: Feel free to check it out and if you find a problem, let me know or take the source code and fix it yourself.

Blog , , ,