I have had no success in getting the following code snippet to output "Hello World!" in PS7
$string = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string))
The above code is an example of decrypting a secure string without specifying a length.
This same code works in PS6 and PS5 to fully decrypt the Secure String, but does not work in PS7. The only way around this I have found is to use PtrToStringBSTR. Then it works as expected across all versions of PS for this use case.
I raised an issue at the Powershell repo on Github, but haven't had any responses. I'm honestly just looking for some confirmation that the behavior is the same for others.
https://github.com/PowerShell/PowerShell/issues/11953
I would think something like this would be a breaking change for a lot of code being ported to PS7.
Here is what I have found so far:
Documentation
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.ptrtostringauto?view=netframework-4.8
According to the documentation, when specifying an integer, PtrToStringAuto:
Allocates a managed String and copies the specified number of characters from a string stored in unmanaged memory into it.
Specifying an int of 11 Returns "Hello", this is because every other char returned is Null. In this case, you must specify an int of 23 to return the complete string "Hello World!" using this method. I have stored the output in a variable to demonstrate this.
$String = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string), 23)
$String[0] Returns H
$String[1] Returns NULL
$String[2] Returns E
$String[3] Returns NULL
etc....
If no integer is specified, PtrToStringAuto:
Allocates a managed String and copies all characters up to the first null character from a string stored in unmanaged memory into it.
I believe this suggests that either the Secure String is being stored with NULL values, whereas in PS6 it was not, or that the behavior of the PtrToStringAuto function has changed, and now adheres to the behavior the documentation describes above.
This is only an issue on macOS; however, using PtrToStringBSTR in place of PtrToStringAuto to decrypt the Secure String works as expected across windows and macOS.
This seems related: https://stackoverflow.com/a/11022662/4257163
I also do not see anywhere that a change was made.
See Question&Answers more detail:
os