Thursday, July 30, 2015

PowerShell(s) of Two

While writing out some IP addressing exercises I needed a quick reminder of some of the powers of 2 that I use a little less frequently. I just opened up a PowerShell console and made a little table like this:
foreach ($i in 0..32) {"{0,8} {1,-11}" -f $i, ([System.Math]::Pow(2, $i))}
Hope you find this useful. Be seeing you.

Tuesday, July 28, 2015

PowerShell - Microsoft's Trident: Part 1, the Shell

The Three Tines of PowerShell

Like the powerful trident in the hands of Poseidon, PowerShell can be wielded for good or ill. It can create vast wellsprings of new possibilities for the savvy administrator and unleash destructive floods of complexity on the uninitiated. To some it solves many problems, to others it is the source of many headaches.
What I want to examine now, though, is the triune nature of this beast. Like Poseidon’s legendary weapon, PowerShell takes a three-pronged poke at the issues that commonly beset us in IT.

The Shell

PowerShell is a shell. That is, it’s an environment in which you can type commands to get your computer to do something. But it’s a really cool shell.

1. It gives you direct access to .NET.

I can’t stress this enough. .NET. From the command line. At your fingertips at all times, ready to do your bidding. If there is anything you must know about PowerShell, it is this. Almost anything that can be done in .NET can be done from the command line in PowerShell. Do you want to get data from a web server?
[System.Net.WebRequest]::Create('http://www.mysite.com/index.html')
Do you want to place the cursor somewhere particular on the screen?
$Host.UI.RawUI.CursorPosition = @{x = 20; y = 47}
I’m talking about some cool stuff. For example, Microsoft failed to give us an equivalent to the DOS ‘pause’ command in the initial release of PowerShell, and their eventual addition of a comparable function is lame. That’s because PowerShell can’t respond when you “Press any key to continue…” It doesn’t know you’ve pressed a key until you hit Enter and send to it the contents of the keyboard buffer. But .NET can access the keyboard at a lower level, bypassing the buffer:
function Wait-Key {
<#
.SYNOPSIS
Prompts the user to press a key and waits until the user does so.
.DESCRIPTION
The Wait-Key function simulates the DOS program pause. It gives a script an
opportunity to wait for the user to press a key before proceeding.
.PARAMETER Message
The prompt message to display when the script pauses.
#>
        [CmdletBinding()] param (
            [string] $Message = "Press any key to continue..."
        )

        $Message
        $Host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown") | Out-Null

}      # end function Wait-Key
With .NET and the MSDN website at your beck and call your command-fu is only limited by your imagination.

2. It allows you to run any command.*

From PowerShell you can launch any graphical program. Open up a text file in notepad or an html report in your default web browser.
notepad .\seating_chart.txt
Invoke-Expression ./disk_report.html
You can run any command-line utility…
ipconfig /displaydns
… even old CLI tools whose arcane syntax can cause PowerShell to balk—when you use the --% operator between the command and it’s arguments.
ICACLS.EXE --% C:\TEST /GRANT USERS:(F)
* Okay, so not really ANY command. You can’t run commands that are built in to the old CMD.EXE or COMMAND.COM command shells. This makes sense, as those commands are not stand-alone tools but are BUILT-IN. That’s why there’s point number 3.

3. PowerShell has cool aliases for useful commands.

As stated in the caveat above, CMD.EXE had several commands integrated into the shell itself. There are no executables for DIR or CD or DEL, so you can’t get at those from PowerShell. However, Microsoft has borrowed a page from other shells and given us aliases. While not quite as useful as the UNIX implementation of the concept they do allow us to create familiar or shortened names for common commands. So I can type DIR—or ls for that matter—and get a directory listing. Granted, what I get is not the result of DIR but the PowerShell Get-ChildItem command, so things are a little different, but not completely alien. I can easily create aliases of my own, if I like:
Set-Alias -Name unlink -Value Remove-Item
Set-Alias -Name goto -Value Set-Location
With aliases I can customize the shell to suit the way I prefer to work. To me, that makes PowerShell the best Windows shell around.

So stop using that old command interpreter. PowerShell is a much better shell than anything Microsoft has given us before, and with it we can do so much more than CMD will allow. And stay tuned for the other two prongs in the PowerShell trident.

Be seeing you.