Home > Blogs > VMware PowerCLI Blog > Monthly Archives: July 2010

Monthly Archives: July 2010

Enhanced VMkernel Networking Configuration in vSphere PowerCLI 4.1

You can now use PowerCLI to manipulate VMKernel networking and routing. There is a new functionality that supports setting a default gateway for VMKernel networks as well as creating, removing and updating of host routes.


Here is an example illustrating how to set a default gateway for VMKernel. All you need is to have a configured VMKernel adapter in the same subnet as the gateway you want to set to default. Let’s say you want to set a default gateway 10.21.84.1. First you should check which VMKernel adapter to use:


Get-VMHostNetworkAdapter  -VMKernel | select ‘Ip’, ‘SubnetMask’, ‘DeviceName’


IP     SubnetMask    DeviceName


——————-    ———- ———-


10.21.84.39   255.255.255.0     vmk1


10.21.113.249    255.255.252.0     vmk0



 



You should select the vmk1 network adapter which is in the same subnet as the default gateway:


# Example 1: Setting the default VMKernel gateway


$net = Get-VMHostNetwork


$net | Set-VMHostNetwork -VMKernelGateway ‘10.21.84.1’ -VMKernelGatewayDevice ‘vmk1’



 


The next example illustrates creating a VMKernel route that splits the VMKernel traffic. Looking at the previous example you can see that the vmk0 device is in a subnet with a host IP range (10.21.112.1 – 10.21.115.254). Below there is a sample code that splits the VMKernel traffic for the (10.21.113.0 – 10.21.113.255) and (10.21.114.0 – 10.21.114.255) subnets to different gateways:


# Example 2: Creating host routes


New-VMHostRoute -Destination ‘10.21.113.0’ -PrefixLength 24 -Gateway ‘10.21.113.1’


New-VMHostRoute -Destination ‘10.21.114.0’ -PrefixLength 24 -Gateway ‘10.21.114.1’



 



You can remove these routes using the Get-VMHostRoute and Remove-VMHostRoute cmdlets:


#Example 3: Removing host routes


Get-VMHostRoute  | where { $_.Destination -eq “10.21.113.0”} | Remove-VMHostRoute


Get-VMHostRoute  | where { $_.Destination -eq “10.21.114.0”} | Remove-VMHostRoute



 


For more details about host routing with PowerCLI 4.1, see the cmdlets help and the online documentation.



Regards,


Gospodin Gochkov

New Nested Properties for Navigating to Parent Objects in PowerCLI 4.1

While automating with PowerCLI scripts, you have most probably stumbled upon a situation when you need to access the parent of an object – the virtual machine of a CD drive, the host of virtual machine, the cluster of a host etc. In PowerCLI 4.0 U1 all object types which have “parents” are enhanced with the “Parent ID” property. Using this property you can easily get the parent object by invoking the corresponding Get-* cmdlet and filtering by ID. In the latest PowerCLI 4.1 release these “child” object types are enhanced with an even more useful nested property which holds the parent object itself. Using the nested parent object you can access the parent right away without the need to invoke an additional Get-* cmdlet.

Here is a simple example that illustrates the reference to the parent objects in PowerCLI. Let’s assume you have retrieved a virtual machine from your environment and for some troubleshooting reason, you need to check the time zone of the host where the virtual machine is running on. To do it, you have to access the host (parent object) of the virtual machine and get the value of its Timezone property.

Here is how this simple scenario can be achieved with PowerCLI 4.0 U1 by using the “VMHostID” property of the virtual machine object:

> $vm = Get-VM -Name "myVM" -Location "MyCluster"

> (Get-VMHost -ID $vm.VMHostId).Timezone

In PowerCLI 4.1 a new “VMHost” property is introduced to the “VirtualMachine” type to hold the reference to the object’s parent. So, now you can simply navigate from the virtual machine object to the time zone property of its host and no explicit retrieval with Get-VMHost is necessary:

> $vm = Get-VM -Name "myVM" -Location "MyCluster"

> $vm.VMHost.Timezone

    In addition to the child-to-parent relationship, nested properties are also used to represent another type of relationship: objects which are uniquely identified with another object. For example, besides the new “Parent” property, the “VMHost” type now has “StorageInfo”, “NetworkInfo”, “VMSwapfileDatastore”, “DiagnosticPartition”, and “FirewallDefaultPolicy” properties which let you know a whole lot more about a virtual machine host by just navigating through these properties. The new nested properties are initialized on demand, i.e. they will not be populated until the first time you access them, so no performance loss is expected when retrieving an object which has a parent property. Note that in future releases we’ll deprecate the old “Parent ID” properties so stick to nested properties when you need to access an object’s parent.

    I hope you’ll find the new nested properties useful and will start using them in your scripting activities J

 

