Skip to content

Commit 481a019

Browse files
Add string input/output support to migration tool
Adds ConvertTo-PSResourceGetString function and -InputScript parameter to the entry-point script, enabling direct string-to-string conversion without needing files on disk. Usage: .\ConvertTo-PSResourceGet.ps1 -InputScript 'Install-Module -Name Pester' 'Find-Module -Name Az' | .\ConvertTo-PSResourceGet.ps1 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 618e016 commit 481a019

4 files changed

Lines changed: 180 additions & 8 deletions

File tree

tool/migration/ConvertTo-PSResourceGet.ps1

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66
Converts PowerShellGet v2 cmdlet usage to PSResourceGet equivalents.
77
88
.DESCRIPTION
9-
Scans PowerShell files (.ps1, .psm1, .psd1) for PSGet v2 cmdlet usage
10-
(e.g., Install-Module, Find-Module) and converts them to their
11-
PSResourceGet equivalents (e.g., Install-PSResource, Find-PSResource).
9+
Scans PowerShell files (.ps1, .psm1, .psd1) or inline script strings for
10+
PSGet v2 cmdlet usage (e.g., Install-Module, Find-Module) and converts them
11+
to their PSResourceGet equivalents (e.g., Install-PSResource, Find-PSResource).
1212
1313
By default, runs in WhatIf/report mode. Use -Apply to modify files.
1414
1515
.PARAMETER Path
1616
Path to a file or directory to scan. Supports wildcards.
17-
Defaults to the current directory.
17+
Defaults to the current directory. Cannot be used with -InputScript.
18+
19+
.PARAMETER InputScript
20+
A string containing PowerShell script text to convert. The converted string
21+
is returned as output. Cannot be used with -Path.
1822
1923
.PARAMETER Recurse
2024
When Path is a directory, scan subdirectories recursively.
@@ -39,17 +43,31 @@
3943
.EXAMPLE
4044
# Scan a single file and get structured output
4145
.\ConvertTo-PSResourceGet.ps1 -Path .\deploy.ps1 -PassThru
46+
47+
.EXAMPLE
48+
# Convert a script string and get the converted text back
49+
.\ConvertTo-PSResourceGet.ps1 -InputScript 'Install-Module -Name Pester -Force'
50+
51+
.EXAMPLE
52+
# Pipe a string for conversion
53+
'Find-Module -Name Az -AllowPrerelease' | .\ConvertTo-PSResourceGet.ps1
4254
#>
4355

