admin管理员组

文章数量:1315258

So I was working on a script and found an unusual behavior:

$Drives = Get-WmiObject -Class Win32_logicalDisk -Filter 'DriveType=3' | Select -ExpandProperty DeviceID #this will exclude CD drives and shared drives, etc, returning only local logical drives.
$MisconfiguredConfigFiles = [List[object]]::new()
$AllConfigFiles = [List[object]]::new()

foreach ($drive in $Drives) {
    $ConfigFiles = dir "$drive\*.config" -Recurse
    $AllConfigFiles.Add($ConfigFiles.FullName)
}

If I do $AllConfigFiles.Count with that code, it gives me the number of drives instead of the number of files. But if I do this:

$Drives = Get-WmiObject -Class Win32_logicalDisk -Filter 'DriveType=3' | Select -ExpandProperty DeviceID #this will exclude CD drives and shared drives, etc, returning only local logical drives.
$MisconfiguredConfigFiles = [List[object]]::new()
$AllConfigFiles = @()

foreach ($drive in $Drives) {
    $ConfigFiles = dir "$drive\*.config" -Recurse
    $AllConfigFiles += $ConfigFiles.FullName
}

Then, $AllConfigFiles.Count will return the accurate number of files I was expecting. How can I continue to use the List object (and its correlated "Add" method) instead of an array using the "+=" operator?

So I was working on a script and found an unusual behavior:

$Drives = Get-WmiObject -Class Win32_logicalDisk -Filter 'DriveType=3' | Select -ExpandProperty DeviceID #this will exclude CD drives and shared drives, etc, returning only local logical drives.
$MisconfiguredConfigFiles = [List[object]]::new()
$AllConfigFiles = [List[object]]::new()

foreach ($drive in $Drives) {
    $ConfigFiles = dir "$drive\*.config" -Recurse
    $AllConfigFiles.Add($ConfigFiles.FullName)
}

If I do $AllConfigFiles.Count with that code, it gives me the number of drives instead of the number of files. But if I do this:

$Drives = Get-WmiObject -Class Win32_logicalDisk -Filter 'DriveType=3' | Select -ExpandProperty DeviceID #this will exclude CD drives and shared drives, etc, returning only local logical drives.
$MisconfiguredConfigFiles = [List[object]]::new()
$AllConfigFiles = @()

foreach ($drive in $Drives) {
    $ConfigFiles = dir "$drive\*.config" -Recurse
    $AllConfigFiles += $ConfigFiles.FullName
}

Then, $AllConfigFiles.Count will return the accurate number of files I was expecting. How can I continue to use the List object (and its correlated "Add" method) instead of an array using the "+=" operator?

Share Improve this question asked Jan 30 at 8:08 JosephJoseph 6763 gold badges13 silver badges27 bronze badges 4
  • Did not work, lol. I appreciate the effort, lol. – Joseph Commented Jan 30 at 9:08
  • 1 $ConfigFiles.FullName evaluates to an array, change $AllConfigFiles.Add($ConfigFiles.FullName) to $AllConfigFiles.AddRange($ConfigFiles.FullName) – Mathias R. Jessen Commented Jan 30 at 11:09
  • Ah, an array of arrays. Goodness. Thanks! – Joseph Commented Jan 30 at 11:35
  • Technically a list of objects that may be either arrays, strings, or $null - all of which are assignable to [object], which is why it never errors :) – Mathias R. Jessen Commented Jan 30 at 11:42
Add a comment  | 

1 Answer 1

Reset to default 3

The "direct" answer is Mathias': you are adding a collection, so you should use .AddRange().
+= unpacks the collection automatically but that obviously is a problem if you want to add a collection as a single item :)

That said, the best way to deal with your needs is direct assignment.

# DO NOT USE WMI CMDLETS. It has been Obsoleted snce Powershell 3.  
# And completely removed from 6+ .    
# Use CIM ones instead.  
# Force-casting removes a few hassle in calling the drive later on.  
# Specifying the property on Get-CimInstance is mostly superfluous optimization
# in this case: it makes it so the cmdlet only returns that property of the
# device.  
# I added it mostly as a Teaching Moment(TM) about Left Side Filtering.    
[System.IO.DriveInfo[]]$DriveList = Get-CimInstance -Class Win32_logicalDisk -Filter 'DriveType=3' -Property DeviceID |     
    Select-Object -ExpandProperty DeviceID 

# Force-casted direct assignment FTW.   
# If you do NOT need to add\remove items AFTER the collection has been created,
# remove the casting and you'll have a nice Array perfectly fine to use.
[System.Collections.Generic.List[object]]$AllConfigFiles = foreach ($Drive in $DriveList) {
    # Evaluate adding -Force, -Depth and -ErrorAction SilentlyContinue .  
    Get-ChildItem -LiteralPath $Drive -File -Filter '*.config' -Recurse 
}

$AllConfigFiles.Count

本文标签: windows serverList objects vs Arrays in PowerShellStack Overflow