Author Posts

July 26, 2015 at 7:05 pm

I want the following command executed. which should be 6 spaces with a red background with no newline

write-host " "*6 -backgroundcolor red -nonewline

I am trying to accomplish this with variables, but am missing something

$newline = " -nonewline"
$color = " -backgroundcolor red" 
$count = " "*6

write-host $count $color $newline

I need to be able to use variables to control the color and -nonewline switch. My example of how I am trying to do it is faulty. How could I accomplish this?

July 26, 2015 at 7:55 pm

I think I found a good solution: invoke-expression

invoke-expression "write-host $count $color $newline"

July 27, 2015 at 1:51 am

You were almost there. Have a look at splatting. You can create a hash table with the names of the parameters and the values you wish to supply to those parameters then pass the hash table variable to the cmdlet prefixed with an @ symbol. Eg.

$hash=@{object="test";foregroundcolor="red"}
Write-host @hash

July 27, 2015 at 5:10 am

other acceptable variant

$nonewline = $true
$color = 'red'
$count = " "*6
write-host $count -backgroundcolor $color -nonewline:$nonewline

invoke-expression is a BAD variant. It's contr-intuitive and vulnerable to exploits and nasty bugs that difficult to detect

July 27, 2015 at 6:57 am

$foo=13
write-host $(" "*$foo) -BackgroundColor red -NoNewline

July 27, 2015 at 7:50 pm

I finished my introduction to my first program, a tic tac toe game. What do you think.

July 28, 2015 at 3:30 am

Optimized code style (with comments, why that way is better )

#this function converts a value to pixels to create billy
function write-billy{
    
    #these are the pixels(spaces) that make up the ascii image
    $billy = ('sb8','nl9','sb6','sl4','sw5','nl4','sb5','sl3','sw9',
    'nl3', 'sb4','sl3','sw11','nl3','sb3','sl3','sw3','sr3','sw1',
    'sr3','sw3','nl3','sb3','sl3','sw2','sl1','sr1','sl1','sr1','sw1',
    'sr1','sl1','sr1','sl1','sw2','nl4','sb2','sl3','sw4','sr3','sw1',
    'sr3','sw4','nl3','sb2','sl3','sw1','sr1','sw1','sr1','sw7','sr1',
    'sw1','sr1','sw1','nl3','sb1','sl5','sw1','sr1','sw9','sr1','sw1',
    'nl5','sb1','sl7','sw1','sr7','sw1','nl7','sb2','sl6','sw2','sl1',
    'sw3','sl1','sw2','nl6','sb3','sl4','sr2','sw1','sl1','sw3','sl1',
    'sw1','sr2','nl4','sb7','sl1','sr9','nl1','sb5','sl2','sr2','sl2',
    'sw3','sl2','sr2','nl2','sb3','sl9','nl9','sb2','nl21','sb1','nl23')

    foreach ($i in $billy){
        
       #this part determines how many spaces to print
       # if you need string from some character to end
       # you can use another substring() overload
       $manychars = $i.substring(2)
       
        #this next part determines the color to print
        # switch statement in this case more intuitive and readable
        # you can user [] indexer if you need string characters one by one
        switch ($i[1]) {
            'r' { $color = 'red' }
            'l' { $color = 'black' }
            'w' { $color = 'white' }
            default { $color = $host.UI.RawUI.BackgroundColor } # default console color
        }
        
        #this part determines if it needs a -nonewline added
        $newline = ($i[0] -eq 's') # already boolean(true/false) type
        # right variable usage in this case ( Invoke-Expression > $null )
        Write-Host (' '*$manychars) -BackgroundColor $color -NoNewLine:$newline

    }
}

function write-slow ($text, $delay){
     # Do not need string splitting, you can use string as char array
     foreach ($i in $text.ToCharArray()){
         # do not need any intermediate variables
         Write-Host -NoNewline $i
         Start-Sleep -Milliseconds $delay
     }
     Write-Host
}


write-billy
Write-Host
write-slow 'Would you like to play a game?' 125
Write-Host
write-slow 'press enter to fulfill your destiny' 125
Read-Host

July 28, 2015 at 5:16 am

Thanks Max. Those were some great suggestions 🙂

July 28, 2015 at 6:14 am

forget to say, i change write slow style to one-by-one character output, and youth – word by word
your variant without extra variables:
function write-slow ($text, $delay){
foreach ($i in $text.split(" ")){
Write-Host -NoNewline ($i + " ")
Start-Sleep -Milliseconds $delay
}
write-host
}

another variant with -byword output, but it out space symbol as word (and implement delay on it, thus you need two times shorter delay to the same speed). this time use powershell native split operator with regular expression

function write-slow ($text, $delay){
foreach ($i in ($text -split '(\s)')){
Write-Host -NoNewline $i
Start-Sleep -Milliseconds $delay
}
write-host
}

third variant 🙂

function write-slow ($text, $delay){
# Do not need string splitting, you can use string as char array
foreach ($i in $text.ToCharArray()){
# do not need any intermediate variables
Write-Host -NoNewline $i
if ($i -eq ' ') {
Start-Sleep -Milliseconds $delay
}
}
Write-Host
}

July 28, 2015 at 5:26 pm

I like the code, but when I am trying it, I am not able to use the envirmental variable for background color

PS C:\Users\shane> Write-Host gggggggggg -BackgroundColor $host.UI.RawUI.BackgroundColor
Write-Host : Cannot process the color because -1 is not a valid color.
Parameter name: value
Actual value was -1.
At line:1 char:1
+ Write-Host gggggggggg -BackgroundColor $host.UI.RawUI.BackgroundColor
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Write-Host], ArgumentOutOfRangeException
    + FullyQualifiedErrorId : SetInvalidBackgroundColor,Microsoft.PowerShell.Commands.WriteHostCommand

July 29, 2015 at 12:49 pm

This is because you use ISE,
in pure Powershell: PS D:\> $host.UI.RawUI.BackgroundColor
DarkMagenta

in ISE: PS D:\> $host.UI.RawUI.BackgroundColor
-1

You can use this workaround
somewhere in the beginning of your script:
$defaultColor = $host.UI.RawUI.BackgroundColor
if ($defaultColor -eq -1) { $defaultColor = 'DarkMagenta' } #or some another color you need

and in switch()
default { $color = $defaultColor }