Refresh Content in New-UDParagraph (After a New-UDInput event)

I am getting started with universal dashboard, and as a proof of concept, I am building a services Dashboard.
(My Aim is to display all Services ‘live’ and be able to turn them on or off).

Currently, it is like this but for all Services:

But I have become stuck on updating the New-UDParagraph after I change the Service.Status using a New-UDInput event, But the change is not reflected until I fully reload the dashboard.

I have made a New-UDInputAction -Toast to display the change, but I am unable to reflect the change to the New-UDParagraph.
And as such its not reflecting that back to the user (other than the Toast)

Is there a good way to get the reload the Dashboard or the update Service.Status?

I have attached my code below:

   $Service = Get-Service

$Dashboard = New-UDDashboard  -Title "Update-Services " -Content {
    New-UDHeading -Text "Here is a list of Services Running on your computer" -Size 5

    New-UDLayout   -Columns 6 -Content {  
       
        ForEach ($S in $Service) {
            New-UDCard  -Content {
                New-UDParagraph -Text ('Name: '+ $S.name) 
                New-UDParagraph -Text ('DisplayName: ' + $S.DisplayName)
                Switch ($S.Status) {
                    'Stopped' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color red }
                    'Running' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color green }
                    Default { New-UDParagraph -Text ('Status: ' + $S.Status) }
                }
                New-UDInput -Title "Stop-Service" -SubmitText 'Stop' -Endpoint {
                    stop-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status
            
                }
                New-UDInput -Title "Start-Service" -SubmitText 'Start'  -Endpoint {
                    Start-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status

                 
                } 
            }
        }
    }
}

Start-UDDashboard -Dashboard $Dashboard -Port 1000

There are 2 types of pages in play. Static pages won’t pickup any changes until the Web server is restarted. Dynamic pages pickup changes dynamically without restarting the web server. Review the references on how to create a dynamic web page and this will get you going in the right direction.

1 Like

You would want to test this, but couldn’t you wrap the UDParagraphs in New-udelement? Then add a new UDInputAction to Sync-UDElement. Something like this;

$Service = Get-Service

$Dashboard = New-UDDashboard  -Title "Update-Services " -Content {
New-UDHeading -Text "Here is a list of Services Running on your computer" -Size 5

New-UDLayout   -Columns 6 -Content {  
   
    ForEach ($S in $Service) {
        New-UDCard  -Content {

            New-UDElement -Tag div -Id "Div1" -Endpoint {
            New-UDParagraph -Text ('Name: '+ $S.name) 
            New-UDParagraph -Text ('DisplayName: ' + $S.DisplayName)
            }
            Switch ($S.Status) {
                'Stopped' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color red }
                'Running' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color green }
                Default { New-UDParagraph -Text ('Status: ' + $S.Status) }
            }
            New-UDInput -Title "Stop-Service" -SubmitText 'Stop' -Endpoint {
                stop-Service $S.name
                New-UDInputAction -Toast (Get-Service $S.name).Status
                New-UDInputAction -Content {
                    Sync-UDElement -Id "Div1"
                }
        
            }
            New-UDInput -Title "Start-Service" -SubmitText 'Start'  -Endpoint {
                Start-Service $S.name
                New-UDInputAction -Toast (Get-Service $S.name).Status
                New-UDInputAction -Content {
                    Sync-UDElement -Id "Div1"
                }

             
            } 
        }
    }
}
}
Start-UDDashboard -Dashboard $Dashboard -Port 1000

Again you would want to test this, as I have not. I am also still learning myself.

1 Like

Hi Guy,

New-UDElement -Tag div -Id "Div1" -Endpoint {
*-*DATA*-*
}

It looks like the for-each loop runs but then the New-UDElement syncs all cards in the for-each loop with the last entry. :frowning:

Notably, this happens even when the New-UDInputAction -Content { Sync-UDElement -Id "Div1" } is not called
.

