Community Showcase

Explore and share solutions built with Devolutions PowerShell Universal

avatar

DataTraveler

Connect your AI service to PowerShell Universal with MCP

You can connect an AI service to PSU, ask questions in plain English, and have it use the PowerShell tools you choose to expose. The connection uses MCP (Model Context Protocol) , a standard way for AI applications to work with external tools and data. Through its MCP-capable client, the AI service calls a tool, PSU runs the PowerShell, and the AI service uses the returned result in its answer. You’ll need an AI service with an MCP-capable client. That could be a commercial AI service, or an application connected to a large language model (LLM) your organization provides . In either case, you need a compatible application and model that can work with tools. Familiar MCP-capable options include GitHub Copilot in VS Code , Codex and Claude Code . I built Incident Command Center (ICC) as a working example so you can try this connection and see how you might use it yourself. Version 0.1.3 is now available as a regular release. ICC provides a small incident rehearsal at fictional Acme Inc. Once connected, try asking your AI service: Use ICC_Demo_Incident. What needs attention in the current rehearsal? Acknowledge it, check that the response was saved, try acknowledging it again, and prepare a handoff. Stop if any tool call fails. The AI service uses PSU tools to carry out that workflow. You can then check the same saved response in the dashboard. The warning is synthetic; the acknowledgment is a real record saved on the server, and it performs no service repair. [image] ICC is a starting point for learning the pattern. You could build other PSU tools to answer questions about your automation, retrieve application data or run selected administrative workflows. Start with the 0.1.3 download , README and FAQ , and MCP connection guide . Existing installations should follow updating and recovery . This example targets Windows, PSU and Devolutions.PowerShellUniversal 2026.3.3, and PowerShell 7.5.4 or later , with an app-capable PSU license and an Administrator app token. The documented AI walkthrough was tested with Codex ; other clients and organization-provided model setups need separate validation. It remains a single-server learning example. If you’ve been looking for a practical way to try AI with your existing PowerShell work, I hope this gives you a useful place to start.

45

0

avatar

check_of

Can't create topics?

re-registered and can't seem to create a topic? Testing

64

2

avatar

michaeelphillips

avatar

steviecoaster

Bookworm - Your own personal library catalog

Yes, GoodReads exists. But this allowed me to make a Barcode Scanner component so I could scan ISBN numbers from my phone in a store to prevent duplicate purchases. Repo with screenshots: https://github.com/steviecoaster/PowerShellUniversal.Apps.Bookworm

265

2

avatar

michaeelphillips

avatar

rodmacleod

Workflow and Automation

I’ve been working on a Workflow Manager built on PowerShell Universal that has gradually evolved into a fairly comprehensive IT automation and self-service platform. The goal is to make it possible to build, manage, and securely expose IT automation without having to create a custom PowerShell Universal page for every task. Workflows are created visually from reusable actions and can have configurable inputs, dynamic lookups, conditional logic, transitions, approvals, scheduling, and multi-step processes. Actions can use PowerShell as well as integrations with systems such as Active Directory, Microsoft Graph/Microsoft 365, NinjaOne, HaloPSA and other services, while a Script Runner is available when a purpose-built action doesn’t exist. The application also includes a Form Builder and Report Manager , allowing custom user-facing forms, dashboards and reports with cards, grids, tabs, charts, lookups, dynamic content and conditional visibility. It has its own role-based security and approval system , controlling who can see, run, edit and publish individual workflows and reports, with support for access requests and workflows that require approval before execution. More recently I’ve added AI-assisted workflow creation , where the AI understands the available actions, integrations and application capabilities and can build workflows from a natural-language request, preferentially using existing built-in actions rather than generating PowerShell unnecessarily. The overall goal has become something closer to a low-code IT automation platform built on PowerShell Universal —allowing administrators to build reusable automation once and then safely expose it to IT staff or end users through a simple self-service interface. [image] [image] [image] [image] [image] [image] [image]

158

6

avatar

rodmacleod

avatar

Adam Driscoll

VM Onboarding Wizard

