第一次在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
这是它产生的错误:
The term 'logMessage' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
+ CategoryInfo : ObjectNotFound: (logMessage:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
+ PSComputerName : [localhost]
我已经尝试在文件中移动logMessage函数,甚至尝试过Global scope .
在任何其他语言中,我都可以从任何其他函数调用logMessage . 因为这是一个功能的目的 .
重用一段代码的“工作流方式”是什么?
我是否需要创建一些加载到工作流中的日志记录模块?
3 回答
您可以将函数和函数调用移动到工作流内的
InlineScript
(PowerShell ScriptBlock),如下所示 .输出:
正如@JeffZeitlin在他的回答中提到的,工作流程不是PowerShell,而是更具限制性 . InlineScript块允许解释普通的PowerShell代码,但范围将与InlineScript块相关联 . 例如,如果您在脚本块中定义函数然后尝试在InlineScript块之外调用
func1
函数(但仍在工作流中),则它将失败,因为它超出了范围 .如果您在工作流程之外或工作流程内部而不是在InlineScript块中定义两个函数,则会发生相同的情况 .
现在举例说明如何将其应用于运行
foreach -parallel
循环 .对此工作流程的示例调用如下所示
您将注意到(并且如预期的那样)输出顺序是随机的,因为它是并行运行的 .
Powershell要求在使用前定义函数('lexical scope') . 在您的示例中,您在定义之前调用
logMessage
函数 .您还将示例结构化为Powershell工作流程 . 工作流有一些普通脚本没有的限制;你需要意识到这些差异 . 我做了this search找到一些关于差异的描述和讨论; the first "hit"提供了很好的信息 . 我还没有找到任何关于是否可以在工作流中定义函数的内容,但我会非常谨慎地在函数(或工作流)中定义函数 .
从
func1
函数中看不到logMessage
函数 . 即使logMessage
函数在func1
之上声明,它也是有效的 .对于这个简单的情况,您可以使用nested functions,如下所示:
Output :