函数在PowerShell中的返回值

我开发了一个PowerShell函数来执行许多涉及configurationSharePoint Team站点的操作。 最终,我希望函数返回供应网站的URL作为string,所以在我的函数结束我有以下代码:

$rs = $url.ToString(); return $rs; 

调用此函数的代码如下所示:

 $returnURL = MyFunction -param 1 ... 

所以我期待一个string,但事实并非如此。 相反,它是System.Management.Automation.PSMethodtypes的对象。 为什么它返回的是types而不是stringtypes?

PowerShell的返回语义确实很古怪 – 至less从更传统的编程angular度来看。 有两个主要的想法来包装你的头:

  • 所有输出都被捕获并返回
  • return关键字实际上只是表示一个逻辑出口点

因此,以下两个脚本块将有效地完成同样的事情:

 $a = "Hello, World" return $a 
 $a = "Hello, World" $a return 

第二个例子中的$ avariables作为stream水线上的输出,如前所述,所有输出都被返回。 事实上,在第二个例子中,你可以完全省略返回,你会得到相同的行为(返回将隐含着函数自然完成和退出)。

没有更多的函数定义,我不能说为什么你得到一个PSMethod对象。 我的猜测是,你可能有几行没有被捕获,并被放置在输出pipe道上。

还值得一提的是,你可能不需要这些分号 – 除非你在一行中嵌套多个expression式。

您可以阅读有关TechNet上about_Return页面上的返回语义的更多信息,或者从PowerShell本身调用help return命令。

PowerShell的这部分可能是最愚蠢的方面。 在函数中产生的任何多余的输出都会污染结果,有时候没有输出,在某些情况下,除了计划的返回值外,还有一些其他的非计划输出。

所以,我所做的就是从原始函数调用中除去赋值,这样输出就会在屏幕上显示出来,然后逐步执行,直到我不打算在debugging器窗口中popup(使用PS ISE)。

即使像在外部范围预留variables的东西会导致输出,如[boolean]$isEnabled这将恼人地吐出一个错误,除非你使[boolean]$isEnabled = $false

另外一个好的是$someCollection.Add("thing") ,这个新的集合数量是吐出来的。

作为一个解决方法,我已经返回数组中的最后一个对象,你从函数中得到…不是一个很好的解决scheme,但它总比没有好:

 someFunction { $a = "hello" "Function is running" return $a } $b = someFunction $b = $b[($b.count - 1)] # or $b = $b[-1] # simpler 

使用PowerShell 5,我们现在可以创build类。 改变你的function到一个类不仅你可以键入它,并返回将只返回它之前的对象。 这是一个真正简单的例子。

 class test_class{ [int]return_what() { $a = "Hello World" return 808979 } } $tc = New-Object -TypeName test_class $tc.return_what() 

如果这是一个函数,预期的输出将是

 Hello World 808979 

但作为一个类,唯一返回的是INT 808979.一个类就像一个保证,它只会返回声明或无效的types。

不看代码就很难说。 确保你的函数不返回多个对象,并且捕获其他调用的结果。 你得到什么:

 @($returnURL).count 

无论如何,两点build议:

将对象转换为string:

 ... return [string]$rs 

或者把它用双引号括起来,与上面相同,但是缩写为:

 ... return "$rs" 

卢克对这些情景下的function描述似乎是正确的。 只希望了解根本原因,PowerShell产品团队会对行为做些事情,似乎是相当普遍的,并且花费太多的debugging时间。

为了解决这个问题,我一直在使用全局variables,而不是返回并使用函数调用的值。

下面是使用全局variables的另一个线程: 从全局variables名称是一个variables传递给函数的函数中设置一个全局的PowerShellvariables

我绕过一个简单的Hashtable对象与一个单一的结果成员,以避免返回疯狂,因为我也想输出到控制台。 它通过传递行为。

 function sample-loop($returnObj) { for($i = 0; $i -lt 10; $i++) { write-host "loop counter: $i" $returnObj.result++ } } function main-sample() { $countObj = @{ result = 0 } sample-loop -returnObj $countObj write-host "_____________" write-host "Total = " ($countObj.result) } main-sample 

你可以看到我的GitHub项目unpackTunes的真实例子用法

以下简单地返回4作为答案。 当你replacestring的添加expression式时,它返回第一个string。

 Function StartingMain { $a = 1 + 3 $b = 2 + 5 $c = 3 + 7 Return $a } Function StartingEnd($b) { Write-Host $b } StartingEnd(StartingMain) 

这也可以为一个数组完成。 下面的例子将返回“文本2”

 Function StartingMain { $a = ,@("Text 1","Text 2","Text 3") Return $a } Function StartingEnd($b) { Write-Host $b[1] } StartingEnd(StartingMain) 

请注意,您必须调用函数本身下面的函数,否则第一次运行它将返回一个错误,它不知道“StartingMain”是什么。

我希望它有帮助。