Category Archives: Other

Hijacking a meme for the sole glorification of PowerShell

Yesterday I saw this post on James Bennet’s blog -basically, people are posting the top 10 or so commands from their shell history. Now, using Windows on the desktop myself, I have nothing much to contribute there (I do manage a couple debian servers, but the data is probably too distributed to be useful in this context).

However, I recently decided that I would renew my interest in PowerShell (I was in the beta program early on – the pillars of Longhorn timeframe – but never did much with it). And porting this seemed like a nice opportunity to get started.

First of all, it might be worth noting that PowerShell, at least the default host, only provides a session-based history feature – close and it’s gone. Apparently it is easily possible to add persistence yourself, using a combination of the add-history cmdlet, a startup script, and aliasing exit, but I haven’t tried that (yet).

I know the suspense must be killing you, so here’s what I came up with:

PS> history | group commandline | sort count -desc | select -f 10

Or the more verbose version:

PS> get-history | group-object -property commandline | sort -property count -descending | select -first 10

That was actually pretty simple, and should be quite easy to read. Compare it to the original:

$ history | awk '{print $2}' | sort | uniq -c | sort -rn | head

Now, I like the object-based approach a lot, but you have to admit: The *nix version isn’t half bad, considering it’s text-based.

Let’s take it one step further. PowerShell conveniently stores the start and end timestamps for each history item, so instead of by count, wouldn’t it be cool to sort the list by total runtime? Unfortunately, this is considerably more difficult. The following took me about an hour (but note that I am basically new to PowerShell, and needed to figure out a lot about commands, syntax etc. along the way):

PS> history | select commandline,@{name="duration";expression={($_.endExecutionTime - $_.startExecutionTime).totalMilliseconds}} | group commandline | foreach { $_ | add-member NoteProperty Time (($_.group | measure-object -p duration -sum).sum/1000); $_ } | sort time --desc | select name,time -f 10

It’s a bit long, but – in retrospect, considering the time I spent creating it – should be moderately simple to follow as well: Calculate the runtime duration for each item, then group by the commandline string. For each group (of instances of the same command) sum up the total duration. Finally sort, and return the top 10.

There might very well be a better way. Particularly, I had trouble with the following:

  • After calculating the sum execution time for a group with measure-item, I wasn’t sure how to continue so that the next step in the pipeline has access to both the measurement result and the commandline string. I tried a hash, but failed to get sort working with it. I suppose one could use new-object, but I wasn’t keen on bothering with it’s syntax and long .NET dotted namespace hierarchies.

    As you can see, the version above simply adds the measure-item output to each group object itself, using add-member (which by itself doesn’t seem to output/return anything btw, which is why the foreach block ends with a single $_). Stuff like add-member feels slightly strange to me anyway – why is it even necessary? Why not allow adding new properties on the fly? It kind of feels like Powershell has to work around .NETs static nature. I wonder if the DLR might change some of this.

  • I’m also not sure as to how you would use measure-object to sum up timespan objects, which is why the above disposes of them early on and continues to work with milliseconds.

Openfire, MD5-Digest, Psi, Pidgin

I’m running my own personal Jabber server, using Openfire, which I recently switched to a setup using SRV records. So while the JID-Domain would be @foo.com, the server is actually running on jabber.foo.com (I also used that opportunity to upgrade to the latest version of Openfire, 3.5.1).

Connecting with Psi, which I use myself, works fine. Unfortunately, it soon turns out that Pidgin (which, as luck has it, one of my users insists on) isn’t quite has happy with the new status quo and fails on login with “Not Authorized”. Some googling suggests setting xmpp.fqdn in Openfire to the actual server host name, jabber.foo.com). And indeed, that looked like the solution – but not for long, because now Psi tells me “Not Authorized”. Comical, in a way.

So here’s what appears to be happening:

  • Openfire offers DIGEST-MD5 auth, which both Pidgin and Psi pick up.
  • Decoding the challenge response from both clients reveals:
    • Pidgin sets the digest-uri field to xmpp/jabber.foo.com (i.e. it uses the hostname resolved via the SRV records)
    • Psi sets digest-uri to xmpp/foo.com (i.e. it uses the JID domain)
  • Openfire expects xmpp.fqdn (jabber.foo.com) if set, or xmpp.domain (foo.com) otherwise. If there is a mismatch, it sends non-authorized.

Apparently neither shall work while the other … – or something like that. Note that I also tried meebo and Spark, both of which work with either configuration.

Now there are tickets about this in the Pidgin tracker (5008, 5149, 5161, all closed as invalid), and a thread in the Openfire forums (with no resolution). I wasn’t able to find much on the Psi side, shy of possibly a few mentions in older IRC logs. Nothing conclusive.

I am a bit confused that there appears to be no solution, since this shouldn’t be such and exotic situation I have here. For now, I configured Openfire to only allow PLAIN auth (over SSL though), which you can do by inserting this in your ./conf/openfire.xml:

<sasl><mechs>PLAIN</mechs></sasl>

Note that the tag is named <mechs>, not <mechanisms>. The latter seems to be suggested at times in the forums, but won’t work (not for me anyway).