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!
Alright based on the answer by Keith I've modified my function as follows:
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: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%
.