44-
[CmdletBinding(SupportsShouldProcess)]
56+
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Path')]
4557
param(
46-
[Parameter(Position = 0)]
47-
[string] $Path = '.',
58+
[Parameter(Position = 0, ParameterSetName = 'Path')]
59+
[string] $Path,
60+
61+
[Parameter(Mandatory, ParameterSetName = 'String', ValueFromPipeline)]
62+
[string] $InputScript,
4863

64+
[Parameter(ParameterSetName = 'Path')]
4965
[switch] $Recurse,
5066

67+
[Parameter(ParameterSetName = 'Path')]
5168
[switch] $Apply,
5269

70+
[Parameter(ParameterSetName = 'Path')]
5371
[string] $BackupPath,
5472

5573
[switch] $PassThru
@@ -59,6 +77,23 @@ param(
5977
$modulePath = Join-Path $PSScriptRoot 'PSGetMigration.psm1'
6078
Import-Module $modulePath -Force
6179

80+
# String input mode
81+
if ($PSCmdlet.ParameterSetName -eq 'String') {
82+
$result = ConvertTo-PSResourceGetString -InputScript $InputScript
83+
if ($PassThru) {
84+
$result
85+
}
86+
else {
87+
$result.ConvertedScript
88+
}
89+
return
90+
}
91+
92+
# File/directory mode
93+
if (-not $Path) {
94+
$Path = '.'
95+
}
96+
6297
# Resolve files to scan
6398
$resolvedPath = Resolve-Path -Path $Path -ErrorAction Stop
6499

tool/migration/PSGetMigration.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
'Find-PSGetCommand',
1717
'Convert-PSGetCommand',
1818
'ConvertTo-PSResourceGetScript',
19+
'ConvertTo-PSResourceGetString',
1920
'Format-MigrationReport'
2021
)
2122
CmdletsToExport = @()

tool/migration/PSGetMigration.psm1

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,87 @@ function ConvertTo-PSResourceGetScript {
454454

455455
#endregion
456456

457+
#region String Converter
458+
459+
function ConvertTo-PSResourceGetString {
460+
<#
461+
.SYNOPSIS
462+
Converts PSGet v2 cmdlet usage in a script string to PSResourceGet equivalents.
463+
.PARAMETER InputScript
464+
A string containing PowerShell script text with PSGet v2 commands.
465+
.OUTPUTS
466+
PSCustomObject with: ConvertedScript, Conversions (detail array), Warnings
467+
.EXAMPLE
468+
$result = ConvertTo-PSResourceGetString -InputScript 'Install-Module -Name Pester -Force'
469+
$result.ConvertedScript # → 'Install-PSResource -Name Pester -Reinstall'
470+
#>
471+
[CmdletBinding()]
472+
[OutputType([PSCustomObject])]
473+
param(
474+
[Parameter(Mandatory, ValueFromPipeline)]
475+
[string] $InputScript
476+
)
477+
478+
process {
479+
# Write to a temp file so the AST parser can process it
480+
$tempFile = [System.IO.Path]::GetTempFileName() -replace '\.tmp$', '.ps1'
481+
try {
482+
[System.IO.File]::WriteAllText($tempFile, $InputScript)
483+
484+
$commands = @(Find-PSGetCommand -Path $tempFile)
485+
$allWarnings = [System.Collections.Generic.List[string]]::new()
486+
487+
if ($commands.Count -eq 0) {
488+
return [PSCustomObject]@{
489+
ConvertedScript = $InputScript
490+
Conversions = @()
491+
Warnings = @()
492+
}
493+
}
494+
495+
# Convert each command and collect results
496+
$conversions = foreach ($cmd in $commands) {
497+
$result = Convert-PSGetCommand -CommandInfo $cmd
498+
$result | Add-Member -NotePropertyName 'StartOffset' -NotePropertyValue $cmd.StartOffset
499+
$result | Add-Member -NotePropertyName 'EndOffset' -NotePropertyValue $cmd.EndOffset
500+
foreach ($w in $result.Warnings) { $allWarnings.Add($w) }
501+
$result
502+
}
503+
504+
# Apply replacements in reverse offset order
505+
$output = $InputScript
506+
$sortedConversions = $conversions |
507+
Where-Object { $_.Status -eq 'Converted' -and $null -ne $_.ConvertedText } |
508+
Sort-Object -Property StartOffset -Descending
509+
510+
foreach ($conv in $sortedConversions) {
511+
$output = $output.Substring(0, $conv.StartOffset) +
512+
$conv.ConvertedText +
513+
$output.Substring($conv.EndOffset)
514+
}
515+
516+
return [PSCustomObject]@{
517+
ConvertedScript = $output
518+
Conversions = @($conversions | ForEach-Object {
519+
[PSCustomObject]@{
520+
Line = $_.Line
521+
OriginalText = $_.OriginalText
522+
ConvertedText = $_.ConvertedText
523+
Warnings = $_.Warnings
524+
Status = $_.Status
525+
}
526+
})
527+
Warnings = $allWarnings.ToArray()
528+
}
529+
}
530+
finally {
531+
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
532+
}
533+
}
534+
}
535+
536+
#endregion
537+
457538
#region Formatting
458539

459540
function Format-MigrationReport {
@@ -540,5 +621,6 @@ Export-ModuleMember -Function @(
540621
'Find-PSGetCommand',
541622
'Convert-PSGetCommand',
542623
'ConvertTo-PSResourceGetScript',
624+
'ConvertTo-PSResourceGetString',
543625
'Format-MigrationReport'
544626
)

tool/migration/Tests/PSGetMigration.Tests.ps1

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,58 @@ Find-Module -Name Az -AllowPrerelease
282282
}
283283
}
284284
}
285-
}
285+
286+
Context 'ConvertTo-PSResourceGetString' {
287+
It 'Converts a simple command string' {
288+
$result = ConvertTo-PSResourceGetString -InputScript 'Install-Module -Name Pester'
289+
$result.ConvertedScript | Should -Be 'Install-PSResource -Name Pester'
290+
$result.Conversions.Count | Should -Be 1
291+
}
292+
293+
It 'Converts multiple commands in a script string' {
294+
$script = @'
295+
Install-Module -Name Pester -Force
296+
Find-Module -Name Az -AllowPrerelease
297+
'@
298+
$result = ConvertTo-PSResourceGetString -InputScript $script
299+
$result.ConvertedScript | Should -Match 'Install-PSResource'
300+
$result.ConvertedScript | Should -Match 'Find-PSResource'
301+
$result.ConvertedScript | Should -Match '-Prerelease'
302+
$result.ConvertedScript | Should -Not -Match 'Install-Module'
303+
$result.ConvertedScript | Should -Not -Match 'Find-Module'
304+
$result.Conversions.Count | Should -Be 2
305+
}
306+
307+
It 'Returns the original string when no PSGet commands are found' {
308+
$script = 'Get-Module -Name Pester'
309+
$result = ConvertTo-PSResourceGetString -InputScript $script
310+
$result.ConvertedScript | Should -Be $script
311+
$result.Conversions.Count | Should -Be 0
312+
}
313+
314+
It 'Collects warnings from removed parameters' {
315+
$result = ConvertTo-PSResourceGetString -InputScript 'Install-Module -Name Pester -AllowClobber -Force'
316+
$result.Warnings.Count | Should -BeGreaterThan 0
317+
$result.ConvertedScript | Should -Match '-Reinstall'
318+
}
319+
320+
It 'Preserves surrounding script content' {
321+
$script = @'
322+
# Setup
323+
$moduleName = 'Pester'
324+
Install-Module -Name $moduleName -Scope CurrentUser
325+
Write-Host 'Done'
326+
'@
327+
$result = ConvertTo-PSResourceGetString -InputScript $script
328+
$result.ConvertedScript | Should -Match '# Setup'
329+
$result.ConvertedScript | Should -Match '\$moduleName = ''Pester'''
330+
$result.ConvertedScript | Should -Match 'Install-PSResource'
331+
$result.ConvertedScript | Should -Match "Write-Host 'Done'"
332+
}
333+
334+
It 'Accepts pipeline input' {
335+
$result = 'Find-Module -Name Az' | ConvertTo-PSResourceGetString
336+
$result.ConvertedScript | Should -Be 'Find-PSResource -Name Az'
337+
}
338+
}
339+
}

0 commit comments

Comments
 (0)