Saturday, June 19, 2010

Danish User Group CoLabora startup meeting

Hi everyone,

Fellow MVP and Exchange MCM Peter Schmidt and I have recently founded a Danish User Group focusing on UC (OCS/CS and Exchange) called CoLabora. It is run on a non-profit basis and the goal is to establish a Danish independent forum for professionals working with Microsoft Unified Communications.

We are now announcing our first User Group meeting for CoLabora, which is taking place on June 29th from 14.00 – 17.00 (followed by a Sandwich / networking) and the agenda will be focusing on Communications Server ‘14’' and the news in Exchange Server 2010 SP1 (Seen from a Danish/Nordic perspective).

For more information (In Danish) and registration go to http://www.colabora.dk/.

We hope to see some of our Danish readers at the event !

Vitamins, Painkillers and Viagra (this is not spam)

Dick Hardt has written a interesting, reflective article. Is your product or our consulting service a vitamin, a painkiller or viagra? Read the definitions in http://dickhardt.org/2010/01/vitamins-painkillers-and-viagra/

Monday, June 14, 2010

Get-Line and Got-NewJob

Hi. It has been a while as I have been busy with my new job. I’m now working LEGO as Senior Solution Architect for www.lego.com. Visit a great web site and any feedback is welcome.

Consequently, I’m not using PowerShell as much as I used – to at least not for so complicated solution. On the other hand I’m using it almost daily as is it so useful for test web related things.

But my new colleagues know that I know PowerShell so today Michael asked about how to get a few lines from a text file. This is easy, but if it was easy, Michael would have figured it out himself. The problem is that the file is huge (E.G. 1.5GB), so using Get-Content with Select-Object or similar would be very memory intensive and thus slow. I said that I would either call .Net directly or embed some C# code in a script.

Well, now it is evening and I’m watching the Italian-Paraguay match and – hey – why not do a little blogging while and again!

As thought, so done. Here’s my solution. It took as little more than an hour including help and validation. For newcomers, use Get-Line –? for displaying the help nicely formatted.

The script -

<#
.Synopsis
Get line or lines from a text file
.Description
Get one of more lines from the specified file. Line numbers are positive and the first line is number 1.
.Inputs
Path
.Outputs
Array of strings
.Example
Get-Line $env:temp\lines.txt 23,897,45
Get lines 23, 45 and 897. Lines are returned in increasing order. E.g. line 23 is returned first, then line 45 and finally, line 897

#>
param(
[parameter(Mandatory=$true)]
[alias("file")]
[alias("fullname")]
[alias("name")]
[string]
[ValidateScript({Test-Path $_})]
# The path of the file to get the lines from
$path,
[Parameter(Mandatory=$true)]
[alias("numbers")]
[int64[]]
[ValidateScript({$_ -gt 0})]
# One or more line numbers (e.g. first line is 1) to retrieve from the file
$lines
)

add-type -TypeDefinition @'
using System;
using System.Collections.Generic;
using System.IO;

namespace Per
{
public class FileFunctions
{
public List<string> GetLines(string file, System.Collections.Generic.Queue<long> lines)
{
FileStream fs;
StreamReader sr;
List<string> linesFound = new List<string>();
using (fs = new System.IO.FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 10 * 1024 * 1024))
{
using (sr = new System.IO.StreamReader(fs))
{
int lineCounter = 0;
int linesIndex = 0;
if (lines.Count == 0)
{
return new List<string>();
}
long findLine = lines.Dequeue();
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
lineCounter++;
if (lineCounter == findLine)
{
linesFound.Add(line);
linesIndex++;
if (lines.Count == 0)
{
break;
}
findLine = lines.Dequeue();

}

}
}
sr.Close();
}
fs.Close();

return linesFound;
}
}
}

'
@
$c=new-object Per.FileFunctions
[int64[]]$sortedLines=$lines | sort -unique | where {$_ -gt 0}
$c.GetLines((Resolve-Path $path),$sortedLines)





As always: Have fun!