Dashboard - VMWare

Hi all,

I’ve seen elsewhere on the forum issues with VMWare and needing to Connect-VIServer with the session secret etc. I’ve got a couple of VMWare parts on my dashboard working lovely but i am hitting a brick wall with my current page. Basic task… Grab the hosts, for each host get the VMs on that host, stick in a table the VM Name and the AD Description. I can get it working outside of the table/dashboard but i can’t within.

So i was hoping somebody might be able to take a look and tell me where i’ve been stupid! To me it seems a loop issue but i’m struggling to troubleshoot it withing my dashboard script.

Thanks in advance to anyone that can tell me what i’ve stupidly done!

Current code:

$VMsHostsData = New-UDRow { 
    New-UDColumn -Size 12 -Endpoint {
        $null = Connect-VIServer -Server $Cache:ViServerList.Name -Session $Cache:ViServerList.SessionSecret
        $HostList = Get-VMHost 
        New-UDLayout -Columns 3 -Content {
              foreach($VMHost in $HostList){
              $ResultsForTable = New-Object System.Collections.Generic.List[System.Object]
                New-UDcard -Title ($VMHost.name) -TextAlignment center -TitleAlignment center -Size large  -Content {
                    New-UDTable -Headers @("VM Name","AD Description") -Endpoint {
                        $null = Connect-VIServer -Server $Cache:ViServerList.Name -Session $Cache:ViServerList.SessionSecret
                        Get-VM | Where-Object {$_.VMHost.Name -eq $VMHost.Name} | ForEach-Object {
                        $Name = $_.Name
                            try {
                                $Desc = (Get-ADComputer $_.Name -Properties Description -ErrorAction Stop).Description
                                }Catch{
                                $Desc = ""
                                }
                        Clear-Variable -Name ResultsForTableData 
                        $ResultsForTableData = New-Object psobject -Property @{
                        Server = $Name
                        Description = $Desc
                        }
                        $ResultsForTable.Add($ResultsForTableData)          
                    $ResultsForTable | Out-UDTableData -Property @("Server","Description")
                    }    
                    } 
                }  
            } 
        }  
    } 
}

Looking further into this it looks more like a scoping issue with the variables and the endpoint for the tables.

Anyone able to help?

Hey @JoeKinsey1988,

I don’t actually have a VMware server but I’d recommend moving the List creation into the endpoint directly to see if that helps.

$VMsHostsData = New-UDRow { 
    New-UDColumn -Size 12 -Endpoint {
        $null = Connect-VIServer -Server $Cache:ViServerList.Name -Session $Cache:ViServerList.SessionSecret
        $HostList = Get-VMHost 
        New-UDLayout -Columns 3 -Content {
              foreach($VMHost in $HostList){
              
                New-UDcard -Title ($VMHost.name) -TextAlignment center -TitleAlignment center -Size large  -Content {
                    New-UDTable -Headers @("VM Name","AD Description") -Endpoint {
                        $null = Connect-VIServer -Server $Cache:ViServerList.Name -Session $Cache:ViServerList.SessionSecret
                        Get-VM | Where-Object {$_.VMHost.Name -eq $VMHost.Name} | ForEach-Object {

                            $ResultsForTable = New-Object System.Collections.Generic.List[System.Object]
                            $Name = $_.Name
                            try 
                            {
                                $Desc = (Get-ADComputer $_.Name -Properties Description -ErrorAction Stop).Description
                            }
                            Catch
                            {
                                $Desc = ""
                            }

                            $ResultsForTableData = New-Object psobject -Property @{
                                Server = $Name
                                Description = $Desc
                            }

                            $ResultsForTable.Add($ResultsForTableData)          
                            $ResultsForTable | Out-UDTableData -Property @("Server","Description")
                        }    
                    } 
                }  
            } 
        }  
    } 
}

Hi Adam,

Thanks for the reply.

If i moved $Hostlist inside the endpoint it would be inside the foreach and that the is var i wish to loop through.

I’ve managed to recreate this on another page which doesn’t use VMWare. It’s just a var of SSL certs from various servers.

See below. It’s obviously the -Endpoint and the scope of the var. Should i be passing it with -ArgumentList?

$CertificatesPageContent = New-UDRow {
New-UDColumn -Size 12 -Endpoint {
$SSLServers = Get-ADComputer -Filter {OperatingSystem -like “Windows Server”}
$SSLData = foreach ($SSLServer in $SSLServers){
$SSLServerName = $SSLServer.Name
Get-RemoteSSLCertificate -ComputerName $SSLServerName -ErrorAction SilentlyContinue | Select-Object @{N=‘Server’;E={$SSLServerName}},DnsNameList,NotAfter
}
$Certs = $SSLData | Select-Object -ExpandProperty DnsNameList -Unique
$CertsFormatted = $Certs | Select-Object -ExpandProperty Unicode
New-UDLayout -Columns 4 -Content {
Foreach($Cert in $CertsFormatted){
New-UDCard -TextAlignment center -TitleAlignment center -Size large -Content {
New-UDTable -Title $Cert -Headers @(“Server Name”,“Expiry”) -ArgumentList $SSLData -Endpoint {
Clear-Variable -Name SSLTableData
$SSLTableData = SSLData | Where-Object {_.dnsnamelist -like “$Cert”} | Select-Object Server,NotAfter
$SSLTableData | Out-UDTableData -Property @(“Server”,“NotAfter”)
}
}
}
}
}
}

Hey Joe,

I didn’t move $HostList. I moved $ResultsForTable into the loop so it’s all within the endpoint context.

$ResultsForTable = New-Object System.Collections.Generic.List[System.Object]

You certainly could try to pass it via ArgumentList. Here’s some info about that and why it might be necessary: https://docs.universaldashboard.io/endpoints/event-handler-endpoints#manual-variable-scoping

Ah yes sorry my bad. Just tried but no change in the outcome. Just holds onto the last set of data from the loop.

The 2nd lot of code i provided does exactly the same.

I’ll read up on the -ArugumentList. Definitley seems to be what i need.

1 Like

@adam Really struggling to figure this out. I’ve tried -ArgumentList but no joy. I’m obviously not understanding this. See code snippit below, this is just the table for simple viewing.

If you could point me in the right direction please.

New-UDTable -Title $Cert -Headers @(“Server Name”,“Expiry”) -Endpoint {
$SSLTableData = SSLData | Where-Object {_.dnsnamelist -like “$Cert”} | Select-Object Server,NotAfter
$SSLTableData | Out-UDTableData -Property @(“Server”,“NotAfter”)
} -ArgumentList @($SSLData, $Cert)

I’ve seen the following exaple on github from yourself from 2018 but i don’t understand how you’ve called the variable inside the endpoint.

foreach($item in $items) {
    New-UDTable -Title "Item $($item.id)" -Headers @(" ", " ") -AutoRefresh -Endpoint {
        $ArgumentList[0].GetEnumerator() | Out-UDTableData -Property @("Name", "Value")
    } -ArgumentList @($Item)
}

Thanks in advance, Joe

When you use -ArgumentList, you need to use the $ArgumenstList variable, not $SSLData.

New-UDTable -Title $Cert -Headers @(“Server Name”,“Expiry”) -Endpoint {
$SSLTableData = $ArgumentList[0]| Where-Object { $_.dnsnamelist -like $ArgumentList[1] } | Select-Object Server,NotAfter
$SSLTableData | Out-UDTableData -Property @(“Server”,“NotAfter”)
} -ArgumentList @($SSLData, $Cert)

That’s the little nugget of information i was missing!

Superb, all works now.

1 Like