0

There are powershell cmdlets in our project for finding data in a database. If no data is found, the cmdlets write out a $null to the output stream as follows:

Write-Output $null

Or, more accurately since the cmdlets are implemented in C#:

WriteOutput(null)

I have found that this causes some behavior that is very counter to the conventions employed elsewhere, including in the built-in cmdlets.

Are there any guidelines/rules, especially from Microsoft, that talk about this? I need help better explaining why this is a bad idea, or to be convinced that writing $null to the output stream is an okay practice. Here is some detail about the resulting behaviors that I see:

If the results are piped into another cmdlet, that cmdlet executes despite no results being found and the pipeline variable ($_) is $null. This means that I have to add checks for $null.

Find-DbRecord -Id 3 | For-Each { if ($_ -ne $null) { <do something with $_> }}

Similarly, If I want to get the array of records found, ensuring that it is an array, I might do the following:

$recsFound = @(Find-DbRecord -Category XYZ)
foreach ($record in $recsFound)
{
    $record.Name = "Something New"
    $record.Update()
}

The convention I have seen, this should work without issue. If no records are found, the foreach loop wouldn't execute. Since the Find cmdlet is writing null to the output, the $recsFound variable is set to an array with one item that is $null. Now I would need to check each item in the array for $null which clutters my code.

brader24
  • 485
  • 2
  • 10
  • Relevant: [PowerShell null doesn't get piped](http://stackoverflow.com/questions/25657560/powershell-null-doesnt-get-piped) – beatcracker Feb 11 '16 at 16:58

1 Answers1

0

$null is not void. If you don't want null values in your pipeline, either don't write null values to the pipeline in the first place, or remove them from the pipeline with a filter like this:

... | Where-Object { $_ -ne $null } | ...

Depending on what you want to allow through the filter you could simplify it to this:

... | Where-Object { $_ } | ...

or (using the ? alias for Where-Object) to this:

... | ? { $_ } | ...

which would remove all values that PowerShell interprets as $false ($null, 0, empty string, empty array, etc.).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • I agree that this could be done. What I'm looking for is justification one way or another, within the context of a Find or even a Get where the idea is to get any results found, why you would write a $null to the output if no results are found. It should effectively be an empty array. This is most easily accomplished by not writing anything to the pipeline. – brader24 Feb 11 '16 at 16:44
  • I can only give you my personal opinion on that, which is: don't write unless you do have a result. – Ansgar Wiechers Feb 11 '16 at 17:03
  • That is my opinion as well, though my goal is to find a guideline or rule from a large community or specifically from Microsoft. Or some rationale that I haven't thought of that might help persuade others that my approach is better. – brader24 Feb 11 '16 at 17:21