I have a PowerShell script that connects to a localhost API that returns a dictionary of "sessions" and whether they are active
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$response = Invoke-RestMethod 'https://localhost:44356/api/RDM/getSessions' -Method 'GET' -Headers $headers
$numOfUsers = Invoke-RestMethod 'https://localhost:44356/api/RDM/countSessions' -Method 'GET' -Headers $headers
for($x = 0; $x -lt $numOfUsers; $x++)
{
$user = $response.userId[$x]
$name = $response.sessionName[$x]
"`nSession Name: $name"
"User Logged In: $user`n"
}
pause
When more than one session is active it returns correctly:
Session Name: ExampleSession
User Logged In: ExampleUser
But when only 1 is active it returns only the first letter:
Session Name: E
User Logged In: E
I do know that this bug is caused by the script and not the API, however so far I am unable to find the source of the problem.
The implication is that if only one session is returned, $response.userId
and $response.sessionName
are not one-element arrays but just strings - and indexing into strings returns characters (e.g., 'foo'[0]
returns 'f'
).[1]
You can use @()
, the array-subexpression operator to ensure that you're always dealing with arrays:
$user = @($response.userId)[$x]
$name = @($response.sessionName)[$x]
If the count of sessions can be large, the following performs better (because @(...)
creates a (shallow) copy of an array[2], whereas an [array]
cast uses an existing array as-is):
$user = ([array] $response.userId)[$x]
$name = ([array] $response.sessionName)[$x]
[1] Note that, unlike in C#, the character returned is technically also a string ([string]
, System.String
), not a [char]
(System.Char
) instance, because PowerShell itself doesn't use the [char]
type.
[2] In older PowerShell versions (up to v5.0), this also applied to arrays with explicitly enumerated elements; e.g., @('foo', 'bar')
, but this case has since been optimized to accommodate the widespread practice of using such expressions to define array literals - even though the @(...)
isn't strictly needed ('foo', 'bar'
alone will do).