In my last post I wrote about how you could make a WPF Splash screen window in PowerShell, but I stated that: “if the images are remote, the WPF window has to download them, and therefore won’t work” correctly. I had played with downloading images directly by setting the Source attribute of the image to the image URL, and hadn’t been able to find a way to get the threading to work well enough to actually download the image.
Well, I figured that out, so I thought I’d go ahead and share … basically, all you have to do is call Invoke() on the window’s dispatcher. The reason that works is that WPF handles events and “work” in general in the order it needs to be done, so since the most important thing is drawing the UI it will do that first, and since your UI is based on downloading the image, it will take care of that first.
All of this code is written to target the CTP2 release of PowerShell v2 — it will not work in PowerShell v1 or even in v2 CTP1 … and it may not work in later releases, although I expect it will. Also, as with any code which uses WPF from PowerShell, these code examples require you to launch PowerShell with the -STA option.
That’s almost as simple as it could get, but let me explain a few things which I left out previously, in case you’re new to XAML or even WPF. The Window tag is one of several acceptable root tags in XAML, but it’s the only one which will let you POP (Short for POP3 (Post Office Protocol 3 - for email), the Post Office Protocol) up a new window (in PoshConsole, you can display XAML inline using Out-WPF, and you can use almost any XAML nodes, but for now, lets focus on what works in general in the CTP2 console). The xmlns attribute is required in order for the xml to be verifiable to the schema, but in XAML it’s particularly important because without it, this would just be XML —not Xaml— and wouldn’t produce UI.
There’s several fun tricks you can do in WPF with the Window that you can’t do in Windows Forms without a lot of hacking. ShowInTaskbar is hardly worth mentioning (it just does what it says). The Opacity attribute is kind of cool — it just controls the translucency level (valid values are from 0 to 1, but below the smaller values aren’t really very useful) — but you can animate this pretty easily to cause your windows to fade in and out. But there are a few that are more impressive:
One of my favorite features of WPF windows it that you can use SizeToContent to have the form automatically take the size of whatever is inside it (which is really useful when you’re loading images off the web). You have to be careful with this though, because WPF is resolution independent but it’s also aware of how many pixels-per-inch images have been saved with. Typically, if you have a PNG (Portable Network Graphics) file, it’s been saved at something like 200 or 300 pixels per inch to make it printable … but your screen’s resolution is only (approximately) 96 pixels-per-inch. This results in images being displayed, by default … at HUGE sizes compared to what you expect. Caveat emptor.
A WPF window with AllowsTransparency set to true can be non-rectangular! It’s very important that you understand this isn’t about allowing translucency (that is, it has nothing to do with the Opacity setting). With this setting on, your window will basically not exist in any spot where there’s no color (See demo4 below). It will be not only be invisible — mouse-clicks won’t register. You’ll also be able to have true per-pixel transparency, with the ability to set the alpha level of each pixel, since WPF colors can be specified as #AARRGGBB quads.
This wouldn’t merit mentioning, except that it has a tie-in with Transparency. You can set the WindowStyle in Windows Forms too, and just like Windows Forms, the valuesfor WPF are None, SingleBorderWindow, ThreeDBorderWindow, and ToolWindow … however, if you use AllowsTransparency, the only valid value for WindowStyle is “None.”
As with WindowStyle, this attribute is mostly special because of it’s exceptions. You can use WindowStartupLocation to specify where you want the form to appear. Valid values are Manual, CenterScreen, and CenterOwner. CenterScreen is the obvious choice for a splash screen, but I should point out something about the other two as well. CenterOwner means to center the window on it’s parent window … but it only works with other WPF windows. If you don’t set the owner to a WPF window, CenterOwner works just like Manual. The Manual setting allows you to specify the window position with the Top and Left attributes, or just let Windows position you in the default location.
There’s one line of code in the sample above which bears explaining — the call to Dispatcher.Invoke. The point of this call is to basically transfer the thread control to the window for a moment. In fact, the signature of the Invoke method is that it takes a priority (I use render because it’s basically immediate), a delegate (I pass a scriptblock), and arguments for the scriptblock. PowerShell will let you easily cast a scriptblock to a delegate method which takes two object parameters and doesn’t return a value … but it won’t let you convert them to any other method without using reflection and IL.Emit. Thus, we cast our scriptblock to any handy delegate type, and pass $null for both parameters.
Of course, we don’t like having to manually update the window by calling Invoke(), but I still haven’t figured out how to spin out another thread safely … so the only other option is to just give control to the window (actually I think this could be done with background jobs, but I can’t seem to get the WinRM CTP configured properly).
Giving control to the window is actually the normal way of doing UI programming … and isn’t really a very big deal in PowerShell — you can write your event handlers for the controls on the window, and then call ShowDialog() and you’re off. Just to give you an example, I’ve tweaked an old WPF sample I had and ported it to PowerShell … the xaml file is here and I’ll paste the code (with comments) inline, but if you may also download the PowerShell script. You need both files for it to work, because the clock.xaml file is the only argument to the demo-wpf4.ps1 script 
Check it out:

