Function not handling variable correctly

I have this function in my script:

function writeLog {
Param ([string]$LogString)
	$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
	$LogMessage = "$Stamp $LogString"
	Add-content $writeLogFile -value $LogMessage
}

In my PS code, I collect a user’s name into the variable:

$Mgrname

and I collect his Direct Reports into the variable:

$CrewList

Then, I write the information to the console (through another function which is working fine) and to a text file via the function above:

writeColor -text " $Mgrname ($Manager) ","DirectReports are:" -color yellow,green
$CurrentCrew

writeLog "  $Mgrname current crew is: "
writeLog $CurrentCrew

The screen output looks like this:

Bob Peters (btpeters) DirectReports are:

Name

SgPMIE TestUser II
SG PMTest 1

However, the output into the log file looks like this:

image

Can’t seem to figure out what I’m doing that drops the data out of

$Crewlist

going into the writeLog function

Here’s how I’m getting the Direct Reports names:

$CurrentCrew = get-aduser $Manager -properties * | select-object -expandproperty directreports| ForEach-Object { Get-ADUser -Identity $_ | Select-Object Name }

Suggestions anyone?

Thanks!

Where do you define the variable $writeLogFile you use in your writeLog function? You should not use outside variables inside of functions!! :point_up:

And since you’re getting objects from your query but needing strings for your function you should use writeLog $CurrentCrew.Name to get only the names without the header for your function.

BTW: There are some great solutions for logging out there already. You don’t have to re-invent the wheel again. One of the more famous ones is

Thanks, Olaf.

The logfile is defined just before the script lines I quoted and looks like this:

$writeLogFile = "c:\utils\Logs\NewCrew-$Manager.log"

I didn’t include it in the OP because it works as expected, and seemed extraneous. Anyway, I found the text logging function a long time ago and just have it in a template that I use for scripting. It’s been working great except for this one thing.

Would you clarify what outside variable is? I’m still learning PS.

I’ll give your writeLog suggestion a try, but the header in the text log is fine with me.

Re-inventing was not a plan, just happened when this function was first thing I found to do what I was looking for in logging what my scripts do.

I appreciate your input and will let you know what the writeLog suggestion does.

Progress:

Changed to

writeLog "  $Mgrname current crew is: "
writeLog $CurrentCrew.name

And now get this in the text log:

If I can get a CRLF after each name, I’m in like Flynn

While it might not be an issue for you now it can cause hard to find errors when your code gets more complex. In general: inside a function you should only use variables you defined inside the function. If you want to use resources from outside a function you should pass it to it as parameter.

I’m not sure if that works / looks good … try

writeLog ($CurrentCrew.name -join "`n`r")  

I’d prefer

writeLog ($CurrentCrew.name -join ', ')

More progress, thank you!

The comma - ', ’ - is okay for short lists, but some of my guys have a dozen Direct Reports

So, I did this

writeLog "  $Mgrname current crew is: "
writeLog ($CurrentCrew.name -join "`n ")

And got this:

So now it seems that to be truly in like Flynn I need a CR before the first name, and write it like this:

(and thanks, also, for the instructional link)

I don’t know what you’re using the log files for but if it’s about collecting data you may look into other options. IMHO the purpose of log files is to help with finding errors. If you need to store information for later you may collect data as structured data in CSV files for example.

It’s not formal logging like, for example, court testimony. Just for my record on what I’m getting done and when. Specifically this time, I have to make some changes to direct reports and want to collect before and after info.
If it gets more serious, I will record CSV information - which I do have a bit of experience with in PS - but for now a simple text file is sufficient.

Success!! Thank you Olaf. Got me on the right track and I have exactly what I wanted:

writeLog "  $Mgrname current crew is: "
writeLog ("`n" + ($CurrentCrew.name -join "`n"))

Writes the log file like this:

I’m on mobile so forgive my lack of examples but you may try using Out-File instead of Add-Content because of the way it handles writing objects.

That’s an interesting idea. I’ll play around with that and see how it differs.

Thanks for the suggestion!

Followup now that I’m on a computer.
When you’ve got an array of just values, like this:

$Crew = @(
    "John",
    "Bob",
    "OtherBob",
    "Janet"
)

Whether you use Add-Content or Out-File if you’re just passing that array as the input the end result is that the values are written one by one on separate lines in the text file looking like this:

John
Bob
OtherBob
Janet

However, if you try to combine your date string with any kind of variable inside double-quotes you’re now trying to convert whatever is in that variable to some kind of string. If I just wrap $Crew in quotes you can see this is similar to what you were getting:

PS> "$Crew"
John Bob OtherBob Janet

When I ran in to this, what I decided to do if I knew I was trying specifically to write something other than a string (i.e. an object with multiple properties) to a file I would write my date string on its own line with a declaration that what follows is “Object Output” and then write my object variable by itself using Out-File.
Let’s look at an array of objects that have two properties as an example:

PS> $Users

Name     Title
----     -----
John     Worker
Bob      Worker
OtherBob Worker
Janet    Worker

If I wanted to record that variable to a text file and have it look the same way the console output does, I would use Out-File.

function Write-LogObject {
    param (
        $InputObject
        )
	$Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    Out-File -FilePath $WriteLogFile -InputObject "$Stamp Output Object:" -Append
	Out-File -FilePath $WriteLogFile -InputObject $InputObject -Append
}

PS> Write-LogObject $Users

and now the text file will look like this:

2025/06/24 15:44:15 Output Object:

Name     Title 
----     ----- 
John     Worker
Bob      Worker
OtherBob Worker
Janet    Worker

Out-File has different parameters than Add-Content so double-check if you’re going to switch up your code.

1 Like

Thanks, Grey! That’s a really nice solution. Very much appreciate the explanation; helps me learn as well as solve the problem.

1 Like