PSCustomObject to Table

Product: PowerShell Universal
Version: 2.8.1

I have some steps that run in my New-UDButton -OnClick block that end up creating a PSCustomObject. This is run inside of a foreach loop that is saved to a variable. This is a stripped out example.

New-UDButton -OnClick {
  $Results = foreach ($object in $objects) {
  ##
  ## Bunch of logic to populate the variables in $PSCO ##
  ##
  $PSCO = [PSCustomObject]@{
          'Date'           = $Date
          'Time'           = $Time
          'MACAddress'     = $MAC
          'SMBIOSGUID'     = $SMBIOSGUID
          'ComputerOfMAC'  = $MacPcName.Name
          'ComputerOfGUID' = $CMGUID.Name
          'User'           = $MacPcName.UserName
          'Model'          = $MacPcName.Model
      }
   }
}

Then my table with columns to build it out.

$Columns = @(
    New-UDTableColumn -Title 'Date' -Property 'Date' -IncludeInSearch    
    New-UDTableColumn -Title 'Time' -Property 'Time' -IncludeInSearch
    New-UDTableColumn -Title 'MAC Address' -Property 'MACAddress' -IncludeInSearch
    New-UDTableColumn -Title 'SMBIOSGUID' -Property 'SMBIOSGUID'
    New-UDTableColumn -Title 'Computer of MAC' -Property 'ComputerOfMAC' -IncludeInSearch
    New-UDTableColumn -Title 'ComputerOfGUID' -Property 'ComputerOfGUID' -IncludeInSearch
    New-UDTableColumn -Title 'User' -Property 'User' -IncludeInSearch
    New-UDTableColumn -Title 'Model' -Property 'Model' -IncludeInSearch
)


    New-UDTable -Columns $Columns -Data $Results -Sort -ShowSearch -ShowPagination -Dense -PageSize 10

I am getting a blank table and am obviously doing something wrong. Does anyone have any input on how to get this to display properly in the table?

Is it because you aren’t returning anything from the foreach? For example, don’t store in a variable and just return from the foreach.

  $Results = foreach ($object in $objects) {
  ##
  ## Bunch of logic to populate the variables in $PSCO ##
  ##
[PSCustomObject]@{
          'Date'           = $Date
          'Time'           = $Time
          'MACAddress'     = $MAC
          'SMBIOSGUID'     = $SMBIOSGUID
          'ComputerOfMAC'  = $MacPcName.Name
          'ComputerOfGUID' = $CMGUID.Name
          'User'           = $MacPcName.UserName
          'Model'          = $MacPcName.Model
      }
   }
1 Like

Yea. The PSCO inside the the loop is stored as a variable, $PSCO, then output. And the foreach loop is stored in another final variable, $RESULTS, comprising all of whatever was processed in the foreach.

So here is the full test dashboard I have instead of just some parts, maybe it will be more helpful.

