• subscribe
November 28, 2009 12:00 AM

Solving PowerShell Argument Input Errors with Wrapper Scripts

Here are 3 solutions for correctly passing strings with embedded spaces into PowerShell scripts
Windows IT Pro
InstantDoc ID #103174
Downloads
103174.zip

Listing 1: Cmd.exe Wrapper Scripts that Demonstrate %* Variable Expansion

::wrapper0.cmd
:: just expands and echoes arguments to standard output
echo %*

::wrapper1.cmd
:: Everything inside {} is echoed as a string
powershell -Command { .\echodemo.ps1 %* }

::wrapper2.cmd
:: Doublequotes are stripped out completely
powershell -Command "& {.\echodemo.ps1 %* }"

::wrapper3.cmd
:: Expanded arguments become one string in '%*'
powershell -Command "& {.\echodemo.ps1 '%*' }"

::wrapper4.cmd
:: Works properly - PowerShell 2 only
powershell -File .\echodemo.ps1 %*

::wrapper5.cmd
:: Input processed as a command; works in PowerShell 1 and 2
echo .\echodemo.ps1 %* | powershell -Command -

::wrapper6.cmd
:: As wrapper5.cmd, but -NoExit keeps PowerShell running.
echo .\echodemo.ps1 %* | powershell -NoExit -Command -

Listing 2: Generic WSH Wrapper Script for Any PowerShell Script

' BEGIN WSH wrapper script
' Should have same basename as PS script it will run,
' and must be in same folder as PS script.
' ex: if c:\tmp\fred.ps1, this must be c:\tmp\fred.vbs

dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
Dim WshScript: WshScript = WScript.ScriptFullName
Dim PsScript
PsScript = fso.BuildPath( _
    fso.GetFile(WshScript).ParentFolder.Path, _
    fso.GetBaseName(WshScript) & ".ps1")

' Escape spaces embedded in script path, if any.
PsScript = Replace(PsScript, " ", "` ")
' Escape single quotes by doubling.
PsScript = Replace(PsScript, "'", "'")


Dim i, arg
i = 0
Dim ArgSet: Set ArgSet = CreateObject("Scripting.Dictionary")
Argset(i) = PsScript

For each arg in WScript.Arguments
	' EXPLICITLY ensure these resolve to file/folder paths
    if fso.FileExists(arg) or fso.FolderExists(arg) then
        i = i + 1
        ' Include escapes for singlequotes in paths, if any
        Argset(i) = "'" & Replace(arg, "'", "'") & "'"
    End If
Next

Dim base

' BEGIN Callout A
base = "PowerShell -Command ""& {"
' END Callout A

' Use the following base instead to keep the window open.

' BEGIN Callout B
'base = "powershell -NoExit -Command ""& {"
' END Callout B

Dim Command

Command = base & Join(ArgSet.Items) & "}"""

' WScript.Echo "command as passed to PowerShell:", Command
Dim WshShell: Set WshShell = CreateObject("WScript.Shell")

' Now run the command

' BEGIN Callout C
WshShell.Run Command, 2
' END Callout C

' END WSH Wrapper Script


ARTICLE TOOLS

Comments
    There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here