我试图让这个PowerShell脚本,要求用户input一个服务名称,通过Get-Service
运行,并显示结果给用户。
例如,如果用户要inputvmtools
,则会显示:
Status Name DisplayName ------ ---- ----------- Running vmtools VMware Tools
这是我的代码:
Write-host "Enter Service name" $ServiceName = read-host $Result = get-service $ServiceName Write-Output "$Result"
但是,它只输出: System.ServiceProcess.ServiceController
这是因为当你为某些类型的变量添加引号时,它会输出变量类型,而不是变量的实际内容。 因此,在变量输出中删除引号可以解决您的问题。 用你的最后一行代替:
Write-Output $Result
TL;博士
$Result # Implicitly outputs $Result - no need for Write-Output or "..."
与类似POSIX的shell(Unix)不同:
PowerShell 从不需要 "..."
围绕变量引用 (如$Result
。
如果你确实需要一个字符串 , 经常在变量引用周围使用"..."
,但不一定会导致与打印到终端 (控制台)时不同的表示形式 。
如果要进一步处理对象,则按原样传递对象 ,否则将失去PowerShell面向对象的好处。
PowerShell传递对象 – 这代表了它从传统外壳进化的巨大飞跃,并且仅在(a) 输出到终端或者将输出发送到具有>
( Out-File
)/ Out-String
或(b) inside的文件中"..."
或者(c) 当应用.ToString()
,这些对象是字符串化的 :
(a)使用PowerShell的默认格式化系统,该系统允许您为任何.NET类型定义自定义表示(有多个预定义的表示形式); 例如输出散列表@{ one = 1; two = 2}
@{ one = 1; two = 2}
产生一个相当漂亮的2列布局; 请参阅Get-Help about_format.ps1xml
。
(b)和(c) 绕过 PowerShell的默认格式:
(c),直接调用每个对象的.ToString()
方法 – 可以范围从一个虚拟的无意义类型名称的唯一表示 (如在你的情况,或在@{ one = 1; two = 2 }.ToString()
,其中(Get-Date '2017-01-01').ToString()
1/1/17 12:00:00 AM
(Get-Date '2017-01-01').ToString()
1/1/17 12:00:00 AM
系统上产生1/1/17 12:00:00 AM
) – 取决于任何给定的类型支持。
对于.NET 基本类型 , .ToString()
表示与PowerShell的默认格式相同 。
(b)的规则( "..."
隐式字符串化) 与 (c) 类似 ,除了PowerShell按设计寻求文化不变的表示 (详情请参阅我的答案 )。