# Get-hVm.ps1 # Purpose : Returns collection of objects representing each Virtual Machine on one or more # VMware ESX Server hosts. # Requirements: plink.exe from the Putty project must be in $env:path # Use -help parameter for instructions Param ( $Credential = $(Get-Credential), [switch]$Help, [switch]$Snapshot, [switch]$Verbose ) # This function converts the SecureString password in $Credential to plaintext we can use with plink.exe Function GetSecurePass ($SecurePassword) { $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($SecurePassword) $password = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr) [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr) $password } # Obtains list of VMX (config files) corresponding to each VM on a given ESX server Function GetVMX ($user, $pass, $srv) { $cmd = "plink.exe $user@$srv -pw $pass" $cmd += " vmware-cmd -l" Write-Verbose "Command line: $cmd" Invoke-Expression $cmd } # Queries each VM to see if any snapshots are present. Slow as Xmas. Function HasSnapshot ($user, $pass, $srv, $vmx) { $cmd = "plink.exe $user@$srv -pw $pass" $cmd += " vmware-cmd $vmx hassnapshot" Write-Verbose "Command line: $cmd" $results = Invoke-Expression $cmd if ( $results -match "1" ) { $true } else { $false } } # Returns help text Function ShowUsage { $helptext = @' Get-Vm Requirements: plink.exe from the Putty project must be in $env:path INPUT: [pipeline] : name or IP of ESX server(s) (REQUIRED) Credential : Object containing credentials for ESX server(s) (use Get-Credential cmdlet to create) Snapshot : boolean switch, if true, query snapshots (slow) Help : shows usage '@ Write-Host $helptext } # Main if ($help -or !$Credential) { ShowUsage; exit; } if ($verbose) { $verbosepreference = "continue" } $username = $credential.UserName -replace "^\\" # strip backslash from beginning of username $password = GetSecurePass $credential.Password # convert password to plaintext $collOut = @() # create collection which holds all of the objOut objects Write-Verbose "$(get-date -f 's') ESX Query Status:`tGetting list of VMs" # Iterates through each item in the pipeline. This should be a list of IPs or hostnames of ESX servers. We hope. $input | ForEach-Object { Write-Verbose "$(get-date -f 's') Querying host: $_..." $VmHost = $_ $VmList = GetVMX $username $password $vmhost # Calls the GetVMX function to obtain list of virtaul machines $VmList | ForEach-Object { $objOut = "" | Select-Object VmHost, VmName, VMXpath, HasSnapshot # create our output object with desired properties Add-Member -InputObject $objOut -MemberType ScriptMethod -Name RemoveSnapshots ` -Value { "Reserved for future user, nyah!" } $objOut.VmHost = $VmHost $objOut.VMXpath = $_ $objOut.VmName = (Split-Path $_ -Leaf) -replace ".vmx$" if ($snapshot) { Write-Verbose "$(get-date -f 's') Getting snapshot status for VM: $($objOut.VmName)" $objOut.HasSnapshot = HasSnapshot $username $password $VmHost "$_" } $collOut += $objOut } } Write-Verbose "$(get-date -f 's') ESX Query completed" Write-Output $collOut