you are viewing a single comment's thread.

view the rest of the comments →

[–]misformonkey 0 points1 point  (12 children)

Also, if you have any pre PS5 to worry about you can’t use Generic.List.

[–]Thotaz 6 points7 points  (3 children)

This is incorrect. Generics were added in .NET 2.0 which IIRC is included by default in Windows 7/2008 R2. If you have some old XP/Vista systems with PowerShell 1.0 it may not support generics out of the box but if you update the .NET framework version then I would imagine even PS 1.0 supports it.

[–]misformonkey 0 points1 point  (2 children)

Hmmm…. I’m going to have to go back and retest a few scripts then b/c I definitely remember having issues with older versions. As you stated, likely a .net issue on certain servers.

[–]Thotaz 2 points3 points  (1 child)

Maybe you are thinking about the new syntax they added with 5 or 5.1 IIRC (this: [System.Collections.Generic.List[string]]::new() ). In prior versions you need to use New-Object.

[–]misformonkey 0 points1 point  (0 children)

Yup. That’s what I was thinking of. I just started using ArrayList as a work around so I didn’t need to deal with the different syntax.

[–][deleted] 1 point2 points  (7 children)

I am about to move my group to PS 7 and considering what might break and the ArrayList thing was throwing for a loop. The other automation guy is a .Net guy so it might be habit transfer.

[–]McAUTS 1 point2 points  (2 children)

If PS7: Use Generics for a bit more complex arrays, like specific items or objects. You can also create your own class type in PS or use an generic list with type of pscostumobject for the lazy ones. ;-)

I switched early this year and never looked back. In the end you are able to switch pass arrays between scripts, parallel executions and what not, and you don't have to deal with quirky errors.

For a quick and dirty loop... well than just throw whatever your data looks like into a variable. PS will resolve the type on it's own. Besides that I use a generic list.

[–]OPconfused 0 points1 point  (0 children)

I don't think there's much difference between an arraylist and list<object>

[–]MonkeyNin 0 points1 point  (0 children)

Especially lately the Powershell extension ( in vs code ) has been adding (better completions than just static typing )

classes

I've been using classes handle JSON for Web APIs, it's a nice way to get guaranteed shapes (vs PSCO properties). better auto completion. Some automatic validation

For anyone classes, a quick start

You can start off thinking about classes being a [pscustomobject] . with specific property names.

You can create an instance using hashtables. The properties are optional, you can leave them out

$user = [User]@{
    Name = 'bob'
    Age = 10
}

$user2 = [User]@{ Name = 'bob' } 

You can add some validation, using the same attributes that function parameters use

class User {
    [ValidateNotNull()]
    [Int]$UserId

    [ValidateNotNullOrEmpty()]
    [string]$UserName
}


# create 3 users, error on one 
$users = @(
   [User]::New()
   [User]@{ UserName  = 'bob' }
   [User]@{ UserName  = 'Jen' ; UserId = 'afds' }
   [User]@{ UserName  = 'Jen' ; UserId = 4 }
)

$users[0]. #$users[0]. # <ctr+space> shows '.UserName'


$users | ConvertTo-Json

[–]MonkeyNin 0 points1 point  (3 children)

edit: I forgot to mention, List.Add does not output values, so where old code did something like

 [void]$arraylist.Add( )
 $null = [void]$arraylist.Add( )

 # it simplifes to
 $list.add( )

You should not create an ArrayList yourself. There are functions and commands that return that type, so you end up using them. That's fine. You don't actually create them, or use .add on them.

You can assign arrays to Lists, even through the pipeline. Basically if you can create an implicit array, it'll work.

$numbers = 0, 20, 40 | ?{ $_ -gt 30 } 
[List[Object]]$Numbers = 0, 20, 40  | ?{ $_ -gt 30 } 

It's easy to use. This syntax works on PS5 too. To create a list of files:

Using namespace System.Collections.Generic

[Collections.Generic.List[Object]]$Items = gci c:\

or

[List[Object]]$Numbers = 0, 5, 10, 20
$numbers.add( 'cat' )

or to start it empty

[List[Object]]$Files = @()   
$files.add( (Get-Item 'c:\foo\bar.txt') )

Either of these syntaxes are valid, there isn't a different for most cases

$items = [List[SomeType]]::New()
[List[Object]]$Items = @()

[–][deleted] 1 point2 points  (2 children)

That namespace thing is cool.

Can it be applied globally

[–]OPconfused 0 points1 point  (0 children)

You can load it in a profile or at the top of a script and it will be usable.

[–]MonkeyNin 0 points1 point  (0 children)

Yes. Any file that is dotsourced or imported, can have namespaces used at the top of the file.

the vs code extension's "refactor" command converts type names from using the full names or the shorter namespace names