What’s that machine called?

Mamood had a problem! He needed to get some information on a bunch of machines he manages and like a good follower of the church of PowerShell, he fired up his favourite blue and white command line tool (which he for some reason changes to be black with green text) and set about trying to obtain the information required.

Somewhere along the way he got stuck, so somehow he managed to find his Office Communicator window in amongst what must have been at least 50 others including several terminal server client sessions (each containing at least another 20 windows) and contacted me. He needed to perform a nslookup on an IP Address and grep the resolved host name for his information.

I sent him back the following three functions (cobbled together on the spur of the moment):

function Ping-Host([string]$hostName) {
$pinger = new-object system.Net.NetworkInformation.Ping;
$pinger.Send($hostName);
}

function Resolve-HostByAddress([string]$ipAddress) {
return [System.Net.Dns]::GetHostByAddress($ipAddress);
}

function Resolve-HostByName([string]$hostName) {
return [System.Net.Dns]::GetHostByName($hostName);
}

I then told him to save them in a script called networkTools.ps1 and then Dot-source them into his session and have a play to see if they do what he wanted:

[D:\PsScripts]
1> . .\networkTools.ps1

[D:\PsScripts]
2> resolve-hostByName “localhost”
HostName Aliases AddressList
——– ——- ———–
machine1.cpatinliteral.net {} {127.0.0.1}

[D:\PsScripts]
3> resolve-hostByAddress “192.168.8.5″
HostName Aliases AddressList
——– ——- ———–
machine1.cpatinliteral.net {} {192.168.8.5}

[D:\PsScripts]
4> “machine1″, “machine2″, “machine3″ | % { resolve-hostByName $_ }
HostName Aliases AddressList
——– ——- ———–
machine1.captainliteral.net {} {192.168.8.5}
machine2.captainliteral.net {} {192.168.8.3}
machine3.captainliteral.net {} {192.168.8.8}

PowerShell Basics – .NET

One of the reasons why PowerShell is so good and so easy to sell to people is because of .NET. PowerShell is a .NET 2.0 application and it uses .NET to achieve virtually everything it does – but how can users leverage to power of .NET from within PowerShell?

How do I create an object?

There are basically two way to get an object to work with in PowerShell, either call new-object or get one returned by calling something.

Things return objects?

[D:\PsScripts]
1> get-process

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
——- —— —– —– —– —— — ———–
256 12 77716 70736 558 0.91 5680 powershell

What’s actually going on here? It turns out that the get-process cmdlet returns .NET objects, in the above case it’s an array of System.Diagnosticts.Process objects and that allows us to work with them the same as if we had created them in code.

You can work with objects by either keeping a reference to them or by passing them down the pipeline to another cmdlet, object or piece of script. If you want to know what you can do with an object, call get-member:

[D:\PsScripts]
2> $processes = get-process
[D:\PsScripts]
3> $processes.Length
90
[D:\PsScripts]
4> get-member -InputObject $processes

TypeName: System.Object[]

Name MemberType Definition
—- ———- ———-
Count AliasProperty Count = Length
… … …

An object array? Where are the process objects?

[D:\PsScripts]
5> get-member -InputObject $processes[0]

TypeName: System.Diagnostics.Process

Name MemberType Definition
—- ———- ———-
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
… … …

Measure-Object { PowerShell }

I’ve been using PowerShell now for a few months and it’s become a standard feature on my desktop. Having used it for a while I have some observations to share:

IDE

PowerShell doesn’t have an IDE shipped as part of the product, so the out-of-the-box experience of scripting it limited to nothing more fancy than Notepad. My experience though has been that an IDE of some sorts really is required for working with anything but the most basic .ps1 script files. Additionally, I’ve had bugs in one-liners that pipe together several command and full IDE support for pipelines would be a real winner – imagine being able to set a breakpoint between piped commands.

The main features that I would like an IDE for PowerShell to provide are:

  • Colourisation of text – Different types and operators get different colours when viewed in an IDE, so you can see what you’re working on more clearly.
  • Full Debugging capabilities – Including breakpoints and watch windows. Without these basic tools, scripts get littered with write-Debug commands all over the place, it kind of reminds me of days gone by when I’ve been debugging ASP3 web applications – doable, but not as easy as it should be.
  • IntelliSense – tab completion is a godsend, but you need to know what’s there before it really works, I’m constantly piping to get-member to find out what an object supports.