I have written a PowerShell script that traverses over a directory and captures a list of folder names that are nested inside. It uses the following loop to achieve this
Get-ChildItem -Path $targetPath -Directory -Recurse |
Select-Object -ExpandProperty "Fullname" |
ForEach-Object {
#log folder name
}
However I want the script to skip directories that have a configured number of folders nested inside.
For example in the following example I do not want to capture the 'Folder C' because it has more than 3 folders nested.
Folder A/Folder AA
Folder A/Folder AB
Folder B/Folder BA
Folder C/Folder CA #DO NOT CAPTURE
Folder C/Folder CB #DO NOT CAPTURE
Folder C/Folder CC #DO NOT CAPTURE
Folder C/Folder CD #DO NOT CAPTURE
Folder D
So I would like my output of the script to be
Folder A/Folder AA
Folder A/Folder AB
Folder B/Folder BA
Folder D
How can I edit my script to achieve this?
If you just want to exclude folders on the top level you could do something like this:
Get-ChildItem -Path $targetPath -Directory | Where-Object {
(Get-ChildItem $_.FullName -Directory).Count -le 3
} | ForEach-Object {
Get-ChildItem $_.FullName -Directory -Recurse
} | Select-Object -Expand Fullname
If you want to exclude any (sub)folder that contains more than 3 subfolders you'll have to implement the recursion yourself. Get-ChildItem does not provide that kind of filtering mechanism.
Related
currently I am trying to delete files inside a folder structure
root
|
|__subfolder1 (includes files)
|
|__subfolder2 (includes files)
|
etc
The script has to delete all files inside the subfolders except subfolder1 and not delete the subfolders. The thing I am not getting to work is to exclude the files inside of "subfolder1".
I am trying something like this
Get-ChildItem -Path E:\root -Include *.* -File -Recurse -Exclude E:\root\subfolder1 | foreach {$_.Delete()}
Since the subfolder you want to exclude is always directly under the root folder I'd do the processing in 2 steps:
Enumerate the child folders of the root folder and exclude subfolder1.
Enumerate all files from the remaining folders and delete them.
Something like this:
$root = 'root'
$excludes = 'subfolder1'
Get-ChildItem $root -Directory -Exclude $excludes | ForEach-Object {
Get-ChildItem $_.FullName -File -Recurse -Force | Remove-Item -Force
}
I have 1000 files in a folder and similar named files in another folder. The objective is to have identical filenames in both folders but keep the file extension.
I would like to run a script to compare each folder's content (except their file extension) and if they are not in on folder If there is a file called BILL in folder1 but not in folder2 it deletes the file in one of the folders.
Example:
C:\TempFolder1\RandomFile1
C:\TempFolder2
If RandomFile1 does not exist in TempFolder2 it deletes it from TempFolder1 and vice versa.
Here you go... this script assumes you aren't looking recursively through subfolders, ignoring directories as well underneath either parent folder... it works by pulling the file list, then comparing each folders child files' BaseName with the list of BaseNames from the other, then removing the unique ones:
$folder1 = "C:\TempFolder1"
$folder2 = "C:\TempFolder2"
$files1 = Get-ChildItem $folder1 | Where-Object {$_.PsIsContainer -eq $false}
$files2 = Get-ChildItem $folder2 | Where-Object {$_.PsIsContainer -eq $false}
# Remove unique file baseNames from $folder1 that don't exist in $folder2
$files1 | Where-Object {$files2.BaseName -notcontains $_.BaseName} | Remove-Item -Force
# Remove unique file baseNames from $folder2 that don't exist in $folder1
$files2 | Where-Object {$files1.BaseName -notcontains $_.BaseName} | Remove-Item -Force
Is there a way how to remove only last empty folder with PowerShell?
Example: I have a folder structure
..-mainFolder
...................-subFolder1
........................................- a
........................................- b
........................................- c
..................-subFolder2
........................................- a
........................................- b
Every night with robocopy i copy everything to another server and afterword i should delete all last sub folders (a,b,c, etc..).
With /MUVE it removes "subFolder1" & "subFolder2" but they should stay there
(if i remove folders "a", "b", "c" the "subFolder1" is empty too so i cant delete all empty folders.)
I cant use /FX and i don't know the name of folders just root directory path "C:\SharedFolders\". and i know that the folders that should be removed is in 3rd level.
You could use the Get-ChildItem cmdlet with the -Directory switch to retrieve all folders, filter the empty folders using the Test-Path cmdlet and finally delete the folders using Remove-Item:
Get-ChildItem 'C:\SharedFolders' -Directory -Recurse |
where { -not (Test-Path (Join-Path $_.FullName '*')) } |
Remove-Item
This will remove only the last empty folders, result:
..-mainFolder
...................-subFolder1
..................-subFolder2
You can use Get-ChildItem -Recurse to retrieve all folders, then call the GetFiles() and GetDirectories() methods on the directory objects to determine if they are empty:
$EmptyDirs = Get-ChildItem C:\path\to\mailFolder -Directory -Recurse | Where {-not $_.GetFiles() -and -not $_.GetDirectories()}
# and then remove those
$EmptyDirs | Remove-Item
I want to get all "*.exe" files from one folder. It has 3 sub folders. but I want get files from 2 sub folders only. I am trying to use -Exclude in PowerShell. It is working to exclude single file but it is not working to exclude a folder. can anybody tell how to solve it.
This is what I am using the below code it is working to exclude "HWEMNGR.EXE" etc files but Its not allowing me to exclude a sub folder from main folder.
$Files = Get-ChildItem -Path "D:\depot\main" -Recurse -Include "*.exe" -Exclude HWEMNGR.EXE,wmboot.exe,SDClientMobileEdition.exe | % { $_.FullName }
Thanks
-Exclude is good for file names however it does not have a good track record for folder name\path exclusion. You should use a Where-Object clause to address that.
$Files = Get-ChildItem -Path "D:\depot\main" -Recurse -Include "*.exe" -Exclude "HWEMNGR.EXE","wmboot.exe","SDClientMobileEdition.exe" |
Select-Object -ExpandProperty FullName |
Where-Object{$_ -notmatch "\\FolderName\\"}
The snippet % { $_.FullName } was replaced by Select-Object -ExpandProperty FullName which does the same thing. Then we use Where-Object to exclude paths where FolderName is not there. It is regex based so we double up on the slashes. This also helps make sure we exclude folders and not a file that might be called "FolderName.exe"
Alternate approach
Like TheMadTechnician points out you could come at this from another direction and just ensure the files come from the only two folders you really care about. Get-ChildItem will take an array for paths so you could also use something like this.
$paths = "D:\depot\main\install","D:\depot\main\debug"
$excludes = "HWEMNGR.EXE","wmboot.exe","SDClientMobileEdition.exe"
$Files = Get-ChildItem $paths -Filter "*.exe" -Exclude $excludes | Select-Object -ExpandProperty FullName
$paths is the only two folders you want results from. You still exclude the files you dont want and then just return the full file paths.
I will take the following example to explain how I do it:
Get-ChildItem C:\a -include "*.txt" -recurse | %{$_.fullname}
C:\a\b\b1.txt
C:\a\b\b2.txt
C:\a\b\b3.txt
C:\a\c\c1.txt
C:\a\c\c2.txt
C:\a\c\c3.txt
C:\a\d\d1.txt
C:\a\d\d2.txt
Here under C:\a, the subfolders are b,c and d
Now I want *.txt files from b and c to be listed and I want to exclude any file under d subfolder.
To achieve this I introduce a where (also used as "?") condition as follows
Get-ChildItem C:\a -include "*.txt" -recurse | ?{$_.fullname -notlike "C:\a\d\*"} | %{$_.fullname}
C:\a\b\b1.txt
C:\a\b\b2.txt
C:\a\b\b3.txt
C:\a\c\c1.txt
C:\a\c\c2.txt
C:\a\c\c3.txt
I hope this solves your problem.
I am trying to write a PowerShell script that will search for all folders named "abc" within a network share. There a multiple instances of this folder located throughout this share all named "abc" in different DIR's
I would like to list the file and folder contents, of every folder named "abc" within said directory. So far I have got PowerShell to list all instances of folders named "abc" within the network drive, but I am stuck after that.
Can I pipe this into another command that will then search and list each folders contents?
You can try something like htis
Get-ChildItem -Filter "abc" -Recurse -Path "\\myserver\share" | #Find abc
Where-Object { $_.PSIsContainer } | #Get only abc-folders
Get-ChildItem -Recurse | #Search through each abc-folder
Where-Object { !$_.PSIsContainer } #Get only files
The performance would be better if you run the script locally on the server or using psremoting(ex. using Invoke-Command). The problem is that it searches through all files and folders recursively before removing the files from the search result in that first Get-ChildItem line.
If you have PS 3.0 or PS 4.0, you can also use:
Get-ChildItem -Filter "abc" -Recurse -Path "\\myserver\share" -Directory | #Find abc-folders
Get-ChildItem -Recurse -File #Get files inside those folders