Four PowerCLI One-Liners That Saved The World!

Ok, So maybe they didn’t save the world, but the sure saved my weekend. Rather than spend a lot of time on the intro, let’s dive right in. These will be in Problem/PowerShell/Output format.

The Problem:

More spaghetti environments, this time we need to count some resources. The first counts CPU, the second Memory. Yes there are pretty reports for this, but when you need the answer, you need it now.

The PowerShell:

get-datacenter "SomeDC" | get-cluster "clustername" |get-vm | select numcpu | %{ $cpus += $_.numcpu }
get-datacenter "SomeDC" | get-vm | select memorymb | %{ $memorymb += $_.memorymb }

The Output:

$cpus
60

$memorymb
401388

The Problem:

Need to rapidly identify what Datastore is associated with a VM or VMs. This is helpful to get a handle on the spaghetti that an poorly maintained environment can become over time.

The PowerShell:

get-datacenter | get-vm | %{ $_.Name; ($_ | get-datastore | select Name).Name }

The Output:

VM1.professionalvmware.com
VM Storage

The Problem:

Need to rapidly identify what the condition is in. Because perusing the entire VI for one server, and then clicking “Configuration > Server Health” is too much work.

The PowerShell:

get-vmhost -name "servername" | get-view | %{$_.Runtime.HealthSystemRuntime}  | %{ $_.HardwareStatusInfo.StorageStatusInfo } | where { $_.Name -like "Battery*" } | %{ $_.Status}

The Output:

Key             : Green
Label           : Green
Summary         : Physical element is functioning as expected
DynamicType     :
DynamicProperty :

The Problem:

Cold migrating A LOT of VMs. Note: This could be changed in a few ways that would allow much cooler things, but this is what I needed at the time and how I got there.

The PowerShell:

import-csv c:\maint.csv | %{ get-vm -name $_.ServerName -Location (get-datacenter "SomeDatacenter") | move-vm -Datastore (get-datastore -name "SomeDataStore") -RunAsync -Confirm:$false }

Example CSV:

ServerName
vm1.professionalvmware.com
vm5.professionalvmware.com
vm6.professionalvmware.com
vm7.professionalvmware.com

The Output:

Id              :
IsCancelable    : False
IsComplete      : False
Result          :
Name            : RelocateVM_Task
Description     : Relocate Virtual Machine storage
State           : Running
PercentComplete : 0
StartTime       : 9/12/2009 7:14:17 PM
FinishTime      :
ObjectId        :

vSphere 4 Hot Add Hardware and PowerShell

One of the most amazing new features of vSphere is the ability to hot add hardware into a supported guest OS. However, when you need to upgrade your 20 node web farm, all of the right clicks and slider moves can become cumbersome. That is where VMware PowerCLI (PowerShell) comes to the rescue! A few notes:

  • This can only be done on vSphere
  • This can only be done on supported guest OSs.
  • This can only be done after the VMware tools have been updated
  • And only with VM Hardware version 7.
  • You must enable hot-add in the settings of the VM (this one got me for a bit)

Got that? Now, the basic procedure is not all that different from changing resources of a powered off VM. Before:

2009-08-24_2053 2009-08-24_2055

The Magic Command! – get-vm -Name "dc01" | Set-VM -MemoryMB 512

Where “dc01” is the VM or list of VMs you want to change and 512 is the new memory config in MB you want.

Here is what it looks like during:

2009-08-24_2059

Here is what it looks like after:

2009-08-25_0552 2009-08-25_0558

And with that, your web farm is happy, and you have again saved the day with PowerShell. As always drop a line in the comments if this was useful, or if you have any questions or comments.

PowerShell Owners Manual

I almost wish I had stumbled on this before. Microsoft has published an “Owners Manual” for PowerShell. You know, that little book in the back of your glove box? Yeah, only this one is uber useful, and while not PowerCLI specific, will make your life as a VI admin, and Windows admin that much nicer.

From the pipelining section:

Piping and the Pipeline

It’s inevitable: no sooner do you get Windows PowerShell installed then you start hearing about and reading about “piping” and “the pipeline.” In turn, that leads to two questions: 1) What’s a pipeline?, and 2) Do I even need to know about piping and pipelines?

