$string.Substring Index/Length exception

I'm doing the following to try and get the last character from the string (in this case, "0").

$string = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\hid\Parameters\0"
$parameter = $string.Substring($string.Length-1, $string.Length)

But I'm getting this Substring-related exception:

Exception calling "Substring" with "2" argument(s): "Index and length must
refer to a location within the string.
Parameter name: length"
At line:14 char:5
+     $parameter = $string.Substring($string.Length-1, $string ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

I understand its meaning, but I'm not sure why I'm getting given the index and length are correct.

Even attempting to hard code it throws the same exception:

$parameter = $string.Substring(68, 69)

Is there something I'm missing?


Solution 1:

Your first argument is that starting position in the string, and the second is the length of the substring, starting at that position. The expression for the 2 characters at positions 68 and 69 would be:

$parameter = $string.Substring(68,2)

Solution 2:

What the error message is trying to tell you is this: the beginning of the substring plus the length of the substring (the second parameter) must be less or equal to the length of the string. The second parameter is not the end position of the substring.

Example:

'foobar'.Substring(4, 5)

This would attempt to extract a substring of length 5 beginning at the 5th character (indexes start at 0, thus it's index 4 for the 5th character):

foobar
    ^^^^^  <- substring of length 5

meaning that the characters 3-5 of the substring would be outside the source string.

You must limit the length of a substring statement to the length minus the starting position of the substring:

$str   = 'foobar'
$start = 4
$len   = 5
$str.Substring($start, [Math]::Min(($str.Length - $start), $len))

Or, if you want just the tail end of the string starting from a given position, you'd omit the length entirely:

$str = 'foobar'
$str.Substring(4)

Solution 3:

If the last character of the string is all you want, you can achieve this by simply treating the string as an array of chars and use the according index notation:

'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\hid\Parameters\0'[-1]