298 lines
27 KiB
JavaScript
298 lines
27 KiB
JavaScript
import { psadtCatalog } from './psadtCatalog.js';
|
|
|
|
const powershellCoreUrl = 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/?view=powershell-5.1';
|
|
|
|
function article(id, category, title, summary, sections, tags = []) {
|
|
return { id, category, title, summary, sections, tags };
|
|
}
|
|
|
|
function section(heading, body = [], code = '') {
|
|
return { heading, body, code };
|
|
}
|
|
|
|
function apiExample(method, route, description, body = '') {
|
|
const code = [
|
|
'$base = "http://localhost:3000"',
|
|
'$token = (Invoke-RestMethod -Method Post -Uri "$base/api/auth/login" -ContentType "application/json" -Body (@{ email = "admin@posh.local"; password = "change-me-now" } | ConvertTo-Json)).token',
|
|
'$headers = @{ Authorization = "Bearer $token" }',
|
|
body
|
|
? `Invoke-RestMethod -Method ${method} -Uri "$base${route}" -Headers $headers -ContentType "application/json" -Body (${body} | ConvertTo-Json -Depth 10)`
|
|
: `Invoke-RestMethod -Method ${method} -Uri "$base${route}" -Headers $headers`
|
|
].join('\n');
|
|
return section(`${method} ${route}`, [description], code);
|
|
}
|
|
|
|
const operationsArticles = [
|
|
article('ops-overview', 'Operations', 'Application Operations Overview', 'How operators move through POSHManager day to day.', [
|
|
section('Daily workflow', [
|
|
'Build scripts in the Scripts workspace, assign credentials to hosts in Host Library and Credential Vault, create RunPlans, execute jobs, then review job and system logs.',
|
|
'The UI is intentionally API-first. Every create, update, delete, execute, migration, and publishing action calls the Express API so automation can use the same workflows.'
|
|
]),
|
|
section('Navigation map', [
|
|
'Dashboard shows metrics, charts, recent jobs, and configurable widgets.',
|
|
'Scripts contains the VS Code-style Monaco PowerShell editor, script library, variable studio, and metadata panel.',
|
|
'PSADT contains the deployment factory, verifier, migration wizard, and Intune Publishing Wizard.',
|
|
'Hosts, Credential Vault, RunPlans, Logs, Users & Groups, and Config are separate operational surfaces.'
|
|
])
|
|
], ['dashboard', 'operations', 'navigation']),
|
|
article('ops-scripts', 'Operations', 'Scripts And Variables', 'Create folders, author scripts, use variables, and keep versions.', [
|
|
section('Script storage', [
|
|
'Use the Script Library rail to create folders and scripts. Right-click folders or scripts for contextual create/delete actions.',
|
|
'Scripts are versioned by the API. Saving an existing script creates a new script_versions row.'
|
|
]),
|
|
section('Variables', [
|
|
'Open Variable Studio from the script toolbar. POSHManager runtime variables can be inserted as PowerShell variables or token syntax.',
|
|
'Custom variables are encrypted at rest and can be personal, shared, or group-scoped.',
|
|
'PSADT reference variables are cataloged for authoring, but POSHManager does not fake PSADT runtime values. Those are available only inside a valid PSADT session.',
|
|
'The editor autocomplete suggests PowerShell cmdlets, PSADT functions, PSADT snippets, POSHManager variables, custom variables, and Asset Library reference tokens.'
|
|
])
|
|
], ['scripts', 'variables', 'monaco']),
|
|
article('ops-assets', 'Operations', 'Asset Library', 'Upload, organize, link, preview, and reference package assets.', [
|
|
section('What belongs here', [
|
|
'Use Assets for installers, archives, icons, detection scripts, configs, PSADT Files content, SupportFiles content, and reusable files referenced by normal PowerShell scripts.',
|
|
'The library has its own folder tree, separate from script folders, so deployment package content can be organized by app, vendor, platform, or lifecycle stage.',
|
|
'Uploaded files are handled by multer and stored under the API FileLocker tree by asset type: packages, images, scripts, configs, documents, or generic.'
|
|
]),
|
|
section('Using assets in scripts and packages', [
|
|
'Each asset has a reference token such as {{asset:ast_123}}. Insert the token from the asset details panel into a script when you need the API container file path during RunPlan execution.',
|
|
'Each asset also has a package path such as Files/setup.exe or SupportFiles/config.json. PSADT and Intune package-building workflows use that path to stage content into the correct deployment structure.',
|
|
'Assets can be linked to scripts, RunPlans, PSADT profiles, or Intune deployment plans with a role such as installer, support-file, icon, detection-script, or reference.'
|
|
])
|
|
], ['assets', 'packages', 'psadt', 'intune', 'uploads']),
|
|
article('ops-hosts-runplans', 'Operations', 'Hosts, Credential Vault, RunPlans, And Jobs', 'Manage target systems and execute scripts safely.', [
|
|
section('Hosts and credentials', [
|
|
'Create credentials in Credential Vault first, then attach them to hosts. Secrets are encrypted using AES-256-GCM.',
|
|
'Hosts support WinRM, SSH, local, and API transport metadata. PowerShell remoting and firewall prerequisites must be configured outside POSHManager.'
|
|
]),
|
|
section('RunPlans', [
|
|
'A RunPlan joins one script with one or more hosts. The backend creates a job and host-level log rows during execution.',
|
|
'RunPlans can be personal, shared, or group-scoped. Use the execute action to queue the plan.'
|
|
]),
|
|
section('Logs', [
|
|
'Job logs are aggregated by job and host. System Logs show Winston request/application logs for API request and response troubleshooting.'
|
|
])
|
|
], ['hosts', 'credentials', 'runplans', 'jobs', 'logs']),
|
|
article('ops-admin-config', 'Operations', 'Administration And Configuration', 'Manage users, groups, settings, themes, and deployment variables.', [
|
|
section('Users and groups', [
|
|
'Users & Groups is a dedicated administration menu item. Add users and groups through modal create flows.',
|
|
'Scripts, RunPlans, variables, PSADT profiles, and Intune deployment plans can use personal, shared, or group visibility.'
|
|
]),
|
|
section('Configuration', [
|
|
'Config is grouped into collapsible sections for Deployment, Authentication, Execution, Runtime, and Other settings, with Microsoft Graph Intune environments managed in the Config / Intune panel.',
|
|
'Settings can be controlled through the UI and environment variables for Docker deployment. Trusted origins, server FQDN, Entra fields, PowerShell binary, and script execution switch are key operational settings.'
|
|
])
|
|
], ['admin', 'groups', 'settings', 'docker'])
|
|
];
|
|
|
|
const apiArticles = [
|
|
article('api-auth-bootstrap', 'API', 'Authentication And Bootstrap API', 'Login, profile, health, and bootstrap examples with PowerShell.', [
|
|
apiExample('Post', '/api/auth/login', 'Authenticate with local credentials and receive a JWT token.', '@{ email = "admin@posh.local"; password = "change-me-now" }'),
|
|
apiExample('Get', '/api/auth/me', 'Return the current authenticated user.'),
|
|
apiExample('Put', '/api/auth/profile', 'Update display name, profile fields, and avatar URL.', '@{ displayName = "POSH Admin"; email = "admin@posh.local"; jobTitle = "Platform Administrator"; phone = ""; timezone = "America/Chicago"; avatarUrl = "" }'),
|
|
apiExample('Get', '/api/bootstrap', 'Return dashboard summary, settings payload, and Entra status.'),
|
|
section('Notes', [
|
|
'Use the Bearer token returned by /api/auth/login for every protected request.',
|
|
'The default development login is seeded only when the users table is empty. Change defaults for real deployments.'
|
|
])
|
|
], ['api', 'auth', 'bootstrap', 'powershell']),
|
|
article('api-library', 'API', 'Script Library API', 'Folder and script API usage with PowerShell examples.', [
|
|
apiExample('Get', '/api/folders', 'List visible folders.'),
|
|
apiExample('Post', '/api/folders', 'Create a script folder.', '@{ name = "Deployments"; parentId = $null; visibility = "shared" }'),
|
|
apiExample('Get', '/api/scripts', 'List visible scripts.'),
|
|
apiExample('Post', '/api/scripts', 'Create a script and initial version.', '@{ name = "Health Check.ps1"; folderId = $null; description = "Simple host health check"; content = "Get-Date"; visibility = "personal" }'),
|
|
apiExample('Put', '/api/scripts/scr_123', 'Update a script. Replace scr_123 with the script id.', '@{ name = "Health Check.ps1"; folderId = $null; description = "Updated"; content = "Get-ComputerInfo"; visibility = "personal" }')
|
|
], ['api', 'scripts', 'folders']),
|
|
article('api-assets', 'API', 'Asset Library API', 'Upload and manage package assets with PowerShell examples.', [
|
|
apiExample('Get', '/api/assets/folders', 'List visible asset folders.'),
|
|
apiExample('Post', '/api/assets/folders', 'Create an asset folder.', '@{ name = "Contoso VPN"; parentId = $null; description = "VPN package assets"; visibility = "shared" }'),
|
|
apiExample('Get', '/api/assets', 'List visible assets with referenceToken, packagePath, checksum, viewUrl, and downloadUrl metadata.'),
|
|
section('POST /api/assets', [
|
|
'Upload an asset with multipart form-data. The file field must be named file; metadata fields such as folderId, name, description, packagePath, visibility, and groupId travel alongside it.',
|
|
'The API uses multer to stage uploads into FileLocker/_incoming, then promotes them into FileLocker/assets/<bucket>/<assetId>/<filename>.'
|
|
], '$file = "/packages/install-notes.txt"\n$form = @{ file = Get-Item $file; folderId = ""; name = "install-notes.txt"; description = "Package note"; packagePath = "SupportFiles/install-notes.txt"; visibility = "shared" }\nInvoke-RestMethod -Method Post -Uri "$base/api/assets" -Headers $headers -Form $form'),
|
|
apiExample('Get', '/api/assets/ast_123/download', 'Download an asset. Replace ast_123 with the asset id.'),
|
|
apiExample('Post', '/api/assets/ast_123/links', 'Link an asset to a script, RunPlan, PSADT profile, or Intune deployment.', '@{ targetType = "script"; targetId = "scr_123"; linkRole = "reference"; packagePath = "SupportFiles/install-notes.txt" }')
|
|
], ['api', 'assets', 'uploads', 'packages']),
|
|
article('api-hosts-credentials-runplans', 'API', 'Hosts, Credentials, RunPlans, Jobs, And Logs API', 'Manage execution targets and inspect results through the API.', [
|
|
apiExample('Post', '/api/credentials', 'Create an encrypted username/password credential.', '@{ name = "WinRM Admin"; kind = "username_password"; username = "CONTOSO\\svc-posh"; secret = "change-me"; visibility = "personal" }'),
|
|
apiExample('Post', '/api/hosts', 'Create a managed host.', '@{ name = "APP01"; address = "app01.contoso.local"; fqdn = "app01.contoso.local"; osFamily = "windows"; transport = "winrm"; port = 5986; credentialId = $null; tags = @("prod","web"); notes = "" }'),
|
|
apiExample('Post', '/api/runplans', 'Create a RunPlan. hostIds should contain existing host ids.', '@{ name = "Patch Validation"; description = "Run validation script"; scriptId = "scr_123"; visibility = "shared"; parallel = $true; hostIds = @("hst_123") }'),
|
|
apiExample('Post', '/api/runplans/rp_123/execute', 'Execute a RunPlan and create a job. Replace rp_123 with the RunPlan id.'),
|
|
apiExample('Get', '/api/jobs', 'List job history.'),
|
|
apiExample('Get', '/api/jobs/job_123', 'Read one job with host rows and logs.'),
|
|
apiExample('Get', '/api/logs/system', 'Read system/request logs from the Winston log stream.')
|
|
], ['api', 'credentials', 'hosts', 'runplans', 'jobs']),
|
|
article('api-psadt', 'API', 'PSADT And Intune API', 'Use the PSADT catalog, verifier, migration wizard, profiles, and Intune publishing plans through API calls.', [
|
|
apiExample('Get', '/api/psadt/catalog', 'Return PSADT source links, module/function/ADMX catalogs, snippets, and Intune publishing guidance.'),
|
|
apiExample('Post', '/api/psadt/validate', 'Validate raw PSADT script content.', '@{ platform = "intune"; content = "Invoke-AppDeployToolkit.exe -DeploymentType Install" }'),
|
|
apiExample('Post', '/api/psadt/migration/plan', 'Plan a legacy script migration to PSADT 4.2.0.', `@{ targetVersion = "4.2.0"; content = "Deploy-Application.ps1\`nExecute-Process -Path setup.exe\`n$appName = 'Legacy App'" }`),
|
|
apiExample('Post', '/api/psadt/profiles', 'Create a reusable PSADT deployment profile.', '@{ name = "Edge Enterprise"; appVendor = "Microsoft"; appName = "Edge"; appVersion = "126.0"; appArch = "x64"; appLang = "EN"; appRevision = "01"; templateVersion = "v4"; deploymentType = "Install"; deployMode = "Auto"; requireAdmin = $true; zeroConfig = $false; suppressReboot = $false; closeProcesses = @(); installTasks = @(@{ type = "exe"; phase = "Install"; filePath = "setup.exe"; arguments = "/S"; secureArguments = $false }); uiPlan = @{ welcome = $true }; configPlan = @{}; admxPlan = @{}; visibility = "shared" }'),
|
|
apiExample('Post', '/api/psadt/intune/deployments', 'Create an Intune Publishing Wizard plan.', '@{ name = "Edge Pilot"; sourceFolder = "C:\\Packages\\Edge\\PSADT"; intunewinFile = "Edge.intunewin"; commandStyle = "v4"; installBehavior = "system"; restartBehavior = "return-code"; uiMode = "native-v4"; requirements = @{ architecture = "x64"; minOs = "Windows 10 22H2"; diskSpaceMb = 512; runAs32Bit = $false }; installCommand = "Invoke-AppDeployToolkit.exe -DeploymentType Install"; uninstallCommand = "Invoke-AppDeployToolkit.exe -DeploymentType Uninstall"; detectionType = "custom-script"; detectionRule = "Write-Output detected"; returnCodes = @(@{ code = 0; type = "success"; meaning = "OK" }, @{ code = 1602; type = "retry"; meaning = "Deferred" }, @{ code = 3010; type = "softReboot"; meaning = "Reboot" }); assignments = @(@{ ring = "Pilot"; intent = "available"; groupName = "IT Pilot"; notes = "Validate" }); status = "ready"; visibility = "shared" }')
|
|
], ['api', 'psadt', 'intune', 'migration'])
|
|
,
|
|
article('api-graph-intune', 'API', 'Microsoft Graph Intune Tracking API', 'Configure Graph environments in Config / Intune and sync Intune deployment status for PSADT publishing plans.', [
|
|
apiExample('Post', '/api/graph/connections', 'Create a Microsoft Graph environment. In the UI this belongs under Config / Intune. The client secret is encrypted and never returned.', '@{ name = "Production Intune"; tenantId = "contoso.onmicrosoft.com"; clientId = "00000000-0000-0000-0000-000000000000"; clientSecret = "secret"; cloud = "global"; graphBaseUrl = "https://graph.microsoft.com"; authorityHost = "https://login.microsoftonline.com"; defaultApiVersion = "v1.0"; enabled = $true; visibility = "shared" }'),
|
|
apiExample('Post', '/api/graph/connections/graph_123/test', 'Test token acquisition and Intune app read access. Replace graph_123 with the connection id.'),
|
|
apiExample('Get', '/api/graph/connections/graph_123/mobile-apps?q=Edge', 'List Intune mobile apps visible to the Graph app registration.'),
|
|
apiExample('Post', '/api/psadt/intune/deployments/intune_123/graph/link', 'Link a POSHManager Intune deployment plan to an Intune mobileApp id.', '@{ connectionId = "graph_123"; graphAppId = "intune-mobile-app-id" }'),
|
|
apiExample('Post', '/api/psadt/intune/deployments/intune_123/graph/sync', 'Sync device/user install status and failure details from Microsoft Graph Intune reports.', '@{ connectionId = "graph_123"; graphAppId = "intune-mobile-app-id"; mode = "reports" }'),
|
|
apiExample('Get', '/api/psadt/intune/deployments/intune_123/graph/status', 'Read stored status rows, failure rows, and sync run history for a deployment.')
|
|
], ['api', 'graph', 'intune', 'failures'])
|
|
];
|
|
|
|
const psadtArticles = [
|
|
article('psadt-integration-overview', 'PSADT', 'PSADT Integration Overview', 'How POSHManager supports PSAppDeployToolkit authoring, verification, migration, and publishing.', [
|
|
section('What is modeled', [
|
|
'POSHManager catalogs PSADT variables, functions, ADMX policy surface, deployment structure, launch commands, snippets, and upstream v4 template shape.',
|
|
'Profiles generate Invoke-AppDeployToolkit scaffolds and Intune-ready commands. The verifier checks known best practices and gotchas. The migration wizard upgrades common legacy patterns.'
|
|
]),
|
|
section('What is not faked', [
|
|
'POSHManager does not emulate PSADT runtime session variables. They exist when PSADT opens an ADTSession during deployment.',
|
|
'POSHManager does not redistribute PSADT modules/templates. Operators bring the actual PSADT deployment package content.'
|
|
])
|
|
], ['psadt', 'integration']),
|
|
article('psadt-authoring', 'PSADT', 'Authoring PSADT Scripts', 'Use profiles, variables, snippets, and generated scaffolds to create package scripts.', [
|
|
section('Recommended authoring path', [
|
|
'Create a PSADT profile with application metadata, deployment type, install tasks, close-process list, and UI plan.',
|
|
'Render or create the script from the profile, then continue editing in the Scripts workspace.',
|
|
'Use Variable Studio for PSADT variables and POSHManager custom variables. Use snippets for common UI, installer, reboot, and logging patterns.'
|
|
]),
|
|
section('Session guidance', [
|
|
'Current v4 scaffolds use ADTSession metadata, package-local module import, Remove-ADTHashtableNullOrEmptyValues, Open-ADTSession, phase invocation, and Close-ADTSession.',
|
|
'DeployMode should remain Auto unless the package intentionally requires Interactive, NonInteractive, or Silent.'
|
|
])
|
|
], ['psadt', 'authoring', 'profiles']),
|
|
article('psadt-verifier-migration', 'PSADT', 'Best Practice Verifier And Migration Wizard', 'Validate and migrate PSADT scripts before publishing.', [
|
|
section('Verifier targets', [
|
|
'Validate a saved script, a rendered PSADT profile, or pasted raw content. Choose platform context such as Intune so platform-specific rules apply.',
|
|
'Findings include severity, rule id, category, line/excerpt, and remediation.'
|
|
]),
|
|
section('Migration wizard', [
|
|
'The migration wizard plans automatic replacements and manual review steps for saved scripts or raw legacy content.',
|
|
'Automatic replacements include common legacy function names, Deploy-Application naming, and $appName-style variables.',
|
|
'Manual review flags include ServiceUI wrappers, raw msiexec, missing Open-ADTSession, legacy phase shape, and missing DeferRunInterval for Intune deferrals.'
|
|
])
|
|
], ['psadt', 'verifier', 'migration']),
|
|
article('psadt-intune-deploy', 'PSADT', 'Deploying PSADT Applications With Intune', 'End-to-end PSADT Win32 app publishing guidance.', [
|
|
section('Core workflow', [
|
|
'Place installers in Files and supporting files in SupportFiles. Keep icons/assets, config, and strings in the correct PSADT folders.',
|
|
'Edit Invoke-AppDeployToolkit.ps1 for variables, pre/main/post install, uninstall, and repair logic.',
|
|
'Wrap the entire PSADT folder with the Microsoft Win32 Content Prep Tool into a .intunewin package.',
|
|
'Create a Windows app (Win32) in Intune, upload the package, configure commands, requirements, detection, return codes, and assignments.'
|
|
]),
|
|
section('Commands and UI context', [
|
|
'For PSADT v4 packages, prefer Invoke-AppDeployToolkit.exe -DeploymentType Install and Invoke-AppDeployToolkit.exe -DeploymentType Uninstall.',
|
|
'Older v3 examples often use Deploy-Application.exe -DeploymentType "Install" -DeployMode "Interactive". Keep this only for legacy compatibility packages.',
|
|
'Install behavior should normally be System. PSADT v4.1+ supports native user-session UI for Intune SYSTEM installs without ServiceUI. ServiceUI should be legacy-only.'
|
|
]),
|
|
section('Return codes and detection', [
|
|
'Map 0 as success, 1602 as retry/user defer, 3010 as soft reboot, and keep custom PSADT app codes out of 60000-68999.',
|
|
'Some historical guidance uses 1703 as a soft reboot mapping; POSHManager includes it for compatibility.',
|
|
'Use MSI product code, file/version, registry, or custom PowerShell detection. Custom scripts should be fast, side-effect free, and return success only when the app is installed.'
|
|
])
|
|
], ['psadt', 'intune', 'deployment', 'serviceui'])
|
|
,
|
|
article('psadt-graph-tracking', 'PSADT', 'Tracking Intune Deployments With Microsoft Graph', 'Use Graph environments to view deployment reach, failures, devices, and users.', [
|
|
section('Graph environment setup', [
|
|
'Create a Microsoft Entra app registration with application permissions such as DeviceManagementApps.Read.All for read-only tracking. Use DeviceManagementApps.ReadWrite.All only when you intend to manage Intune app objects or assignments.',
|
|
'Store tenant id, client id, and client secret in Config / Intune Graph environments. Client secrets are encrypted and hidden after save.',
|
|
'Use Test to validate token acquisition and read access to deviceAppManagement.'
|
|
]),
|
|
section('Deployment tracking workflow', [
|
|
'Create or open an Intune Publishing Wizard plan, then link it to a Graph environment and Intune mobileApp id.',
|
|
'Sync status to read Intune report data into POSHManager. Stored rows include device name, user principal name, install state, error code, detail, and raw Graph/report data.',
|
|
'Use the failures count and status table to quickly identify who and which devices failed, then correlate with Intune Management Extension logs and PSADT logs.'
|
|
]),
|
|
section('Graph reporting notes', [
|
|
'POSHManager prefers Intune reporting endpoints for install status tracking because older mobileApp deviceStatuses/userStatuses relationships have changed over time.',
|
|
'Microsoft Graph returns request ids and status codes that should be kept for troubleshooting tenant permission, throttling, and report availability issues.',
|
|
'This brings POSHManager closer to full Intune publishing and package lifecycle management. Package content/module redistribution is still a separate future capability unless explicitly implemented.'
|
|
])
|
|
], ['psadt', 'graph', 'intune', 'tracking', 'failures'])
|
|
];
|
|
|
|
const cmdletArticles = [
|
|
article('cmdlets-core-reference', 'PowerShell', 'Microsoft.PowerShell.Core Cmdlet Reference', 'Common core cmdlets and links to the Microsoft reference.', [
|
|
section('Reference source', [
|
|
`Microsoft documents the Microsoft.PowerShell.Core snap-in and common cmdlets at ${powershellCoreUrl}. The snap-in is loaded automatically by Windows PowerShell and cannot be imported or removed like a normal module.`
|
|
]),
|
|
section('Common cmdlets', [
|
|
'Get-Help: display help for commands and concepts.',
|
|
'Get-Command: discover cmdlets, functions, aliases, and applications.',
|
|
'Get-Module and Import-Module: inspect and import modules.',
|
|
'Invoke-Command: run commands locally or against remote sessions.',
|
|
'New-PSSession, Enter-PSSession, Get-PSSession, Remove-PSSession: manage PowerShell remoting sessions.',
|
|
'Start-Job, Get-Job, Receive-Job, Stop-Job, Remove-Job, Wait-Job: manage background jobs.',
|
|
'ForEach-Object and Where-Object: pipeline iteration and filtering.',
|
|
'Set-StrictMode: enforce safer script practices.',
|
|
'Update-Help and Save-Help: maintain local help content.'
|
|
]),
|
|
section('Discovery examples', [], 'Get-Help Invoke-Command -Detailed\nGet-Command -Module Microsoft.PowerShell.Core\nGet-Command *PSSession*\nUpdate-Help -Force')
|
|
], ['powershell', 'cmdlets', 'reference']),
|
|
article('cmdlets-remoting', 'PowerShell', 'PowerShell Remoting Cmdlets', 'Useful cmdlets for WinRM/PSSession workflows used around POSHManager.', [
|
|
section('Session workflow', [
|
|
'Enable-PSRemoting configures a computer to receive remote commands. This must be done on targets outside POSHManager.',
|
|
'New-PSSession creates reusable remote sessions. Invoke-Command can run commands through a session or directly against computers.',
|
|
'Get-PSSession shows current sessions. Remove-PSSession closes them.'
|
|
], '$session = New-PSSession -ComputerName "APP01"\nInvoke-Command -Session $session -ScriptBlock { Get-Service }\nGet-PSSession\nRemove-PSSession $session'),
|
|
section('Interactive troubleshooting', [
|
|
'Enter-PSSession starts an interactive remote shell. Exit-PSSession returns to the local shell.',
|
|
'Use Test-WSMan outside the Core module to verify WinRM reachability before adding a host.'
|
|
], 'Enter-PSSession -ComputerName "APP01"\nExit-PSSession')
|
|
], ['powershell', 'remoting', 'winrm']),
|
|
article('cmdlets-jobs-pipeline', 'PowerShell', 'Jobs And Pipeline Cmdlets', 'Common cmdlets for async work and object processing.', [
|
|
section('Jobs', [
|
|
'Start-Job runs a command in the background. Get-Job inspects state, Receive-Job collects output, Stop-Job stops work, Wait-Job blocks until completion, and Remove-Job cleans up.',
|
|
'Use jobs for local async work. POSHManager jobs are application records and not the same thing as PowerShell Start-Job jobs.'
|
|
], '$job = Start-Job -ScriptBlock { Get-Process }\nWait-Job $job\nReceive-Job $job\nRemove-Job $job'),
|
|
section('Pipeline processing', [
|
|
'Where-Object filters pipeline objects. ForEach-Object performs an action for each item.',
|
|
'Prefer object properties over text parsing whenever possible.'
|
|
], 'Get-Service | Where-Object Status -eq "Running" | ForEach-Object { $_.Name }')
|
|
], ['powershell', 'jobs', 'pipeline'])
|
|
];
|
|
|
|
function snippetArticles() {
|
|
const catalog = psadtCatalog();
|
|
const snippetItems = (catalog.snippets || []).map((snippet) => section(snippet.title, [
|
|
`${snippet.category} snippet for ${snippet.functionName}. Use Send to editor from the old snippet flow or copy the snippet from Help.`
|
|
], snippet.body));
|
|
return [
|
|
article('snippets-psadt', 'Snippets', 'PSADT Snippet Library', 'Common PSADT examples moved into searchable help.', snippetItems, ['snippets', 'psadt', 'examples']),
|
|
article('snippets-api-powershell', 'Snippets', 'PowerShell API Snippets', 'Reusable PowerShell snippets for POSHManager API automation.', [
|
|
section('Login helper', [], '$base = "http://localhost:3000"\n$token = (Invoke-RestMethod -Method Post -Uri "$base/api/auth/login" -ContentType "application/json" -Body (@{ email = "admin@posh.local"; password = "change-me-now" } | ConvertTo-Json)).token\n$headers = @{ Authorization = "Bearer $token" }'),
|
|
section('Create script and RunPlan', [], '$script = Invoke-RestMethod -Method Post -Uri "$base/api/scripts" -Headers $headers -ContentType "application/json" -Body (@{ name = "Inventory.ps1"; content = "Get-ComputerInfo"; visibility = "personal" } | ConvertTo-Json)\n$plan = Invoke-RestMethod -Method Post -Uri "$base/api/runplans" -Headers $headers -ContentType "application/json" -Body (@{ name = "Inventory"; scriptId = $script.id; parallel = $true; hostIds = @() } | ConvertTo-Json -Depth 5)')
|
|
], ['snippets', 'api', 'powershell'])
|
|
];
|
|
}
|
|
|
|
export function helpCatalog() {
|
|
return [
|
|
...operationsArticles,
|
|
...apiArticles,
|
|
...psadtArticles,
|
|
...cmdletArticles,
|
|
...snippetArticles()
|
|
];
|
|
}
|
|
|
|
export function helpCategories() {
|
|
return [...new Set(helpCatalog().map((item) => item.category))].sort();
|
|
}
|
|
|
|
export function helpSearch(query = '', category = '') {
|
|
const needle = query.trim().toLowerCase();
|
|
return helpCatalog().filter((item) => {
|
|
const categoryMatch = !category || item.category === category;
|
|
if (!needle) return categoryMatch;
|
|
const haystack = [
|
|
item.title,
|
|
item.summary,
|
|
item.category,
|
|
...(item.tags || []),
|
|
...item.sections.flatMap((part) => [part.heading, ...(part.body || []), part.code || ''])
|
|
].join(' ').toLowerCase();
|
|
return categoryMatch && haystack.includes(needle);
|
|
});
|
|
}
|