By using Out-String, you are converting the output of gwmi win32_bios | select serialnumber to a string and storing it in $sn. So, $sn will now have the following content: 
PS> $sn
serialnumber
------------
xxxxxxx
So, $sn.length is showing you the length of this entire string. If you want to change it only to the serial number:
PS> $sn = gwmi win32_bios | select -Expand serialnumber | out-string
PS> $sn
xxxxxxx    
PS> $sn.Length
9
As you can see, my serial number (I removed the original) is only 7 characters wide. But, $sn.length shows 9. There are probably a couple hidden chars after the output. I can see a blank line after the output at the console.
Coming to the real point, this space is added by Out-String. So, you don't even need that. you can do:
PS> $sn = gwmi win32_bios | select -Expand serialnumber
PS> $sn
XXXXXX
PS> $sn.Length
7
$sn is still a string.
PS> $sn.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object