Regards,

Irina Nikolova

 

Dealing with the inevitable events in life – reporting problems with PowerCLI

There are certain events in life that we all strive to avoid, yet they seem practically inevitable. Facing problems, when using some software product is one of those. And using PowerCLI and vSphere makes no exception. Occasionally, you will stumble upon a configuration, environment, or a PowerCLI/vSphere problem itself. This article shows how you can effectively report the problem to VMware. You will need this if cannot solve some problem yourself and need outside help or just want to inform VMware about the problem so they can fix it at some later point.

Reporting a problem with PowerCLI is easy. What you have to do is generate a diagnostic bundle with the Get-ErrorReport cmdlet and send it to VMware (or someone else with enough expertise on PowerCLI). There are 2 main scenarios for reporting the problem. The first is sending the bundle to VMware tech support (if you have a tech support account). The second is to post it in the PowerCLI community forum (http://communities.vmware.com/community/vmtn/vsphere/automationtools/powercli), attach the bundle to your post, and wait for someone to take a look at it. 

Here is the online documentation of the cmdlet: http://www.vmware.com/support/developer/PowerCLI/PowerCLI41/html/Get-ErrorReport.html

Get-ErrorReport has the following signature:

Get-ErrorReport 

  • ProblemScript <ScriptBlock> 
  • ProblemScriptTimeoutSeconds <Double> 
  • ProblemDescription <String> 
  • Destination <DirectoryInfo>
  • DontIncludeServerLogs
  • <CommonParameters>

-ProblemScript is the Powershell script that reproduces the problem. Get-ErrorReport executes this script and captures all the actions caused by it, so someone at VMware can be able to analyze them later.

-ProblemScriptTimeoutSeconds is the time limit in which the script must finish execution. If the script exceeds this time limit it’s considered an error. This parameter is needed because Get-ErrorReport cannot know what time an arbitrary script should take, so it cannot know if the script has blocked or is still operating as expected.

-ProblemDescription is your description of the problem you observed. It should be as specific as possible. It should describe what the erroneous behavior is and what the expected behavior is.

-Destination is the directory where you want to save the diagnostic bundle. It’s a .zip file.

-DontIncludeServerLogs specifies if vCenter logs should be captured as well. If this switch parameter is not set, the cmdlet will extract the vCenter logs + the logs of all ESX servers managed by the vCenter. This is quite a slow operation and will increase the size of the diagnostic bundle dramatically. Including vCenter logs is useful if the problem you’re reporting is on the vCenter/ESX side. So it’s better to set this parameter if you report a PowerCLI-specific problem.

Let’s see some examples now. 

Example 1.

Let’s say you have a problem moving a virtual machine from one host to another. You can assign the script that moves the virtual machine to a variable and pass it to Get-ErrorReport.

Example 2.

Let’s say you want to connect to a server and retrieve the virtual machines but the operation hangs. Again, you can create the script that gets the virtual machines and pass it to Get-ErrorReport, specifying that you expect that the script should take no longer than 60 seconds to finish. Let’s assume you also want to include the vCenter logs in the report. 

Now you know how to record diagnostic information that will help someone with PowerCLI expertise understand your problem (and hopefully provide a solution). This someone will probably be VMware tech support (for those of you who have a tech support account) or the PowerCLI community forum where someone from VMware or the community can hopefully take a look at it.

Surely, some of you are curious about the contents of the diagnostic bundle. You can take a look yourself by unpacking the .zip file. Here is the list of the types of information the support bundle includes:

– The problem description that the user has supplied

– The PowerCLI version and configuration

– The script that reproduces the error

– The output objects of the script that reproduces the error

– A snapshot of the Powershell session state before and after the script execution. This snapshot includes all the Powershell variables and their values (the contents of the PSCmdlet.SessionState object). 

– All the Soap communication messages between PowerCLI and the vCenter/ESX it’s connected to;

– [Optionally] The vCenter logs.

PS. Any information that is previously known to be sensitive (like passwords used when authenticating to the server) is not included in the diagnostic bundle. But, note that if you have a clear-text password stored in a Powershell variable – it will go in the log, since there is no way for Get-ErrorReport to know that some arbitrary variable contains a password.

Best regards,

– Angel Evrov,  MTS at VMware

Error handling with PowerCLI 4.1

Complex scripts need to handle errors and resolve common error scenarios without user interaction. A step in that direction is exposing the entire specter of vCenter server error hierarchy along with PowerCLI specific exceptions (for example when validating input parameters). 

This improvement makes possible to write scripts which handle expected errors and deal with them as it’s shown below:

In addition to this feature the full exception chain is available in the error records as inner exception.  So if the error is PowerCLI specific exception, the inner exception can be used to get the underlying vCenter Server error.

PowerCLI41 error

Thanks to that you can easily tune your script to check the returned by the server NoDiskSpace MethodFault and deal with it specifically.

Deploying a VM with Static IP in 3 Steps

VM customization is a very powerful feature that can make miracles during the deployment process. Since vSphere PowerCLI 4.0 U1,  you can use cmdlets to modify a number of network settings of the newly created virtual machines. Here is how to do it:



Regards,

Nedko Nedev

Member of PowerCLI Dev Team

Customizing Guest Cmdlets

PowerCLI has several cmdlets that work inside the guest of a VM:

These cmdlets are script-based and this makes them user-customizable. By default, they are supported on Windows (XP, 2003) and RedHat 5 guest operating systems. But if you want to execute the cmdlets on a different guest OS, you can extend their guest OS support either by modifying the existing scripts, or by adding your own ones. The scripts are located in the PowerCLI installation folder: “<Install_Folder>\Scripts”.

Naming the Scripts

The script names follow this convention: <operation_identifier>_<guest_OS_identifier>[.bat]. The operation identifier is “GuestDiskExpansion” for Set-HardDisk and the cmdlet name (without dash between verb and noun) for the VMGuestNetworkInterface and VMGuestRoute cmdlets (e.g. “GetVmGuestNetworkInterface”). The OS identifier should be either an OS family (e.g. “WindowsGuest” or “LinuxGuest”) or a specific OS version – guest id (e.g. “winXPProGuest”). You can see the guest id using Get-VMGuest cmdlet. The script extension must be “.bat” for Windows scripts and must be omitted for Linux scripts.

Executing the Scripts

When you pass a collection of VMs to one of these cmdlets, the cmdlet checks the guest OS and chooses the most appropriate script for each VM. In short, this is how it works: PowerCLI searches for a script for the specific guest id (specific OS version) of the VM and if there is such a script – it uses it; if no such script is found – PowerCLI checks for a script that matches the guest OS family and uses it. In this way, you can have a specific script for a specific OS (e.g. Windows 7) and use the common OS family script (e.g. Windows) for all other OS versions (e.g. XP, 2003).

Modifying the Scripts

Each script receives its parameters in a specific order and must also print its output in a specific format. Each predefined script contains a comment at the beginning which describes the expected parameters and output. You can either modify the existing scripts or write new ones (e.g. for a specific OS version). Either way you need to ensure that the script handles the expected parameters and prints the expected output – only then the cmdlet will be able to use the script. 

Output type changes in PowerCLI 4.1

In PowerCLI 4.1 we changed the namespaces in which output types live. This was done to improve the internal structure and enable other VMware teams to write cmdlets for the products they develop.

While the types remain the same (save for new features), the namespaces have changed and this affects scripts which use full namespace paths, for example:

if ($myObject -isnot VMware.VimAutomation.Client20.VirtualMachineImpl)

If you have scripts which quote full namespace paths, you need to replace the old namespace with the new one. A full listing of the changes is available in this file:
Download TypeMapping – PowerCLI 4.0.1 to 4.1

Here are few examples to give you an idea of what’s in the file:

VMware.VimAutomation.Types.VirtualMachine -> VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine
VMware.VimAutomation.Types.VMHost -> VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost
VMware.VimAutomation.Client20.VirtualMachineImpl -> VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
VMware.VimAutomation.Client20.VMHostImpl -> VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl

You can always check for incompatible types with a simple script:

ManagedObjectReference Made Easier

PowerCLI 4.1 introduces easier way to initialize ManagedObjectRefernce (MoRef) instances which are necessary while playing with the Get-View cmdlet.

Till now there were several ways to get MoRefs. The most popular one is to get the view object and to use its MoRef property. Another approach is to parse the values of the ID into two parts – type and value.

For example, to convert virtual machine hard disks to thin-provisioned format it is necessary to have the target datastore MoRef:

 # getting the datastore view object, later we use its MoRef  
 $dsView = Get-View $datastore
$relocateSpec = New-Object VMware.Vim.VirtualMachineRelocateSpec
$relocateSpec.Datastore = $dsView.MoRef
$relocateSpec.Transform = "sparse"

With PowerCLI 4.1, it is possible to initialize MoRefs from the ID or UId property of the objects. For example you can do this:

PS> $datastore.Id
Datastore-datastore-12523
PS> [VMware.Vim.ManagedObjectReference] $moRef = $datastore.Id
PS> $moRef | ft -AutoSize
Type      Value
----      -----
Datastore datastore-12523
Because the Datastore property of the $relocateSpec is of ManagedOjbectReference type, you can rewrite the previous rows to look like this:

 $relocateSpec = New-Object VMware.Vim.VirtualMachineRelocateSpec
 $relocateSpec.Datastore = $datastore.Id
$relocateSpec.Transform = "sparse"
Skipping the Get-VIew call makes the code shorter and the scripts faster, because you avoid a unnecessary server roundtrip.
Enjoy it! 

vDS in PowerCLI 4.1

At last vDS features are here with the new PowerCLI . The vSphere PowerCLI 4.1 release is the first touch of PowerCLI with vNetwork distributed switches, so please don’t expect to find fully supported vDS functionality in it. Still as you probably know, the Get-View cmdlet provides an opportunity to add extra functionality to your PowerCLI scripts. What you’re going to find in this post is how to create virtual network adapters on vDS and how to move VMs in and out of a vDS. At the bottom you can find a sample function that creates vDS.

When you have your vDS ready, you can create your virtual network adapters there. What you have to know is the name of the vDS and the name of the port group that you’re going to use. The line below will create VMKernel adapter with DHCP settings on the specified vDS and port group:

New-VMHostNetworkAdapter -VMHost $myHost -VirtualSwitch “myVDS”-PortGroup “dvPortGroup”

 

You can move VMs in and out of a vDS. Again, the only thing you have to know is the name of the port group:

$vm | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName “vdPortGroup”

On the same principle you can create new network adapters directly on your vDS:

New-NetworkAdapter -VM $vm -NetworkName “vdPortGroup”

And you can directly create VM, specifying its network adapter, to be on vDS network:

New-VM -Name “myVM” -VMHost $myHost -DiskMB 10240 -NetworkName “vdPortGroup”

The sample function below creates vDS, using the vSphere SDK for .Net. First, the function creates DVSCreateSpec, where vDS name and uplink port names are populated (Note that the name of the class matches the previous name of the vDS – “distributed virtual switches”, instead of “vNetwork distributed switches”. So don’t be confused of that ). Then the function creates DistributedVirtualSwitchHostMemberConfigSpec, where it populates the host(s), which will be added to the vDS. For the example I am adding a single ESX host, but you can modify the function to add a collection of hosts. For the added hosts, the function specifies the physical network adapter ID, which will be used for the connection to the vDS, which is done by adding DistributedVirtualSwitchHostMemberPnicSpec. Next, the function creates the vDS using CreateDVS method of the network folder view. Then the function creates DVPortgroupConfigSpec and adds a port group using the AddDVPortgroup method of the vDS view. Finally the function returns the managed object reference of the vDS.

 

 

 

Having the vDS managed object reference, later we can delete the vDS:

$vdsView = Get-View -Id $vdsMoRef

$vdsView.Destroy()

One thing you have to remember is that you won’t be able to remove your vDS until there are virtual adapters available there.

I hope that you’ll find this post somehow helpful and that it will make you feel a little bit more comfortable, when working with vNetwork distributed switches .

PowerCLI 4.1 is out

Tonight we released PowerCLI 4.1

Feature Highlights:

  • Easier to customize and extend PowerCLI, especially for reporting

    • Output objects can be customized by adding extra properties
    • Better readability and less typing in scripts based on Get-View. Each output object has its associated view as nested property. Less typing is required to call Get-View and convert between PowerCLI object IDs and managed object IDs.
  • Basic vDS support – moving VMs from/to vDS, adding/removing hosts from/to vDS
  • More reporting: new getter cmdlets, new properties added to existing output objects, improvements in Get-Stat.
  • Cmdlets for host HBAs
  • PowerCLI Cmdlet Reference now documents all output types
  • Cmdlets to control host routing tables
  • Faster Datastore provider

The complete change log is available here.

In the next few weeks we’ll present the most exciting new features with specific posts so stay tuned. In the meantime don’t forget to download and try the new release.