我试图了解Powershell中的内容(v2.0,如果重要的话)。我正在将一个命令的结果捕获到变量中,当我将它写入控制台时,我没有得到我期望的结果。除输出外的所有内容都按预期运行。
这是一个MCVE,其行为方式与我编写的脚本相同。我只是将其分解,以便我可以提供有关正在发生的事情的评论,它不按照我认为应该工作的方式进行评论,以及我认为可能发生的事情。
在第一个代码段中,我正在验证服务MyService
的状态
在计算机上svr0123
。这给出了我期待的输出。
PS C:\Temp> Get-Service -Name MyService -CN svr0123
Status Name DisplayName
------ ---- -----------
Stopped MyService My_Service_Display_Name
PS C:\Temp>
在第二个片段中,我正在做同样的事情,只是将输出分配给
$results
旨在重新启动任何已停止的服务。再次,这
给出了我期待的输出。
PS C:\Temp> $results = Get-Service -Name MyService -CN svr0123
PS C:\Temp> Write-Output $results
Status Name DisplayName
------ ---- -----------
Stopped MyService My_Service_Display_Name
PS C:\Temp>
最后,我正在重新启动服务,然后编写$results
的内容
到控制台。这会按预期执行不功能。我期待
$results
的内容与前两个输出相同,
但我得到了:
PS C:\Temp> $results | Where { $_.Status -eq "Stopped" } | Set-Service -Status Running
PS C:\Temp> Write-Output $results
Status Name DisplayName
------ ---- -----------
Running MyService My_Service_Display_Name
PS C:\Temp>
这是不正确的,除非每次我引用的内容
$results
它再次调用Get-Service
命令,这是违反直觉的。如果是这样的话,那就是
似乎我没有存储命令的输出,而是我
将别名存储到命令中。如果我在重新启动之前将$results
的内容写入控制台,则所有内容都会按预期输出。
这是一个微不足道的修复,但我试图理解我观察的背后的“为什么”。我的问题是:
答案 0 :(得分:1)
我认为在显示服务对象时它不会重新调用Get-Service
。我认为$service
对象有一个内部状态,它是一个文本值,当你将它传递给Set-Service
时,状态值会被改变,服务也会被启动/停止。
由于尝试使用$service.Status = "Running"
直接更改它会生成错误,因为该属性是只读的,因此可以通过服务对象自己的$service.Start()
和$service.Stop()
方法进行此更改$service | get-member
支持一些快速测试的证据:
我$service = get-service testsvc; $service
看到状态正在运行,然后我转到控制面板并停止那里的服务,$service
状态不会改变。
我直接调用$service.Start()
来重启服务,我得到一个异常(可能是因为我的PowerShell没有作为管理员运行)所以服务实际上并没有开始运行,但是{{1}确实改变(错误地)说服务正在运行。
通过这种方式,我在报告状态和实际状态之间断开连接令我信服,以及每个对象“知道”它是如何生成并且任意重新运行该代码的方式似乎难以置信/不切实际(如果这是一个30分钟的查询来生成它吗?)但我不知道确定交互是什么。
答案 1 :(得分:1)
当你致电Get-Service -Name MyService -CN svr0123
时,它会返回一个ServiceController
对象,而不仅仅是输出文本。
所以,当你拨打这一行时:
$results = Get-Service -Name MyService -CN svr0123
$results
不仅仅是一个包含命令输出的字符串变量。它实际上是ServiceContoller
类型的变量。
运行此以查看:
$results.GetType()
你会得到这个:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ServiceController System.ComponentModel.Component
因此,第二次执行Write-Output $results
时,服务已启动,$results
变量显示服务的当前状态。