Powershellスクリプティング:お勧めの食べ方を教えを実施ShouldProcessが関数呼び出しは入れ子?
-
21-09-2019 - |
質問
テストスクリプト:
function outer
{
[cmdletbinding(supportsshouldprocess=$true)]
param($s)
process
{
$pscmdlet.shouldprocess("outer $s", "ShouldProcess") | out-null
"" | out-file "outer $s"
inner ImplicitPassthru
inner VerbosePassthru -Verbose:$Verbose
inner WhatifPassthru -WhatIf:$WhatIf
}
}
function inner
{
[cmdletbinding(supportsshouldprocess=$true)]
param($s)
process
{
$pscmdlet.shouldprocess("inner $s", "ShouldProcess") | out-null
"" | out-file "inner $s"
}
}
"`n** NORMAL **"
outer normal
"`n** VERBOSE **"
outer verbose -Verbose
"`n** WHATIF **"
outer whatif -WhatIf
出力:
** NORMAL **
VERBOSE: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
** VERBOSE **
VERBOSE: Performing operation "ShouldProcess" on Target "outer verbose".
VERBOSE: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
** WHATIF **
What if: Performing operation "ShouldProcess" on Target "outer whatif".
What if: Performing operation "Output to File" on Target "outer whatif".
What if: Performing operation "ShouldProcess" on Target "inner ImplicitPassthru".
What if: Performing operation "Output to File" on Target "inner ImplicitPassthru".
What if: Performing operation "ShouldProcess" on Target "inner VerbosePassthru".
What if: Performing operation "Output to File" on Target "inner VerbosePassthru".
What if: Performing operation "ShouldProcess" on Target "inner WhatifPassthru".
What if: Performing operation "Output to File" on Target "inner WhatifPassthru".
私の目が奇妙。
- の指定-WhatIf:$fooま 常に on$WhatIfの相手先(およびそのcallees)何$fooです。
- いの指定-WhatIf"リアル"な制約が存在しない変数を指示し、向かって伝搬することを観測しcallees暗黙のうちに.なpassthruはsplatting.
- とは異なり-WhatIf、明示的な-デフォルト値が設定されないカスケードへのcallees暗黙のうちに.
- ようとする時は手動でpassthru-Verbose:$fooだ見の動作が同様にWhatIf:$foo.ただそれだけで影響するスクリプトを手動で試験$psCmdlet.ShouldProcess()--築cmdletsなります。
N.B.:確認の動作と同じWhatIf.私は省略で簡潔.
検索に接続し、ほとんどないので密度の濃いディスカッションのShouldProcess行動(プロコンとしては差がある高度な機能を最も近いものが ポストジェームズ-O'neill ることを推奨通の単一のインスタンス$psCmdlet通じて、コールスタックです。しかし、たいへの回避策の異なる問題を避ける複数の確認を促).一方で、こだわりの標準$psCmdlet各機能が思い当たらないdocsに何を期待する...いデザインパターン、ベストプラクティスなど...
解決
したりすることはできませんを参照$WhatIfドにデフォルト値が設定さいことから、合成するこれらの変数は存在しなおす。ユーザが指定しいスタイルを取り入れながら、でき得したい$PSBoundParametersただし、ユーザかを指定し明らかになれるハッシュテーブル.
きい値に切り換えユーの代表的な強制処理しようとする変換指定された値をbool.か$whatif定義されていないこevalsに$nullの場合その結果、スイッチに設定される値$trueです。このと考えることがでのスイッチを明示的に指定した効果的な価値に相当するかを指定する-Whatifのない値です。このときのパラメータbinding:
function Foo
{
[CmdletBinding(SupportsShouldProcess=1)]
param()
Process
{
$PSBoundParameters
}
}
Trace-Command -name ParameterBinding -expr {Foo -whatif:$xyzzy} -PSHost
DEBUG: BIND NAMED cmd line args [Foo]
DEBUG: BIND arg [] to parameter [WhatIf]
DEBUG: COERCE arg to [System.Management.Automation.SwitchParameter]
DEBUG: Arg is null or not present, type is SWITCHPARAMTER, value is true.
DEBUG: BIND arg [True] to param [WhatIf] SUCCESSFUL
DEBUG: BIND POSITIONAL cmd line args [Foo]
DEBUG: MANDATORY PARAMETER CHECK on cmdlet [Foo]
DEBUG: CALLING BeginProcessing
DEBUG: CALLING EndProcessing
の$WhatIfPreferenceや$VerbosePreferenceが適切に設定し、外部から外したというとデフォルト値が設定されたwhatif.いている場合は、それらの数値を伝搬内です。ような気があることをユーバ$pscmdlet.ShouldProcess.するという趣旨を尊重し、これを順守値$VerbosePreferenceます。きみを通る-詳細を内部はこのように:
inner VerbosePassthru -Verbose:($VerbosePreference -eq 'Continue')
別のオプションを使用します可変範囲はこのように:
function Outer
{
[CmdletBinding(SupportsShouldProcess=1)]
param()
Process
{
$pscmdlet.ShouldProcess("Outer process", '') > $null
inner
#inner -Verbose:($VerbosePreference -eq 'Continue')
}
}
function Inner
{
[CmdletBinding(SupportsShouldProcess=1)]
param()
Process
{
$pscmdlet = (Get-Variable -Scope 1 -Name PSCmdlet).Value
$pscmdlet.ShouldProcess("Inner process", '') > $null
"Inner $VerbosePreference"
}
}
Outer -Verbose
なんなのかしこのようになることを知っていま外が1つ上のレベルです。き"徒歩"の範囲のスタックにPSCmdlet変数のスタックです。この効果を排除に渡PSCmdletは、(総)はまだまだhack.うことを検討すべき原則として"出所の明示"修MSに接続す。
他のヒント
たく同じ質問に、私はこの7年にわたります。驚いているとのマイクロソフト社のユーチームは固定されていないこなった。を再現してい問題ユー第6版プレビュー(最新バージョン)。
私たちは、簡単な回避策、内部の Inner
機能を作っていまションを行うとともに、 scriptblock
, 設定の -Verbose
フラグ確認 $VerbosePreference
が正しく設定さ Continue
, てはいるものが尊重されていない ShouldProcess
:
Function Outer {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
param([string]$Name)
Process {
Write-Host "Outer called";
Inner $Name
}
}
Function Inner {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
param([string]$Name)
Process {
if (-not ($PSBoundParameters.ContainsKey('Verbose'))) {
$PSBoundParameters.Add('Verbose', [bool]$VerbosePreference -eq 'Continue');
}
& {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="Medium")]
param([string]$Name)
if ($PSCmdlet.ShouldProcess($Name, "Inner")) {
Write-Host "Inner called";
}
} @PSBoundParameters;
}
}
Export-ModuleMember *