PowerShell Get-ChildItem Not always returning a Directory Name

78 views Asked by At

I am searching the drives of multiple servers for a specific file. The code looks something like this...

$servers = Get-ADComputer -filter {Name -like "SERVER-*"}
foreach ($server in $Servers){
    $Server.Name
    Invoke-Command -ComputerName $server.Name -ScriptBlock {
        $filename="db2cmd.exe"
        $listOfDrives=(get-psdrive | ? { $_.provider -match 'FileSystem'}).root
        foreach ($Drive in $listOfDrives){
            If ($Drive -ne "C:\" -and $Drive -ne "A:\") {
                Get-ChildItem -Path $Drive -Filter $filename -Recurse -ErrorAction SilentlyContinue -Force
            } 
        }
    }
}

When I run it, in most instances, when the file is encountered, it returns the Directory where the file was found..

   Directory: E:\IBM\DB2\SQLLIB\BIN


Mode                LastWriteTime         Length Name                                                                                       PSComputerName                                                                           
----                -------------         ------ ----                                                                                       --------------                                                                           
-a----         1/5/2024  11:32 AM          55888 db2cmd.exe                                                                                 ServerA 

Yet on other servers, neither the Directory nor the Column titles are displayed.

-a----         1/5/2024  11:32 AM          55888 db2cmd.exe                                                                                 ServerB

I really do not understand the reason for this as it is running the same command on each server. Any help you can provide would be appreciated.

I have tried different parameters, but they seem to change where and what the Get-ChildItems is looking for, and not the way the results are output.

1

There are 1 answers

2
Dennis On

PowerShell is normally used as a functional language and as such should only return one object.

As @Mathias R. Jessen, states. You are trying to return both $Server.Name and the result of Get-ChildItem and PowerShell really don't care about the order returned, so they might interact and mix up in the output.

You might get other results if you actually specify it should be pure outputs using Write-Output instead.

$Servers = Get-ADComputer -Filter {Name -like "SERVER-*"}

foreach ($Server in $Servers){
  Write-Output $Server.Name
  Invoke-Command -ComputerName $Server.Name {
    $FileName = 'db2cmd.exe'
    $ListOfDrives = (Get-PsDrive | where Provider -match 'FileSystem').Root

    foreach ($Drive in $ListOfDrives){
      if ($Drive -ne 'C:\' -and $Drive -ne 'A:\') {
        $Db2CmdFiles = Get-ChildItem -Path $Drive -Filter $FileName -Recurse -ErrorAction SilentlyContinue -Force
        Write-Output $Db2CmdFiles
      }
    }
  }
}

But the best option would be adding the $Server.Name property to the object returned by Get-ChildItem. Then there could be no object mix up.
(On the other hand, that property is already available in PsComputerName since you are using remote sessions.)