2017-11-24 13 views
1

私はPowerShellを初めて使い慣れていますが、Windowsマシン上で多くのタスクを自動化するのが大好きです。私はあなたが他のスクリプトから関数を呼び出すことができるのは大好きですが、私が書いたスクリプトはすべてユーザーが提供できるパラメータを使用しています(同僚がそれらを使うのは簡単です)。Powershellがスクリプトに必須のパラメータがある場合に関数を呼び出す

スクリプトには通常必須のパラメーターが1つあります。私が直面している問題は、必須パラメータを持つスクリプトから関数を呼び出すことです。あなたが-VirtualMachine "VMnameHere" -Attempts 123を提供するスクリプトとしてこれを実行する

Param(

[Parameter()] 
[ValidateNotNullOrEmpty()] 
[string]$VirtualMachine=$(throw "Machine name missing!"), 

[int]$Attempts = 150 

) 

Function DoSomething($VirtualMachine, $Attempts){ 

    write("$VirtualMachine and $Attempts") 

} 

は、ここで簡単な例を示します。これを実行するとVMnameHere and 123が生成されます。完璧!私はここに

例...別のスクリプトから関数としてこれを呼び出そうとした場合しかし..:

. ".\Manage-Machine.ps1" 

DoSomething -VirtualMachine "nwb-thisisamachine" -Attempts 500 

これは、エラーを生成:

フィールドがあるので、明らかである
Machine name missing! 
At C:\Users\something\Desktop\Dump\play\Manage-Machine.ps1:33 char:28 
+ [string]$VirtualMachine=$(throw "Machine name missing!"), 
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : OperationStopped: (Machine name missing!:String) [], RuntimeException 
    + FullyQualifiedErrorId : Machine name missing! 

必須です。この場合関数の呼び出し方法が間違っていますか?それが属しているスクリプトが必須パラメータを持っている場合、関数を呼び出す別の方法があります。なぜなら、パラメータの検証を取り除くと、それがすべて機能するからです。

いくつかの入力を大好きだ、

ありがとうございました!

+1

ps1ファイルに関数を呼び出す行がありますか?あなたのサンプルは出力を生成すべきではないからです。それでは、ps1を呼び出してあなたの引数を提供してください。 – Matt

+0

'[parameter(Mandatory = $ true)]'を使用して '= $を取り除くと(Machine name missing!)' –

+0

@Mattいいえ、現時点では、関数を(必須のパラメータなしで記述したように)呼び出すと、うまく動作します。スクリプトを実行すると正常に動作しますが、実際には1つのスクリプトで複数の関数を実行してから、スクリプト全体を実行するのではなく、別のスクリプトで関数を呼び出す必要があります。最後に呼び出された関数を実行すると、一度に関数を使用することはできません。 –

答えて

2

[parameter(Mandatory = $true)]を使用し、=$(throw "Machine name missing!")を削除します。

-NonInteractiveフラグ(documentation link)でpowershellを実行すると、必須パラメータがないとエラーが発生し、ゼロ以外の終了コードが返されます。

この戻りコードは、CIプロセスによって取得される必要があり、それ自体がエラーを処理します。

+0

あなたが示唆していることは、OPの問題とは無関係です。 あなたの提案は、_interactive_呼び出しシナリオでは、例外をスローするのではなく必須のパラメータ値がないときに_prompt_に '$(throw Machine name missing!)' )。 – mklement0

0

は、私はそれがこれを行うには、このような素晴らしいアイデアだわからないんだけど、次はうまくいくように聞こえる:

Param(

    [ValidateNotNullOrEmpty()] 
    # Do NOT use = $(Throw ...) or [Parameter(Mandatory)]. 
    [string]$VirtualMachine, 

    [int]$Attempts = 150 

) 

# Determine if the script is being "dot-sourced". 
# Note: The `$MyInvocation.Line -eq ''` part detects being run from the 
#  ISE or Visual Studio Code, which implicitly perform sourcing too. 
$isDotSourced = $MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '' 

# NOT sourced? Enforce mandatory parameters. 
if (-not $isDotSourced) { 
    if (-not $VirtualMachine) { Throw "Machine name missing!" } 
} 

Function DoSomething($VirtualMachine, $Attempts) { 
    "$VirtualMachine and $Attempts" 
} 


# NOT sourced? Call the default function or 
# do whatever you want the script to do when invoked as a whole. 
if (-not $isDotSourced) { 
    DoSomething $VirtualMachine $Attempts 
} 
  • . .\Manage-Machine.ps1は、単には、関数を定義します。この中DoSomethingケース)、の後に呼び出し。
    スクリプトパラメータのいずれも技術的に必須と宣言されていないため、パラメーターを指定しない呼び出しは成功します(throwステートメントがいつも呼び出されたか、ドットソースされたかにかかわらず)。対照的に、$VirtualMachineパラメータ値の存在を強制し、即座にDoSomethingを呼び出し、パラメータ値を通します。

もちろん、パラメータを入力して検証属性を追加することで、関数に役立つことに注意してください。

関連する問題