2

I'm very new to PowerShell, and self-teaching myself it at that. My question is can you have 'write-host' and 'log-write' on the same line, to run as one action?

What I have is this:

Write-Host "Node Id is $nodeProps["NodeID"]" 
LogWrite "Node Id is $nodeProps["NodeID"]"

But I'm wondering if there is a way to do it like:

Write-Host, LogWrite "Node Id is $nodeProps["NodeID"]"

Thanks for any and all help!

Spence Rico
  • 23
  • 1
  • 3
  • Assuming Log-write is a function you have written yourself? Could not every call to it also execute a Write-Host on whatever is passed to that function? – campbell.rw Dec 20 '16 at 23:41
  • If `LogWrite` is something OP control over, the function could implement passthru: `"Node Id is..." | LogWrite -PassThru | write-Host` – xXhRQ8sD2L7Z Dec 21 '16 at 00:04
  • @campbell.rw Yes, LogWrite is my own function that took the message I had and appended it to the logfile that had been created earlier in my script – Spence Rico Dec 21 '16 at 00:33

2 Answers2

5

You can use a pipeline with the ForEach-Object cmdlet (% is its built-in alias) as follows:

"Node Id is $($nodeProps["NodeID"])" | % { Write-Host $_; LogWrite $_ }

Note how the reference to $nodeProps["NodeID"] needs to be enclosed in $(...) to work.

If you need this repeatedly, define a (simple) function:

function writeAndLog([string] $msg) { Write-Host $msg; LogWrite $msg }

writeAndLog "Node Id is $($nodeProps["NodeID"])"

P.S.: Prompted by campbell.rw's comments:

If you don't like the idea of using ForEach-Object - which is typically used to loop over multiple input objects - on a single input item, you can use a script block, with &, the call operator:

& { Write-Host $args[0]; LogWrite $args[0] } "Node Id is $($nodeProps["NodeID"])"

$args is the collection of all (unbound) arguments, so $args[0] refers to the first one. (In this particular case, just referencing $args would have worked too.)

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • I'm not sure what the point of the loop is in this answer, which is why I like the other answer better – campbell.rw Dec 20 '16 at 23:39
  • @campbell.rw: With a single input object, it's not a _loop_ - the script block (`{ ... }`) is only invoked _once_. The other answer shows how to send the pipeline input to a _file_, which is good to know in general, but not directly related to the question (we don't know what `LogWrite` does; it's quite likely that it's adding metadata to the input message and not just writing to a file, let alone _replacing_ that file instead of _appending_ to it). – mklement0 Dec 20 '16 at 23:48
  • @mklement0 hmm this looks like it may be what I'm looking for! I'll give this shot and let you know, thanks! – Spence Rico Dec 21 '16 at 00:34
  • @mklement Yes it's only invoked once, but looks odd to see a loop when there's no looping going on. How would is be any different than something like &{$d = "message"; Write-host $d; LogWrite $d} – campbell.rw Dec 21 '16 at 01:41
  • @campbell.rw: Personally, I prefer the `ForEach` solution, because it doesn't involve a custom variable, but that is a matter of taste. (You could pass a parameter to a script block, but I wouldn't consider that an improvement). – mklement0 Dec 21 '16 at 01:51
  • 1
    @mklement0 Fair enough, nothing wrong with personal preference. It's actually interesting a lot of the time to see how others solve the problems! – campbell.rw Dec 21 '16 at 01:54
3

You can use Tee-Object cmdlet to copy the pipeline stream to a file:

"Node Id is $($nodeProps["NodeID"])" |Tee-Object -FilePath C:\dev\test2.txt -Append |Write-Host
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • `Tee-Object` is handy in general, but while we don't know what the OP's `LogWrite` does specifically, its name suggests that _replacing_ the log file on every invocation is probably not a good idea, so you should at least add `-Append`. Beyond that, if `LogWrite` does more than just appending the message to a file (such as adding timestamps), this solution won't work. – mklement0 Dec 20 '16 at 23:53
  • 1
    @mklement0 Absolutely true. Append parameter added – Mathias R. Jessen Dec 20 '16 at 23:54