Creating local users – en mass

The traditional way of creating a vast amount of users would include a lot of time as well as patience. Or – maybe just a few lines of (magic) PowerShell code.

So first of all, we have to connect to the local ADSI. This can be done via WinNT://[ComputerName]:

$ComputerName = $env:COMPUTERNAME
$Computer = [adsi]"WinNT://$ComputerName"

This is already the most crucial part. Next we create a new user, set the username, fullname and description and the password.

function Add-User([string]$UserName, [string]$FullName, [string]$Description, [string]$Password)
{
    $User = $Computer.Create("user", $UserName)
    $User.Put("fullName", $FullName)
    $User.Put("description", $Description)
    $User.SetPassword($Password)
    $User.SetInfo()
}

The SetInfo() call ensures, that the data is actually persisted.

Voila, that’s already all you need to get going. Well, in order to create a massive amount of users you will want to create a csv-file of users like:

UserName,FullName,Description,Password
usera,User A,Desc A,passworda
userb,User B,Desc B,passwordb

This can be read with just a single line of code.

function Import-Users([string]$UserFile)
{
    Import-Csv $UserFile | foreach-object { Add-User $_.UserName $_.FullName $_.Description $_.Password }
}

So now all you need is to call Import-Users myNewUsers.csv from the PowerShell command-line and off you go!

Which version of SharePoint?

Update 29.04.2010: I added the latest CUs for February and April 2001. The download for the April CU doesn’t seem to be available yet, so I cannot provide any version numbers.

There are currently a lot of updates available for SharePoint (Services as well as Portal Server), like SP1, Infrastructure Rollup, SP2 and various cumulative updates. That makes it hard to keep up to date with the latest patch-level. This little table should give some overview:

Update Name owssvr.dll Microsoft.SharePoint.portal.dll
RTM 12.0.4518.1016 12.0.4518.1016
October public update (2007) 12.0.6039.5000 12.0.6036.5000
Service Pack 1 12.0.6219.1000 12.0.6219.1000
Post-Service Pack 1 rollup 12.0.6300.5000 12.0.6300.5000
Infrastructure Update (IU) 12.0.6320.5000 12.0.6320.5000
August Cumulative Update (2008) 12.0.6327.5000 12.0.6327.5000
October Cumulative Update (2008) 12.0.6331.5000 12.0.6331.5000
December Cumulative Update (2008) 12.0.6335.5000 12.0.6335.5000
February Cumulative Update (2009) 12.0.6341.5000 12.0.6341.5002
Service Pack 2 12.0.6421.1000 12.0.6420.1000
April Cumulative Update (2009) 12.0.6504.5000 12.0.6504.5000
June Cumulative Update (2009) 12.0.6510.5001 12.0.6507.5000
August Cumulative Update (2009) 12.0.6514.5000 12.0.6514.5002
October Cumulative Update (2009) 12.0.6520.5000 12.0.6520.5000
February Cumulative Update (2010) (WSS, MOSS) 12.0.6529.5000 12.0.6529.5000
April Cumulative Update (2010) (WSS, MOSS)    

To verify the version of SharePoint you’re running go to %CommonFiles%\Microsoft Shared\Web Server Extensions\12\ISAPI and look at the file-versions of owssvrdll and/or Microsoft.SharePoint.portal.dll.

To get detailed information about hwo to deploy updates for SharePoint, check the TechNet sites on Deploy software updates for Windows SharePoint Services 3.0 and Deploy software updates for Office SharePoint Server 2007.

Live writing with unsafe certificates

Once in a while you might not have a 100% safe certificate, and you don’t want to go through the hassle of getting a 100% certificate just for testing purpose.

So I wanted to test my new blog, but I already had everything setup to connect via SSL only. This unfortunatly screwed Windows Live Writer, because I couldn’t connect.

Until I figured, that you can supply commandline parameters to WindowsLiveWriter.exe, such as /allowunsafecertificates … so hello live writing!

A new era

After about 5 years I had the urge to move on – concerning my current blog. All these years Zope/Plone served me very well, but I just couldn’t really keep up with maintaining Plone and paying the attention it deserved. Also update to newer versions started to be a pain, and I just could afford the time to get new features in place.

OK – so this was the starting point to look for a new home; and here we are now. WordPress offered a lot of what I wanted from a blog-system, so I though – hell, give it a try.

The Migration

The worst thing about moving to WordPress was getting all of my existing content over. So I had to get about 170 blog posts and several other posts out of the Zope-Database and into WordPress. Fortunately I found a very good posts about how to move from Plone to WordPress. Basically I followed the steps outlined there.

To get my blog-posts, which are based on CoreBlog2, I had to modify the page-template a little, to find the right items in my plone catalog.

The next step was to convert the xml to an Moveable-Type format. Apposed to Len I didn’t do anything to convert my URL – at least not at this point. So the moveable-type format was now ready to be imported. Since CoreBlog allowed for posts to be grouped into categories as well as to have keywords assign, I decided to map the categories (contained in the element tag2) to PrimaryCategories and to map the keywords from Plone to Moveable Type keywords.

<xsl:text>&#xa;-----&#xa;KEYWORDS:&#xa;</xsl:text>
<xsl:for-each select="keyword">
<xsl:value-of select="." />,
</xsl:for-each>

So now I had my posts imported into WordPress. The last step was to make sure that at least some URLs would still work. Unfortunately I missed to get the names of the posts just as they where before – but I couldn’t find any Moveable Type property to specify the name of a post. So I doubt that this is actually possible – at least not with Moveable Types. And this was the way I had chosen, so I was stuck with “wrong” post-names.

But fortunately the post-dates where correct and unique. So created a little XSLT to generate update-statements for the WordPress database.

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8" omit-xml-declaration="no" indent="yes" />
    <xsl:template match="/">
        <xsl:for-each select="//post">
update wp_posts set post_name='<xsl:value-of select="textFix" />' where post_date='<xsl:value-of select="creationDate" />';
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

So that took care of that.

I’m actually surprised how smooth this went – let’s see if nothing is missing.