function - 从 PowerShell 中的另一个函数调用一个函数

标签 function powershell workflow powershell-5.0 powershell-workflow

第一次在 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”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。
+ CategoryInfo : ObjectNotFound: (logMessage:String) [], CommandNotFoundException
+fullyQualifiedErrorId:CommandNotFoundException
+ PSComputerName:[本地主机]

我尝试在文件中移动 logMessage 函数,甚至尝试了全局范围。

在任何其他语言中,我都可以从任何其他函数调用 logMessage。因为那是函数的目的。

重用代码块的“工作流程方式”是什么?

我是否需要创建一些加载到工作流程中的日志记录模块?

最佳答案

您可以将函数和函数调用移至 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 block 允许解释普通的 PowerShell 代码,但是范围将绑定(bind)到 InlineScript block 。例如,如果您在脚本 block 中定义函数,然后尝试调用 func1在 InlineScript block 之外的函数(但仍在工作流程内)它将失败,因为它超出了范围。

如果您在工作流之外或在工作流内部但不在 InlineScript block 中定义这两个函数,也会发生同样的情况。

现在举例说明如何将其应用于运行 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

您会注意到(正如预期的那样)输出顺序是随机的,因为它是并行运行的。

关于function - 从 PowerShell 中的另一个函数调用一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770877/

相关文章:

javascript - Javascript 中这些函数被称为什么

arrays - 将System.UInt16数组转换为字符串

powershell - 检查字符串是否在字符串列表中

powershell - TFS2015 变量问题(Build.SourceBranch 和 Build.SourceBranchName)

java - 在java中一次设置属性文件中的所有属性

c# - 如何从工作流对话框中删除标题中的问号?

c++ - 非法调用非静态成员函数

arrays - 从 ksh 数组中删除特定值

javascript - 使用 javascript 隐藏数字,而不使用 jQuery

workflow - 如何从之前的事件中获取结果?