Home > Software design >  I want to take the output of Get-PSDrive to get the drive letter of all drives and do a search for I
I want to take the output of Get-PSDrive to get the drive letter of all drives and do a search for I

Time:12-05

I am trying to use Get-PSDrive to put all the drive letters used by disks into a string that returns each letter (That works)

I am having problems using the $ISODeviceLetter variable to use it as a path to search all drives for .ISO files.

$ISODeviceLetter = Get-PSDrive | Select-Object -ExpandProperty 'Name' | Select-String -Pattern '^[a-z]:$'

$ISOLocation = Get-ChildItem -Path $ISODeviceLetter -Recurse -Include *.ISO

This is the error I get:

Get-ChildItem : Cannot find path 'C:\Users\Administrator\C' because it does not exist.
At line:1 char:16
  ... OLocation = Get-ChildItem -Path $ISODeviceLetter -Recurse -Include *. ...
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : ObjectNotFound: (C:\Users\Administrator\C:String) [Get-ChildItem], ItemNotFoundException
      FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

I see by the error the get-childitem is using the default location which is the C:\Users\Administrator.

The desired output is to pass $ISODriveLetter as the Path for all drives on the server "C:","D:","E:", so all the drives can be searched for .ISO files.

Thanks a head of time for the help.

CodePudding user response:

The issue is that when referencing drives, they have to be distinguished using a colon (:) to disambiguate the drive from a regular folder/file:

  • Use the Foreach-Object command to append the Colon to each drive letter returned.
  • Changed the filter from -Include to -Filter, to speed up the process as -Filter is implemented by the FileSystemProvider, and you're also not looking for multiple files.
  • Added -File switch for a more efficient query as well, since an .ISO extension is associated to a file.
$ISODeviceLetter = [array](Get-PSDrive | 
    Where-Object -FilterScript {$_.Name -match "^.$"}).Foreach{
        $_.Name   ':'
    }

$ISOLocation = Get-ChildItem -Path $ISODeviceLetter -File -Recurse -Filter *.ISO

Bonus: You can use Simplified Syntax to achieve the same results as above for better readability:

$ISODeviceLetter = (Get-PSDrive).Where{$_.Name -match "^.$"} | 
    Select -exp Name | Foreach Insert -ArgumentList 1,':' 

Only real "downside" of this is, that you're using the pipeline even more. Even though it may not affect the speed in your return for this example, other time sensitive tasks can take quite a performance hit using the pipeline.

  • Related