I’ll keep working on this today, and I’ll let you know if I have any breakthroughs.

Thank you for your help with this. :slight_smile:

Cheers
Maylife

Hi cadayton,

Is there some good documentation on Dynamic pages?
The best I have been able to find is the article on

PowerShell Pro Tools - Ironman Software.

I will keep working down this line of thinking. But I can’t see a way to re-run the for-each loop from Dynamic pages.

I am sure I missed something.

Maylife

Hi Guy,

I edit the layout a bit. I moved the New-UDElement -Tag div -Id "Div1" -Endpoint { above the New-UDLayout -Columns 6 -Content {

But it looks like the update isn’t working, I’ll let you know if I find out anything else.

I have tried to simplify the question, I have added a $Test variable to see if we can update that from the New-UDInput and see if we can solve the simple issue first.

$Service = Get-Service
$Test = 'foo'
Stop-UDDashboard -port 1000

$Dashboard = New-UDDashboard  -Title "Update-Services " -Content {
New-UDHeading -Text "Here is a list of Services Running on your computer" -Size 5

New-UDElement -Tag div -Id "Div1" -Endpoint {
    New-UDLayout   -Columns 6 -Content {  
   
        ForEach ($S in $Service) {
            New-UDCard  -Content {

            
                New-UDParagraph -Text ('Name: '+ $S.name) 
                New-UDParagraph -Text ('DisplayName: ' + $S.DisplayName)
                $Test
            
                Switch ($S.Status) {
                    'Stopped' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color red }
                    'Running' { New-UDParagraph -Text ('Status: ' + $S.Status) -Color green }
                    Default { New-UDParagraph -Text ('Status: ' + $S.Status) }
                }
                New-UDInput -Title "Stop-Service" -SubmitText 'Stop' -Endpoint {
                    stop-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status
                    New-UDInputAction -Toast $Test
                    $Test = 'bar'
                    New-UDInputAction -Toast $Test
                    New-UDInputAction -Content {Sync-UDElement -Id "Div1"}
        
                }
                New-UDInput -Title "Start-Service" -SubmitText 'Start'  -Endpoint {
                    Start-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status
                    New-UDInputAction -Toast $Test
                    $Test = 'bar'
                    New-UDInputAction -Toast $Test
                    New-UDInputAction -Content { Sync-UDElement -Id "Div1"}
                
                    }
             
                } 
            }
        }
    }
}

Start-UDDashboard -Dashboard $Dashboard -Port 1000

Some thing I did notice that was odd though, when your press the stop button twice I would Expect ‘foo’ ‘bar’ | ‘bar’ ‘bar’ but I get ‘foo’ ‘bar’ | ‘foo’ ‘bar’ in the pop Toast.
This is implying that the update $Test is getting reset back to ‘foo’ after each run.
Any ideas?
Maylife

@ maylife The link you referenced is where I started on dynamic pages. Just have to play with the example to get the experience. I put together a UDGrid showing the Windows Services with start and stop buttons. The buttons need a little more work to have them functional. The refresh icon in the bottom right corner does pickup the current status for each service.


$ServicesStatus = New-UDPage -Name "Windows Service Dashboard" -Icon home -Content {

  New-UDGrid -Title "Windows Service Report" -Endpoint {
    $servicesDB = Get-Service;
    [int]$psIdx = $servicesDB.Count - 1;
    if ($psIdx -gt 0) {
      $PSreports = 0 .. $psIdx | ForEach-Object {
        [PSCustomObject] @{Status = 'data1'; Name = 'data2'; DisplayName = 'data3'; Action = 'data4';}
      }
    } else {
      $PSreports = [PSCustomObject] @{Status = 'data1'; Name = 'data2'; DisplayName = 'data3'; Action = 'data4';}
    }
    $psIdx = 0;
    $servicesDB | ForEach-Object {
        $PSreports[$psIdx].Name = $_.Name
        $PSreports[$psIdx].DisplayName = $_.DisplayName
        if ($_.Status -eq "Running") {
          $PSreports[$psIdx].Status = "Running";
          $PSreports[$psIdx].Action = New-UDButton -Text "Stop" -BackgroundColor Red -OnClick (New-UDEndpoint -Endpoint {
            Stop-Service $_.Name;
            Show-UDToast -Message "Stopped $_.Name" -CloseOnClick
          })
        } else {
          $PSreports[$psIdx].Status = "Stopped";
          $PSreports[$psIdx].Action = New-UDButton -Text "Start" -BackgroundColor Green -OnClick (New-UDEndpoint -Endpoint {
            Start-Service $_.Name;
            Show-UDToast -Message "Started $_.Name" -CloseOnClick
          })
        }
        $psIdx++;
    }

    $PSreports | Select-Object Status,Name,DisplayName,Action | Out-UDGridData

  }
}

$DB1 = New-UDDashboard -Title "Windows Service Dashboard" `
  -Pages @($ServicesStatus);

Start-UDDashboard -Name "Services" -Dashboard $DB1 -Port 10062;```
2 Likes

Hi, cadayton

You just beat me to the punch I got my dashboard working aswell,
(Yours also looks cleaner than mine though)

My issue was as you said I wasn’t using a dynamic page, so I was unable to call it New-UDInputAction -RedirectUrl "Dympage"

As well as what Guy said about I needed to reload the element New-UDInputAction -Content {Sync-UDElement -Id "Div1"}

As S.stauts is read-only ( as its a ServiceController )

I had to re-lookup Get-Service in my switch.

Switch ((Get-Service ($S.name)).Status) {
(Get-Service (($S).name)).Status) -Color red

Etc. It’s not pretty, but it is working now.

I really like your layout and the use of the Else is a good call for screen space.

Thank you both so much for your help,
I think I know how to proceed from here, but any tips would be appreciated.
As I’m sure you can tell, I’m very new to UD (It’s fantastic) and I would very much like to improve my skills with it.

Warm Regards
Maylife

Code below in the case anyone needs it

$Service = Get-Service
Stop-UDDashboard -port 1000

$page1 = New-udpage  -name "Dympage" -Content {
New-UDHeading -Text "Here is a list of Services Running on your computer" -Size 5

New-UDElement -Tag div -Id "Div1" -Endpoint {
    New-UDLayout   -Columns 6 -Content {  
   
        ForEach ($S in $Service) {
            New-UDCard  -Content {

            
                New-UDParagraph -Text ('Name: '+ $S.name) 
                New-UDParagraph -Text ('DisplayName: ' + $S.DisplayName)
                
                Switch ((Get-Service ($S.name)).Status) {
                    'Stopped' { New-UDParagraph -Text ('Status: ' + (Get-Service (($S).name)).Status) -Color red }
                    'Running' { New-UDParagraph -Text ('Status: ' + (Get-Service (($S).name)).Status) -Color green }
                     Default  { New-UDParagraph -Text ('Status: ' + (Get-Service (($S).name)).Status) }
                }
                New-UDInput -Title "Stop-Service" -SubmitText 'Stop' -Endpoint {
                    stop-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status
                    New-UDInputAction -Content {Sync-UDElement -Id "Div1"}
                    New-UDInputAction -RedirectUrl "Dympage"
        
                }
                New-UDInput -Title "Start-Service" -SubmitText 'Start'  -Endpoint {
                    Start-Service $S.name
                    New-UDInputAction -Toast (Get-Service $S.name).Status
                    New-UDInputAction -Content { Sync-UDElement -Id "Div1"}
                    New-UDInputAction -RedirectUrl "Dympage"
                
                    }
                } 
            }
        }
    }
}

$Dashboard = New-UDDashboard -Pages @($Page1)
Start-UDDashboard -Dashboard $Dashboard -Port 1000
1 Like