To list linked clones on your vCenter 4.0 Server, grouped (in most cases) by the base disks that they are sharing:

function Get-LinkedClone {
   #The following line is a fast replacement for:  $vms = get-vm args[0] | get-view
   if( $args[0] -eq $null ) {
      $vms = Get-View -ViewType VirtualMachine -Property Name,Summary,Config.Hardware.Device
   } else {
      $vms = Get-View -ViewType VirtualMachine -Property Name,Summary,Config.Hardware.Device -Filter @{Name = $args[0]}
   }

   $linkedClones = @()
   foreach ($vm in $vms) {
      $unshared = $vm.Summary.Storage.Unshared
      $committed = $vm.Summary.Storage.Committed
      $ftInfo = $vm.Summary.Config.FtInfo

      if ( ($unshared -ne $committed) -and (($ftInfo -eq $null) -or ($ftInfo.InstanceUuids.Length -le 1)) ){
         # then $vm is a linked clone. 

         # Find $vm's base disks.
         $baseDisks = @()
         foreach ($d in $vm.Config.Hardware.Device) {
            $backing = $d.backing
            if ($backing -is [VMware.Vim.VirtualDeviceFileBackingInfo] -and $backing.parent -ne $null) {
               do {
                  $backing = $backing.parent
               } until ($backing.parent -eq $null)
               $baseDisks += $backing.fileName

            }
         }

         $linkedClone = new-object PSObject
         $linkedClone | add-member -type NoteProperty -Name Name -Value $vm.name
         $linkedClone | add-member -type NoteProperty -Name BaseDisks -Value $baseDisks
         $linkedClones += $linkedClone
      }
      #else { do nothing for VMs that are not linked clones }
   }

   $linkedClones | sort BaseDisks, Name
}

Although there isn’t any single property of a VirtualMachine or its disks in the vSphere 4.0 API that indicates whether a VM is a linked clone, there are a few properties that can be used together to determine if a VM is a linked cloned, under certain assumptions.

For vSphere 4.0, there are two scenarios in which a VM shares files with another VM:

  • a VM is a linked cloned, or
  • a VM is part of a fault-tolerant pair.

(In releases following vSphere 4.0, there may be additional scenarios where VMs share files.)

If a VM is sharing files with another VM, then the following is true:

VirtualMachine.Summary.Storage.Unshared < VirtualMachine.Summary.Storage.Committed

and if a VM is not sharing files with another VM, then Unshared = Committed. So for vSphere 4.0 (but not necessarily later releases), if you know that FT is not enabled on your VMs, then you can tell whether a VM is a linked clone by checking whether Unshared != Committed:

 
$vm.Summary.Storage.Unshared -ne $vm.Summary.Storage.Committed

(Note that the above test is valid only if you are connected to a vCenter Server. If you are connected directly to an ESX host, then Unshared = Committed regardless of whether a VM is a linked clone or not.)

If a VM is part of an FT pair, the following will be true

(VirtualMachine.Config.FtInfo is not null) and (VirtualMachine.Config.FtInfo.InstanceUuids.Length > 1)

So to determine if a VM is a linked clone on a vCenter 4.0 Server that might contain FT-enabled VMs, you can use this:

 
($vm.Summary.Storage.Unshared -ne $vm.Summary.Storage.Committed) -and (($vm.Summary.Config.FtInfo -eq $null) -or ($vm.Summary.Config.FtInfo.InstanceUuids.Length -le 1))

You can also use vSphere Client to determine whether a VM is sharing files with other VMs. If the "Non-shared storage" displayed for a VM is less than the "Used Storage", and you are using vSphere 4.0, then the VM is either a linked clone or part of an FT pair. This is because the "committed","uncommitted", and "unshared" properties of VirtualMachine.Summary.Storage are used by vSphere Client to calculate the "Used Storage" (committed), "Provisioned Storage" (uncommitted + committed), and "Non-shared storage" (unshared) displayed for each VM.

Aside from VirtualMachine.Summary.Storage (and the similar properties in VirtualMachine.Storage.PerDatastoreUsage[]), I haven't seen any other good properties in the vSphere 4.0 API that indicate whether a VM is a linked clone or whether a disk is shared. A VM's virtual disks (and those disks' ancestor disks) have properties to indicate how much disk space they are using and who their parent disk is, but they don't have a property like a share count or list of child disks.

For the relevant vSphere 4.0 API documentation, see:

Thanks to Ben Neise for this question.