3
votes

After writing a Powershell script to build a list of servers and then perform some maintenance activity on each, I decided to split it into two parts. The inner script, call it scriptB, does its thing on the server whose name is passed in; the outer script, scriptA, builds the list of servers and runs scriptB on each. The idea is that scriptA will someday be able to run a choice of scripts -- scriptB or scriptC, for instance -- against each server, depending on a control parm. And the maintenance script (B or C) can also be run by itself, i.e. by passing it the name of the target server.

I call scriptB from scriptA using invoke-command with the -filepath option, and this appears to work just fine. Except that, for each iteration, the content of scriptB appears in the output. If I call it three times then I have three copies of scriptB in the output. I already have write-output statements in scriptB that explain what's going on, but those messages are hard to spot amid all the noise.

I have tried assigning the output to a variable, for instance:

$eatthis = invoke-command -computername sqlbox -filepath c:\dba\scriptB.ps1

and then it was quiet, but the variable ate the good output along with the unwanted listings ... and it is large enough that I would prefer not to parse it. I tried reading up on streams, but that didn't look like a promising direction either. At this point I'm ready to convert scriptB to a function and give up the benefits of having it be a standalone script, but if anyone knows an easy way to suppress the listing of an invoke-command scriptblock specified via -filepath then that would be helpful.

Alternatively, a good way to phrase this for Google would be welcome. Search terms like "listing," "echo," and "suppress" aren't getting me what I need.

1
Invoke-Command -FilePath does not produce file listing. So scriptA print scriptB, or scriptB print itself.user4003407
you will likely need to modify the functions in your scriptB and throw something in each statement to suppress what it is you are seeing that you don't want to see. Like Out-Null, or save its output to a variable and then send it to a Write-Verbose so you can see that content when desired.ATek
Thanks, I found it! I typically set a variable to $myinvocation.mycommand, which usually returns the path and filename used to invoke the script, and then print that out along with a time stamp. But when the script is invoked via a filepath the entire content is returned, apparently, instead of just the location and name. So now I have to go back and learn more about $myinvocation.johnpr

1 Answers

0
votes

Convert your scripts into advanced functions. They can be stored in separate files and dotsourced in the master script. This loads the function and makes it available.

e.g.

c:\scripts\ComplicatedProcessfunctions.ps1 

(which contains function Run-FunctionB {...} and later function RunFunctionC {...})

Then call the function

$dataResults = RunFunctionA

or even

$dataResults += RunFunctionA

if you're running within a loop and building a collection of results. Which sounds like you might be.

Make sure each function returns its data as an object or collection of objects. Probably a custom powershell object of your creation.

The master script then processes the results.

I would recommend Get-Help about_advanced_functions, the scripting guys blog, and the Powershell Scripting Games website for information on how to build advanced functions, and how to do it right.