Powershell: Null checking issue with Powershell 7 (rc3)

Created on 26 Feb 2020  路  5Comments  路  Source: PowerShell/PowerShell

if condition checking for a null variable is incorrect in Powershell 7 (rc3)

Steps to reproduce

  • Run this code in Powershell 7(rc3)
$Body = $Body | ConvertTo-Json -Depth 10 -Compress
if ($Body) {
   Write-Host "I am not Null."
}
else{
   Write-Host "I am NULL." 
}


Expected behavior

It should show "I am NULL."

Actual behavior

It shows "I am not Null.".

Here is the screenshot. I run the same scripts in Powershell 7 (rc3), Powershell 6 and Powershell 5. It works correctly in PS5 and 6 but not in PS7rc3.

image

Environment data

` Name Value ---- ----- PSVersion 7.0.0-rc.3 PSEdition Core GitCommitId 7.0.0-rc.3 OS Microsoft Windows 10.0.18363 Platform Win32NT PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0

Issue-Question Resolution-Answered

Most helpful comment

JSON is a string representation of object data. The string representation may contain the literal null, but the data itself is still a string until the data is converted back _from_ JSON format.

If you check the contents of $body you'll see that it contains the word "null" -- this is a non-null string containing those letters. When converting back from JSON it will indeed resolve to a proper null value, but a valid JSON object must _always_ be string in JSON format, and will not be null in any context except after being converted back into object format.

EDIT: For clarity, the fact that it has previously returned a true null or empty string value rather than the JSON equivalent is, effectively, a bug that has been fixed since. 馃檪

All 5 comments

JSON is a string representation of object data. The string representation may contain the literal null, but the data itself is still a string until the data is converted back _from_ JSON format.

If you check the contents of $body you'll see that it contains the word "null" -- this is a non-null string containing those letters. When converting back from JSON it will indeed resolve to a proper null value, but a valid JSON object must _always_ be string in JSON format, and will not be null in any context except after being converted back into object format.

EDIT: For clarity, the fact that it has previously returned a true null or empty string value rather than the JSON equivalent is, effectively, a bug that has been fixed since. 馃檪

@vexx32 Thansk, Joel.

Do you mean that there is a bug in Powershell 5 and 6.. but it has been fixed in Powershell 7?

Please refer to the screenshot that I posted. I run the same scripts in Powershell 5, Powershell 6 and Powershell 7. I got the different result in Powershell 7. It is going to break our existing code when we migrate it to Powershell 7.

Yep, I think the old behaviour was bugged. The results we currently get are consistent with what you'd get if you attempted something similar with most JSON libraries available in other languages like Python and others, as far as I'm aware. :slightly_smiling_face:

You can modify your test to work in both versions:

```powershell
if ($Body -and $Body -ne "null") {
"I am NOT null"
}
else {
"I am NULL"
}

I think the old behaviour was bugged

Thanks, Joel. Yes. It makes sense. I am sure it's easy to fix if it's just a small code-base. but the only issue that I see is that a lot of existing scripts that work in PS 5 and PS 6 will not work in PS 7 without changing the code. It's a big breaking change.

Any word from the Product team? CC- @SteveL-MSFT

Windows PowerShell uses old .Net Framework API. It is deprecated now. PowerShell Core uses NewtonSoft Json .Net API. After we move to .Net Core 5.0 PowerShell Core will use (I expect) new .Net Core API for Json.

Was this page helpful?
0 / 5 - 0 ratings