Powershell 如何将字符串同时输出到变量和控制台

Powershell 如何将字符串同时输出到变量和控制台,powershell,Powershell,powershell中是否有一种简单的方法可以同时向变量和控制台输出字符串 我想将脚本的输出捕获到一个变量,这样我就可以在脚本结束时对其进行分析,将其保存到日志文件中,并通过电子邮件发送给操作员 我的意图是拥有一个变量$output,并向其添加任何输出字符串,还可以立即输出到控制台,比如 $output="Process started" $output=+"Doing step 1" "Doing step 1" $output=+"Doing step 2" "Doing step 2"

powershell中是否有一种简单的方法可以同时向变量和控制台输出字符串

我想将脚本的输出捕获到一个变量,这样我就可以在脚本结束时对其进行分析,将其保存到日志文件中,并通过电子邮件发送给操作员

我的意图是拥有一个变量$output,并向其添加任何输出字符串,还可以立即输出到控制台,比如

$output="Process started"

$output=+"Doing step 1"
"Doing step 1"

$output=+"Doing step 2"
"Doing step 2"
因此,最终我可以将$output保存到日志文件中,通过电子邮件发送并解析它

我使用了tee对象,它可能会为此目的工作,但不幸的是,它会重写$output变量,而不是向其追加字符串

更新 这是我决定采用的最终解决方案-感谢manojlds

$script:output = ""

filter mylog {
    $script:output+= $_+"`n"
    return $_
}


"doing step {0}" -f 1 | mylog
"doing step {0}" -f 2 | mylog
"doing step {0}" -f 3 | mylog

#in the end of the script
$script:output

实现最终目标的方法有很多:

在您的脚本中,只需执行以下操作:

"Process started"
<step1>
"Doing step 1"
<step2>
"Doing step 2"
...
请注意,输出可用于
Tee对象
,因此在出现时可用于控制台。只有在整个脚本运行之后才能获得输出。这就是管道在Powershell中的工作方式。当对象出现时,它们会沿着下游传递。在两个步骤之间插入一个
sleep 10
,查看输出是否在可用时立即出现

此外,您不一定要有另外一个脚本(launcher.ps1)。您可以在脚本中使用函数、脚本块等

其他一些方式:

function test {

"Process started"
sleep 5
"Doing step 1"
sleep 5
"Doing step 2"

}

test | %{$output+=$_;$_}
#use output
write-host -fore blue $output
您可以创建一个过滤器:

$script:output = ""

filter appendOutput {

    $script:output+= $_
    return $_
}

"Process started" | appendOutput
sleep 5
"Doing step 1" | appendOutput
sleep 5
"Doing step 2" | appendOutput
#use output
write-host -fore blue $script:output

可能还有更多的方法可以做到这一点。

我对powershell的研究还不够深入,无法给出具体的答案,但如果我在C中这样做,我会利用副作用

//Psuedo-C
string con (oldString, newString) {
  print(newString);
  return oldString + newString;
}
使用如下函数:

myString = con(myString, "Process started");
这将产生预期的效果。(撇开正确的C语法和迂腐的语言,比如处理换行符)我不知道如何将其转换为powershell


然而,你想做的事情可能会被认为是一团糟。如果您只是显式地输出和记录输出,并在代码中一个接一个地记录,可能会更清楚。副作用不可避免地会回来咬你。保持模块化。

这里有一个很好的技巧,将变量赋值括在括号中。您可以在PowerShell语言规范(第7.1.1节分组括号)中找到有关此方面的更多信息,可下载:


我在看类似的东西,除了以后我不需要分析它,只需要收集输出


其他人可能会看到,因为您的答案似乎是使用PowerShell成绩单(开始成绩单和停止成绩单)。我从中发现,当您遇到服务器错误时,它确实存在一些问题,但他展示了他是如何处理的。

要对@manojlds answer进行一点扩展,您可以简单地使用
Tee Object
cmdlet,但您可以告诉它直接写入变量,而不是指定要写入的文件,如下所示:

.\test.ps1 | Tee-Object -Variable output

脚本/cmdlet/function/etc的所有输出将实时写入控制台屏幕,并在脚本完成运行时存储在
$output
变量中。因此,您可以使用该变量对其进行分析或将其写入文件。这避免了在操作完成后必须将文件内容读入变量。

脚本将在输出屏幕上写入数据,并将相同的数据存储在变量中

get-process | Tee-Object -Variable test

$test can use further 

谢谢,但它不工作-$x将被重置,每次当我需要它来积累所有的脚本输出-1。这根本不管用
$x
将为空,因为
out host
已经获得了字符串,您将获得该字符串的输出以设置变量,这没有什么(写入host并不意味着它可以在管道中使用)。这是我第一次实现的方法,但最终得到了两个脚本。我现在有更复杂的脚本,需要在调用脚本中进行一些分析,这使得我的调用脚本更复杂。我刚刚找到了这篇文章,我现在在想,如果我可以做一些类似的事情来覆盖Default抱歉,只是让我说清楚…我有我的主脚本(比如main.ps)和launcher.ps(类似于你的.\test.ps1 | Tee Object-file log.txt),所以launcher将捕获主脚本的输出。虽然它可以工作,但这种方法有两个问题-在主脚本完成之前,我在控制台中看不到任何内容,并且我无法在主脚本中进行任何分析/解析script@mishking-
\test.ps1 | Tee对象-file log.txt
-如果您正在执行此操作,您将在发生时在控制台中看到输出。在上述脚本中的字符串之间添加
sleep 10
,请参见。另见我的最新答案谢谢你的帮助!日志文件在我的脚本中是可选的,这就是为什么我想首先在变量中收集输出,在脚本结束时,根据传递给脚本的参数,可以将其保存到日志文件和/或通过电子邮件发送。我在我的启动程序脚本中没有使用点源,只是在$output变量中捕获了主脚本的输出-我想这就是为什么我没有以RealTime的方式看到控制台输出的原因。如果我总是需要输出日志文件,您建议的方式将非常有效,但是如果这是像我这样的可选方式,该怎么办?我也希望有一个脚本,而不是两个和变量在它的最后,我可以解析一些关键字和控制台输出的实时。有可能拥有所有这些吗?太棒了!这是一个非常酷的把戏,谢谢你在那里提供了大量的好信息。这个技巧对我的情况没有太大帮助,因为如果我需要在单个变量中累积输出,比如:$output=“”($output+=“执行步骤{0}”-f1)($output+=“执行步骤{0}”-f2),我会得到:执行步骤1执行步骤1执行步骤2,我现在会像上面建议的那样使用过滤器。谢谢!它可能对一些人有用,我也研究过,但它也有局限性,就像这里描述的那样
PS > ($var=1)
1
PS >
.\test.ps1 | Tee-Object -Variable output
get-process | Tee-Object -Variable test

$test can use further