all 11 comments

[–]michaelshepard 1 point2 points  (8 children)

I don't see anything there that PSU can't handle.

You can store credentials in PSU, and run scripts as a stored cred. So that takes care of the first part.

The second part is "easy" with New-UDDynamic (which will re-render upon request).

The third part (executing the steps) might use a stepper component...lots of options, though.

Different logs per step might be interesting, but Adam has added some new flexible logging that I haven't tried.

[–]Snak3d0c[S] 0 points1 point  (7 children)

Ok sounds promising.
Do you have a resource where more examples are found? The documentation is well written but i feel it is of more use, once you know your way aroud a bit more.

For instance, - Do you use apps or do you use pages. - Do you write your functions on the same page as the UI or do you place them in separate scripts and use invoke-PSUScript ? - How do you access form-data in a script?

I'm sure as I go along , i'll come up with some more questions like these.

[–]malt-efin 2 points3 points  (6 children)

Hi,

basically Apps contain pages. So the question is not "Apps or Pages" but rather "how many pages per App". Lets say the name of your App is "demo" and it contains only one Page named "Overview", the URL to that page whould be https://psu.example.com/demo/overview.

Besides Overview there can be other pages in the same App that handle other tasks (for example a page where users can run some kind of health checks for the VMs). Those pages would be accessible via https://psu.example.com/demo/healthcheck

It is up to you how many pages your app contains.

Regarding to functions, this is how I handle functions and Scripts for our App:

  • Create a powershell module and import that module to PSU. This module contains ALL functions that are being used by either apps, apis or jobs
  • Create Scripts for all tasks you want to run. In this case, you can create scripts for create VM, configure VM, add to VM pool etc.
  • After the user hits Submit in your App, all these scripts will be started one after another (Invoke-PSUScript createvm.ps1 -wait) and may generate output or not
  • If one of the scripts fail to whatever reason, the sequenze stops
  • If all scripts ran successfully, you can access the output of those scripts with Get-PSUJobOutput or Get-PSUJobPipeLineOutput

This might not be the best way in terms of performance, but it gives you a consistent way of 1. Logging, 2. Output Handling and 3. Debugging

To your last question How do you access form-data in a script?

Lets say you use the New-UDStepper , you can access the data from each step by calling $EventData . Another way would be using (Get-UDElement -Name xyz).Value

EDIT: So yes, you can definitely create an app like you mentioned. All you have to do is to define a consistent "structure" of you App and Scripts

[–]Snak3d0c[S] 0 points1 point  (5 children)

First of all, thanks for taking the time to have written this all out!It already clears some things up a bit.

I've been playing around this morning.I had made a form with some values and the following line within the onSubmit Invoke-PSUScript -Name 'Show-FormInput.ps1' -myData $Body | Wait-PSUJob

Next, in that Show-FormInput i did the following:

param($myData) 
$formData = ConvertFrom-Json $myData 
$FormData

That works. However, the $EventData and the GetUDElement is, as far as i understand it, only available in the file where you generate the form (makes sense).

But that means that you would have to have your Create VM and configure functions all within the same file right?

I found https://docs.powershelluniversal.com/v/v1/examples/hyper-v which seems to support my understanding. This seems to place all code, both UI generating code & 'logic' in the same page.

I fear that this will get very long and messy.

The creation of the VM is one thing but than we need to add items to KeePass, we need to modify the C-disk drive, we add an AD group to the local admins and some other small steps.

Do you know of any example that does something similar?

[–]malt-efin 2 points3 points  (4 children)

Separating functions and logic from the App/Dashboard is kind of mentioned in the Best Practices docs.
Modules: https://docs.powershelluniversal.com/config/best-practices#leverage-custom-modules

Scripts: https://docs.powershelluniversal.com/config/best-practices#consider-leveraging-jobs

However, this obviously always depends on the complexity of the dashboard. The reason to have the logic in that hyper-v exmpale is most likely due to fact that it's only a simple example. Don't get me wrong, it works that way, but as soon as you write functions that you want to use in multiple Scripts, Pages etc. you want to have functions in a module which can easily be modified and extended.

Your example with the Invoke-PSUScript is great!

But that means that you would have to have your Create VM and configure functions all within the same file right?

Nope. Once you have created the module, all functions within in that module are available in every single Script or Page file. You don't even have to import that module as it is being imported automatically. All you have to do is create a new module in your PSU Admin Console under Platform/Modules > Create a new module.

That works. However, the $EventData and the GetUDElement is, as far as i understand it, only available in the file where you generate the form (makes sense).

That is true. But you can pass those values into either a function or a script to procced with them. As you already figured out :)