Post ScriptI should probably mention that I coded the XAML for that clock by hand, using kaxaml, rather than using Expression Blend — I don’t necessarily recommend it, but it’s good practice once in a while.
XAML supports a lot of animations, and I spent almost an entire day trying different things to create a smooth animation for the CPU and RAM bars which would let them animate smoothly from one value to the next. In the end I decided it would have to be written in code rather than XAML markup, and would complicate things even more than they already were.
I mentioned in my last post that the new PowerShell 2 CTP2 release includes a STA switch which lets PowerShell run in Single Threaded Apartment mode. I also mentioned that this means we can do WPF and build UIs in XAML ... but I left it at that.
I thought I should go ahead and give you a better idea what sort of things that makes possible, but I have to admit that I haven’t had a whole lot of time to play with it — and there’s still going to be threading issues unless someone can help me figure out a way to spin out a new thread for the UI. So far everything I’ve tried to get a thread has just managed to crash PowerShell.
Luckily, the first couple of WPF tricks I could think of don’t really need threads at all, so they’ll work fine — lets just dive right in.
Don’t forget to run PowerShell with the -STA switch in order to try these demos, and before you run any of these scripts, you need to have .Net 3.0 or later installed. There are lots of ways to build WPF UIs, but perhaps the simplest thing is to build it in XAML since PowerShell supports XML natively. The first thing we have to do is add a reference to the WPF library, and then we can have some fun.
As you can see, I’ve also loaded my PoshHttp snapin so I can use Get-Web to retrieve a web page as XML and then load the image — this is mostly about convenience (to save myself the trouble of parsing html as text) but also because if the images are remote, the WPF window has to download them, and therefore won’t work unless you ShowDialog() and give the WPF window the thread. You can just use the path to any image on your hard-drive.
2 May
The PowerShell team has released the second CTP of PowerShell 2 and it’s got so much new stuff in it, that it’s honestly hard to know where to start, so this first post is just going to be a list of the things I find the most exciting.
You can run PowerShell in Single Threaded Apartment mode, which will let us create WPF/XAML and some neat UI tricks that we couldn’t do before.
Modules are … like classes. They export public functions, and can have private functions and variables… you basically import the functions into your runspace, so you can call them, and they can share data via variables and even other functions in the same module. This is really awesome, and will almost certainly improve a dozen or more of my scripts which I’ve been using as containers for sets of functions.
PowerShell has support for events, including a whole set of cmdlets: Register-ObjectEvent, Register-PSEvent, Wait-PSEvent, Remove-PSEvent, Unregister-PSEvent, Get-PSEvent, New-PSEvent, Get-PSEventSubscriber which will, in many cases, seem extremely familiar to users of x0n’s PSEventing snapin.
I haven’t had a chance to test this out yet, but the word is that we can create constrained runspaces that limit access to commands, scripts, and language elements. I’m not sure if this lets you prevent access to part of the .Net framework, but it looks interesting in terms of running other peoples scripts.
When you’ve got an array, you can split it up and pass it to a function so each element in the array shows up as a separate argument to the function, so if you have a function foo can call a function bar and pass it all the arguments that get passed to foo, without needing to know what they are or how many there are. (in v1, you have to do things like this: iex "&'bar' $args" which just gets ugly).
I haven’t figured out how to really do anything with this yet, but the release notes say that these streams now contain string messages, invocation information and even pipeline metadata like counts of how many times each command in a pipeline has been invoked — someone was just asking for this on the usenet newsgroup the other day …
Add-TypeThere’s no help for this cmdlet, but it’s primarily a wrapper around the .net compilers (CSharp, CSharpVersion3, VisualBasic, and JScript, by default). However, it can also replace all the [Reflection.Assembly]::Load* methods so you can save some typing. I’ve figured out a couple of uses so far, and both are really useful:
Incidentally, there’s no help for Add-Type for some reason, but you can get basic information about how to use a cmdlet by running a command like this: (Get-Command Add-Type).Definition -replace "`n","`n`n" …
I keep hearing from new users who are used to bash-style aliases, how frustrating it is not to be able to create aliases with parameters, the way you can in bash …
I’m going to show you how to make the “alias” command work roughly the way it does in bash, but first, let me clear this up:
| Bash or Csh | PowerShell |
|---|---|
| script | script |
| alias, shell functions | function |
| ... | alias |
In Bash, the recommendation is that “for almost every purpose, shell functions are preferred over aliases” ... and that recommendation is even stronger for PowerShell. The PowerShell “alias” is a true alias — it’s just another name for a command, script, function, etc. and it doesn’t support passing parameters or making mini-scripts at all.
Usually, an alias serves to give you a name you can remember, but sometimes it’s just to shorten the name, . Another use for them is to let you specify the default cmdlet — if you have two cmdlets (or script functions) with the same name, you can use an alias to override which one is executed by default.
The PowerShell function can do everything a bash alias can do (and everything a function or script can do, but this isn’t a tip about that, it’s a tip about making an alias
and unalias command that works the way you expect it to). So …
You can save that as alias.ps1 and create your aliases the way you used to in bash alias ls='ls -recurse' and still be able to invoke them and, you can pass them extra parameters somewhat like in csh when you invoke them.
I’ve added some extra text in the function name and content and in the alias description, so it’s actually pretty easy to find all the aliases and functions this script creates and dump them to a file so you can reload them later if you want … but I haven’t actually written a function to do that yet myself.
One important note: You must not use recursive aliases in the bindings on v1 — that is, alias ls='ls -recurse' will loop until it hits PowerShell’s recursive limit (only 100) and exit if you try to use it on v1 — because the script won’t be able to resolve the alias “ls” to Get-ChildItem … you’re probably better off not relying on that feature anyway.
Well, after multiple attempts at a wget PowerShell script (the last one works very well for downloading web pages, files, as long as you don’t need to send post parameters or anything like that) ... I found myself writing a script last week that included a custom HTTP POST function as well as using some prior functionality I wrote (ConvertFrom-Html) to convert HTML files to XML documents — which PowerShell can deal with nicely.
So I’ve taken my Huddled.Html code and worked it in together with a few extra bits … and I’m releasing it under the new name “PoshHttp” (which has the sole benefit of being short, in the case when you need to type the full command names, like: PoshHttp\Get-Web.
In lieu of providing proper documentation for this, there’s a script below which shows off some of the features of the Get-Web cmdlet … but first, you’re going to want to download PoshHttp and I can give you a basic overview.
Downloads a file from the web URI (Uniform Resource Identifier), optionally passing POST or GET parameters which it accepts as a Hashtable. If the resulting file is an xml or html file, it converts it to XML and outputs it as an XmlDocument object. If they are not, it saves them to file, and outputs the FileInfo object.
Converts HTML to XML. I’ll eventually tweak this so it supports passing it a file path and even saving the xml in-place on the original file … but for now you can use it on a stream of text, like this: (Get-Content file.html | ConvertFrom-Html).save( "file.xml" ). Note that it outputs an xmldocument object … you can get the xml as text to the console using Get_OuterXml().
Converts a url-style query string or NameValueCollection into a Hashtable. It’s mainly to make it easier to use the Get-Web in cases where you’re getting the URL or POST data from elsewhere.
1 May
Edit: I made a mistake …
I wrote this a few weeks ago, and made an error in the script which causes it to not work properly with most binary files … I’ve fixed the script down below now, and while I was at it, I went ahead and added a download progress report 
About a year ago, I wrote a script to download files from the web using PowerShell, but it was so simple that you had to specify the url to download and the file to save to. At the time I knew there was a way to find the file name of the download in the header, but I couldn’t remember how to get to the headers, and it’s not possible using System.Net.WebClient so I just dropped it.
Then the other day I saw an old post from Script Fanatic about querying Http status codes, and it reminded me of my annoyance with my wget script. So I fixed it, and I’m letting you have it.
The new version of wget for PowerShell (or Get-WebFile) is on the PowerShell Repository and it’s been completely rewritten to use System.Net.HttpWebRequest and HttpWebResponse which gives us access to the the name of the file in those cases where the URL is something like .../scripts/?dl=189 (assuming the server puts the file name in the headers as it should).
It still doesn’t support authentication, and even though the headers include the size (and I have to do the streams myself so I could easily read a few bytes at a time and give you progress reports)
Read the rest of this entry »28 Apr
Someone sent this link as a “great article about Live Mesh” ... and it was so bad, that I just have to rant about it. Your 9th grade English teacher would have flunked you for this … it’s just a horrible example of the Anguish Languish.
Steve Gillmor has an analogy or a metaphor for everything (and I mean literally every paragraph). Most of them are bad, but some of them are truly awful, so I’m just going to pick on a couple to vent steam.
So it went with Microsoft, as the seeming invulnerability of Gates’ machine accelerated to the boundaries of global saturation. Though we tend to think of Google as the conqueror, the reality is that Microsoft has struggled most with itself, the victim not of decline but of lack of fuel — the very customers who created the megalith in the first place.
The who, did what?
megalith — [noun] ( ‘meh gE “lIth ) 1. a huge stone, esp. one used in prehistoric times as a monument.
First of all, megaliths are erected, not created. Secondly, they don’t use (or lack) fuel. Thirdly, they’re a bad counterpoint to “conquerors.” If you wanted to use that many metaphors in one sentence, you should have said something like this: though we tend to think of Google as the conqueror, the reality is that Microsoft has struggled most with itself, the victim of a decline like that of the Roman empire, and yet Google has still not dared challenge the megalith of Windows, propped up as it is by millions of customers around the world …
The microbigs can seem transcendent like Facebook or possessing the lifetime of a gnat like a thousand forgotten startups or neverwases (sic), but nowhere are the range of possible outcomes more encapsulated than Twitter.
First of all, “can seem transcendent” works, but “can seem possessing the lifetime of a gnat” doesn’t. But more importantly, if Facebook is your example of transcendent, then the “lifetime of a gnat” takes on a whole new meaning — maybe you meant to invoke the branding of Hotmail, or Yahoo!, or SlashDot. Finally, “Neverwases” might be okay in poetry, but isn’t this still a technology magazine?
Yes? Yes. So what you’re saying is that Google is a microbig. Yes, did I say that? No, but I didn’t ask that either and the answer is still yes. Bottom line: Microsoft can’t gain and retain traction with Mesh unless the answers are yes.
What?! Exactly who is he having this conversation with in his head, and why did he write it down on paper?
I hate to ask, but, what is a “Coke Classic question” ... and how did “When’s the Mac version?” get on any list of classic questions? Why are you asking questions without question marks? What is a “Net-grappling” product line? Incidentally, the mental image conjured by combining “flailing” with “grappling” is rather frightening. It’s a no wonder that there are so many comments on this post that say things like “what is he talking about?”
Steve claims that “orthogonal and complementary” is “MicroBig language” (by the way, can we get a little capitalization consistency on your made up words please?) but I’m pretty sure that these are terms usually used by the (it hurts to write this) BigBigs to assuage fears of internal competition, as in: Microsoft’s advertising assets and aQuantive’s complementary expertise… or Yahoo! is complementary to Microsoft and so on. The so-called MicroBigs are usually more concerned with disruptive and revolutionary.
Bah. Anyway.
A relatively new PowerShell user came into #PowerShell on IRC.FreeNode.net this week to ask a question about scripts and the pipeline, and the conversation went so well, that I thought I’d share it with you all in case it helps clear things up for you. We’ll call him “user” since he left before I could get his permission to paste this, and I’ve cleaned up, reordered and in a couple of cases added lines to make the conversation seem a little more linear than the chat really was.
user: Can you explain the distinction between $_ and a param in a script context?
Jaykul: I sure can. And I think I can do it simply … take an example script|function … actually, we’ll just use a scriptblock
Jaykul: it can have pipeline blocks, or not (the pipeline blocks are the BEGIN{...} PROCESS{...} END{...})
user: yeah, I’m with you
Jaykul: so if you pass a value via an argument, it’s present in all three blocks, and has the same value the whole time (unless you change it in your script)
user: really
Jaykul: But when you put that script in a pipeline, your BEGIN {} block is called first, and then for EACH item in the pipeline, powershell sets $_ and calls your PROCESS block, and finally, your END{} block is called after all pipeline items have been processed
Jaykul: Here, check this out (run it so you can see) Read the rest of this entry »
23 Apr
Microsoft is announcing a big new software + services product and platform this week (well, today, and tomorrow, apparently). It’s called Live Mesh (how much do you suppose mesh.com set them back?) and it’s primarily a synchronization platform — updates shared files across multiple devices (PC, Laptop, handheld, Mac … yes, they said Mac OS X support is coming). They have some of FolderShare in there, and some of Groove and some of FeedSync … initially, this looks like a folder sync and backup service (see their Mesh help files), but it’s designed to become so much more…
At the core is this concept that a single user has a “mesh” of devices, applications, and data that they regularly use. The Mesh Service persists the relationship between these various resources and authorizes access to them … The Mesh Platform means that ultimately, (down the road) customers will license applications and content to their mesh instead of to a specific computer, device, or application. Microsoft actually envisions apps running seamlessly across multiple devices “from the mesh” ... using Remote Desktop and the mesh software to enable that connectivity regardless of your network topology (meaning it can punch through firewalls because you’re running the client software on all the devices). That platform part could really transform the industry if they actually deliver on this cross-platform support for OS X … are they going to deliver a remote desktop server for OS X?
The most interesting part of this platform concept is that they’re trying to extend their OS and Application -based dominance to the web by making the web a part of this “combined experience and storage platform” and trying to reduce the pressure on consumers to choose between local storage and “storage in the cloud.” Thus, an important part of The Mesh Platform is the fact that each mesh object (be it a document, a picture, a song, or a blog post) can be dealt with in different ways on different platforms — so you might have a folder on your computer containing Word documents … which are transformed into blog posts via the mesh and the concept of synchronized feeds. This could revolutionize web development, if it’s done right. Imagine: a mesh object can be a range of cells in an Excel spreadsheet ... which could be published to the web … and edited … and synchronized … and the whole time you have explicit control over the location and custody of the data, and you have built-in support for groups, group memberships, group permissions and ownership, etc.
To sum up … Live Mesh will not just be another folder sync service ...
Am I interested? Maybe … I need to see some licensing and terms of service information which isn’t really available at the moment (since the whole thing is in a closed beta).
Some screenshots of the client portion of Live Mesh are on CNet, and webware has some analysis of the app portion as well — they seem to say that it will will include full Remote Desktop access to a Windows “Live desktop.”
22 Apr
In the #PowerShell IRC channel (on irc.freenode.net) we have a bot and pastebin (which is set up here on my site) ... if you paste something in the pastebin site, the bot posts a link to it in the IRC channel for you, so you don’t have to mess with copying the resulting URL and pasting it to the channel to ask for help.
I also run a version of pastebin that’s been modified for long term storage as the main PowerShell Script Repository (which is, among other things, the main repository for the PowerShell Community).
So, when someone showed me sprunge earlier today, along with a python script for pasting there … I couldn’t help but think that it would be nice to have that for our pastebin sites… so here it is, Send-Paste