How do I get $selected_files to populate with files that are included in $fileList. $fileList is a text file that only contains the name of the file, path and extension not included. I have tried the following:
$fileList = "C:\Users\HKJ\Desktop\Test\ListofFilesToDelete.txt"
$selected_files = Get-ChildItem -Path "$targetFolder\*" -File -Name -Include #(Get-Content $fileList)
You can do it this way:
$fileList = "C:\Users\HKJ\Desktop\Test\ListofFilesToDelete.txt"
$fileBaseNames = Get-Content $fileList
$selected_files = Get-ChildItem -Path "$targetFolder\*" -File -Name | Where-Object BaseName -in $fileBaseNames
Using the built in -Include on Get-ChildItem only works for simple things. Here we use the BaseName property on the files and use the -in operator to see whether the array $fileBaseNames contains that name. The BaseName property contains just the file name without the extension.
If you are on an older version of Powershell you might need to change the last line to this:
$selected_files = Get-ChildItem -Path "$targetFolder\*" -File -Name | Where-Object { $_.BaseName -in $fileBaseNames }
Try the following:
$filelist = Get-Content "C:\Users\HKJ\Desktop\Test\ListofFilesToDelete.txt"
Get-ChildItem | Where-Object {$filelist.Contains([io.path]::GetFileNameWithoutExtension($_.Name))}
Get-ChildItem -Path $dir -Recurse -File | ForEach-Object `
{
Write-Host $_.fullname
}
Get-ChildItem : A parameter cannot be found that matches
parameter name 'File'.
Version
-------
5.1.17763.771
I have many other ps scripts running that use this and it works fine, but for some reason it's not working in this new script I wrote. What's going on?
Thank you everyone for helping.
The value of $dir was
" S:\folder\folder\"
Removing the space before the drive letter resolved the issue.
In addition to the OP's particular instance, there are other cases where this error can occur. Get-ChildItem can be used on other providers besides the file provider (e.g., the registry), and the -File switch is not valid in those cases.
Example:
$dir = 'C:\Temp'
Get-ChildItem -Path $dir -File # Works just fine
$dir = 'HKCU:\Software'
Get-ChildItem -Path $dir # Works without -File switch
Get-ChildItem -Path $dir -File # Throws "parameter cannot be found" error
That wasn't the source of the problem for me.
All I did was surround the variable with ( ) and that resolve it.
In my case I wanted the full filename of the 'found' file
$curdir = "C:\Program Files\"
(Get-Childitem -Path ($curdir) -File -filter "node.exe" -recurse -Force -ErrorAction SilentlyContinue).Directory.FullName
In your case I'm sure just using this would work for you:
Get-ChildItem -Path ($dir) -Recurse -File | ForEach-Object `
{
Write-Host $_.fullname
}
The following query searched for locations of a file in PowerShell. Is there any way to just return the directory instead of the directory attributes and filename?
Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse
(Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse).DirectoryName
I'm assuming you only want the names of the directories that contain matched files here:
Get-ChildItem -Path C:\random\random -Filter nameofile -Recurse | % { split-path $_.fullname } | sort -uniq
I have the following code to try locating a folder within my project.
$rootDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$fileName = "Scripts*"
$paths = gci -path $rootDir -filter $fileName -Recurse | Select-Object -Expand FullName
The problem I am having is that I don't want it finding the folder inside of bin or obj folder. Is there a way to exclude those from the search?
Basically I need to recursively search my solution folder for a folder name, excluding the bin/obj locations.
When I try using the -Exclude it gives my compile errors. I imagine there has to be a easier way than this to do it.
I think the problem is that -Exclude only accepts strings. You'll need to use Where-Object to filter out multiple strings.
$paths = gci -path $rootDir -filter $fileName -Recurse | Where-Object {$_.FullName -notlike "*bin*\*" -and $_.FullName -notlike "*obj*\*"} | Select-Object -Expand FullName
The problem is that the -Exclude is passed along to the Provider, and the file system provider is not good at filtering in general. I would suggest using a Where clause and using one of the -Match operators (-inotmatch is a case insensitive inverted match, so it excludes anything that matches the text) like this:
$rootDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$fileName = "Scripts*"
$paths = gci -path $rootDir -filter $filename -Recurse | Select-Object -Expand FullName | ?{$_ -inotmatch "\\(bin|obj)\\"}
That looks for a string that starts with a backslash (), followed by either bin or obj, and trailed by another backslash.
I'm using PowerShell 2.0 and I want to pipe out all the subdirectories of a certain path. The following command outputs all files and directories, but I can't figure out how to filter out the files.
Get-ChildItem c:\mypath -Recurse
I've tried using $_.Attributes to get the attributes but then I don't know how to construct a literal instance of System.IO.FileAttributes to compare it to. In cmd.exe it would be
dir /b /ad /s
For PowerShell 3.0 and greater:
Get-ChildItem -Directory
You can also use the aliases dir, ls, and gci
For PowerShell versions less than 3.0:
The FileInfo object returned by Get-ChildItem has a "base" property, PSIsContainer. You want to select only those items.
Get-ChildItem -Recurse | ?{ $_.PSIsContainer }
If you want the raw string names of the directories, you can do
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName
In PowerShell 3.0, it is simpler:
Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files
Use
Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files
If you prefer aliases, use
ls -dir #lists only directories
ls -file #lists only files
or
dir -dir #lists only directories
dir -file #lists only files
To recurse subdirectories as well, add -r option.
ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively
Tested on PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac, and Linux), and PowerShell 7.0 (Windows 10, Mac, and Linux).
Note: On PowerShell Core, symlinks are not followed when you specify the -r switch. To follow symlinks, specify the -FollowSymlink switch with -r.
Note 2: PowerShell is now cross-platform, since version 6.0. The cross-platform version was originally called PowerShell Core, but the the word "Core" has been dropped since PowerShell 7.0+.
Get-ChildItem documentation: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem
A cleaner approach:
Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}
I wonder if PowerShell 3.0 has a switch that only returns directories; it seems like a logical thing to add.
Use:
dir -r | where { $_ -is [System.IO.DirectoryInfo] }
From PowerShell v2 and newer (k represents the folder you are beginning your search at):
Get-ChildItem $Path -attributes D -Recurse
If you just want folder names only, and nothing else, use this:
Get-ChildItem $Path -Name -attributes D -Recurse
If you are looking for a specific folder, you could use the following. In this case, I am looking for a folder called myFolder:
Get-ChildItem $Path -attributes D -Recurse -include "myFolder"
Less text is required with this approach:
ls -r | ? {$_.mode -match "d"}
The accepted answer mentions
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName
to get a "raw string".
But in fact objects of type Selected.System.IO.DirectoryInfo will be returned. For raw strings the following can be used:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }
The difference matters if the value is concatenated to a string:
with Select-Object suprisingly foo\#{FullName=bar}
with the ForEach-operator the expected: foo\bar
Use:
dir -Directory -Recurse | Select FullName
This will give you an output of the root structure with the folder name for directories only.
You'll want to use Get-ChildItem to recursively get all folders and files first. And then pipe that output into a Where-Object clause which only take the files.
# one of several ways to identify a file is using GetType() which
# will return "FileInfo" or "DirectoryInfo"
$files = Get-ChildItem E:\ -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} ;
foreach ($file in $files) {
echo $file.FullName ;
}
Use:
Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name | convertto-csv -NoTypeInformation | Out-File c:\temp\mydirectorylist.csv
Which does the following
Get a list of directories in the target location:
Get-ChildItem \\myserver\myshare\myshare\ -Directory
Extract only the name of the directories:
Select-Object -Property name
Convert the output to CSV format:
convertto-csv -NoTypeInformation
Save the result to a file:
Out-File c:\temp\mydirectorylist.csv
A bit more readable and simple approach could be achieved with the script below:
$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
if ($_.Attributes -eq "Directory") {
Write-Host $_.FullName
}
}
Hope this helps!
My solution is based on the TechNet article Fun Things You Can Do With the Get-ChildItem Cmdlet.
Get-ChildItem C:\foo | Where-Object {$_.mode -match "d"}
I used it in my script, and it works well.
This question is well and truly answered but thought I'd add something extra as I've just been looking at this.
Get-ChildItem happens to produce two types of objects whereas most commands produce just one.
FileInfo and DirectoryInfo are returned.
You can see this by viewing the 'members' available to this command like so:
Get-ChildItem | Get-Member
TypeName: System.IO.DirectoryInfo
TypeName: System.IO.FileInfo
You'll see the various methods and properties available to each type. Note that there are differences. For example that the FileInfo object has a length property but the DirectoryInfo object doesn't.
Anyway, technically, we can return just the directories by isolating the DirectoryInfo object
Get-ChildItem | Where-Object {$_.GetType().Name -eq "DirectoryInfo"}
Obviously as the top answer states the most straightforward solution is to simply use Get-ChildItem -Directory but we now know how to work with multple object types in future :)
Use this one:
Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"
You can try the PsIsContainer Object
Get-ChildItem -path C:\mypath -Recurse | where {$_.PsIsContainer -eq $true}
To answer the original question specifically (using IO.FileAttributes):
Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -band [IO.FileAttributes]::Directory}
I do prefer Marek's solution though:
Where-Object { $_ -is [System.IO.DirectoryInfo] }