Jak w PowerShellu przekazać argumenty do polecenia

PowerShell, podobnie jak w przypadku uruchamiania programów, posiada kilka sposobów na przekazanie zestawów parametrów do poleceń. Odróżnia je wygoda oraz czytelność, choć niekiedy decydującym czynnikiem są też wymagania uruchamianego programu.

Chesz przetestować działanie poniższych instrukcji, a nie masz dostępu do serwera Linuxowego? Po rejestacji na DigitalOcean otrzymasz 100 dolarów do wykorzystania w ciągu 60 dni, a z przyjaznym interfejsem uruchomisz ulubioną dystrybucję w ciągu paru minut.

Aby lepiej zademonstrować działanie poszczególnych metod wywoływane będzie następujące, dość skomplikowane polecenie.

C:\> "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\amd64\msbuild.exe" "D:\Projekty\super projekt\super-projekt.csproj" /t:Rebuild /P:DeployOnBuild=true /P:VisualStudioVersion=17.0 /P:Configuration=Release /P:OutDir="D:\Projekty\super projekt\bin\Release"

Dodatkowo wartości niektórych parametrów będą , tam gdzie to możliwe, przechowywane w postaci zmiennych oraz zawierać spacje.

Metoda tradycyjna

Metoda tradycyjna polega na przekazaniu parametrów w taki sam sposób jak miało to miejsce w Wierszu Polecenia. Czyli wpierw ścieżka do polecenia, a następnie parametry.

$msbuildExe = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\amd64\msbuild.exe"
$superProjektCsproj = "D:\Projekty\super projekt\super-projekt.csproj"
$outputDirectory = "D:\Projekty\super projekt\bin\Release"


& $msbuildExe $superProjektCsproj /t:Rebuild /P:DeployOnBuild=true /P:VisualStudioVersion=17.0 /P:Configuration=Release /P:OutDir=$outputDirectory

Metoda ta powinna sprawdzić się dla nieskomplikowanych argumentów bądź gdy uruchamiany program nie ma co do nich specjalnych wymogów. Pewnym jej minusem jest mała czytelność, aczkolwiek można temu częściowo zaradzić stosując utworzone wcześniej zmienne.

Operator –%

Kolejny sposób to skorzystanie z operatora --% który wymusi przekazanie następujących po nim argumentów bez żadnego przetwarzania.

& $msbuildExe --% "D:\Projekty\super projekt\super-projekt.csproj" /t:Rebuild /P:DeployOnBuild=true /P:VisualStudioVersion=17.0 /P:Configuration=Release /P:OutDir="D:\Projekty\super projekt\bin\Release"

Jest to idealny sposób gdy trzeba jednorazowo wykorzystać istniejące polecenie bezpośrednio z Wiersza Poleceń bądź istniejącego pliku bat. Jego minusem jest niska czytelność oraz brak jakiegokolwiek przetwarzania zmiennych przez PowerShella.

Splatting z użyciem tablic

W splattingu kolejne elementy tablicy zawierają nazwy oraz wartości poszczególnych paramentów. Następnie do polecenia przekazywana jest cała tablica za pomocą operatora @.

$msbuildExe = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\amd64\msbuild.exe"
$msbuildArguments = @(
  "D:\Projekty\super projekt\super-projekt.csproj",
  "/t:Rebuild",
  "/P:DeployOnBuild=true",
  "/P:VisualStudioVersion=17.0",
  "/P:Configuration=Release",
  "/P:OutDir=D:\Projekty\super projekt\bin\Release"
)

& $msbuildExe @msbuildArguments

Zaletą tej metody jest duża czytelność i łatwość edycji nazw i wartości poszczególnych argumentów. Można także dowolnie stosować zmienne czy wyrażenia oraz, gdy zajdzie taka potrzeba, wygodnie podmieniać wartości pojedynczych parametrów.

Splatting z tablicami asocjacyjnymi (hashtables)

Rozwiązanie to doskonale spisuje się gdy argumenty przekazywane są w parach klucz-wartość. Taka sytuacja ma miejsce we wszystkich PowerShellowych cmdletach.

$gciArguments = @{
  Path = "C:\Windows";
  Include = "*.exe";
  Recurse = $true;
  File = $true 
}

Get-ChildItem @gciArguments

Rozwiązanie to nie znajdzie zastosowania w przykładowym wywołaniu msbuilda albowiem ścieżka do projektu przekazywana jest bez klucza. Nadaje się ono jednak gdy wymagana jest duża liczba parametrów przy których hashtable prezentuje się bardzo przejrzyście.