Soory to jump in so late. IMHO, the function should return the error code only in EXIT @ERROR and the $ChangeVLKey whatever the SET/GETOBJCT generates (0 in case of success otherwise WMI error code, thus
Code:

Function ChangeVLKey($VOL_PROD_KEY)
Dim $obj, $objects
;Key is without hyphens (ABCDEFGHIJKLMNOPQRSTUVWXY)
$objects = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("win32_WindowsProductActivation")
If @ERROR
;ChangeVLKey should not have a value if we got an error
$ChangeVLKey = Val('&' + Right(DecToHex(@ERROR), 4))
;Convert the error to readable format
Exit Val('&' + Right(DecToHex(@ERROR), 4))
EndIf
For Each $obj in $objects
$ChangeVLKey = $obj.SetProductKey($VOL_PROD_KEY)
Next
;Assumes we got here okay so exit with no error
Exit @ERROR
EndFunction

_________________________
There are two types of vessels, submarines and targets.