Delete items at given path, and then all parents recursively - powershell

I have a path. Could be path to a file, could be path to a directory.
Now I need to delete the file (if it is a path to a file) and then check if there's no more files in the same folder, delete it as well, and then check the parent folder and so on.
if it is a path to a directory, delete directory, and then check if the parent is empty - delete it as well, and then its parent and so on.

This script will remove the top folder in the path including everything under it. the $path variable can point to either a file or directory.
$path = "D:\temp\temp2\file.txt"
$parts = $path.Split([System.IO.Path]::DirectorySeparatorChar)
# The following will remove D:\temp and everything in it
Remove-Item (Join-Path $parts[0] $parts[1]) -Recurse

I guess by combining these possible to build something:
Get-ChildItem
Split-Path $path -parent
Remove-Item

If you haven't already done the job this might help you:
You can use this to find out if the child item is a folder
| ? {$_.PSIsContainer}
and combined with this you can see if it is an empty folder
| ? {$_.GetFiles().Count -eq 0}
Good luck!

Related

Remove everything before \

I need to copy a lot of files and use the same sort of folder structure where the files needs to go.
So for instance if I have the following two documents:
\\Server1\Projects\OldProject\English\Text_EN.docx
\\Server1\Projects\OldProject\English\Danish\Text_DA.docx
I would need to move them to a new place on the server, but they need to be in the same "language folder". So I need to move them like this:
\\Server1\Projects\OldProject\English\Text_EN.docx -> \\Server1\Projects\NewProject\English\Text_EN.docx
\\Server1\Projects\OldProject\English\Danish\Text_DA.docx -> \\Server1\Projects\NewProject\English\Danish\Text_DA.docx
The issue here is, that I would need to take names of the "language" folder and create them in the NewProject folder.
How would I be able to take and remove everything before the \, so I end up with only having the "language" folders like English\ and English\Danish
If the goal it to just replace the 'OldProject' folder with 'NewProject' in the file path you could use replace to make the change to the file path:
$filePath = Get-ChildItem \\Server1\Projects\OldProject\English\Text_EN.docx
Copy-Item $filePath.FullName -Destination ($filepath.FullName -replace "\bOldProject\b", "NewProject")
The '\b' is used to do a regex EXACT match for anything inside the tags.
Try the following, which, for each input file:
constructs the target dir. path by replacing the old project dir.'s root path with the new one's, thereby effectively replicating the old dir.'s subdirectory structure.
makes sure that the target dir. exists
then copies the input file to the target dir.
$oldProjectRoot = '\\Server1\Projects\OldProject'
$newProjectRoot = '\\Server1\Projects\NewProject'
Get-ChildItem -Recurse -Filter *.docx -LiteralPath $oldProjectRoot |
ForEach-Object {
# Construct the target dir. path, with the same relative path
# as the input dir. path relative to the old project root.
$targetDir =
$newProjectRoot + $_.Directory.FullName.Substring($oldProjectRoot.Length)
# Create the target dir., if necessary (-Force returns any preexisting dir.)
$null = New-Item -Force -Type Directory $targetDir
$_ # Pass the input file through.
} |
Copy-Item -Destination { $targetDir } -WhatIf
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

Powershellcommand for jumping to next Folder

Is there a command in Powershell to jump to the next folder? My problem is that Powershell should search a folder with several subfolders for a particular file and when it is found moves it.
Example:
C:\Test\1\error\test.data
This should be moved to
C:\Test\1\data
and then I go back with cd. . cd. .
C:\Test\
Here I would need a command that jumg automatically in
C:\Test\2\error
And here’s my problem, how do I automatically get to the next folder without specifying it. So that I insert the command into a loop?
Thanks for the help :)
Use Get-ChildItem to enumerate the directories nested under C:\Test then use a loop to go through them one by one:
$targetFolders = Get-ChildItem -Path C:\test -Directory
foreach($targetFolder in $targetFolders){
# Switch to target folder
Push-Location -LiteralPath $targetFolder.FullName
# Check if file is there
if(Test-Path error\test.data){
# If so, move it
Move-Item error\test.data -Destination data
}
# Leave directory again
Pop-Location
}

Copying a folder with contents without knowing the full path to the folder to another folder

