Inspired by this post, I created the script below 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
However, on execution it returns this error:
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
I've searched for this error but can't figure it out. It seems to me that it can't convert the string type correctly! Please help!
Your best bet is to use --%
in PowerShell V3 or higher. See this blog post I wrote on using --%
. In V1/V2 the situation is just bad as you can see in this Connect bug on the issue. The common workaround in V1/V2 is to use Start-Process or .NET's Process.Start. From those list of workarounds, I kind of like this one:
[System.Diagnostics.Process]::Start("Cmd", "/c anything you want to put here with embedded quotes, and variables")
Which is effectively what --%
does to the parsing of all parameters following it i.e. it parses them in a dumbed down mode similar to cmd.exe parameter parsing including expanding env vars referenced with %envVarName%
.
Alright based on the answer by Keith I've modified my function as follows:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With