Friday, February 23, 2007

Another perfect score in the Scripting Games!

I'm jumping the gun...  I am predicting another 100/perfect score in the 2007 Scripting Games.

I think event #10 turned out to be the most challenging, and fun!

My score for event #8 hasn't been marked online yet, but I checked my submission, and they match the event solution.

For what it is worth, I really did get all the correct answers for the 20 questions in event 8...

I enjoyed the minor struggles I had with PowerShell, and am really glad I went with PowerShell and the advanced category.

For next year (hopefully they'll have this again), I'm going to suggest a "developer category" with even harder challenges!

Tuesday, February 20, 2007

Example of grouping common RSS feeds together using /n software products

I visit the PowerGadgets forums quite a bit to see what's going on, and ask questions (as "fedrac").  I had recently asked PowerGadgets to enable RSS feeds to the forum, and seeing as they are using Community Server, this apparently was pretty easy to do.

One thing annoyed me slightly: there are 2 kinds of feeds:

1. There are feeds to each discussion forum.  This feed only presents the new *threads* in the forum.

2. There are feeds to each thread.  This feed only presents the new *posts* to the thread.

So signing up to a forum is easy, but if you're interested in seeing *all* of the activity, you also need to sign up to each thread.  That's a lot of work, and needed a PowerShell solution!

I had a vision of my end goal, but wanted to try a solution just using PowerShell, PSCX's feedstoreprovider, and IE7's RSS features.  I spent way too much time on that though.

Then, I decided to go straight for what I was envisioning...  Using /n software's RSSBus (free desktop version!) to find a way to *combine* all the PowerGadgets feeds for forums and threads in one single RSS feed.

So, to accomplish this, first I wrote a PowerShell script using /n software's NetCmdlets (free desktop version!) and their get-rss cmdlet.  This script goes and grabs the forums' feeds, and from that gets all the threads within each feed.  It creates a dynamic RSBScript (scripting language for RSSBus), that then is copied to RSSBus' working directory.

Here's my PowerShell script:

$ErrorActionPreference="silentlycontinue"

$feed_script="C:\rssbus\www\powergadgets.rsb"

if(test-path $feed_script){
  remove-item $feed_script
}

$j=1

$rss_feeds=@("http://powergadgets.com/csPg/forums/rss.aspx?ForumID=4&Mode=0",
"http://powergadgets.com/csPg/forums/rss.aspx?ForumID=5&Mode=0",
"http://powergadgets.com/csPg/forums/rss.aspx?ForumID=6&Mode=0",
"http://powergadgets.com/csPg/forums/rss.aspx?ForumID=14&Mode=0")

$rss_url="http://powergadgets.com/csPg/forums/rss.aspx?ForumID="

$threads=@()

for($i=0;$i -lt $rss_feeds.count;$i++){
  $threads+=(get-rss $rss_feeds[$i]|%{$forum=$rss_feeds[$i].split('/.=&')[8];$thread=$_.link.split('/.')[7];${rss_url}+${forum}+"&PostID="+${thread}})
}

$rss_feeds+=$threads

$rss_feeds+="http://powergadgets.com/csPg/blogs/MainFeed.aspx"

$rss_feeds|?{$_ -notmatch "^$"}|%{add-content $feed_script "<rsb:set item=`"input`" attr=`"feed#$j`" value=`"$_`" />"$j++}
add-content $feed_script "<rsb:call op=`"rsbFeedUnion`" in=`"input`">"
add-content $feed_script "<rsb:push />"
add-content $feed_script "</rsb:call>"

$ErrorActionPreference="continue"

[end PowerShell script]

I cheat a little bit by setting the error preferences.  Seems there's some extra spaces and strage things going on that cause some errors to the screen.

Now, one can easily call the RSBScript I created, and register it as an RSS feed in their favorite RSS feed viewer.

It's as easy as using this as the RSS feed address when you have RSSBus installed:

http://localhost:1110/powergadgets.rsb

The above RSBScript still needs a little bit of fine tuning to get the name of the feed to something more meaningful, but the guts of the requirements are there.

(I really have to figure out how to properly format code in blogspot...)

Monday, February 19, 2007

1,000 hits!

I've just surpassed 1,000 hits over the weekend.  Hopefully, I've been able to provide some useful/interesting information to any PowerShellers out there.

Keeping track of my 2007 Scripting Games score

As I mentioned a few times before, I'm participating in the 2007 Microsoft Scripting Games.  I've submitted all my 10 answers, and am just waiting for them to be scored.

To keep track of my scores "in the background", I've decided to use a combination of the out-gauge cmdlet from PowerGadgets, and the new write-speech cmdlet from Sapien PrimalToys.

So, I have a graphical display, and a voice telling me every 15 minutes what my score is.

Here's the graphical display:

Here's the script borrowed heavily from a posting by /\/\o\/\/ in the PowerShell newsgroups:

[string]$url="http://www.microsoft.com/technet/scriptcenter/funzone/games/games07/psascores.mspx"
$wc = new-Object System.Net.WebClient
$nl = $wc.DownloadString("$url")
$r = [regex]'l">(.*?)</p'
$m = $r.Matches($nl)
$l = $m |% {$_.groups[1].value}
$list = @()
foreach ($i in 13..($l.count -1) ) {
$Record = new-Object -typename System.Object
$Record | add-Member -memberType noteProperty -name Name -Value $m[$i].groups[1].value
[void] $foreach.MoveNext()
$Record | add-Member -memberType noteProperty -name Country -Value $m[$foreach.current].groups[1].value
1..10 |% {[void] $foreach.MoveNext();$Record | add-Member -memberType noteProperty -name "E$_" -Value $m[$foreach.current].groups[1].value}
[void] $foreach.MoveNext();$Record | add-Member -memberType noteProperty -name "Total" -Value $m[$foreach.current].groups[1].value
$list += $record
}
$score=$($list | ?{$_.name -eq "Marco Shaw"} | %{$_.Total})
write-speech "Games score is $score"
$score

[end script]

Here's how I call it:

[C:\powershell]
21> games.ps1|out-gauge -refresh 00:15:00

I'm using a cool refresh feature of the PowerGadget cmdlet that will automatically call the PowerShell script every 15 minutes to cause it to run again.

Friday, February 16, 2007

Sapien Technologies: PrimalToys for PowerShell

The super guys over at Sapien have released some additional cmdlets for PowerShell:

Read-MsgBox
Read-InputBox
Ping-Computer
Get-SqlDataReader
Get-OleDbDataReader
Invoke-SqlQuery
Invoke-OleDbQuery
Test-NetConnection
Get-UserName
Get-UserDomain
Get-ComputerName
Test-LocalGroupMembership
Get-LocalTime
Get-GMTTime
Get-OSName
Get-OSPlatform
Get-OSVersion
Get-TotalPhysicalMemory
Get-TotalVirtualMemory
Get-AvailablePhysicalMemory
Get-AvailableVirtualMemory
Get-PrimalToysVersion
Write-Speech

I was thinking about how a cmdlet or function to read a DB would be cool...  Well there it is!

Sorry, for not having posted anything lately.  I've been busy with the Microsoft 2007 Scripting Games.  I've just submitted my scripts for all 10 events.  Let's hope for another perfect score this year!

Friday, February 2, 2007

PSCX: Playing with IE7 RSS features

One you have PSCX installed, you have access to all of the RSS features within IE via the "feedstoreprovider".  For example, here's a quick copy and paste from my current session:

[C:\powershell]
76> cd feed:
[Feed:\powershell]
77> ls

Type Name
---- ----
folder PowerGadgets
feed $cript Fanatics

[end]

I've cutoff most of the output to properly add it here.

I like to visually see what goodies are out there to read, so with the help of mabster who developed the feature, I've taken his script and made some slight edits.

all_feeds.ps1:

$ErrorActionPreference="silentlycontinue"

gci feed:\ -rec |
? {$_.Type -eq "Feed"} |
% {
$_.Download();
  if($_.LastDownloadError -eq 0){
    if($_.UnreadItemCount -gt 0){
      write-host -foregroundcolor green -noNewLine $_.Name;
      write-host -foregroundcolor green ("`t(" + $_.UnreadItemCount + ")")
    }
  }
  else {
    write-host -foregroundcolor red -noNewLine $_.Name;
    write-host -foregroundcolor red ("`t(" + "Download failed" + ")")
  }
}

$ErrorActionPreference="continue"

[end of all_feeds.ps1]

My example output is all kind of Christmas-y, but I haven't played with Windows Live Writer enough to get the colors right here for now:

[C:\powershell]
81> .\all_feeds.ps1
You Had Me At EHLO... (1)
Bob Beauchemin's Blog (Download failed)
Slashdot (2)
Precision Computing (Download failed)
[C:\powershell]
82>

So, I get the number of unread items, and a nicer error if the download of the RSS feed fails (I could put the actual code, but an error simply identified as "1" means nothing to me).  Previously to setting $ErrorActionPreference, the error on the screen was annoying.

PowerShell Community Extensions (PSCX)

PSCX is a CodePlex project aiming at delivering high-quality community written add-ons to PowerShell.  At release 1.0 now, it provides lots of useful PSH cmdlets, and the list is growing.

Everyone should have it installed, even beginners.  One thing it does that saved me a few times, is to automatically setup a transcript (or log) of all of your sessions to a log file that you can refer back to later.