Powershell脚本在函数中的do while中对if语句的结果进行排队

时间:2018-02-23 22:19:34

标签: powershell

我正在使用我从另一个脚本调用的函数。它会提示用户输入,直到它返回非空或空的内容。

function GetUserInputValue($InputValue)
{
  do{
    $UserValue = Read-Host -Prompt $InputValue
    if (!$UserValue) { $InputValue + ' cannot be empty' }
  }while(!$UserValue)
  $UserValue
  return $UserValue
}

这个问题很奇怪,可能是因为我缺乏PowerShell经验。当我运行代码并提供空结果时,来自if语句的消息排队,并且仅在我最终提供有效输入时显示。请参阅下面的控制台输出。

控制台结果

test:

test:

test:

test:

test:

test:
test: 1

test cannot be empty

test cannot be empty

test cannot be empty

test cannot be empty

test cannot be empty

test cannot be empty

1

我可以在主文件中使用硬编码值进行此操作。

do{
    $Server = Read-Host -Prompt 'Server'
    if (!$Server) { 'Server cannot be empty' }
}while(!$Server)

我正在使用Visual Studio Code。这是我在另一个名为functions.ps1的文件中的函数。

我从我的主文件中这样调用,

$test = GetUserInputValue("test")
$test

1 个答案:

答案 0 :(得分:1)

如果您将裸值放在"here's a message"5这样的脚本中,或者甚至是自己$PID的变量,那么您隐含做的就是调用Write-Output反对这个价值。

将对象返回到管道,并将其添加到返回的对象中。所以在一个函数中,它是函数的返回值,在ForEach-Object块中它是块的返回值等。这会使堆栈/管道的所有后退。

当它无处可去时,主持人会处理它。

控制台主机(powershell.exe)或ISE主机(powershell_ise.exe)通过在控制台上显示对象来处理此问题;这恰好是他们处理它的方式。另一个主机(例如,自定义C#应用程序可以托管powershell运行时)可能会以不同方式处理它。

所以,这里发生的是你要返回你想要显示的信息,作为你的功能的返回值的一部分,这不是你想要的。

相反,您应该使用Write-Host,因为这会将直接写入主机,跳过管道。当您要向用户显示必须显示的消息时,这是正确的命令(对于其他信息,您可以使用不同的命令,如Write-VerboseWrite-WarningWrite-Error等)。

执行此操作将为您提供正确的结果,并防止您的信息性消息成为您的函数返回值的一部分。

说到这,你要两次返回值。你不需要这样做:

$UserValue
return $UserValue

第一个仍然返回值(参见本答案的顶部);第二个做同样的事情,除了它立即返回。因为无论如何它都在函数的末尾,你可以使用枯萎的一个,但只使用一个。

还有一点需要注意:不要用括号调用PowerShell函数:

$test = GetUserInputValue("test")

这只是因为函数有一个参数。如果它有多个参数并且您试图将其称为方法(带括号和逗号),则它将无法正常工作。您应该使用空格分隔参数,并且通常应该按名称调用参数:

$test = GetUserInputValue "test"
# better:
$test = GetUserInputValue -InputValue "test"