我开发了一个PowerShell函数,它执行了许多涉及提供SharePoint团队站点的操作。最终,我想函数返回的URL提供的网站作为字符串,所以在我的函数结束,我有以下代码:

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

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

$returnURL = MyFunction -param 1 ...

我期待的是一个字符串,但它不是。相反,它是System.Management.Automation.PSMethod类型的对象。为什么它返回的是那个类型而不是String类型?


当前回答

作为一种变通方法,我一直在返回数组中的最后一个对象,你从函数中返回…这不是一个很好的解决方案,但总比什么都没有好:

someFunction {
   $a = "hello"
   "Function is running"
   return $a
}

$b = someFunction
$b = $b[($b.count - 1)]  # Or
$b = $b[-1]              # Simpler

总而言之,写同一件事的一种更简洁的方式是:

$b = (someFunction $someParameter $andAnotherOne)[-1]

其他回答

我传递了一个简单的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中看到真实的使用示例。

PowerShell有非常古怪的返回语义——至少从更传统的编程角度来看是这样。这里有两个值得你思考的观点:

捕获并返回所有输出 return关键字实际上只是指示了一个逻辑退出点

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

$a = "Hello, World"
return $a

 

$a = "Hello, World"
$a
return

第二个示例中的$a变量被保留为管道上的输出,并且如前所述,将返回所有输出。事实上,在第二个示例中,您可以完全省略返回,并且您将得到相同的行为(返回将在函数自然完成和退出时隐含)。

没有更多的函数定义,我不能说为什么你得到一个PSMethod对象。我的猜测是,您可能有一些未被捕获的内容,它们被放置在输出管道中。

同样值得注意的是,您可能不需要这些分号——除非您在一行上嵌套多个表达式。

您可以在TechNet的about_Return页面上阅读更多关于返回语义的信息,或者通过从PowerShell本身调用帮助返回命令。

在PowerShell 5中,我们现在能够创建类。将函数更改为类,return将只返回它前面的对象。这里有一个简单的例子。

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

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

Hello World
808979

但是作为一个类,唯一返回的是整数808979。类有点像一个保证,它只返回声明的类型或void。

如果不查看代码,就很难说。确保函数不返回一个以上的对象,并且捕获其他调用产生的任何结果。你得到了什么:

@($returnURL).count

总之,我有两个建议:

将对象转换为字符串:

...
return [string]$rs

或者用双引号括起来,和上面一样,但是要短一点:

...
return "$rs"

作为一种变通方法,我一直在返回数组中的最后一个对象,你从函数中返回…这不是一个很好的解决方案,但总比什么都没有好:

someFunction {
   $a = "hello"
   "Function is running"
   return $a
}

$b = someFunction
$b = $b[($b.count - 1)]  # Or
$b = $b[-1]              # Simpler

总而言之,写同一件事的一种更简洁的方式是:

$b = (someFunction $someParameter $andAnotherOne)[-1]