This was an example I made using our new MCP server for a user that was looking to replace some existing VM onboarding tools. [image] <# .SYNOPSIS Sample PowerShell Universal app for collecting and reviewing a VM creation request. .NOTES This version has been anonymized for sharing. Organization-specific values such as location names, Active Directory paths, VLAN identifiers, PAM group names, and patching group identifiers have been replaced with generated sample data. The application flow and validation behavior are otherwise unchanged. #> $vlanOptions = @( '0100', '0101', '0102', '0103', '0104', '0105', '0106', '0107', '0108', '0109', '0110', '0111', '0112', '0113', '0114', '0115', '0116', '0117', '0118', '0119', '0120', '0121', '0122', '0123', '0124', '0125', '0126', '0127', '0128', '0129', '0130', '0131', '0132', '0133', '0134', '0135', '0136', '0137', '0138', '0139', '0140', '0141', '0142', '0143', '0144', '0145', '0146', '0147', '0148', '0149', '0150', '0151', '0152', '0153', '0154', '0155', '0156', '0157' ) $serverPatchingGroupOptions = @( @{ Name = 'Manual Patching'; Value = 'Manual Patching' }, @{ Name = 'Every week on Sunday at 0200 AM'; Value = 'server - patch - (010200) Every week on Sunday at 0200 AM' }, @{ Name = 'Every week on Sunday at 0300 AM'; Value = 'server - patch - (010300) Every week on Sunday at 0300 AM' }, @{ Name = 'Every week on Sunday at 0400 AM'; Value = 'server - patch - (010400) Every week on Sunday at 0400 AM' }, @{ Name = 'Every week on Sunday at 0500 AM'; Value = 'server - patch - (010500) Every week on Sunday at 0500 AM' }, @{ Name = 'Every week on Sunday at 0600 AM'; Value = 'server - patch - (010600) Every week on Sunday at 0600 AM' }, @{ Name = 'Every week on Sunday at 0700 AM'; Value = 'server - patch - (010700) Every week on Sunday at 0700 AM' }, @{ Name = 'Every week on Sunday at 0800 AM'; Value = 'server - patch - (010800) Every week on Sunday at 0800 AM' }, @{ Name = 'Every week on Sunday at 1200 PM'; Value = 'server - patch - (011200) Every week on Sunday at 1200 PM' }, @{ Name = 'Every week on Monday at 0200 AM'; Value = 'server - patch - (020200) Every week on Monday at 0200 AM' }, @{ Name = 'Every week on Monday at 0300 AM'; Value = 'server - patch - (020300) Every week on Monday at 0300 AM' }, @{ Name = 'Every week on Monday at 0400 AM'; Value = 'server - patch - (020400) Every week on Monday at 0400 AM' }, @{ Name = 'Every week on Monday at 0500 AM'; Value = 'server - patch - (020500) Every week on Monday at 0500 AM' }, @{ Name = 'Every week on Monday at 0600 AM'; Value = 'server - patch - (020600) Every week on Monday at 0600 AM' }, @{ Name = 'Every week on Monday at 0700 AM'; Value = 'server - patch - (020700) Every week on Monday at 0700 AM' }, @{ Name = 'Every week on Monday at 0800 AM'; Value = 'server - patch - (020800) Every week on Monday at 0800 AM' }, @{ Name = 'Every week on Tuesday at 0200 AM'; Value = 'server - patch - (030200) Every week on Tuesday at 0200 AM' }, @{ Name = 'Every week on Tuesday at 0300 AM'; Value = 'server - patch - (030300) Every week on Tuesday at 0300 AM' }, @{ Name = 'Every week on Tuesday at 0400 AM'; Value = 'server - patch - (030400) Every week on Tuesday at 0400 AM' }, @{ Name = 'Every week on Tuesday at 0500 AM'; Value = 'server - patch - (030500) Every week on Tuesday at 0500 AM' }, @{ Name = 'Every week on Tuesday at 0600 AM'; Value = 'server - patch - (030600) Every week on Tuesday at 0600 AM' }, @{ Name = 'Every week on Tuesday at 0700 AM'; Value = 'server - patch - (030700) Every week on Tuesday at 0700 AM' }, @{ Name = 'Every week on Tuesday at 0800 AM'; Value = 'server - patch - (030800) Every week on Tuesday at 0800 AM' }, @{ Name = 'Every week on Wednesday at 0200 AM'; Value = 'server - patch - (040200) Every week on Wednesday at 0200 AM' }, @{ Name = 'Every week on Wednesday at 0300 AM'; Value = 'server - patch - (040300) Every week on Wednesday at 0300 AM' }, @{ Name = 'Every week on Wednesday at 0400 AM'; Value = 'server - patch - (040400) Every week on Wednesday at 0400 AM' }, @{ Name = 'Every week on Wednesday at 0500 AM'; Value = 'server - patch - (040500) Every week on Wednesday at 0500 AM' }, @{ Name = 'Every week on Wednesday at 0600 AM'; Value = 'server - patch - (040600) Every week on Wednesday at 0600 AM' }, @{ Name = 'Every week on Wednesday at 0700 AM'; Value = 'server - patch - (040700) Every week on Wednesday at 0700 AM' }, @{ Name = 'Every week on Wednesday at 0800 AM'; Value = 'server - patch - (040800) Every week on Wednesday at 0800 AM' }, @{ Name = 'Every week on Thursday at 0200 AM'; Value = 'server - patch - (050200) Every week on Thursday at 0200 AM' }, @{ Name = 'Every week on Thursday at 0300 AM'; Value = 'server - patch - (050300) Every week on Thursday at 0300 AM' }, @{ Name = 'Every week on Thursday at 0400 AM'; Value = 'server - patch - (050400) Every week on Thursday at 0400 AM' }, @{ Name = 'Every week on Thursday at 0500 AM'; Value = 'server - patch - (050500) Every week on Thursday at 0500 AM' }, @{ Name = 'Every week on Thursday at 0600 AM'; Value = 'server - patch - (050600) Every week on Thursday at 0600 AM' }, @{ Name = 'Every week on Thursday at 0700 AM'; Value = 'server - patch - (050700) Every week on Thursday at 0700 AM' }, @{ Name = 'Every week on Thursday at 0800 AM'; Value = 'server - patch - (050800) Every week on Thursday at 0800 AM' }, @{ Name = 'Every week on Friday at 0200 AM'; Value = 'server - patch - (060200) Every week on Friday at 0200 AM' }, @{ Name = 'Every week on Friday at 0300 AM'; Value = 'server - patch - (060300) Every week on Friday at 0300 AM' }, @{ Name = 'Every week on Friday at 0400 AM'; Value = 'server - patch - (060400) Every week on Friday at 0400 AM' }, @{ Name = 'Every week on Friday at 0500 AM'; Value = 'server - patch - (060500) Every week on Friday at 0500 AM' }, @{ Name = 'Every week on Friday at 0600 AM'; Value = 'server - patch - (060600) Every week on Friday at 0600 AM' }, @{ Name = 'Every week on Friday at 0700 AM'; Value = 'server - patch - (060700) Every week on Friday at 0700 AM' }, @{ Name = 'Every week on Friday at 0800 AM'; Value = 'server - patch - (060800) Every week on Friday at 0800 AM' }, @{ Name = 'Every week on Saturday at 0200 AM'; Value = 'server - patch - (070200) Every week on Saturday at 0200 AM' }, @{ Name = 'Every week on Saturday at 0300 AM'; Value = 'server - patch - (070300) Every week on Saturday at 0300 AM' }, @{ Name = 'Every week on Saturday at 0400 AM'; Value = 'server - patch - (070400) Every week on Saturday at 0400 AM' }, @{ Name = 'Every week on Saturday at 0500 AM'; Value = 'server - patch - (070500) Every week on Saturday at 0500 AM' }, @{ Name = 'Every week on Saturday at 0600 AM'; Value = 'server - patch - (070600) Every week on Saturday at 0600 AM' }, @{ Name = 'Every week on Saturday at 0700 AM'; Value = 'server - patch - (070700) Every week on Saturday at 0700 AM' }, @{ Name = 'Every week on Saturday at 0800 AM'; Value = 'server - patch - (070800) Every week on Saturday at 0800 AM' }, @{ Name = 'Monthly - 3rd Tuesday - 2100'; Value = 'LAB-SRV-PATCH - Monthly - 3rd Tuesday - 2100' }, @{ Name = 'Monthly - 3rd Tuesday - 2200'; Value = 'LAB-SRV-PATCH - Monthly - 3rd Tuesday - 2200' }, @{ Name = 'Everyday 0200 - DMZ/Workgroup'; Value = 'LAB-SRV-PATCH - Everyday 0200 - DMZ/Workgroup' }, @{ Name = 'server - patch - download and notify'; Value = 'server - patch - download and notify' } ) $pamUserGroups = @( 'None', 'LAB-SG-PAM-0001', 'LAB-SG-PAM-0002', 'LAB-SG-PAM-0003', 'LAB-SG-PAM-0004', 'LAB-SG-PAM-0005', 'LAB-SG-PAM-0006', 'LAB-SG-PAM-0007', 'LAB-SG-PAM-0008', 'LAB-SG-PAM-0009', 'LAB-SG-PAM-0010', 'LAB-SG-PAM-0011', 'LAB-SG-PAM-0012', 'LAB-SG-PAM-0013', 'LAB-SG-PAM-0014', 'LAB-SG-PAM-0015', 'LAB-SG-PAM-0016', 'LAB-SG-PAM-0017', 'LAB-SG-PAM-0018', 'LAB-SG-PAM-0019', 'LAB-SG-PAM-0020', 'LAB-SG-PAM-0021', 'LAB-SG-PAM-0022', 'LAB-SG-PAM-0023', 'LAB-SG-PAM-0024', 'LAB-SG-PAM-0025', 'LAB-SG-PAM-0026', 'LAB-SG-PAM-0027', 'LAB-SG-PAM-0028', 'LAB-SG-PAM-0029', 'LAB-SG-PAM-0030', 'LAB-SG-PAM-0031', 'LAB-SG-PAM-0032', 'LAB-SG-PAM-0033', 'LAB-SG-PAM-0034', 'LAB-SG-PAM-0035', 'LAB-SG-PAM-0036', 'LAB-SG-PAM-0037', 'LAB-SG-PAM-0038', 'LAB-SG-PAM-0039', 'LAB-SG-PAM-0040', 'LAB-SG-PAM-0041', 'LAB-SG-PAM-0042', 'LAB-SG-PAM-0043', 'LAB-SG-PAM-0044', 'LAB-SG-PAM-0045', 'LAB-SG-PAM-0046', 'LAB-SG-PAM-0047', 'LAB-SG-PAM-0048', 'LAB-SG-PAM-0049', 'LAB-SG-PAM-0050', 'LAB-SG-PAM-0051', 'LAB-SG-PAM-0052', 'LAB-SG-PAM-0053', 'LAB-SG-PAM-0054', 'LAB-SG-PAM-0055', 'LAB-SG-PAM-0056', 'LAB-SG-PAM-0057', 'LAB-SG-PAM-0058', 'LAB-SG-PAM-0059', 'LAB-SG-PAM-0060' ) $diskDriveLetterOptions = @( 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z' ) $diskSqlOptions = @('Yes', 'No') function Get-CreateVmSummaryItems { param($FormData) $operatingSystem = switch ($FormData.operatingSystem) { 'win2025' { 'Windows 2025' } 'win2022' { 'Windows 2022' } 'win2019' { 'Windows 2019' } 'win2016' { 'Windows 2016' } default { $FormData.operatingSystem } } $subnetMask = switch ($FormData.netMask) { '22' { '22 (255.255.252.0)' } '23' { '23 (255.255.254.0)' } '24' { '24 (255.255.255.0)' } '25' { '25 (255.255.255.128)' } '26' { '26 (255.255.255.192)' } '27' { '27 (255.255.255.224)' } '28' { '28 (255.255.255.240)' } default { $FormData.netMask } } @( [PSCustomObject]@{ Label = 'Email Address'; Value = $FormData.emailAddress }, [PSCustomObject]@{ Label = 'RITM Number'; Value = $FormData.ritmNum }, [PSCustomObject]@{ Label = 'Server Hostname'; Value = $FormData.hostName }, [PSCustomObject]@{ Label = 'Operating System'; Value = $operatingSystem }, [PSCustomObject]@{ Label = 'Location'; Value = $FormData.Location }, [PSCustomObject]@{ Label = 'Network VLAN'; Value = if ($FormData.vlan) { $FormData.vlan -replace '^vlan:', 'VLAN ' } else { '' } }, [PSCustomObject]@{ Label = 'IP Address'; Value = $FormData.ipAddress }, [PSCustomObject]@{ Label = 'Subnet Mask'; Value = $subnetMask }, [PSCustomObject]@{ Label = 'Default Gateway'; Value = $FormData.defaultGateway }, [PSCustomObject]@{ Label = 'Organizational Unit'; Value = $FormData.OU }, [PSCustomObject]@{ Label = 'Server Patching Group'; Value = $FormData.serverPatchingGroup }, [PSCustomObject]@{ Label = 'PAM User Group'; Value = $FormData.pamUserGroup }, [PSCustomObject]@{ Label = 'SecureLink Group'; Value = $FormData.secureLinkGroup }, [PSCustomObject]@{ Label = 'Additional Disks'; Value = $Session:DiskGrid.Count } ) } function Show-AddDiskModal { Show-UDModal -MaxWidth 'sm' -FullWidth -Header { New-UDTypography -Text 'Add Disk' } -Content { New-UDRow -Columns { New-UDColumn -SmallSize 6 -LargeSize 6 -Content { New-UDSelect -Id 'diskDriveLetter' -Label 'Drive Letter' -Option { foreach ($driveLetter in $diskDriveLetterOptions) { New-UDSelectOption -Name $driveLetter -Value $driveLetter } } } New-UDColumn -SmallSize 6 -LargeSize 6 -Content { New-UDTextbox -Id 'diskSize' -Label 'Size GB' -Placeholder '1 - 3072' } } New-UDRow -Columns { New-UDColumn -SmallSize 6 -LargeSize 6 -Content { New-UDTextbox -Id 'diskLabel' -Label 'Label' -Placeholder 'Enter disk label' } New-UDColumn -SmallSize 6 -LargeSize 6 -Content { New-UDSelect -Id 'diskSql' -Label 'SQL' -Option { foreach ($sqlOption in $diskSqlOptions) { New-UDSelectOption -Name $sqlOption -Value $sqlOption } } } } } -Footer { New-UDButton -Text 'Cancel' -OnClick { Hide-UDModal } New-UDButton -Text 'Add Disk' -OnClick { if ($Session:DiskGrid.Count -ge 5) { Show-UDToast -Message 'You can add a maximum of 5 disks.' -Duration 4000 return } $driveLetter = (Get-UDElement -Id 'diskDriveLetter').Value $sizeValue = (Get-UDElement -Id 'diskSize').Value $labelValue = (Get-UDElement -Id 'diskLabel').Value $sqlValue = (Get-UDElement -Id 'diskSql').Value if ([string]::IsNullOrWhiteSpace($driveLetter)) { Show-UDToast -Message 'Drive letter is required.' -Duration 4000 return } if ([string]::IsNullOrWhiteSpace($sizeValue)) { Show-UDToast -Message 'Size GB is required.' -Duration 4000 return } $parsedSize = 0 if (-not [int]::TryParse($sizeValue, [ref]$parsedSize)) { Show-UDToast -Message 'Size GB must be a whole number.' -Duration 4000 return } if ($parsedSize -lt 1 -or $parsedSize -gt 3072) { Show-UDToast -Message 'Size GB must be between 1 and 3072.' -Duration 4000 return } if (@($Session:DiskGrid | Where-Object { $_.DriveLetter -eq $driveLetter }).Count -gt 0) { Show-UDToast -Message "Drive letter $driveLetter is already in use." -Duration 4000 return } [void]$Session:DiskGrid.Add([PSCustomObject]@{ DriveLetter = $driveLetter Size = $parsedSize Label = $labelValue Sql = if ([string]::IsNullOrWhiteSpace($sqlValue)) { 'No' } else { $sqlValue } }) Hide-UDModal Sync-UDElement -Id 'diskGridSection' } } } New-udapp -content { $Session:DiskGrid = [System.Collections.ArrayList]::new() New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTypography -Text 'Create VM Request' } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDStepper -Id 'createVmStepper' -AlternativeLabel -NonLinear -NextButtonText 'Next Section' -BackButtonText 'Previous Section' -Steps { New-UDStep -Label 'Request Details' -OnLoad { New-UDTypography -Text 'Provide the core request details for the VM.' New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextBox -Id 'emailAddress' -Label 'Email Address' -Placeholder 'Enter your email address' -FullWidth } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextbox -Id 'ritmNum' -Label 'RITM Number' -Placeholder 'Enter the RITM number' -FullWidth } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextBox -Id 'hostName' -Label 'Server Hostname' -Placeholder 'Enter the server hostname' -FullWidth -OnValidate { if ($eventData.Length -gt 15) { New-UDValidationResult -ValidationError "HostName can not exceed 15 characters" } } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'operatingSystem' -Label 'Operating System' -FullWidth -Option { New-UDSelectOption -Name 'Windows 2025' -Value 'win2025' New-UDSelectOption -Name 'Windows 2022' -Value 'win2022' New-UDSelectOption -Name 'Windows 2019' -Value 'win2019' New-UDSelectOption -Name 'Windows 2016' -Value 'win2016' } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'Location' -Label 'Location' -FullWidth -Option { New-UDSelectOption -Name 'LAB-Compute-East-01' -Value 'LAB-Compute-East-01' New-UDSelectOption -Name 'LAB-Prod-Compute-01' -Value 'LAB-Prod-Compute-01' New-UDSelectOption -Name 'LAB-Prod-Storage-01' -Value 'LAB-Prod-Storage-01' New-UDSelectOption -Name 'LAB-Test-Dev-01' -Value 'LAB-Test-Dev-01' New-UDSelectOption -Name 'LAB-Archive-01' -Value 'LAB-Archive-01' } } } } New-UDStep -Label 'Network' -OnLoad { New-UDTypography -Text 'Enter the network configuration for the VM.' New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'vlan' -Label 'Network VLAN' -FullWidth -Option { foreach ($vlanOption in $vlanOptions) { New-UDSelectOption -Name "VLAN $vlanOption" -Value "vlan:$vlanOption" } } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextBox -Id 'ipAddress' -Label 'IP Address' -Placeholder 'Enter the IP address' -FullWidth } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'netMask' -Label 'Subnet Mask' -FullWidth -Option { New-UDSelectOption -Name '22 (255.255.252.0)' -Value '22' New-UDSelectOption -Name '23 (255.255.254.0)' -Value '23' New-UDSelectOption -Name '24 (255.255.255.0)' -Value '24' New-UDSelectOption -Name '25 (255.255.255.128)' -Value '25' New-UDSelectOption -Name '26 (255.255.255.192)' -Value '26' New-UDSelectOption -Name '27 (255.255.255.224)' -Value '27' New-UDSelectOption -Name '28 (255.255.255.240)' -Value '28' } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextBox -Id 'defaultGateway' -Label 'Default Gateway' -Placeholder 'Enter the default gateway' -FullWidth } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'OU' -Label 'Organizational Unit' -FullWidth -Option { New-UDSelectOption -Name 'OU=Prod' -Value 'OU=prod,OU=servers,DC=example,DC=internal' New-UDSelectOption -Name 'OU=2022,OU=DEV' -Value 'OU=2022,OU=dev,OU=servers,DC=example,DC=internal' New-UDSelectOption -Name 'OU=2019,OU=DEV' -Value 'OU=2019,OU=dev,OU=servers,DC=example,DC=internal' New-UDSelectOption -Name 'OU=2016,OU=DEV' -Value 'OU=2016,OU=dev,OU=servers,DC=example,DC=internal' } } } } New-UDStep -Label 'Access' -OnLoad { New-UDTypography -Text 'Set maintenance and access-related options.' New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'serverPatchingGroup' -Label 'Server Patching Group' -FullWidth -Option { foreach ($serverPatchingGroupOption in $serverPatchingGroupOptions) { New-UDSelectOption -Name $serverPatchingGroupOption.Name -Value $serverPatchingGroupOption.Value } } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDSelect -Id 'pamUserGroup' -Label 'PAM User Group' -FullWidth -Option { foreach ($pamUserGroup in $pamUserGroups) { New-UDSelectOption -Name $pamUserGroup -Value $pamUserGroup } } } } New-UDRow -Columns { New-UDColumn -SmallSize 12 -LargeSize 12 -Content { New-UDTextBox -Id 'secureLinkGroup' -Label 'SecureLink Group' -Placeholder 'Enter the SecureLink group' -FullWidth } } } New-UDStep -Label 'Review and Disks' -OnLoad { New-UDTypography -Text 'Review the request details and manage any additional disks.' New-UDDivider -Id 'createVmReviewDivider' -Children { New-UDTypography -Text 'Request Summary' } -TextAlign 'left' $summaryItems = @(Get-CreateVmSummaryItems -FormData $Body) foreach ($summaryItem in $summaryItems) { if (-not [string]::IsNullOrWhiteSpace([string]$summaryItem.Value)) { New-UDTypography -Text "$($summaryItem.Label): $($summaryItem.Value)" } } New-UDDivider -Id 'createVmDiskDivider' -Children { New-UDTypography -Text 'Additional Disks' } -TextAlign 'left' New-UDDynamic -Id 'diskGridSection' -Content { $diskTableData = $Session:DiskGrid $diskColumns = @( New-UDTableColumn -Property 'DriveLetter' -Title 'Drive Letter' New-UDTableColumn -Property 'Size' -Title 'Size GB' New-UDTableColumn -Property 'Label' -Title 'Label' New-UDTableColumn -Property 'Sql' -Title 'SQL' New-UDTableColumn -Property 'Actions' -Title 'Actions' -Render { New-UDButton -Text 'Delete' -OnClick { [System.Collections.ArrayList]$Session:DiskGrid = $Session:DiskGrid | Where-Object { $_.DriveLetter -ne $EventData.DriveLetter } Sync-UDElement -Id 'diskGridSection' } } ) New-UDButton -Text 'Add Disk' -OnClick { Show-AddDiskModal } if ($diskTableData.Count -eq 0) { New-UDTypography -Text 'No disks added.' } else { New-UDTable -Title 'Disks' -Data $diskTableData -Columns $diskColumns -Dense } } } } -OnFinish { New-UDTypography -Text 'Request Overview' New-UDDivider -Id 'createVmFinishedOverviewDivider' -Children { New-UDTypography -Text 'Submitted Values' } -TextAlign 'left' $summaryItems = @(Get-CreateVmSummaryItems -FormData $EventData) foreach ($summaryItem in $summaryItems) { $value = if ([string]::IsNullOrWhiteSpace([string]$summaryItem.Value)) { 'Not provided' } else { [string]$summaryItem.Value } New-UDTypography -Text "$($summaryItem.Label): $value" } New-UDDivider -Id 'createVmFinishedDiskDivider' -Children { New-UDTypography -Text 'Additional Disks' } -TextAlign 'left' $diskTableData = $Session:DiskGrid if ($diskTableData.Count -eq 0) { New-UDTypography -Text 'No disks added.' } else { $diskOverviewColumns = @( New-UDTableColumn -Property 'DriveLetter' -Title 'Drive Letter' New-UDTableColumn -Property 'Size' -Title 'Size GB' New-UDTableColumn -Property 'Label' -Title 'Label' New-UDTableColumn -Property 'Sql' -Title 'SQL' ) New-UDTable -Id 'diskGridOverviewTable' -Title 'Disks' -Data $diskTableData -Columns $diskOverviewColumns -Dense } } } } }

272

0

1 - 5 of 5 items