Проблемы, с которыми вы сталкиваетесь в результате анализа аргументов PowerShell. В первом примере, когда PowerShell видит $ a, он передает его как единственный параметр msbuild. Это можно увидеть с помощью утилиты echoargs из PSCX :.
PS> $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build"
PS> & echoargs $a
Arg 0 is <C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build>
Второй пример еще хуже, потому что вы говорите powershell, чтобы он вызывал «$ echoargs $ a» в качестве имени команды, а это неверное имя команды.
Третья строка работает, потому что CMD.exe получает расширенную форму «$ echoargs $ a» в качестве единственного аргумента, который анализирует и выполняет:
У вас есть несколько вариантов здесь. Сначала я делаю это так:
PS> & $msbuild C:\some\project\or\other\src\Solution.sln `
/target:Clean /target:Build
Другой вариант - использовать выражение Invoke-Expression следующим образом:
PS> Invoke-Expression "$msbuild $a"
В целом, я стараюсь быть очень осторожным с Invoke-Expression, особенно если какая-либо часть вызываемой строки предоставляется пользователем.