2

Even though the $logDir variable contains the value "C:\Users\DEVELO~1\AppData\Local\Temp\logs" (obtained from a text file), this code does not behave as I'd expect. It returns an array of strings, not a single string.

$LogFileName = "NoIP-update.log"
$ConfigSection = "NoIp"

function Log-Message ($MSG) {
    $script:Logger += "$(get-date -format u) $MSG`n"
    Write-Output $MSG
}

function Get-LogFileName ($config) {
    $Local:logDir = $config["Section"]["LOGDIR"]
    if ($Local:logDir -ne "") {
      Log-Message "Testing for directory '$Local:logDir'"
      if(!(Test-Path -Path $Local:logDir )){
          New-Item -ItemType directory -Path $Local:logDir
          Log-Message "Created directory '$Local:logDir'"
      }
      return "$Local:logDir\$LogFileName"
    }
    return $LogFileName
}

I'm probably missing something very very basic, as I expect the function to return 1 string, not an array of strings and log one or two lines.

However, it doesn't log, and: if $Local:logDir exists, the function returns an array of 2 strings, otherwise it returns an array of 4 strings.

  • Why?
  • How can I make it return 1 string and still log?

I think it has to do with thinking using the pipelining metaphor versus my background in procedural and object oriented programming languages. Help is much appreciated (:

2-string array:

{Testing for directory 'C:\Users\DEVELO~1\AppData\Local\Temp\logs', C:\Users\DEVELO~1\AppData\Local\Temp\logs\NoIP-update.log}

4-string array:

{Testing for directory 'C:\Users\DEVELO~1\AppData\Local\Temp\logs', C:\Users\Developer\AppData\Local\Temp\logs, Created directory 'C:\Users\DEVELO~1\AppData\Local\Temp\logs', C:\Users\DEVELO~1\AppData\Local\Temp\logs\NoIP-update.log}

Notes:

  • I run from within PowerGUI, but from the PowerShell console it has the same results.
  • $PSVersionTable.PSVersion returns 4.0.
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154

1 Answers1

4

I the issue is with Log-Message and specifically with the line Write-Output.

When you use Write-Output inside a function it is treated as a way to return a value from a function (i.e. it can be used interchangeably with Return). So what is happening is that your logging messages are being included in the Return stream.

If you are just wanting to display logging information to the display, use Write-Host instead. That will display information to the host, but not be included in your Return stream.

So the fix is to change your Log-Message function to:

function Log-Message ($MSG) {
    $script:Logger += "$(get-date -format u) $MSG`n"
    Write-Host $MSG
}
HAL9256
  • 12,384
  • 1
  • 34
  • 46
  • +1; accepted. Thanks a lot. Now I need to read http://stackoverflow.com/questions/8755497/which-should-i-use-write-host-write-output-or-consolewriteline/8755614#8755614 and watch the video. – Jeroen Wiert Pluimers Jul 10 '14 at 22:39