More Power with PowerShell - Class Review
This is the third year that USENIX has offered PowerShell training at LISA, and the first I've been able to get into the class to take it. I'm so glad I could finally do it, because even though I use PowerShell almost every day to administer my vSphere clusters (through the excellent PowerCLI extension by VMware), I don't feel like I have a really solid grasp of the language as a whole.
As it turns out, I'm not alone. There are tens of thousands of "cmdlets" (pronounced "commandlettes") throughout PowerShell, and as instructor Steven Murawski says, "no one knows all of PowerShell". It's a good thing that there are a lot of utilities to help you figure out what you want to use and how to use it!
Steven started us out with the "Big Four":
- Get-Command
This cmdlet will allow you to list all of the available commands - or just a subset, based on a regex of the command name, what type of command it is, and what piece of software provides it.
- Get-Help
This is the equivalent of the 'man' command in UNIX. Get-Help cmdlet-name will give you an explanation of the cmdlet and what it does. You can also get extended documentation, examples, or even launch a web browser to the online documentation (with the very cool -online flag that I didn't know about until today!)
- Get-Member
This is one of my favorite commands. If you're used to slinging around command lines in Linux or UNIX, you're used to pretty much everything being a text string, and if you want information out of a particular field, you need to make sure to get the right line and know the right field number. PowerShell, on the other hand, throws around objects, and because objects are in many ways self-documenting regarding the data that they contain, you can have your command make decisions based on that - pulling out specific fields or doing math on the fly, all by using the data's actual field name instead of something like $8.
A lot of time, though, you don't know (or can't remember) what values a particular object has. That's when the Get-Member command comes to the rescue. Here's an example:
Suppose I'm dealing with a VM. I'm able to select the vm pretty easily:
[vSphere PowerCLI] V:\powergu.211\vSphere PowerCLI> get-vm -name xevious
Name PowerState Num CPUs Memory (MB)
---- ---------- -------- -----------
xevious PoweredOn 1 3072
But according to that, it only has a few values. I know there's more. To see what it's got, I can just pipe that command into Get-Member:
[vSphere PowerCLI] V:\powergu.211\vSphere PowerCLI> get-vm -name xevious | Get-Member
TypeName: VMware.VimAutomation.Client20.VirtualMachineImpl
Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() CDDrives Property VMware.VimAutomation.Types.CDDrive CustomFields Property System.Collections.Generic.IDictio DatastoreIdList Property System.String[] DatastoreIdList {g Description Property System.String Description {get;} DrsAutomationLevel Property System.Nullable`1[[VMware.VimAutom FloppyDrives Property VMware.VimAutomation.Types.FloppyD FolderId Property System.String FolderId {get;} Guest Property VMware.VimAutomation.Types.VMGuest HAIsolationResponse Property System.Nullable`1[[VMware.VimAutom HardDisks Property VMware.VimAutomation.Types.HardDis HARestartPriority Property System.Nullable`1[[VMware.VimAutom Host Property VMware.VimAutomation.Types.VMHost HostId Property System.String HostId {get;} Id Property System.String Id {get;} MemoryMB Property System.Int32 MemoryMB {get;} Name Property System.String Name {get;} NetworkAdapters Property VMware.VimAutomation.Types.Network Notes Property System.String Notes {get;} NumCpu Property System.Int32 NumCpu {get;} PowerState Property VMware.VimAutomation.Types.PowerSt ResourcePoolId Property System.String ResourcePoolId {get; UsbDevices Property VMware.VimAutomation.Types.UsbDevi VMHostId Property System.String VMHostId {get;} VMSwapfilePolicy Property System.Nullable`1[[VMware.VimAutom
That's more like it.
Get-PSDrive
OK, I had no idea this command existed. I had no idea half of these drives existed. This is exciting.
In a UNIX prompt, you have an environment that's set, and you can examine the variables with the command 'env'. It'll print all of the environmental variables and their values for you. Well, you can do the same thing in PowerShell by typing:
dir env:
That's because….get ready for this…the environmental variable space is mapped like a drive. Yes. You can navigate the space and see variable names, and when you cat the files, you get the values. This is currently rocking my world. And there are more drives to explore!
I learned a ton of new tips and tricks that are going to make my existence at the Windows command line much more fun. If you go have to deal with Windows servers and you still hate it, I'd highly recommend learning PowerShell if you don't already know it. Steven does a tremendous job teaching it, and I highly recommend picking up his class next year at LISA, where I'm certain that it will be offered.
If you weren't able to come to LISA this year, you might consider purchasing the video stream from USENIX. The price for this four hour class is $325 and you don't even have to get out of your desk chair.