5

Good day!

I stumbled across a small "problem" the other day...

I have learned scripting through the linux-shell. There, one can construct commands through strings and exceute them as is.

For Example:

#!bin/bash
LS_ARGS='-lad'  
LS_CMD='ls'

CMD="$LS_CMD $LS_ARGS /home"    
$CMD

But now I had to switch to windows powershell:

If ( $BackgroundColor ) {
    Write-Host -BackgroundColor $BackgroundColor
}
If ( $ForegroundColor ) {
    Write-Host -ForegroundColor $ForegroundColor
}
If ( $ForegroundColor -AND $BackgroundColor ) {
    Write-Host -ForegroundColor $ForegroundColor
               -BackgroundColor $BackgroundColor
}

If ( $NoNewline ) {
    If ( $BackgroundColor ) { ... }
    ElseIf ( $ForegroundColor ) { ... }
    ElseIf ( $ForegroundColor -AND $BackgroundColor ) { ... }
    Else { ... }
}

I think you know what I mean ;) Does anyone know a way of cutting this down like:

[string] $LS_CMD  = 'Write-Host'
[string] $LS_ARGS = '-BackgroundColor Green -NoNewLine'
[string] $CMD     = "$LS_CMD C:\temp $LS_ARGS"

Maybe I am trying to change something that should not be changed due to these stupid comparisons with other languages. The main reason I want to do this is because I am trying to reduce all the unnecessary conditions and passages from my scripts. Trying to make them more legible... Would be nice if someone could help me out here.

Michael

3 Answers 3

7

You can build a string and execute using Invoke-Expression:

Invoke-Expression "$cmd $cmd_args"
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! Strangly.. I was faster than you
2

The simplest way to build up a set of arguments for a cmdlet is to use a hashtable and splatting:

$arguments = @{}
if( $BackgroundColor ) { $arguments.BackgroundColor = $BackgroundColor }
if( $ForegroundColor ) { $arguments.ForegroundColor = $ForegroundColor }
if( $NoNewline ) { $arguments.NoNewline = $NoNewline }
...

Write-Host text @arguments

The @ in Write-Host text @arguments causes the values in $arguments to be applied to the parameters of the Write-Host cmdlet.

1 Comment

This is very beautiful! I did not know about the @ marker! Thanks a lot!
2

As I skimmed through the current powershell questions here I stumbled over:
How to dynamically create an array and use it in Powershell

One can use the "Invoke-Expression" Cmdlet:
The Invoke-Expression cmdlet evaluates or runs a specified string as a command and returns the results of the expression or command. Without Invoke-Expression, a string submitted at the command line would be returned (echoed) unchanged.

[string] $Cmd = ""
if ( $BackgroundColor ) {
   $Cmd += ' -BackgroundColor Green'
}
if ( $ForegroundColor ) {
   $Cmd += ' -ForegroundColor Black'
}
if ( $NoNewLine ) {
   $Cmd += '-NoNewLine'
}

Invoke-Expression $Cmd

Is there anything wrong with that solution?
It looks pretty to me ;)

Sorry.. Now I look like I did no research and googling :/ Just stumbled over the answer by accident. Thanks Andi Arismendi

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.