I have a directoy X that has say 500 subdirectories. What I need is a quick way to just get only my directory and the names of these 500 subdirectories in my X directory (so, no Mode, no LastWriteTime or anything else, just the name) and pipe it to a file.
So, for example, I have this:
-X
|+Dir1
|+Dir2
|+Dir3
|
...
|+Dir500
What I want to get piped to a txt file is this
X/Dir1
X/Dir2
X/Dir3
...
X/Dir500
How can I do this using PowerShell or CommandLine?
I am using Windows 7 and PowerShell 4.0
Thanks,
Get-ChildItem will do the same thing as dir in command-line: it gets whatever is in your directory. You're looking only for directories. PS v3 and up has this built-in by using the flag of -directory. In older PowerShell versions, you can pipe your Get-ChildItem to a Where{$_.PSIsContainer to get directories and then pipe that to select Name to just get the names of the directories, not their full paths (e.g. "Dir1" vs. "X:\Dir1"). If you want the full path, use select FullName. Assuming you want that as a CSV, pipe that to Export-Csv followed by the name of the CSV you're creating, such as DirectoriesInX.csv and if you don't want the type information, add the flag of -NoTypeInformation.
PowerShell v3 and up:
Get-ChildItem "X:\" -directory | Select FullName | Export-Csv "DirectoriesInX.csv" -NoTypeInformation
PowerShell v2 and below:
Get-ChildItem "X:\" | Where{$_.PSIsContainer} | Select FullName | Export-Csv "DirectoriesInX.csv" -NoTypeInformation
I would have not used -Recurse based on requirement.
Moreover, OP wants to pipe output to a file :
(Get-ChildItem "X" -Directory).FullName | Out-File c:\myList.txt
The -Directory switch is only available from PS3.
The -Recurse switch would go as deep as possible in the tree and list all folders
Related
I am an absolute noob when it comes to Powershell..
Currently I run a simple script to get a file listing across our server.
(gci -filter *.xl* -recurse).FullName > AllExcel.txt
It gives me exactly what I'm looking for, a directory path and the file name all on one line across all subdirectories.
X:\00\This file 1.xls
X:\00\This file 2.xls
X:\aaa\This file Too 1.xls
X:\aaa\This file Too 2.xls
Can I add The date/time the file was last modified for each item? {$_.LastWriteTime}?
If so, can the output be sorted by this date/time? Would prefer newest at the top if possible.
are there also options to get who last modified a file?
Instead of a simple text file, I would store the results in a structured CSV file.
Get-ChildItem -Path 'X:\' -Filter '*.xls*' -File -Recurse |
Select-Object FullName, LastWriteTime |
Sort-Object LastWriteTime -Descending |
Export-Csv -Path 'X:\Somewhere\AllExcel.csv' -NoTypeInformation -UseCulture
This will result in a structured CSV file you can open on a machine with the same regional settings as yours to open in Excel
As for who last modified the files:
You could use Get-Acl on each file and with that get the Owner, but whoever owns the file is not necessarily the one who created/modified it.
You cannot identify creator or user who made the last change in Windows unless have file and folder auditing enabled beforehand, so you can extract the information from the audit logs.
I open a PS in a folder then use
dir -name > asd.xls -recurse.
How can I modify this so it doesn't incude folders in the filenames?
Instead of using -name, try using
(Get-ChildItem -Recurse).Name > asd.xls
and be aware that you won’t get a valid Excel workbook that way. You can get a valid CSV that can be loaded into Excel with
(Get-ChildItem -Recurse) | Select-Object -Property Name | Export-CSV -Path asd.csv -NoTypeInformation
When using powershell to rename files with their directory name and file name, my code works, except in the first file in a directory, it gives it two copies of the directory name. So the file book1.xlsx in folder folder1 should become folder1book1.xlsx but it becomes folder1folder1book1.xlsx. The remaining files in folder1 are correctly named folder1book2.xlsx, folder1book3.xlsx, etc.
I have a directory, with many sub-directories. In each sub-dir are files that need their sub-dir name added in.
I've been following this code. For me it looks like:
dir -Filter *.xlsx -Recurse | Rename-Item -NewName {$_.Directory.Name + "_" + $_.Name}
I've also tried
--setting the Recurse -Depth 1 so that it doesn't keep looking for folders in the sub-folders.
--using ForEach-Object {$_ | ... after the pipe, similar to this.
--running it in Visual Studio Code rather than directly in PowerShell, which turns it into:
Get-ChildItem "C:\my\dir\here" -Filter *.xls -Recurse | Rename-Item -NewName {$_.DirectoryName + '_' + $_.Name}
--putting an empty folder inside the sub-directory, setting -Depth 2 to see if that will "catch" the recurse loop
I would expect the files to be named folder1_book1.xlsx, folder1_book2.xlsx, folder1_book3.xlsx.
But all of the attempted changes above give the same result. The first file is named folder1_folder1_book1.xlsx [INCORRECT], folder1_book2.xlsx[CORRECT], folder1_book3.xlsx[CORRECT].
A workaround might be writing an if statement for "not files that contain the sub-directory name" as suggested here. But the link searches for a text string not an object (probably not the correct term) like #_.Directory.Name. This post shows how to concatenate objects but not something like #_.Directory.Name. Having to put in an if statement seems like an unnecessary step if -Recurse worked the way it should, so I'm not sure this workaround gets at the heart of the issue.
I'm running windows 10 with bootcamp on a 2018 iMac (I'm in Windows a lot because I use ArcMap). Powershell 5.1.17134.858. Visual Studio Code 1.38.0. This is a task I would like to learn how to use more in the future, so explanations will help. I'm new to using PowerShell. Thanks in advance!
This was a script I created for one of my customers that may help
<##################################################################################################################################
This script can be used to search through folders to rename files from their
original name to "filename_foldername.extension". To use this script
please configure the items listed below.
Items to Congfigure
-$Original
-$Source
-$Destination
-$Files
Also please change the Out-File date on line 29 to today's date ****Example: 2019-10-02****
We've also added a change log file that is named "FileChange.txt" and can be found in the location identified on line 30
>
$Original="C:\temp\test" #Location of ".cab" files copied
$Source="C:\temp\Test" #Location were ".cab" files are stored
$Destination="C:\temp\Test\2019-10-02" #Location were you want to copy ".cab" files after the file name change. Be sure to change the date to the date you run this script. The script creates a folder with todays date
$Files=#("*.cab") #Choose the file type you want to search for
$ErrorActionPreference = "SilentlyContinue" #Suppress Errors
Get-ChildItem $Original -Include "*.cab" -File -Recurse | Rename-Item -NewName {$_.BaseName+"_"+$_.Directory.Name +'.cab'}
New-Item -ItemType Directory -Path ".\$((Get-Date).ToString('yyyy-MM-dd'))"; Get-ChildItem -recurse ($Source) -include ($Files) | Copy-Item -Destination ($Destination) -EA SilentlyContinue
Get-ChildItem $Original | Where {$_.LastWriteTime -ge [datetime]::Now.AddMinutes(-10)} | Out-File C:\temp\test\2019-10-02\FileChange.txt
I'm trying this but it doesn't print anything:
Dir -Recurse "C:\temp" | Select Fullname
Looks like this command just selects file names. I want to see them in console.
Take a look at Get-Childitem
Dir -Recurse c:\path\ | Get-Childitem
Concerning your code in the question.
Your command should have worked as is. You are, in fact, already calling Get-ChildItem. If you check Get-Alias you will see what I'm trying to tell you.
PS C:\users\Cameron\Downloads> Get-Alias dir
CommandType Name ModuleName
----------- ---- ----------
Alias dir -> Get-ChildItem
You code translates to
Get-ChildItem -Recurse "C:\temp" | Select Fullname
Again, I'm not sure why your code does not generate output since that is perfectly fine on a folder that contains files or directories. Might be an issue with the positional parameter maybe? What is your PowerShell version? ( Use Get-Host).
The code you have would send all file paths to console. Did you want that output somewhere else?
About the accepted answer
Pretty sure this code will double up output if you have folders in the path since directory will output to the second Get-ChildItem
Dir -Recurse c:\path\ | Get-Childitem
Consider the following folder tree
C:\TEMP\TEST
│ File1.txt
│ File2.txt
│
└───Folder1
File3.txt
Consider the two command run against that folder tree.
PS C:\users\Cameron\Downloads> Dir -Recurse c:\temp\test | Select Fullname
FullName
--------
C:\temp\test\Folder1
C:\temp\test\File1.txt
C:\temp\test\File2.txt
C:\temp\test\Folder1\File3.txt
PS C:\users\Cameron\Downloads> Dir -Recurse c:\temp\test | Get-Childitem | Select Fullname
FullName
--------
C:\temp\test\Folder1\File3.txt
C:\temp\test\File1.txt
C:\temp\test\File2.txt
C:\temp\test\Folder1\File3.txt
The second command shows two files called File3.txt when in reality there is only one.
get-childitem | format-list > filename.txt
This will give you a text file with name, size, last modified, etc.
if you want specific parameters from the item... such as name of the file only the command is
get-childitem | format-list name > filename.txt
this is give you the same text file, but with just the name of the files listed.
It might also be worth mentioning the -force switch which is required to see hidden items.
I have a directory that contains a file called Bruce.txt. I need to copy the file name to a flat file. I tried using the copy-item command but that copies the contents not the name.
Is there a command to copy Bruce.txt (the name not the contents) to a flat file? So after it completes there will be a file called process.txt and its contents will be Bruce.txt. I tried using
Copy-Item -Path "C:\Users\Bruce\deploy\*.txt" -Destination "C:\Users\Bruce\process.txt".
Inside of deploy is a text file called Bruce.txt with the contents of select count() from EMP_NR.
I need Bruce.txt the name copied to process.txt not the Select count() etc.
For Shell script I use the ls command and it works wonderful what can I use for Powershell?
You need to use the Get-ChildItem cmdlet.
Get-ChildItem C:\Users\Bruce\deploy\*.txt | Select-Object -ExpandProperty Name | Out-File C:\Users\Bruce\process.txt -Force -Append
However, as you're using PowerShell, ls would actually work for you here, as would gci and dir as they're all aliases for Get-ChildItem:
> get-alias | ? {$_.DisplayName -ilike "*get-childitem*" }
CommandType Name
----------- ----
Alias dir -> Get-ChildItem
Alias gci -> Get-ChildItem
Alias ls -> Get-ChildItem
You can also use > or >> instead of piping to Out-File if you so wish.
Because the Get-Childitem cmdlet returns a list of objects, you then need to also select which information you want to extract from the object. If you do a ls in a directory with some content, you will see the contents are formatted into a table.
By using the Select-Object cmdlet, you can extract the object properties you want to write to your file, in this case the Name property.