–I referred to the PowerShell Community extensions in the last post. It's interesting, but not especially surprising to find that

  • The Community can do some pretty cool stuff.
  • A Community effort can encompass a lot of things, at the price of lacking clear direction
  • Writing code is give a higher priority than writing documentation.

Lets start with the first of these. There's certainly some cool stuff in the Community extensions. Its a mixture of Scripts, Filters and Functions (which you can look at to get your own ideas) and compiled cmdlets, plus three new providers. It deals with Active Directory, handling files and the file system (everything from Calculating a Hash to Modifying the disk volume label), basic Bitmap handling, Clipboard handling, XML processing, Terminal services management an RSS provider, a speech generator and a lot general stuff to help you get around, including querying information about DLLs and a new tab-expansion function.

The problem is that this can give the impression of  "a very unevenly-edited [work which] contains many [things] which simply seemed to its editors like a good idea at the time."* Of course the question comes up "would you like to be the editor and have to tell people their code can't go in until their documentation is up to scratch." ? I wouldn't. How about "if it should be segmented would you like to be the one deciding what is spun off and what stays in the main part". Probably not. The profile script that comes with the extensions gives you the chance to see what's being loaded apart from the basic snap-in and leave out any bits out that don't appeal to you.

The discussion area on codeplex for the Extensions is has a handful of active threads which suggests that work is going on, but some aspects haven't been touched for a long time. For example everyone seems to expect to be able to pass an object to Get-Member to find  out what its Properties and Methods are; but this doesn't work with Posts returned by RSS provider.  It was suggested that this be corrected some while back but to date nothing has happened (you need to know the properties for the IFEED object). It was also suggested that some documentation be written for the feed provider and (in common with other places) this has not happened.

I don't know who is going to need, for example, speech output and AD support at the same time. Still, I have already found some of the bits pretty useful. Take this bit of code, for example, which I used to create a post at the end of last week.

dir E:\DCIM\102PENTX\Develops\*small* | ForEach-Object -Begin {[String]$myHtml=""} 
  -Process {$myHtml += '<p><img src="' + (upload-blogfile $_.fullname) + '" /></p><p><b>' +  (get-image $_.fullname).title + '</b></p>'} 
-end {New-BlogPost -body $myHtml -Title "Testing Pictures"}

It gets all the pictures named SMALL in a given folder, uploads them to my blog and builds the body of a blog post as it does so; at the end of the process it uploads the post . 

Now the MetaWebLogAPI - which I've already written about needs the picture to be encoded in BASE64 format and the community extensions has ConvertTo-Base64. So the code for Upload-BlogFile is

function upload-Blogfile
  {param($filename, [string] $postUrl=$postUrl, [string] $blogid=$blogID,
[string] $username=$username, [string] $password=$password) #Requires -pssnapin PSCX $base64=convertto-base64 $fileName $ContentType=(get-itemproperty "hklm:\SOFTWARE\Classes\$($filename.substring($filename.lastIndexof('.')))" "content type")."content type" $postTemplate = "<methodCall><methodName>metaWeblog.newMediaObject</methodName><params> 
       <param><value>$blogid</value></param>        <param><value>$username</value></param>        <param><value>$password</value></param>        <param><value><struct> 
write-progress "Uploading to blog" "Sending" -cu $filename
 ([xml]((new-object System.Net.WebClient).UploadString($postURL , $postTemplate) )).methodresponse.params.param.value.struct.member.value.string


This breaks down as
Do the transformation to base 64,
get the MIME type for that kind of file.  
Build the XML to upload.
Put up a progress screen as the upload can be slow
Perform the upload and extract the URL assigned to the image from the XML returned.

So that command line was building up HTML which repeated the following for each image <P><IMG SRC="url"/></P><P><b>Image title</b></P>

Get-Image in that code is a filter for "new-object" using my Exif library to get the title. As I said at the time I like this of for loop - the begin and end blocks let you do stuff outside the actual loop but keeping it to one command, so the -begin {block} sets up an empty string, and the -end {block} posts the completed string to my blog. 

You may be wondering how I got pictures which contained the word "SMALL"  That was using 3 more cmdlets from the extensions

dir "E:\DCIM\102PENTX\Develops\*1*" | ForEach Object {Import-Bitmap -Path $_.fullname | resize-bitmap -percent 20 | 
  export-bitMap -path ($_.fullname.replace("IMGP","SMALL")) -Format JPEG -Quality 70}

Import-BitMap, and resize-bitmap are pretty self explanatory. Export-Bitmap will change the format, and JPEG quality, since these pictures are being resized for the web I'm dropping the size from 3900x2600/4MB to 780x520/32KB 

Playing with the -Output option on PowerGadgets I realized I can do Import-bitmap temp.bmp | set-clipboard to make it easy to paste a chart straight into another application.

Despite the poor documentation I think most people who use PowerShell will find something useful in the community extensions. They are so diverse that everyone will find different bits useful. But if you haven't found which bits are useful to you go and download them from Codeplex and have a look.


*Foot note: Last week I got a copy of Bruce Payette's book "PowerShell in Action" which seems to be accepted as the standard repository of all knowledge and wisdom when it comes to PowerShell,  I was delighted to find chapter one starts with a quote from the Hitch Hikers guide to the Galaxy. Bruce is a guy who clearly knows where his towel is