Let’s answer the second question first: Do you even need to know about piping and pipelines? Yes, you do. There’s no doubt that you can write Windows PowerShell scripts without using pipelines. The question, however, is whether you’d want to write PowerShell scripts without using pipelines. You can order a banana split and ask them to hold the ice cream; that’s fine, but at that point you don’t really have a banana split, do you? The same is true of the PowerShell pipeline: you can write scripts without a pipeline. But, at that point, do you really have

Well worth a read.

New PowerShell Snapin Versions All Around

I’m not sure how I missed this the first time around. Citrix and VMware have both rolled new versions of their PowerShell Snapins for new versions of their products.

Citrix XenServer 5.5 PowerShell SnapIn SDK

VMware PowerCLI (PowerShell Toolkit for vSphere)

As always, drop a line if you have any questions or comments.

Today’s Bit of PowerShell Awesome – Primal Forms

I often find myself with more tools to check out than I have time to do the checking out. One of the tools that has been on my laundry list for a while was Primal Forms from Sapien. In a single word, this tool is “Awesome”.

From the site:

PrimalForms is a free GUI builder tool for PowerShell users. It edits and stores Windows Forms in a native XML format and generates PowerShell code on demand. Sample forms included.

It is important to note that it will not let you write PowerShell itself. It will however let you build a user interface for your scripts, and generate the PowerShell you need in order to make the GUI itself.

Here is a sample:

2009-07-01_1031

Cool, no? Here is what it looks like in action:

2009-07-01_1109

Woot! Actually, I do not have any snapshots running at present in my test environment, and did not want to leave one running for a few days for the demo. What is the script doing behind the scenes? Take a gander:

$findSnaps_OnClick

=

{

$days_Old = $daysOld.Value

$richTextBox1.Text = "Connecting to VI Server…`n"

Get-Credential | Connect-VIServer -Server $vCenterHost.Text

$richTextBox1.Text += "Looking for snapshots older than $days_Old days old…`n"

$snapshots = Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-$days_Old) }

if ($snapshots){

$snapshots | %{

$VM = $_.VM.Name

$snapshot = $_.Name

$created = $_.Created

$richTextBox1.Text += "`nVM: $VM`nSnapshot: $snapshot`nCreated: $created"

}

}

else {

$richTextBox1.Text += "No snapshots found."

}

}

That is actually all of the logic I had to throw in there. Where is the rest? The form control, button, text box, etc were all generated by PrimalForms. The resulting code can be found here. The PrimalForms file for this can be found here.

Building A Hypervisor Independent Script – Part 2

Last time we covered getting the information we care about out of the various PowerShell toolkits, and what that looks like. If you are just joining us, or want to refresh your knowledge, the first part in the series is here.

This time we’re going to cover the Pipeline, and the “Begin” and “Process” code blocks. Lets dive right in.

The Pipeline

The pipeline is what puts the “Power” into PowerShell. Well, maybe not 100% of what does that, but PowerShell is insanely stronger for it. Microsoft provides a stellar introduction to the pipeline and its associated concepts over here. So we’ll not spend too much time repeating it. I’ll wait while you read it.

Now that you’re comfortable with the pipeline, lets talk about how you get your script to take pipeline input.

Begin { }

What better place to begin things than at the beginning. The begin code block is where you put things (bits of code, variables, functions) that you want executed BEFORE the pipeline execution is passed to the body of the script. I use it for variables that need to be defined prior to the script getting underway, and for custom properties as you’ll soon see.

This is what a begin block looks like. In here we’ve defined two expressions, “XenHost_UUID” and “VMHost_UUID”. These are what will actually return our UUID properties form each VM when we put the rest of this script together.

We’re progressing quick tonight, aren’t we? Now on to:

Process { }

When using the Begin/Process setup, This is where all of the real action in the script occurs. Or at least, it’s where the logic and flow take place. This is also where the information from the pipline gets fed into the body of the scrip and the action starts to get good.

download | new post

The first thing we do is to identify the object we’re being fed from the pipeline, and making sure it is something that we’re concerned about. Once we know that, we then fill the $output variable with data from our expressions above, or throw an error.

