在Powershell中获得正确输出的问题

我试图让这个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按设计寻求文化不变的表示 (详情请参阅我的答案 )。