PowerShellでコマンドライン引数を処理する方法


494

コマンドライン引数を処理する「最良の」方法は何ですか?

「最良の」方法とは何かについていくつかの答えがあるようで、その結果、次のように単純なものを処理する方法に行き詰まっています。

script.ps1 /n name /d domain

そして

script.ps1 /d domain /n name.

これをよりよく処理できるプラグインはありますか?私はここで車輪を再発明していることを知っています。

明らかに、私がすでに持っているものは美しくなく、確かに「最高」ではありませんが、それはうまくいきます。そして、それは醜いです。

for ( $i = 0; $i -lt $args.count; $i++ ) {
    if ($args[ $i ] -eq "/n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "/d"){ $strDomain=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-d"){ $strDomain=$args[ $i+1 ]}
}
Write-Host $strName
Write-Host $strDomain

回答:


917

あなたは車輪を再発明しています。通常のPowerShellスクリプトには-script.ps1 -server http://devserver

次にparam、ファイルの先頭のセクションでそれらを処理します。

パラメータにデフォルト値を割り当て、利用できない場合はコンソールから読み取るか、スクリプトの実行を停止することもできます。

 param (
    [string]$server = "http://defaultserver",
    [Parameter(Mandatory=$true)][string]$username,
    [string]$password = $( Read-Host "Input password, please" )
 )

スクリプト内で簡単にできます

write-output $server

すべてのパラメーターがスクリプトスコープで使用可能な変数になるためです。

この例では$server、スクリプトがそれなしで呼び出された場合、はデフォルト値を取得します。-usernameパラメーターを省略した場合、スクリプトは停止し、-password省略された場合、端末入力を要求します。

更新: "フラグ"(ブール値のtrue / falseパラメータ)をPowerShellスクリプトに渡すこともできます。たとえば、スクリプトは、強制が使用されていないときにスクリプトがより注意深いモードで実行される「強制」を受け入れる場合があります。

そのためのキーワードは[switch]パラメータタイプです。

 param (
    [string]$server = "http://defaultserver",
    [string]$password = $( Read-Host "Input password, please" ),
    [switch]$force = $false
 )

スクリプト内では、次のように操作します。

if ($force) {
  //deletes a file or does something "bad"
}

スクリプトを呼び出すときに、switch / flagパラメータを次のように設定します。

.\yourscript.ps1 -server "http://otherserver" -force

フラグが設定されていないことを明示的に述べたい場合は、そのための特別な構文があります

.\yourscript.ps1 -server "http://otherserver" -force:$false

関連するMicrosoftドキュメントへのリンク(PowerShell 5.0の場合、バージョン3.0および4.0もリンクから入手できます):


58
実際、PowerShellの大きな利点の1つは、使いやすい標準パラメーター解析インフラストラクチャを提供することです。
キース・ヒル

14
@ naivists、PowerShell 2.0から[string]$username = $(throw "-username is required.")ではなく、必須パラメーターの構文があります[Parameter(Mandatory=$true)][string]$username。ここではこれらの手法の違いについての詳細情報は以下のとおりです。blogs.technet.com/b/heyscriptingguy/archive/2011/05/22/...
v.karbovnichy

7
argが指定されていない場合は、バグに注意してください。powershellは、コマンドラインから余分なテキストを取得します。。\ yourscript.ps1 -server " serv " -password "mypass" typoこれにより、魔法のように 'typo'が$ usernameに割り当てられます。
sheamus

4
ただし、paramブロックを使用すると、他の意図しない結果が生じるようです。stackoverflow.com
Logan

1
@sheamus:それはバグではありません!Powershellは、適切なパラメーター名を使用してオーバーライドされない限り、引数を指定された順序で処理して割り当てます。たとえば、paramブロックが次のようにリストされている場合:$ user $ pass $ server、およびyourscript.ps1 abcを実行すると、 $ userに設定し、bを$ passに設定し、cを$ serverに設定します。つまり、yourscript.ps1 -pass abcとすると、$ passはaに設定され、残りの(名前のない)パラメーターは、パラメーターブロックにリストされている順に、不足しているパラメーターを埋めるために使用されるため、$ user = b、$ server = c。
Fernando Madruga
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.