Is this possible using powershell or cmd? I only know the possibility to copy folder knowing the full path to the folder to be copied.
We assume that I want to copy to C:\copy the examp1, examp2, examp3 folders from the path
for examp1 C:\Users\Downloads\path1
for examp2 C:\Users\Downloads\path2
for examp3 C:\Users\Downloads\path3
but I don't know the exact name in place of the path1 and so on.
edit:
in general, all the folders that are to be copied (examp1,examp2,examp3 and so on) have a path which is
C:\Users\Downloads\2020random\examp1
C:\Users\Downloads\2021random\examp2
and so on.
but there are also folders in the
C:\Users\Downloads
which I don't want to copy and which also have a path, for example
C:\Users\Downloads\202020random\exampnottocopy.
to sum up, I have a path:
C:\Users\Downloads
which in turn contains various folders that may start with
2020random
2020random
.
.
.
2021random
2021random
and in turn they contain the folders I want to copy - I have a complete list of folders I want to copy.
and it is for example:
C:\Users\Downloads\2020random\examp1
C:\Users\Downloads\2021random\examp2
C:\Users\Downloads\2021random\examp3
and so on.
The difficulty is that not every folder in the location
C:\Users\Downloads\2020random
.
.
.
C:\Users\Downloads\2021random
contains a folder that is in my list - so I don't want to copy everything that is in the location I am copying from and that the full path to the copied folders is not known.
Assuming that you have your folders you'd like to copy in a textfile, you can try this.
Load the content of your textfile into the variable $foldersyouwant
$foldersyouwant = Get-Content -Path "yourPath"
Then you can simply output that data by using this command here
Get-ChildItem -Path C:\Users\Downloads\ -Recurse | Where-Object {$_.Name -in $foldersyouwant}
Does it show your expected folders?
Yes, then you can add another pipe and do the magic
Get-ChildItem -Path C:\Users\Downloads\ -Recurse | Where-Object {$_.Name -in $foldersyouwant} | Copy-Item -Destination "yourDestination"

How to exclude hidden folder/files from getting copied using Copy-Item in PowerShell?

I have this below code which is used to copy DBUpgrade folder to another location, but it copies the hidden folder present inside it as well.
$Demo="F:\source\DBUpgrade"
$new="F:\Test"
Copy-Item $demo $new -Recurse -Force
Is there any command by which I can exclude the hidden folder and one more thing the name of the hidden folder is $tf because of which i am not able to use remove-item command to remove the folder itself as another option.
You could do a
$list = get-childitem $demo $new -recurse -attributes !H | select fullname
And than a foreach loop
foreach ($file in $list){
Copy commands go here
}
Mind you copy commands will require some finesse to get it in the right folder and may not be worth the hassle
You'll have to trim the path out and do checks if it's $demo or $new to get it to the correct folder.
Get-Childitem by default doesn't show hidden items

Powershell getfiles.count() to exclude thumbs.db

We have a script running daily that removes old files and directories from an area that people use to transfer data around. Everything works great except for one little section. I want to delete a folder if it's older than 7 days and it's empty. The script always shows 1 file in the folder because of the thumbs.db file. I guess I could check to see if the one file is thumb.db and if so just delete the folder but I'm sure there is a better way.
$location = Get-ChildItem \\dropzone -exclude thumbs.db
foreach ($item in $location) {
other stuff here going deeper into the tree...
if(($item.GetFiles().Count -eq 0) -and ($item.GetDirectories().Count -eq 0)) {
This is where I delete the folder but because the folder always has
the Thumbs.db system file we never get here
}
}
$NumberOfFiles = (gci -Force $dir | ?{$_ -notmatch "thumbs.db"}).count
You can try the get-childitem -exclude option where all files/items in your directory will be
counted except those that end in db:
$location = get-childitem -exclude *.db
It also works out if you specify the file to exclude, in this case thumbs.db
$location = get-childitem -exclude thumb.db
Let me know if this works out.
Ah, I also just noticed something,
$location = get-childitem -exclude *.db
Will only handle .db items in the location directory, if you're going deeper into the tree (say from your GetFiles() and GetDirectories() methods) then you may still find a thumb.db. Hence you'll have to add the exclude option in these methods to ignore thumbs.db.
So, for example in your $item.getFiles() method, if you use get-childitem you will have to specify the -exclude option as well.
Sorry, I should have read your question more closely.
Use this method to provide a exclusion list in the form of a simple text file to exclude specific files or extensions from your count:
$dir = 'C:\YourDirectory'
#Type one filename.ext or *.ext per line in this txt file
$exclude = Get-Content "C:\Somefolder\exclude.txt"
$count = (dir $dir -Exclude $exclude).count
$count