I call it modern
, but it fully works on PS5.1 without changes!
In the examples below, if you add a using namespace
statement, you can remove Systems.Collections.Generic
tip: System
is always included, so you can omit that prefix anywhere as well.
using namespace system.collections.generic
[List[Object]]$users = @()
$users.AddRange( @('bob', 'jen', 'sue' ) )
$users | ConvertTo-Json
Json is a quick way to visualize the shape
[
"bob",
"jen",
"sue"
]
Using the @()
operator ensures the expression returns an array
no values is still an array type
This is useful when you call functions like gci
or AD users where you might get nothing back.
using the type name [object[]]
is similar. The difference is that's applied as a type constraint.
# get an array of 0-to-many number of pscustomobjects
# 0 items will still create an array with a count of 0
[object[]]$AllPrimaryFilesAttributes = @(
$PrimaryTree | ForEach-Object {
[PSCustomObject]@{
FullPath = $_.FullName
# ...
}
}
)
often powershell will implicitly create arrays, when you output items in the pipeline like above In some cases, arrays can simplify your code.
[Collections.ArrayList]$AllPrimaryFilesAttributes = @()
# then later
$stuff | Foreach-Object {
$x = ...
[void]$allPrimaryFilesAttributes.Add($x)
}
Using List[]
s is almost identical
as a bonus: You never need [void]
[Collections.Generic.List[Object]]$AllPrimaryFilesAttributes = @()
$stuff | Foreach-Object {
$x = ...
$allPrimaryFilesAttributes.Add($x)
}
If you ever have to manually add items, because you want a flat list
# this
foreach($item in $collection) {
$list.Add( $item )
}
# simplifies to
$list.AddRange( $collection )
[List[Object]]$pingArgs = @()
$Config = @{
Count = 2
ResolveNames = $true
}
$pingArgs.Add('www.google.com')
if($Config.Count -gt 0) {
$pingArgs.AddRange(@(
'-n'
$Config.Count
))
}
if($Config.ResolveNames) {
$pingArgs.Add('-a')
}
#'final args: '
$pingArgs -join ' '
& 'ping' @pingArgs