PowerShell seems to perform bounds-checking after arithmetic operations and conversions. For instance, the following operations fail:
[byte]$a = 255
$a++
$a = [byte]256
Is there any way to enforce overflows or the typecast without resorting to a manual calculation via modulo or C# and Add-Type?
Write a “C” function, int addOvf(int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in “result” and returns 0. Otherwise it returns -1.
C# also has the Unchecked keyword. This will allow you prevent overflow checking on certain items. It can be applied to expressions within a Checked method or to entire blocks of code if you have enabled the compiler option.
Overflow is an operation that occurs when a calculation produces a result that is greater in magnitude than that which a given register or storage location can store or represent.
The behavior you want in PowerShell is achievable, though, it's a bit of a hack; and maybe there's a better way.
If you just want cryptographic functionality though, it's worth calling out, that there's a TON of that already built-in to the BCL, and it's fully accessible from PowerShell (MD5, SHA, RSA, X509, a ton of other stuff too).
But if you're dead set on performing unchecked arithmetic in PowerShell, this is a hack that should give you what you want (basically we're embedding C# code, and using the unchecked keyword):
$members = @'
public static UInt32 ToUInt32(int value)
{
unchecked
{
return (UInt32)value;
}
}
public static byte ToByte(int value)
{
unchecked
{
return (byte)value;
}
}
'@;
$type = Add-Type -Name "Convert" -Namespace "Helpers" `
-MemberDefinition $members -PassThru -ErrorAction SilentlyContinue;
Usage:
PS C:\Some\Folder> [Helpers.Convert]::ToUInt32(-1);
4294967295
PS C:\Some\Folder> [Helpers.Convert]::ToByte(-1);
255
PS C:\Some\Folder> [Helpers.Convert]::ToByte(256);
0
Of Note:
[Helpers.Convert]::To...
and not [System.Convert]::To...
.$members
block at the top of the code.Add-Type
multiple times in a row for the same Namespace
and Name
combination, in the same PowerShell session, it will fail; and you will be left with the previously registered type. -- I've added -ErrorAction SilentlyContinue
to ignore this specific scenario. -- That way, you can dump this code into a .ps1 script, and call it every single time, before you use them methods, and they will always be present. -- But if you are modifying the C# code and retesting, you will want to change the type name after every change you make; it's kind of painful.PowerShell is a scripting language, not a programming language, it doesn't support a lot of advanced techniques like overloading operators (which would be handy in this case).
To add to the things you have already suggested, you could just catch the error.
[byte]$a = 255
try {$a++} catch {$a=1}
Or write your own function and do some modulo fun in there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With