Identify a VMWare Datastore on the basis of VMName and Drive Letter with PowerCLI

In the last days I was working with a customer to react automatically to an Alert: „Logical Disk Free Space is low“. If this Alert is raised, Orchestrator should expand the drive located on a VMDK.

The information from the OpsMgr Alerts are Windows related so the useful things are the FQDN of the system (Monitoring Object Path) and the Drive Letter (Monitoring Object Name). We got no VM related information from the Alert.

In my opinion the Integration Pack for VMware vSphere is very limited. The most of my projects automating VMware I use the „Run .Net Script“ Activity with PowerCLI installed on the Runbook Server(s).

To identify the VMWare Datastore on the basis of VMName(FQDN) I wrote this script to execute with „Run .Net Script“ Activity:

#requires System Center Orchestrator, OnlyUseLatestCLR set until SC2016, PowerCLI installed on the Runbook Server(s)
Gets the VMWware Disk Information from Windows System with Drive-letter
Gets the VMWware Disk Information from Windows System with Drive-letter.
Script optimized for "Run .Net Script" Activity from System Center Orchestrator
UserName and Password as Published data

Defined in Orchestrator "Published Data" of Run .Net Script Activity Activity
Version: 1.1
Author: Stefan Horz
Creation Date: 03/12/2109
Purpose/Change: Changed mapping to SerialNumber from WMI and VMWare

Optimized for System Center Orchestrator

$UserName = 'vaslab\sco2vmware' # Subscribe your Variable for User with access to VCenter and VM
$Password = "Secret:-)" # Subscribe your encrypted Variable for the Password

$VIServer = '' #Subscribe the address for your VCenter

$SystemFQFDN= '' #Subscribe the Published Data of the affected VM

$Drive = 'f:' # Subscribe the Published Data of the affected Disk Drive

#VName equals Netbios name here
$VMName = ($SystemFQFDN.Split('.'))[0]

#Make Credentials
$SecureStringPwd = $Password | ConvertTo-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureStringPwd

# Connect to VCenter
cd "C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Modules"
Import-Module VMware.VimAutomation.Core
Connect-VIServer -Server $VIServer -Credential $creds

#Get the Windows Drive with WMI
$Windrive = (((Get-WmiObject -ComputerName $SystemFQFDN -Credential $creds -ClassName 'Win32_LogicalDisk') | WHERE {$_.DeviceID -eq $Drive}).GetRelated('Win32_DiskPartition')).GetRelated('Win32_DiskDrive') | Select *

$SCSIBus =$Windrive.SCSIBus
$SCSITargetId =$Windrive.SCSITargetId
$DiskSNfromWMI = $Windrive.SerialNumber

# Match the VMWare Disk with the windows Disk
$vm = Get-VM -Name $VMName

foreach($ctrl in Get-ScsiController -VM $vm)

foreach($disk in (Get-HardDisk -VM $vm | where{$_.ExtensionData.ControllerKey -eq $ctrl.Key}))

IF (($disk.ExtensionData.UnitNumber -eq $SCSITargetId )-and (($disk.ExtensionData.Backing.Uuid).Replace('-','') -eq $DiskSNfromWMI) )
# The below Variables are for the tab Published Data of "Run .Net Script" Activiy
$VMDiskName = $disk.Name
$VMDiskFilename = $disk.Filename
$DiskUID = $disk.Uid
$DiskCapacityGB = $disk.CapacityGB
$DiskFreeSpaceGB = ((Get-VMGuest -VM $vm).Disks | where {$_.Path -eq "$Drive\"}).FreeSpaceGB
$DiskFreeSpaceGB = "{0:N3}" -f ([math]::Round($DiskFreeSpaceGB,3))


$LUN = Get-HardDisk -vm $vm | Where {$_.Uid -eq $DiskUID} | Get-Datastore

$LUNName = $LUN.Name
$FreespaceGB = "{0:N3}" -f ([math]::Round($LUN.FreeSpaceGB,3))
$CapacityGB = "{0:N3}" -f ([math]::Round($LUN.CapacityGB,3))

$VMNotes = $Vm.Notes

#Output just do show drive size from WMI and VMWare has same result
$WMIDiskCapacityGB = [Math]::Round($Windrive.Size / 1GB)
"CapacityGB from VM $DiskCapacityGB and $WMIDiskCapacityGB from WMI "

Starten Sie jetzt Ihren Weg zu Azure!

Los geht's