piercj2
Enthusiast
Enthusiast

Hash Table not working for one vCenter

Jump to solution

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

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

1. Since CustomFields is of type IDictionary, you have the ContainsKey method.

You can test if that CustomField is present.

Something like this

if($vm.CustomFields.ContainsKey('lala')){

    '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

View solution in original post

0 Kudos
8 Replies
LucD
Leadership
Leadership

Did you define $script:vm_FOUND_YES as an array somewhere?

$script:vm_Found_YES = @()


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
piercj2
Enthusiast
Enthusiast

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.

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
piercj2
Enthusiast
Enthusiast

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

0 Kudos
piercj2
Enthusiast
Enthusiast

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

0 Kudos
piercj2
Enthusiast
Enthusiast

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

    }

}   

0 Kudos
LucD
Leadership
Leadership

1. Since CustomFields is of type IDictionary, you have the ContainsKey method.

You can test if that CustomField is present.

Something like this

if($vm.CustomFields.ContainsKey('lala')){

    '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

0 Kudos
piercj2
Enthusiast
Enthusiast

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

0 Kudos