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

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

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

$returnURL = MyFunction -param 1 ...

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


当前回答

Luke在这些场景中对函数结果的描述似乎是正确的。我只想了解根本原因,PowerShell产品团队会对这种行为采取一些措施。这似乎很常见,并且花费了我太多的调试时间。

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

下面是另一个关于全局变量使用的问题: 从函数设置全局PowerShell变量,其中全局变量名是传递给该函数的变量

其他回答

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

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]

现有的答案是正确的,但有时实际上并没有显式地返回Write-Output或return,但函数结果中有一些神秘的值。这可以是像New-Item这样的内置函数的输出

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result


    Directory: C:\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2/9/2020   4:32 PM                132257575335253136
True

所有创建目录的额外噪音都被收集并在输出中发出。缓解这种情况的简单方法是在New-Item语句的末尾添加| Out-Null,或者您可以将结果分配给一个变量,但不使用该变量。它看起来是这样的……

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory | Out-Null
>>    # -or-
>>    $throwaway = New-Item -Path $folderPath -ItemType Directory 
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result
True

New-Item可能是其中更著名的,但其他方法包括所有StringBuilder.Append*()方法,以及SqlDataAdapter.Fill()方法。

在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。

Luke在这些场景中对函数结果的描述似乎是正确的。我只想了解根本原因,PowerShell产品团队会对这种行为采取一些措施。这似乎很常见,并且花费了我太多的调试时间。

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

下面是另一个关于全局变量使用的问题: 从函数设置全局PowerShell变量,其中全局变量名是传递给该函数的变量

下面的函数简单地返回4作为答案。当你替换字符串的add表达式时,它会返回第一个字符串。

Function StartingMain {
  $a = 1 + 3
  $b = 2 + 5
  $c = 3 + 7
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b
}

StartingEnd(StartingMain)

这也可以用于数组。下面的例子将返回"Text 2"

Function StartingMain {
  $a = ,@("Text 1","Text 2","Text 3")
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b[1]
}

StartingEnd(StartingMain)

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