Unnecessary space in output when using Write-Host - powershell

When I use Write-Host within a Foreach-Object, I get an unnecessary space in the output.
write-host "http://contoso.com/personal/"$_.ADUserName
Output:
http://contoso.com/personal/ john.doe
How can I remove the space before john? Trim does not work because there is no space in $_.ADUserName

This is happening because Write-Host is considering your constant string and your object to be two separate parameters -- you aren't actually joining the strings together the way you're calling it. Instead of calling it this way, actually concatenate the strings:
write-host "http://contoso.com/personal/$($_.ADUserName)"
or
write-host ("http://contoso.com/personal/" + $_.ADUserName)
or
write-host ("http://contoso.com/personal/{0}" -f $_.ADUserName)

Just do it without write-host:
"http://contoso.com/personal/{0}" -f $_.ADUserName

Related

Combining String and Variable causes leading extra Space [duplicate]

When I use Write-Host within a Foreach-Object, I get an unnecessary space in the output.
write-host "http://contoso.com/personal/"$_.ADUserName
Output:
http://contoso.com/personal/ john.doe
How can I remove the space before john? Trim does not work because there is no space in $_.ADUserName
This is happening because Write-Host is considering your constant string and your object to be two separate parameters -- you aren't actually joining the strings together the way you're calling it. Instead of calling it this way, actually concatenate the strings:
write-host "http://contoso.com/personal/$($_.ADUserName)"
or
write-host ("http://contoso.com/personal/" + $_.ADUserName)
or
write-host ("http://contoso.com/personal/{0}" -f $_.ADUserName)
Just do it without write-host:
"http://contoso.com/personal/{0}" -f $_.ADUserName

Powershell remove space from after command

I have this command
Write-Host "Background " -NoNewline; [System.Windows.Forms.SystemInformation]
::PrimaryMonitorSize.Width; Write-Host "x" -NoNewline;
[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
I want it to come out Background 1920x1080
I cant seem to find a way to stop the command
[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width
from making a new line.
Its coming out
Background 1920
x1080
It's less complicated to simply use string formatting or in-line expand into a single string.
"Background {0}x{1}" -f [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width,[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
or
Write-Host "Background $([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width)x$([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height)"
An article on various formatting options: https://blogs.technet.microsoft.com/heyscriptingguy/2013/03/12/use-powershell-to-format-strings-with-composite-formatting/
The reason you're getting the extra newline is that your code sample omitted a Write-Host on the Width portion. The first items went to Write-Host, then an item on the output stream that didn't have a way to omit the newline. Simply correcting that flaw gives you the output you desired, but the approach is overly complicated.
Fixed original sample:
Write-Host "Background " -NoNewline;
Write-Host ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width) -NoNewLine;
Write-Host "x" -NoNewline;
Write-Host ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height)
You are getting multiple lines because you are not calling Write-Host -NoNewLine on the command to output the width. Your code is running the following four commands
Write-Host "Background " -NoNewline
[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width
Write-Host "x" -NoNewline
[System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
The second and fourth commands insert a newline, because you didn't use Write-Host to tell them not to.
Write-Host is not usually the best way to output text. A better option would be to build the output string in one statement using PowerShell's -f formatting operator.
$width = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width
$height = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Height
"Background {0}x{1}" -f ($width, $height)

Displaying block of text

I've done a bit of Googling and can't seem to find an effective method of displaying an entire block of text to the console. I would rather not use the Write-Host command on every line if I need to display a block of code. I'm trying to make an interactive script that's somewhat aesthetic. Is there an example that someone could give me?
PowerShell supports multiline strings, either as here-strings:
Write-Host #"
Some text you
want to span
multiple lines.
"#
or regular strings:
Write-Host "Some text you
want to span
multiple lines."
In addition to Ansgar's examples, Write-Host accepts an array too.
'one','two','three' | Write-Host
So whether your multi-line string is a single string, or an array of lines, it will still work as expected with a single Write-Host call:
Get-Content mycode.txt | Write-Host
Get-Content mycode.txt -Raw | Write-Host

Formatting a Powershell string containing hashtable values

The answer to this is likely to be trivial, but I have spent half an hour and still can't work it out.
Assume I have a the following hashtable:
$hash = #{face='Off';}
What I have tried to do, is output the value of "face" along side some other string elements.
This works:
Write-Host Face $hash['face']
=> Face Off
However, this doesn't:
Write-Host Face/$hash['face']
=> Face/System.Collections.Hashtable[face]
Somehow the lack of a space has affected the operator precedence - it is now evaluating $hash as a string, the concatenating [face] afterwards.
Trying to solve this precedence problem, I tried:
Write-Host Face/($hash['face'])
=> Face/ Off
I now have an extra space I don't want.
This works, but I don't want the extra line just to reassign:
$hashvalue = $hash['face']
write-host Face/$hashvalue
=> Face/Off
Any idea how to get this working as a one-liner?
Sure, use a subexpression:
Write-Host Face/$($hash['face'])
Generally, I'd just use a string, if I need precise control over whitespace with Write-Host:
Write-Host "Face/$($hash['face'])"
Yes, in this case you need a subexpression again, but more because you simply can't include an expression like $foo['bar'] in a string otherwise ;-)
By the way, $hash.face works just as well with much less visual clutter.
In such cases, and more so if there are more variables involved, I prefer using the string formatting. While in this case you can live with the $(..), be aware that string formatting will remove lot of doubt, cruft and improves readability:
write-host ("Face/{0}" -f $hash['face'])
In addition to using sub expressions as Joey showed you can:
Use string formatting:
Write-Host ('Face/{0}' -f $hash.face)
This will stick the value of face key in the place of {0}
Use string concatenation:
Write-Host ('Face/' + $hash.face)
Both of those require an expression to be evaluated which outputs a string which is used as Write-Host's Object parameter.
Another option is to insert your slash with the -Separator option of Write-Host:
$hash = #{Face="off"}
Write-Host ("Face",$hash.Face) -Separator '/'

How to expand member-variables in Write-Host or double quotes?

I have written a PS script and for diagnostic purpose am echoing messages to screen using Write-Host. This is fine as long as I have to expand normal variable like
Write-Host "Hello World, $name"
Problem starts when i try to echo some member variable as below
Write-Host "Hello World, $Person.Name"
This does not expand as expected. The work around that am following is, to use temp variable
as below
$personName = $Person.Name
Write-Host "Hello World, $personName"
Is there an elegant way of doing this with out the use of temp variable?
If you want to use property access within double-quoted strings, you need a subexpression:
"Foo $($bar.Property)"
Try this:
$dir = ls
Write-Host "Dir elements:" $dir.Length