user8379123
user8379123

Reputation: 23

Problems getting correct output in Powershell

I'm trying a to make this PowerShell script that would ask for the user to input a service name, run through Get-Service, and show the result to the user.

For example, if the user was to enter vmtools it would show:

Status      Name      DisplayName
------      ----      -----------
Running     vmtools   VMware Tools

This is my code:

Write-host "Enter Service name"
$ServiceName = read-host
$Result = get-service $ServiceName
Write-Output "$Result" 

However, it only outputs: System.ServiceProcess.ServiceController

Upvotes: 2

Views: 637

Answers (2)

mklement0
mklement0

Reputation: 437062

tl;dr

$Result # Implicitly outputs $Result - no need for Write-Output or "..."

Unlike POSIX-like shells (Unix):

  • PowerShell never requires "..." around a variable reference such as $Result.

    • In fact, doing so converts the variable to a string - which may or may not be the intent.
  • If you do want a string, using "..." around a variable reference often - but not necessarily - results in a different representation than when printing to the terminal (console).

  • If the object is to be processed further, pass it on as-is, otherwise you'll lose the benefits of PowerShell's object orientation.

PowerShell passes objects around - which represents its great evolutionary leap from traditional shells - and only on (a) output to the terminal or sending output to a file with > (Out-File) / Out-String or (b) inside "..." or (c) when applying .ToString() are these objects stringified:

  • (a) uses PowerShell's default formatting system, which allows you to define custom representations for any .NET type (with several representations predefined); e.g., outputting hashtable @{ one = 1; two = 2} yields a pretty-printed 2-column layout; see Get-Help about_format.ps1xml.

  • (b) and (c) bypass PowerShell's default formatting:

    • (c), directly calling each object's .ToString() method - can range from a virtually meaningless type name-only representation (as in your case, or as in @{ one = 1; two = 2 }.ToString(), which yields System.Collection.Hashtable) to a culture-sensitive representation (e.g., (Get-Date '2017-01-01').ToString() yields 1/1/17 12:00:00 AM on a US-English system) - depending on whatever the given type supports.
      For the .NET base types, the .ToString() representation is the same as PowerShell's default formatting.

    • (b)'s rules (implicit stringification inside "...") are similar to (c)'s except that PowerShell by design seeks a culture-invariant representation where supported - for details, see this answer.

Upvotes: 3

Maxime Franchot
Maxime Franchot

Reputation: 1103

That is because when you add quotation marks around certain types of variables, it outputs the variable type, not the actual contents of the variable. Therefore, removing quotation marks on the variable output will fix your problem. Replace your last line with this:

Write-Output $Result 

Upvotes: 0

Related Questions