variables in write-host command

This topic contains 11 replies, has 4 voices, and was last updated by Profile photo of Shane Lindberg Shane Lindberg 1 year, 11 months ago.

  • Author
    Posts
  • #27897
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

    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?

  • #27898
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

    I think I found a good solution: invoke-expression

    invoke-expression "write-host $count $color $newline"
  • #27904
    Profile photo of Peter Jurgens
    Peter Jurgens
    Participant

    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
    
  • #27909
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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

  • #27913
    Profile photo of Bob McCoy
    Bob McCoy
    Participant
    $foo=13
    write-host $(" "*$foo) -BackgroundColor red -NoNewline
    
  • #27937
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

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

  • #27943
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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
    
  • #27947
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

    Thanks Max. Those were some great suggestions 🙂

  • #27949
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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
    }

  • #27972
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

    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
  • #27996
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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 }

  • #27998
    Profile photo of Shane Lindberg
    Shane Lindberg
    Participant

    Thanks 🙂

You must be logged in to reply to this topic.