Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Saturday, January 6, 2018 9:30 PM
I have a section of code that I have used many times in the past, and recently ran into an error. It is used to populate a list, to be used in a GUI dialog, for selection of an item in the list. I have never ran the code under the specific situation where only one item is returned from the function that populates the array. The function returns a collection of strings, but when it returns just one string, its type is just System.String, and it fails.
[System.Collections.ArrayList]$Widgets = (get-Widget).name
When get-Widget returns more than one item, the code works. When it returns only one item, it fails.
Cannot convert the "Widget1" value of type "System.String" to type "System.Collections.ArrayList".
At C:\scripts\set-widgets.ps1:505 char:2
+ [System.Collections.ArrayList]$Widgets= (get-widget).nam ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* + CategoryInfo : InvalidArgument: (:) [], RuntimeException*
* + FullyQualifiedErrorId : ConvertToFinalInvalidCastException*
I assume I need to cast the return from Get-Widgets to something, but in all cases, or just if there is only one record returned?
Thanks,
David
All replies (3)
Saturday, January 6, 2018 9:37 PM ✅Answered | 1 vote
Simple solution. An arraylist can only be initialized from an array. Wrap it in an array and all results will work.
[System.Collections.ArrayList]$Widgets = @(get-Widget).name)
\(ツ)_/
Saturday, January 6, 2018 9:59 PM
See, this is what happens when you let a cut-and-paste, quick and dirty operations scripting try to write his own code.
So, as I have often learned, when their is shorthand for something like this (using @ to cast results as an array) is there another method? I didn't see an '.ToArray' type of option, to post-pend.
Thanks,
David
Saturday, January 6, 2018 10:12 PM
This has nothing to do with casting. We are simply using an array to wrap the results so a singleton can be assigned to any object that requires an array. This is a very basic technique in PowerShell. Most tutorials and books show this in thee first few chapters.
PS D:\scripts> $al = [collections.arraylist](Get-Process).Name
PS D:\scripts> $al = [collections.arraylist](Get-Process|select -first 1).Name
Cannot convert the "aesm_service" value of type "System.String" to type "System.Collections.ArrayList".
At line:1 char:1
+ $al = [collections.arraylist](Get-Process|select -first 1).Name
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
# now wrap all results in an array.
PS D:\scripts> $al = [collections.arraylist]@((Get-Process|select -first 1).Name)
PS D:\scripts> $al = [collections.arraylist]@((Get-Process|select -first 10).Name)
PS D:\scripts>
Works every time.
You can cast a string, int or other singleton to an array:
[collections.arraylist]$x=[array](Get-Process).Name
[collections.arraylist]$x=[array](Get-Process | select -first 1).Name
The cast produces a slightly different type of array but works the same in this case.
\(ツ)_/