HI All,
I've the below script that works across a range of vCenters, except for one.
All vCenters are VCSA 6.5.0.32400
I realize this probably isn't a PowerCLI question but, don't understand why the script will not work when run on this one VCSA
foreach ($line in $targetList){
Write-Progress -Activity "Collecting details on provided VMs" -Status "Working on $line" -PercentComplete (($i*100)/$count.Lines)
try {
write-host "inside TRY, working on $line"
$script:target = Get-VM $line -ErrorAction SilentlyContinue
$powerState = $script:target.PowerState
$ip = $script:target.guest.IPAddress[0]
$memory = $script:target.memoryGB
$hddSize = [math]::Round(((Get-HardDisk -VM $script:target).CapacityGB | Measure-Object -Sum).Sum)
$vraManaged = $script:target.customFields.Item("vrmManagedMachine")
$vraOwner = $script:target.customFields.Item("VRM Owner")
$script:vmProperty = [ordered] @{
'vCenter' = $script:target.Uid.Split('@')[1].Split(':')[0]
'Cluster' = $script:target.VMHost.Parent.Name
'VM Name' = $script:target.Name
'IP Address' = $ip
'PowerState' = $powerState
'Memory (GB)' = $memory
'Disk Capacity (GB)' = $hddSize
'Attribute: vRA Managed' = if ($vraManaged) {"True"} else {"False"}
'Attribute: vRA Owner' = $vraOwner
}
$script:vm_Found_YES += New-Object -TypeName psobject -Property $Script:vmProperty
$i++
}
catch {
Write-Host "inside CATCH working on $line"
$script:notFound = [ordered] @{
'VM Name' = $line
'VM Exists' = "NO"
}
Write-Host -ForegroundColor Red "$line does not exist on the vCenter being searched"
$vm_Found_NO += New-Object -TypeName psobject -Property $script:notFound
}
}
$script:vm_Found_YES | Sort-Object -Property 'VM Name' | Export-Excel -Path $vm_Found_YES_ReportPath -AutoFilter -AutoSize -TableStyle Light2 -Show
if ($vm_Found_NO){
$vm_Found_NO | Export-Excel -Path $vm_Found_NO_ReportPath -AutoFilter -AutoSize -TableStyle Light3 -Show
}
I can confirm that the VM's in the $targetList do exist on this particular vCenter.
When outputting the contents of the variables, they are all populated except for the $script:vmProperty hashtable, which is blank.
For the output of this script, i would expect the $script:vm_Found_YES to ve exported to Excel and, have all the relevant fields populated. Instead, it opens as an empty spreadsheet.
the $vm_Found_NO on the other hand is populated with the VM Names. Even though these VM's do exist in this VCSA.
As i've said, this script works as expected across a lot of other 6.5 VCSA's. Just one is giving this issue and i can't figure it out.
I thought it may be the Inventory Service on the VCSA but, all variables except the Hash table are populated.
thanks
1. Since CustomFields is of type IDictionary, you have the ContainsKey method.
You can test if that CustomField is present.
Something like this
'yes'
}
else{
'nope'
}
2. I can't see an obvious issue, only that you seem to assign the same object twice.
Once inside the Get-vraDetails function and another time just after the call to Get-vraDetails.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Did you define $script:vm_FOUND_YES as an array somewhere?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I did, the defined variables are below
$script:vm_Found_YES =@()
$vm_Found_NO = @()
$isVRAmanaged = @()
$targetList = get-content $Script:file
$count = $targetList | Measure-Object -Line
$i = 1
$dir = $Script:directory
$vm_Found_YES_ReportPath = $Script:directory + "\" + $script:appName + "-FoundReport-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
$vm_Found_NO_ReportPath = $Script:directory + "\" + $script:appName + "-NotFoundReport-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
$isVRAmanaged_ReportPath = $Script:directory + "\" + $script:appName + "-isVRAManaged-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
As mentioned though, this works for 99% of my VCSA's.
it's just one where it doesn't work as expected. i don't think it's a script issue but i've no idea why the hash table remains empty for that one VCSA.
Ok, got it.
I suspect there might be an issue with the Get-VM line.
That ErrorAction will result in your code never reaching the catch-block.
Try changing that line to
$script:target = Get-VM $line -ErrorAction Stop
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks but same result with changing that
I even removed the -errorAction but, same result.
the script is reaching the CATCH, from the output i see
inside TRY, working on jasontst01
inside CATCH working on jasontst01
jasontst01 does not exist on the vCenter being searched
inside TRY, working on jasontst011111111
inside CATCH working on jasontst011111111
jasontst011111111 does not exist on the vCenter being searched
the thing is, jasontst01 does exist so it should not reach the CATCH for this VM
a normal get-vm on jasontst01 works as expected
i'll remove the TRY / CATCH and see what errors it displays
removing the TRY/CATCH highlighted the issue.
It was the following variables
$vraManaged = $script:target.customFields.Item("vrmManagedMachine")
$vraOwner = $script:target.customFields.Item("VRM Owner")
These attributes don't exist on all VM's in the environment.
Because they aren't present in the VM's in this particular vCenter, the $script:vmProperty Hash Table wasn't getting populated. As a result, the output wasn't as expected.
Now, i need to figure out how to account for these variables if present and, skip them cleanly if not present
My first attempt was failing because i am using VM Attributes that don't exist for every VM inside of a TRY/CATCH Statement.
My issue, i need to check for these Attributes on all VM's.
QUESTION 1: How can i do it inside a TRY/CATCH without breaking the script ? (below is my attempt at a solution but still breaks the script)
QUESTION 2: why is $script:vm_Found_YES += New-Object -TypeName psobject -Property $Script:vmProperty not adding to the $script:vm_Found_YES
function Get-vraDetails {
if ($script:target.customFields.Item("vrmManagedMachine")) {
$script:vmProperty.Add("Attribute: vRA Managed","True")
$script:vmProperty.Add("Attribute: vRA Owner", $script:target.customFields.Item("VRM Owner"))
}
else {
$script:vmProperty.Add("Attribute: vRA Managed","False")
$script:vmProperty.Add("Attribute: vRA Owner", "")
}
$script:vm_Found_YES += New-Object -TypeName psobject -Property $Script:vmProperty
}
function Main {
$script:vm_Found_YES =@()
$vm_Found_NO = @()
#$isVRAmanaged = @()
$targetList = get-content $Script:file
$count = $targetList | Measure-Object -Line
$i = 1
$dir = $Script:directory
$vm_Found_YES_ReportPath = $Script:directory + "\" + $script:appName + "-FoundReport-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
$vm_Found_NO_ReportPath = $Script:directory + "\" + $script:appName + "-NotFoundReport-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
#$isVRAmanaged_ReportPath = $Script:directory + "\" + $script:appName + "-isVRAManaged-" + (Get-Date -Format yyyy-MMM-dd-HHmm) + ".xlsx"
foreach ($line in $targetList){
Write-Progress -Activity "Collecting details on provided VMs" -Status "Working on $line" -PercentComplete (($i*100)/$count.Lines)
try {
write-host "inside TRY, working on $line"
$script:target = Get-VM $line -ErrorAction SilentlyContinue
$powerState = $script:target.PowerState
$ip = $script:target.guest.IPAddress[0]
$memory = $script:target.memoryGB
$hddSize = [math]::Round(((Get-HardDisk -VM $script:target).CapacityGB | Measure-Object -Sum).Sum)
#$vraManaged = $script:target.customFields.Item("vrmManagedMachine")
#$vraOwner = $script:target.customFields.Item("VRM Owner")
$script:vmProperty = [ordered] @{
'vCenter' = $script:target.Uid.Split('@')[1].Split(':')[0]
'Cluster' = $script:target.VMHost.Parent.Name
'VM Name' = $script:target.Name
'IP Address' = $ip
'PowerState' = $powerState
'Memory (GB)' = $memory
'Disk Capacity (GB)' = $hddSize
#'Attribute: vRA Managed' = if ($vraManaged) {"True"} else {"False"}
#'Attribute: vRA Owner' = $vraOwner
}
Get-vraDetails
$script:vm_Found_YES += New-Object -TypeName psobject -Property $Script:vmProperty
}
catch {
Write-Host "inside CATCH working on $line"
$script:notFound = [ordered] @{
'VM Name' = $line
'VM Exists' = "NO"
}
Write-Host -ForegroundColor Red "$line does not exist on the vCenter being searched"
$vm_Found_NO += New-Object -TypeName psobject -Property $script:notFound
}
$i++
}
$script:vm_Found_YES | Sort-Object -Property 'VM Name' | Export-Excel -Path $vm_Found_YES_ReportPath -AutoFilter -AutoSize -TableStyle Light2 -Show
if ($vm_Found_NO){
$vm_Found_NO | Export-Excel -Path $vm_Found_NO_ReportPath -AutoFilter -AutoSize -TableStyle Light3 -Show
}
}
1. Since CustomFields is of type IDictionary, you have the ContainsKey method.
You can test if that CustomField is present.
Something like this
'yes'
}
else{
'nope'
}
2. I can't see an obvious issue, only that you seem to assign the same object twice.
Once inside the Get-vraDetails function and another time just after the call to Get-vraDetails.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
That fixed the issue, thanks Luc.
I replaced
function Get-vraDetails {
if ($script:target.customFields.Item("vrmManagedMachine")) {
$script:vmProperty.Add("Attribute: vRA Managed","True")
$script:vmProperty.Add("Attribute: vRA Owner", $script:target.customFields.Item("VRM Owner"))
}
else {
$script:vmProperty.Add("Attribute: vRA Managed","False")
$script:vmProperty.Add("Attribute: vRA Owner", "")
}
$script:vm_Found_YES += New-Object -TypeName psobject -Property $Script:vmProperty
}
with
function Get-vraDetails {
if ($script:target.customFields.ContainsKey("vrmManagedMachine")) {
$script:vmProperty.Add("Attribute: vRA Managed","True")
$script:vmProperty.Add("Attribute: vRA Owner", $script:target.customFields.Item("VRM Owner"))
}
else {
$script:vmProperty.Add("Attribute: vRA Managed","False")
$script:vmProperty.Add("Attribute: vRA Owner", "")
}
}
No more errors on the Script and it successfully runs across all vCenters, even on vCenters where the VM's don't contain these two attributes
Thanks