Good stuff, right? There is also an End {} block, talked about next.

End { }

The End { } block. It is well, the end. It’s where all of your clean up code, and formatting, and the like go. Really, that’s all there is to this block.

We can now wrap this post up. Remember to review the Intro post, subscribe (via RSS) to be notified of the next post “Putting it together”.

If you have any comments, please feel free to drop a line in the comments. Or leave us a note on Twitter

Timmy Fell In The Well! – Get-Help To The Rescue

Timmy was always getting into some sort of trouble, wasn’t he? The famous collie running through the fields, may not be the first thing that comes to mind for a good PowerShell analogy, it does apply. Think about it. Timmy ran into trouble,and he told Lassie to “Get-Help”. Get-Help is one of the most useful PowerShell cmdlets you will ever use.

What does it do?

Get-Help provides well, help, about a given cmdlet, it’s parameters, uses, examples, and other bits of useful information. Pending the vendor of the cmdlet built that information in. Lets take a look at an example: “Get-Help Get-Help –Detailed”

PS C:\> Get-Help Get-Help

NAME
    Get-Help

SYNOPSIS
    Displays information about Windows PowerShell cmdlets and concepts.

SYNTAX
    Get-Help [-Category <string[]>] [-Component <string[]>] [-Full] [-Functionality <string[]>] [-Online] [-Role <strin
    g[]>] [[-Name] <string>] [<CommonParameters>]

    Get-Help [-Category <string[]>] [-Component <string[]>] [-Detailed] [-Functionality <string[]>] [-Online] [-Role <s
    tring[]>] [[-Name] <string>] [<CommonParameters>]

It goes on and on actually, but the above should give you an idea. In the context of Virtualization and PowerShell this is really really (yes that gets two ‘really’ marks, it’s that useful). Say you looked at our sildes and wanted to know more about creating a new XenServer VM, you could simply “Get-Help” the cmdlet:

PS C:\> get-help Create-XenServer:VM

NAME
    Create-XenServer:VM

SYNOPSIS

SYNTAX
    Create-XenServer:VM [-BestEffort [<SwitchParameter>]] [-RunAsync [<SwitchPa
    rameter>]] [-HashTable [<Hashtable>]] [<CommonParameters>]

DETAILED DESCRIPTION
    Create a new VM instance, and return its handle.

RELATED LINKS

REMARKS
    To see the examples, type: "get-help Create-XenServer:VM -examples".
    For more information, type: "get-help Create-XenServer:VM -detailed".
    For technical information, type: "get-help Create-XenServer:VM -full".

