0
votes

I am trying to find a path so that I can run a command. I dont want to find a file, but instead find the full folder name, including drive letter. Often the path drive letter varies, so I need to check a few different drive letters to find the folder which contain my files.

Sometimes the file will exist with the same name, in multiple drive letter locations. This is fine, but I need to determine the folder where each is saved. Currently I have created this ugly one-liner, which works, but isn't exactly what I need... For lack of figuring out how to do it, I created a file which I can save at the path I need to find, so I can have a target to look for.... this file is named file.txt

get-childItem -path f:\,g:\,h:\ -recurse -include file.txt 

Some devices where I run this wont have all the drives, so more ugliness ensues and I set a variable and include some -erroraction to proceed even if the drive letter is not found...

$path= Get-ChildItem -Path f:\, g:\, h:\ -Recurse -Include file.txt -ErrorAction SilentlyContinue

I am certain there must be a more elegant way to accomplish the goal... I really just want to find the path of a folder which contains some specific file names, regardless of the drive letter. I dont have to have the file.txt or any of this code. I just want to solve this and learn the best way to do it with PowerShell. I have a decent batch script to do it, but I am trying to rewrite it with pure PowerShell.

FOR %%i IN (C D E F G H I J K L N M O P Q R S T U V W X Y Z) DO (
    IF EXIST %%i:\scripts\file.txt (
        ECHO Script found at %%i
    )
)

This batch version works great and I can run my command and reference the %%i variable as the path where my file is found... but I want to refactor this into PowerShell.

I saw some other threads on this site, but I am not making much progress and I am failing.. Is there a better way?

$Drives = "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
foreach ($Drive in $Drives) {
   if (Test-Path "${Drive}:\file.txt") {
       $FileLocation = $Drive
   }
}

Write-Host $FileLocation
2
Being new to SO you may not know this, but is customary to accept the answer that solved your problem by clicking ✓ icon on the left. This will help others with a similar question finding it more easily and helps as motivation for people to answer your questions.Theo

2 Answers

1
votes

You can get an array of available drives on a system using [System.IO.DriveInfo]::GetDrives().
From that, you take the Name property and iterate over the drives:

[System.IO.DriveInfo]::GetDrives().Name | ForEach-Object {
    (Get-ChildItem -Path $_ -Filter 'file.txt' -Recurse -File -ErrorAction SilentlyContinue).DirectoryName
}

You can of course capture the returned directory paths if you like:

$paths = [System.IO.DriveInfo]::GetDrives().Name | ...

Another way of retrieving the available drives is by using WMI or CIM: (Get-CimInstance -ClassName Win32_logicaldisk).DeviceID, but remember that the returned drive letters are formatted C: without the backslash

0
votes

Yes try this:

67..90|%{[char]$_}|%{if(test-path "$($_):\file.txt"){$FileLocation=$_}}
write-host $FileLocation