我开发了一个PowerShell函数,它执行了许多涉及配置SharePoint团队站点的操作 . 最后,我希望函数将配置站点的URL作为String返回,因此在我的函数结束时,我有以下代码:
$rs = $url.ToString();
return $rs;
调用此函数的代码如下所示:
$returnURL = MyFunction -param 1 ...
所以我期待一个String,但事实并非如此 . 相反,它是System.Management.Automation.PSMethod类型的对象 . 为什么它返回该类型而不是String类型?
8 回答
使用PowerShell 5,我们现在可以创建类 . 将函数更改为类不仅可以键入它,而且只返回它前面的对象 . 这是一个非常简单的例子 .
如果这是一个函数,那么预期的输出就是
但是作为一个类,唯一返回的是INT 808979.类是一种保证,它只返回声明的类型或void .
以下简单地返回4作为答案 . 替换字符串的add表达式时,它返回第一个字符串 .
这也可以用于阵列 . 以下示例将返回“Text 2”
请注意,您必须在函数本身下方调用函数,否则第一次运行它将返回一个错误,它不知道“StartingMain”是什么 .
我希望它有所帮助 .
我传递一个简单的Hashtable对象和一个结果成员,以避免返回疯狂,因为我也想输出到控制台 . 它通过引用传递 .
您可以在我的GitHub project unpackTunes看到真实的示例用法
作为一种解决方法,我一直在返回数组中你从函数返回的最后一个对象...不是一个很好的解决方案,但它总比没有好:
卢克对这些情景中功能结果的描述似乎正确 . 只希望了解根本原因并且PowerShell产品团队会对该行为做些什么,似乎很常见并且花费了太多的调试时间 .
为了解决这个问题,我一直在使用全局变量而不是返回并使用Function调用中的值 .
这是使用全局变量的另一个线程:Setting a global PowerShell variable from a function where the global variable name is a variable passed to the function
PowerShell具有非常古怪的返回语义 - 至少从更传统的编程角度来看 . 有两个主要想法可以解决问题:
捕获并返回所有输出
return关键字实际上只是表示逻辑出口点
因此,以下两个脚本块将有效地完成相同的操作:
第二个示例中的$ a变量在管道上保留为输出,如上所述,返回所有输出 . 实际上,在第二个示例中,您可以完全省略返回,并且您将获得相同的行为(当函数自然完成并退出时,将隐含返回) .
如果没有更多的函数定义,我无法说明为什么要获得PSMethod对象 . 我的猜测是你可能有几行没有被捕获并被放置在输出管道上 .
值得注意的是,您可能不需要那些分号 - 除非您在一行上嵌套多个表达式 .
您可以在TechNet上的about_Return页面上阅读有关返回语义的更多信息,或者从PowerShell本身调用
help return
命令 .没有看代码就很难说 . 确保您的函数不会返回多个对象,并且您捕获从其他调用中获得的任何结果 . 你得到了什么:
无论如何,两个建议:
将对象转换为字符串:
或者只是用双引号将其括起来,与上面相同但是更短以输入:
PowerShell的这一部分可能是最愚蠢的方面 . 在函数期间生成的任何无关输出都会污染结果,有时没有输出,然后在某些情况下除了计划的返回值之外还有其他一些计划外输出 .
所以,我所做的是从原始函数调用中删除赋值,以便输出在屏幕上结束,然后逐步执行,直到我没有计划在调试器窗口中弹出的内容(使用PS ISE) .
甚至像保留外部作用域中的变量之类的东西也会导致输出,比如
[boolean]$isEnabled
,除非你把它变成_461018,否则它会恼怒地吐出一个False .另一个好的是
$someCollection.Add("thing")
,这会吐出新的收藏计数 .