6

PowerShell 5 で初めて、別の関数からファイルにメッセージを書き込む関数を呼び出すのに問題があります。以下は、私がやっていることの簡略化されたバージョンです。

workflow test {
    function logMessage {
        param([string] $Msg)

        Write-Output $Msg
    }

    function RemoveMachineFromCollection{
        param([string]$Collection, [string]$Machine)

        # If there's an error
        LogMessage "Error Removing Machine"

        # If all is good
        LogMessage "successfully remove machine"
    }


    $Collections = DatabaseQuery1

    foreach -parallel($coll in $Collections) {
        logMessage "operating on $coll collection"

        $Machines = DatabaseQuery2

        foreach($Mach in $Machines) {
            logMessage "Removing $Mach from $coll"

            RemoveMachineFromCollection -Collection $coll -Machine $Mach
        }
    }
}

test

生成されるエラーは次のとおりです。

「logMessage」という用語は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前のスペルを確認するか、パスが含まれている場合は、パスが正しいことを確認してから再試行してください。
    + CategoryInfo : ObjectNotFound: (logMessage:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName : [ローカルホスト]

ファイル内で logMessage 関数を移動しようとしましたが、グローバル スコープも試しました。

他の言語では、他の関数から logMessage を呼び出すことができます。それが関数の目的だからです。

コードのブロックを再利用する「ワークフローの方法」は何ですか?

ワークフローに読み込まれるロギング モジュールを作成する必要がありますか?

4

3 に答える 3

3

以下のように、関数と関数呼び出しをInlineScriptワークフロー内の (PowerShell ScriptBlock) に移動できます。

workflow test {
    InlineScript
    {
        function func1{
            Write-Output "Func 1"
            logMessage
        }

        function logMessage{
            Write-Output "logMessage"
        }
        func1
    }
}

出力します:

Func 1
logMessage

@JeffZeitlin が彼の回答で述べたように、ワークフローは PowerShell ではなく、はるかに制限的です。InlineScript ブロックを使用すると、通常の PowerShell コードを解釈できますが、スコープは InlineScript ブロックに関連付けられます。たとえば、スクリプト ブロックで関数を定義してからfunc1、InlineScript ブロックの外側 (ただし、ワークフロー内) で関数を呼び出そうとすると、範囲外であるため失敗します。

InlineScript ブロックではなく、ワークフローの外部またはワークフローの内部で 2 つの関数を定義した場合も、同じことが起こります。

foreach -parallelこれをループの実行に適用する方法の例を次に示します。

workflow test {
    ## workflow parameter
    param($MyList)

    ## parallel foreach loop on workflow parameter
    foreach -parallel ($Item in $MyList)
    {
        ## inlinescript
        inlinescript
        {
            ## function func1 declaration
            function func1{
                param($MyItem)
                Write-Output ('Func 1, MyItem {0}' -f $MyItem)
                logMessage $MyItem
            }

            ## function logMessage declaration
            function logMessage{
                param($MyItem)
                Write-Output ('logMessage, MyItem: {0}' -f $MyItem)
            }
            ## func1 call with $Using:Item statement
            ## $Using: prefix allows us to call items that are in the workflow scope but not in the inlinescript scope.
            func1 $Using:Item
        }
    }
}

このワークフローへの呼び出しの例は次のようになります

 PS> $MyList = 1,2,3
 PS> test $MyList
     Func 1, MyItem 3
     Func 1, MyItem 1
     Func 1, MyItem 2
     logMessage, MyItem: 3
     logMessage, MyItem: 2
     logMessage, MyItem: 1

並列で実行されたため、出力順序がランダムであることがわかります (そして予想どおり)。

于 2017-01-20T19:40:59.643 に答える