Helps agents migrate PowerShell Windows Forms applications to PowerShell Universal App Framework apps by mapping WinForms controls, event handlers, state, desktop assumptions, and long-running workflows to PSU pages, components, endpoints, scopes, APIs, and automation jobs.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Helps agents migrate PowerShell Windows Forms applications to PowerShell Universal App Framework apps by mapping WinForms controls, event handlers, state, desktop assumptions, and long-running workflows to PSU pages, components, endpoints, scopes, APIs, and automation jobs.
winforms-to-psu
Use this skill when converting an existing PowerShell Windows Forms script or application into a PowerShell Universal (PSU) App Framework app.
The goal is not a one-to-one visual rewrite. Convert a single-user, stateful desktop script into a web/reactive PSU application where the browser renders components, PowerShell runs on the PSU server, and state is scoped deliberately.
When to use
The user has a PowerShell WinForms script using System.Windows.Forms.
The user wants a PSU app, dashboard, portal page, or App Framework implementation.
The task involves translating controls such as Form, Button, TextBox, DataGridView, TreeView, dialogs, menus, or event handlers.
The WinForms script uses control properties, global variables, synchronous click handlers, file dialogs, or desktop-only assumptions that need web equivalents.
Avoid this skill when
The user wants a custom JavaScript, React, Vue, Angular, Svelte, Vite, Tailwind, or static frontend hosted by PSU. Use custom-frontend-psu instead.
The task is only to install or run PSU. Use install-sandbox-psu when available.
The request is about a non-PSU web framework.
Migration workflow
Inventory the WinForms app:
List each form/window, control, control ID/name, event handler, data source, background task, file interaction, and global/module variable.
Identify desktop-only dependencies such as local files, registry access, services, printers, COM automation, UI automation, or machine-specific paths.
Separate UI code from business logic before rewriting. Preserve reusable PowerShell functions where possible.
Choose the PSU app shape:
Convert the main window to New-UDApp with one or more New-UDPage instances.
Convert secondary windows to routes/pages, Show-UDModal, drawers, expansion panels, or wizard-like dynamic regions.
Use responsive New-UDGrid, New-UDStack, New-UDContainer, New-UDCard, and New-UDPaper layouts instead of fixed desktop coordinates.
Map controls to PSU components using the table below.
Convert event handlers to PSU component endpoint scriptblocks, API endpoints, or Automation jobs.
Decide state scope explicitly for every value that was stored in a control, local variable, module variable, or global variable.
Rebuild flows as reactive web interactions:
Initial render creates components.
Event endpoints read values with Get-UDElement, update components with Set-UDElement, or rerender dynamic regions with Sync-UDElement.
Long-running operations move to scripts/jobs with progress polling or loading components.
Put selection handling on the group. receives the selected value.
Event handler conversion
WinForms event delegates become PSU [Endpoint] scriptblock parameters on components. These endpoint scriptblocks run server-side in PSU runspaces and emit changes to browser-rendered React components.
Common conversions:
WinForms pattern
PSU pattern
Notes
$button.Add_Click({ ... })
New-UDButton -OnClick { ... }
Use Get-UDElement for current values, Set-UDElement or Sync-UDElement for updates, and toast/modal components for feedback.
$textBox.Add_TextChanged({ ... })
New-UDTextbox -OnChange { ... }
$EventData is the current text/value. Avoid heavy work on every keystroke. Prefer -OnBlur, -OnEnter, or form submit for expensive logic.
WinForms scripts often store state in control properties, local variables captured by handlers, module variables, or global variables. In PSU, choose state based on who should see the value and how long it should live.
WinForms state source
PSU state target
Use when
Current control value such as $TextBox.Text or $CheckBox.Checked
Component/client state read by Get-UDElement -Id ...
The browser owns the current input value and the endpoint only needs it during an event.
Temporary per-tab flow value
$Page: scope
State is specific to one browser tab/page instance, such as a wizard step, selected row, search criteria, or transient form state.
Per-user workflow or preference
$Session: scope
State should survive page navigation/reload and be shared across tabs for the same user session.
Shared lookup data or expensive read-mostly data
$Cache: scope
Data is safe for all users and sessions. Never put per-user data, secrets, or mutable workflow state here. It does not expire automatically.
Local variables inside event handlers
Endpoint/local scope
Values are for one endpoint invocation. Do not treat them as durable UI state.
WinForms globals/module variables
Usually $Page:, $Session:, persistent storage, or a protected API/job boundary
Avoid process/global mutable state because PSU serves many users.
Rule of thumb: every WinForms variable must answer two questions before migration: "Who can see this?" and "How long should it live?" Then choose component value, $Page:, $Session:, $Cache:, persistent storage, or job output.
PSU web/reactive gotchas
PowerShell runs on the PSU server or agent, not on the user's desktop. Local paths, registry, services, printers, mapped drives, UI automation, and installed applications refer to the server unless you explicitly connect to a remote target.
Browser UI values are not live PowerShell object properties. Read them during an endpoint with Get-UDElement or receive them through $EventData.
Assign stable -Id values to interactive components that need to be read, updated, validated, or refreshed.
Replace direct control mutation such as $TextBox.Text = 'Done' with Set-UDElement, Add-UDElement, Clear-UDElement, or New-UDDynamic plus Sync-UDElement.
Use New-UDDynamic -LoadingComponent, New-UDButton -ShowLoading, progress indicators, jobs, and polling for long operations. Do not block click handlers for work that should run asynchronously.
Do not move single-user WinForms globals into $Cache: or process-global variables unless the data is intentionally shared across every connected user.
Use New-UDTable -LoadData or New-UDDataGrid -LoadRows for large datasets. Do not load huge data into the page like a desktop-bound DataGridView.
In table column renderers or nested components, capture row data into a separate variable before defining an inner -OnClick; nested event $EventData can overwrite the outer row context.
Set-UDElement, Add-UDElement, Clear-UDElement, and Sync-UDElement can use -Broadcast. Default to updating the current connection unless cross-client updates are intentional.
Component endpoints inherit app user context. Custom APIs need explicit New-PSUEndpoint -Authentication, -Role, timeout, and environment settings when appropriate.
Browser file exchange uses uploads, downloads, published folders, or API endpoints. OpenFileDialog and SaveFileDialog do not translate to client filesystem access.
Practical conversion checklist
Create an inventory of controls, events, state variables, data sources, file interactions, and desktop-only dependencies.
Decide app/page/modal/navigation structure before writing component code.
Map every WinForms control to a PSU component and assign IDs to interactive components.
Convert multi-input OK/Apply flows to New-UDForm -OnSubmit when practical.
Convert event handlers to -OnClick, -OnChange, -OnBlur, -OnEnter, -OnSubmit, -OnValidate, table -LoadData, grid -LoadRows, API endpoints, or Automation jobs.
Replace direct control property mutation with component updates or dynamic region refreshes.
Re-scope every global/module/local variable to component state, $Page:, $Session:, $Cache:, persistent storage, endpoint-local variables, or job output.
Move long-running work out of app event handlers into scripts/jobs and expose progress/status in the app.
Replace desktop file dialogs with New-UDUpload, Start-UDDownload, published folders, or API endpoints.
Add authentication and roles to pages, APIs, published folders, and server operations as needed.
Verify refresh, multiple tabs, multiple users, authorization, server file paths, large data, and failure/error states.
Useful prompt pattern
When delegating a migration to another agent, include PSU-specific constraints:
Convert this PowerShell WinForms script to a PowerShell Universal App Framework app. Inventory controls, event handlers, state variables, file interactions, long-running operations, and desktop-only dependencies first. Map controls to PSU components, use stable component IDs, convert grouped input to New-UDForm where practical, and move long-running work to Invoke-PSUScript jobs with progress polling. Do not use global mutable state for per-user data; choose component values, $Page:, $Session:, or $Cache: deliberately. Remember that PowerShell runs on the PSU server, not the browser client.
Final response guidance
When reporting a completed migration, include:
The WinForms controls and major flows converted.
The PSU pages, components, API endpoints, and Automation jobs created or changed.
The state scopes chosen for important values.
Any desktop assumptions that changed, especially file paths, client/server execution, authentication, and long-running operations.
The validation performed, such as PSU sandbox run, page render check, event handler test, API test, or script/job execution.