$DebugPreference = 'Continue'
$Creds = $RunAsCreds
New-UDDashboard -Title 'PXELog' -Content {
    
    $RegExMAC = '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})'
    $RegExUUID = '[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'
    $RegExDate = '(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)[0-9]{2}'
    $RegExTime = '[0-24]\d:[0-59]\d:[0-59]\d(?:\))?Z?'


    New-UDSelect -Option {
        New-UDSelectOption -Name 'PICK-A-SERVER' -Value 'DEFAULTVALUE'
        New-UDSelectOption -Name 'DPSERVER01' -Value 'DPSERVER01'
        New-UDSelectOption -Name 'DPSERVER02' -Value 'DPSERVER02'
    } -Id 'PXEServer' -Label 'PXE Server' -OnChange {
        $Session:PXEServer = $EventData
    }

    New-UDTextbox -Id 'PXELogLines' -Label 'Log Lines' -Value '1000'

    New-UDButton -OnClick {
        $Lines = (Get-UDElement -Id 'PXELogLines').value
        $PXEServer = (Get-UDElement -Id 'PXEServer').value
        New-PSDrive -Name 'PXEDrive' -PSProvider 'FileSystem' -Root "\\$PXEServer\SMS_DP$\SMS\logs" -Credential $Creds -Verbose
        $PXELOG = Get-Content "PXEDrive:\SMSPXE.log" -Tail $Lines | Where-Object { $_ -match 'Device is in the database' -or $_ -match 'SMBIOS ID is a match' -or $_ -match 'MAC Address is a match' }

        $Results = foreach ($LogEntry in $PXELog) {
            $MAC = [regex]::Matches($LogEntry, $RegExMAC).value
            $SMBIOSGUID = [regex]::Matches($LogEntry, $RegExUUID).value
            $Date = [regex]::Matches($LogEntry, $RegExDate).value
            $Time = [regex]::Matches($LogEntry, $RegExTime).value
            $CMMAC = Get-CimInstance -ComputerName 'IRVDCSCCM01' -Class 'SMS_G_system_NETWORK_ADAPTER'  -Namespace 'root\sms\site_XXX' -Filter "MACAddress = '$MAC'"
            $CMGUID = Get-CimInstance -ComputerName 'IRVDCSCCM01' -Class 'SMS_R_System'  -Namespace 'root\sms\site_XXX' -Filter "SMBIOSGUID = '$SMBIOSGUID'"
            $MacPcName = Get-CimInstance -ComputerName 'IRVDCSCCM01' -Class 'SMS_G_system_COMPUTER_SYSTEM'  -Namespace 'root\sms\site_XXX' -Filter "ResourceID = '$($CMMAC.ResourceID)'"
            $PSCO = [PSCustomObject]@{
                'Date'           = $Date
                'Time'           = $Time
                'MACAddress'     = $MAC
                'SMBIOSGUID'     = $SMBIOSGUID
                'ComputerOfMAC'  = $MacPcName.Name
                'ComputerOfGUID' = $CMGUID.Name
                'User'           = $MacPcName.UserName
                'Model'          = $MacPcName.Model
            }
            $PSCO
        }
    } -Text 'Button'
    $Columns = @(
        New-UDTableColumn -Title 'Date' -Property 'Date' -IncludeInSearch    
        New-UDTableColumn -Title 'Time' -Property 'Time' -IncludeInSearch
        New-UDTableColumn -Title 'MAC Address' -Property 'MACAddress' -IncludeInSearch
        New-UDTableColumn -Title 'SMBIOSGUID' -Property 'SMBIOSGUID'
        New-UDTableColumn -Title 'Computer of MAC' -Property 'ComputerOfMAC' -IncludeInSearch
        New-UDTableColumn -Title 'ComputerOfGUID' -Property 'ComputerOfGUID' -IncludeInSearch
        New-UDTableColumn -Title 'User' -Property 'User' -IncludeInSearch
        New-UDTableColumn -Title 'Model' -Property 'Model' -IncludeInSearch
    )
    New-UDTable -Columns $Columns -Data $Results -Sort -ShowSearch -ShowPagination -Dense -PageSize 10
}

I thought that running the dashboard in with a RunAs configuration would have allowed it to connect to the UNC path and parse the log, but I always received “Access Denied.” So I connected with the same creds via a new PSDrive, which worked. But still no data is spit out to the table.

For anyone curious, this code reads the SMSPXE.log file on a SCCM DP and looks for PXE booting devices. It works fine in a shell. Useful for our Support team to figure out basic PXE booting issues with machines.

This looks like a scoping issue to me.
You are defining $results inside the onclick handler/scriptblock for a New-UDButton.
This is effectivly a level down from where you’re using $results on your new-udtable.
It’s like defining a variable inside a function and trying to use that variable at the script level.

Try changing $result to $session:PXELogResult (in both places)

See: Custom Variable Scopes - PowerShell Universal
Also see: Cache - PowerShell Universal

Thank you so much, @insomniacc, this was the solution. I will read over the docs and get my head around scoping. Again, thank you!