Like that actually. Not as helpful as it could be, but a start. Lets look at the ‘-detailed’ information. (output truncated, it’s A LOT of information:

PARAMETERS
    -BestEffort [<SwitchParameter>]
        When set to true all errors will be trapped, printed to the terminal bu
        t not thrown.

    -RunAsync [<SwitchParameter>]
        When set to true this command will run asynchronously

    -Record [<Get-XenServer:VM>]
        The record detailing this Get-XenServer:VM

    -NameLabel [<string>]
        See SDK Help for full details.

    -NameDescription [<string>]
        See SDK Help for full details.

    -UserVersion [<long>]
        See SDK Help for full details.

This get’s you quite a few more parameters to use and points you back to the SDK docs for fuller descriptions. Good stuff? I think so. Here is an example of the same for VMware:

PS C:\> get-help new-vm

NAME
    New-VM

SYNOPSIS
    Creates a new virtual machine.

SYNTAX
    New-VM [-VMHost] <VMHost> -Name <String> [-ResourcePool <ResourcePool>] [-L

Again, truncated like crazy. For the full output, I’ll leave it to you to run the commands.

Installing XenServer in VMware Workstation

Was actually pretty easy. Rather than give a full run down, with youtube video, etc. I’ll give you the cliffs notes version of getting it up and running:

  1. Create Virtual Machine, Custom
  2. WS 6.5 Compatibility
  3. Linux Kernel, other
  4. Number of processors: 2
  5. Memory: 1024
  6. Bridged Networking (change to team later on)
  7. LSI Logic
  8. New disc, SCSI
  9. 15GB, pre-allocated, single file
  10. Customize hardware, remove: soundcard, usb, floppy
  11. Set execution mode to:     Intel VT-x
  12. Edit .vmx and add the following:
    ethernet0.virtualDev = "e1000"
    monitor_control.restrict_backdoor = "true"
  13. Install XenServer

Most of this is actually a modified version from VM/Etc

Building A Hypervisor Independent Script – Intro

What good is having PowerShell everywhere, what do you do, when you run a “Heterogeneous” environment? Today we’ll show you the basics of building a hypervisor agnostic script. We’ll build on this knowledge over time. To do this, we’ll use a slight modification on our existing “get-uuid.ps1” script. We’ll break this out into a few steps:

  • What do we want to know?
  • Detecting it on the pipeline.
  • Putting it together

What do we want to know?

Well, that is a difficult decision actually for the dude on the writing side of this article. In our case, we’ll use a modification of the get-uuid.ps1 script from ProfessionalVMware.com. We’ll expand it to include a bit of Citrix XenServer. Good no? So we need to know two things then: “Is it Xen or VMware?” and “Where do we find the UUID?”

Is it Xen or VMware

This one is actually rather simple. In the PowerShell world, everything is an object. Now you don’t actually need to know what an object is, and explaining it is beyond the scope of what we’re trying to accomplish. Suffice it to say, each object has a type. In this case we’re looking for XenServer or VMware Server types. These can be had using the GetType() Method of the object returned from the hypervisor specific cmdlet for ‘get-vmhost’

For VMware: “Get-VMHost | $_.GetType().Name” This results in a type of: “VMHostImpl”

For XenServer: “Get-XenServer:Host | %{ $_.GetType().Name }” This results in a type of: “Host”

Where do we find the UUID?

Good question, and I’m glad you asked. After having worked with VMware for a long time, it’s second nature to me as to where it’s hidden. However, that does you no good, and provides you with no way of examining other hypervisors (like XenServer) for their properties either. So lets investigate. Starting with what we know to be a VMhost type object (from above):

C:\> $vmhost = Get-VMHost | select -First 1 | Get-View
C:\> $vmhost | fl

Runtime             : VMware.Vim.HostRuntimeInfo
Summary             : VMware.Vim.HostListSummary
Hardware            : VMware.Vim.HostHardwareInfo
Capability          : VMware.Vim.HostCapability

Note, the output is truncated here. The “Summary” bit looks interesting, lets look deeper.

C:\> $vmhost | %{ $_.Summary }

Host               : VMware.Vim.ManagedObjectReference
Hardware           : VMware.Vim.HostHardwareSummary
Runtime            : VMware.Vim.HostRuntimeInfo
Config             : VMware.Vim.HostConfigSummary
QuickStats         : VMware.Vim.HostListSummaryQuickStats

What we did there, was pipe our VMHost object, to a “ForEach-Object” loop, and we asked it to give us the data for the summary property. Since we’re looking for the Bios UUID (I did state that before, no?) I guess it’s under hardware. Continuing to dig:

C:\> $vmhost | %{ $_.Summary.Hardware }

Vendor               : Dell Inc.
Model                : PowerEdge 2950
Uuid                 : 44454c4c-4b00-1059-804d-b4c04f4d4831

Do you see it? I do! So now that we know how to search, what are our types? Take a look:

For VMware: Get-VMHost | Get-View |  %{ $_.Summary.Hardware } | Select Uuid

For XenServer: Get-XenServer:Host | Select Uuid

We’ve covered quite a lot of ground in this post, and given you quite a few tools to go exploring the various virtualizaiton PowerShell snap-ins. Next post we’ll cover detecting this information on the pipeline, followed by a post on making it one cohesive script.

(Note: This was edited, because I lack the basic ability to use a Thesaurus )

    If you have any questions, please feel free to leave a comment, send us an e-mail, or hit us up on Twitter.

The PowerShell Presentation!

So, here is the presentation. Really. Right here. Well… actually it’s on MediaFire here. The Slide Share part can be viewed below:

Got Questions? Drop us a line in the comments.

« Older Entries