无法处理参数转换

时间:2014-02-03 09:52:58

标签: powershell powershell-v2.0

受此post的启发,我创建了DOSCommands.ps1

下面的脚本
Function Invoke-DOSCommands {
    Param(
        [Parameter(Position=0,Mandatory=$true)]
        [String]$cmd,
        [String]$tmpname = $(([string](Get-Random -Minimum 10000 -Maximum 99999999)) + ".cmd"),
        [switch]$tmpdir = $true)
    if ($tmpdir) {
        $cmdpath = $(Join-Path -Path $env:TEMP -ChildPath $tmpname);
    }
    else {
        $cmdpath = ".\" + $tmpname
    }
    Write-Debug "tmpfile: " + $cmdpath
    Write-Debug "cmd: " + $cmd
    echo $cmd | Out-File -FilePath $cmdpath -Encoding ascii;
    & cmd.exe /c $cmdpath | Out-Null
}

Invoke-DOSCommands "Echo ""Hello World""", -tmpdir $false

但是,执行时会返回此错误:

Invoke-DOSCommands : Cannot process argument transformation on parameter 'cmd'. Cannot convert value to type S ystem.String.
At DOSCommands.ps1:20 char:19
+ Invoke-DOSCommands <<<<  "Echo ""Hello World""", -tmpdir $false
    + CategoryInfo          : InvalidData: (:) [Invoke-DOSCommands], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Invoke-DOSCommands

我已经搜索过这个错误,但无法弄明白。在我看来它无法正确转换字符串类型!请帮忙!

2 个答案:

答案 0 :(得分:4)

最好的办法是在PowerShell V3或更高版本中使用--%。请参阅我使用--%撰写的blog post。在V1 / V2中,情况很糟糕,正如您在Connect bug on the issue中看到的那样。 V1 / V2中的常见解决方法是使用Start-Process或.NET的Process.Start。从这些解决方法列表中,我有点像这样:

[System.Diagnostics.Process]::Start("Cmd", "/c anything you want to put here with embedded quotes, and variables")

--%实际上解析了它之后的所有参数,即它以类似于cmd.exe参数解析的虚拟模式解析它们,包括扩展用%envVarName%引用的env变量。< / p>

答案 1 :(得分:1)

好吧,基于Keith的回答,我修改了我的功能如下:

Function Invoke-DOSCommands {
    Param(
        [Parameter(Position=0,Mandatory=$true)]
        [String]$cmd)

    $comspec =  $env:comspec # have to get comspec
    $cwd = Get-Location # ensure correct working directory
    $pstartinfo = new-object -type System.Diagnostics.processStartInfo -Argumentlist "$comspec","/c $cmd"
    $pstartinfo.WorkingDirectory= $cwd
    Write-Debug "cmd: $pstartinfo.FileName"
    Write-Debug "args: $pstartinfo.Arguments"
    Write-Debug "dir: $pstartinfo.WorkingDirectory"
    #[System.Diagnostics.Process]::Start("Cmd", "/c $cmd")
    [System.Diagnostics.Process]::Start($pstartinfo)
}

Invoke-DOSCommands "Echo ""Hello World"" & dir & pause" # testing function