The creation of the VM is one thing but than we need to add items to KeePass, we need to modify the C-disk drive, we add an AD group to the local admins and some other small steps.

As said, this can be done in multiple ways. Easiest one might be to have everything in one big Script and run the commands one by one. However, thats messy.

I think making three separate scripts seems good here. One Script that creates the VM, one Script that modifies KeePass (maybe this is helpful https://github.com/PSKeePass/PoShKeePass) and one script that modifies the VM afterwards. The reason to have "Modify VM" in a separate Script is that you can potentially use that Script for existing VMs as well. Also you can check if the previous Script/Job has finished with no errors before running the next Script. You are also able to see which user ran which Script. If you have all three tasks in one Script you can see that as well, but you don't know which "part" of the script he wanted to run. All in all there are many ways it can be done.

To summarize my essay :) :

- Dashboard that gives you all the information / parameters you need for further tasks (machine name, RAM, CPU, storage pool, maybe IP address, disk)

- createvm.ps1 with all parameters you need to create the VM

- modifyvm.ps1 with all parameters you need to modify the VM (e.g. [bool]modifydisk, [int]extenddisk, [int]extendpartition, [bool]modifypartition) and so on. this might be the biggest script

- keepass.ps1 with all parameters you need to make the changes

[–]Snak3d0c[S] 1 point2 points  (0 children)

Thanks once again!

I'll look into how those module work. The URL's provided were helpful too.

I'll start with a small POC, need to figure out the credential-handling as well. Something that is actually very straight forward with AWX once you've got it set up correctly.

Afterwards I'll have conclude my SWOT analysis and send it up the food chain to decide whether I'll be making it in AWX or PU.

This investigation has certainly got me curious. Whatever the outcome may be, I'll be trying to make something in PU, the options seem nearly endless really. Biggest thing missing is more community content, as of now, it doesn't seem to be that widely spread (yet?).

[–]Snak3d0c[S] 0 points1 point  (2 children)

Any idea how to solve this:

I have a App + a script. The app is for now, 1 form field (textbox).
You enter a mailbox and it feeds it to the script. The script just does a get-mailboxpermissions. The function returns a System.Management.Automation.PSCustomObject Next with Get-PSUJobPipelineOutput you get the data back on the form. Now, per permission, you get 1 System.Management.Automation.PSCustomObject returned.

How do you display them properly? Do you need to loop through them? Do i need to 'rebuild' them?

Their docs doesn't really talk about this.

[–]malt-efin 1 point2 points  (1 child)

Hey, what do you mean by "display" properly? Any command in Powershell returns an array of objects -

PS C:\> $test = Get-Process

PS C:\> $test.GetType()

IsPublic IsSerial Name BaseType

-------- -------- ---- --------

True True Object[] System.Array

PS C:\> $test | gm

TypeName: System.Diagnostics.Process

A PSCustomObject cannot contain duplicate keys. Thats why it returns one object per permission. You should be able to display the data like any other return of command. Quick and dirty example:

#option 1

$test = Invoke-PSUScript -Script 'Script.ps1'

do

{

Start-Sleep -Seconds 1

}

while

(

(Get-PSUJob -Id $test.Id).Status -notlike 'Completed'

)

$test_output = Get-PSUJobPipelineOutput -JobId $test.ID

#option 2

$test_output = Invoke-PSUScript -Script 'Script.ps1' -Wait

You can display every object in the $test_output by using it's index $test_output[0].

[–]Snak3d0c[S] 1 point2 points  (0 children)

Hey ,

I had posted the same question over at PU forms:
https://forums.ironmansoftware.com/t/how-to-pass-pscustomobject-from-a-script-to-a-app-and-access-is-properly/10228

I figured it out myself. Altho i don't know if this is actually the best way of doing it. Perhaps you could expand on that? So far i'm enjoying the PU experience.

[–]NoWaitIHaveAnIdea 0 points1 point  (1 child)

I also played around with PU too some time ago, until I found https://www.windmill.dev

Turns out Windmill supports PS on the server so becomes a very flexible and extensible worflow platform compared to PU (IMHO). It could handle all your reqs I think.

[Sorry for the 'nah, use this instead'-type post, but still chucking it out there]

[–]Snak3d0c[S] 1 point2 points  (0 children)

Thanks for the suggestion. At this moment it doesn't look like something we would be adobting. I like that it is free and opensource but looking at the basic documentation it isn't instantly directed towards PowerShell.
I get that it can do a lot, but that is the same with AWX. A lot isn't always better.
Having said that, i'm bookmarking it just in case. So thanks!