VSTS Rangers - Using PowerShell for Automation - Part II: Using the right tool for the job
PowerShell is magically powerful—besides the beautiful syntax and the cmdlets (not "commandlets"), there is the ability to invoke .NET code, which can lead you down a treacherous path of trying to do the "super solution" by using these, writing a few (hundred) lines of code, and ignoring some old-school (read: DOS) ways of solving a problem. This is similar to the case of "when you only have a hammer, everything looks like a nail"—except this is the alpha-developer (as in alpha male) version, where you have 50 tools but one is newer and shinier, so that’s the tool you just have to use.
So with the VSTS Rangers virtualization project, we’re creating a VM that’s not meant for production (in fact, I think I need to create a special bright pink or green wallpaper for it—with "NOT FOR PRODUCTION" written over it), and we want to make it super easy for connections and the users of this VM. So one example where the PowerShell version of a command and the DOS version differs drastically is allowing all connections via the firewall.
In this case, there’s a command-line tool called netsh (not "netshell"), and if you type just netsh, you get a special command prompt where you can basically change every network-related setting. However, the genius who designed this (and it’s so well designed) is that you can type a single command at a time—or chain commands together in the netsh interface (which makes testing easy)—and then, once you have a working solution, you can provide it as a parameter to the netsh command. So to allow all incoming connections, the command looks like this:
> netsh advfirewall firewall add rule name="Allow All In" dir=in action=allow
Once I had that, I slapped it into a PowerShell script—because PowerShell can run DOS commands—and voilà, another script added to the collection, done in one line!
Another example is that I need the machine hostname for a number of things used in PowerShell. In DOS, there’s a command called hostname. Well, you can easily combine that with PowerShell by assigning it to a variable:
> $hostname = hostname
Now I can just use $hostname anywhere in PowerShell, and everything works well.