3

I have a function in powershell 2.0 named getip which gets the IP address(es) of a remote system.

function getip {
$strComputer = "computername"

$colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $strComputer -filter "IpEnabled = TRUE"



ForEach ($objItem in $colItems)

{Write-Host $objItem.IpAddress}

}

The problem I'm having is with getting the output of this function to a variable. The folowing doesn't work...

$ipaddress = (getip)
$ipaddress = getip
set-variable -name ipaddress -value (getip)

any help with this problem would be greatly appreciated.

tommy
  • 33
  • 1
  • 1
  • 3

3 Answers3

6

Possibly this would work? (If you use Write-Host, the data will be output, not returned).

function getip {
    $strComputer = "computername"

    $colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $strComputer -filter "IpEnabled = TRUE"

    ForEach ($objItem in $colItems) {
        $objItem.IpAddress
    }
}


$ipaddress = getip

$ipaddress will then contain an array of string IP addresses.

Nate Pinchot
  • 3,288
  • 24
  • 35
  • 2
    More specifically, Write-Host sends the data directly to the console host or stdout of the process. Write-Output or not capturing the output (as in Nate's example) will send the output to "stdout" of the current pipeline or function. This is approximately the same behavior as "echo" in a batch file. – JasonMArcher Jun 14 '10 at 18:12
2

you can allso do

function getip {
    $strComputer = "computername"

    $colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $strComputer -filter "IpEnabled = TRUE"

    ForEach ($objItem in $colItems) {
        write-output $objItem.IpAddress
    }
}


$ipaddress = getip

for accessing within the pipline you should use return/write-output

OhadH
  • 156
  • 1
  • 9
1

the problem in a nutshell is, that Write-Host cannot be redirected.

You can use this behaviour to your advantage, for example to return information to the user which will not be captured when he redirects your function's return value, to store it in a variable, but is visible nonetheless.

Use:

  • Write-Host to write directly to the (shell) process - not to a stream
  • Write-Output to write to success-/output-stream.
    • redirect only the success-stream to file: Write-Output "success message" 1>output_stream_messages.txt
    • store in variable: $var=Write-Output "output message"
    • Note: variable assignment always and only redirects the output-/success-stream. Other streams are left untouched
  • Write-Error to write to the error-stream
    • redirect only the error-stream to file: Write-Error "error message" 2>error_stream_messages.txt
    • store in variable: $var=Write-Error "Error message" 2>&1
    • Note: This actually redirects the error-stream to the success-stream. Data already in the success-stream is not overwritten, but appended). As the error output is now in the success-stream (as well) we can store it in a variable by redirecting/assigning the success-stream data to the variable $var.
  • Write-Warningto write to the warning-stream
    • redirect only the warning-stream to file: Write-Warning "warning message" 3>warning_stream_messages.txt
    • store in variable: $var=Write-Warning "Warning message" 3>&1
  • Write-Verbose to write to the verbose-stream
    • redirect only the verbose-stream to file: Write-Verbose "verbose message" -Verbose 4>verbose_stream_messages.txt
    • store in variable: $var=Write-Verbose "Verbose message" -Verbose 4>&1
    • Note: The -Verboseis necessary because the default powershell setting does not output verbose messages. (As defined by the preference variable $VerbosePreference, which is usually "SilentlyContinue". You can also set it to $VerbosePreference="Continue" before evoking the command (in the current powershell session/environment) as to not need the switch -Verbose.) Look here for more info about powershell preference variables.
  • Write-Debugto write to the debug-stream
    • redirect only the debug stream to file: Write-Debug "debug message" -Debug 5>debug_stream_messages.txt
    • store in variable: $var=Write-Debug "Debug message" -Debug 5>&1
    • Note: Depending on your setting of the $DebugPreference variable, your powershell may pause and inquire your input for the next action of choice. Set $DebugPreference="Continue" as to get rid of this behaviour and also lose the need for the -Debug switch before evoking the command.

You can use *>&1 to redirect all streams to the success-stream and then redirect it as you see fit. (Storing it in a variable or redirecting it to $null or a file or something like that.)

For more details I recommend a very good article about powershell's streams on devblogs.microsoft.com

TheUnseen
  • 314
  • 2
  • 6