I'm using PowerShell script to delete folders which are older than x days.
$limit = (Get-Date).AddDays(-15)
$path = "xxxx\path"
# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse`
But it doesn't work always, and I couldn't figure out what's wrong. is there any other way I can delete certain folders for example if there are more then 5 folders..? or is it best to delete which one is older..?
I do a backup via Powershell script which works great, but when I'm using this script to delete older backups some reason it doesn't work always.
is there any alternative way to do this.?
Lot's of love humans
#Alex_P thanks, it's confusing but after changing the path for scripts they seem to be working. before path was like ( Users/admin/folder test/script.p1) I changed it to ( Users/admin/folder-test/script.p1)
after changing it solved the problem, still, don't know why it had happened.
Thanks all
I guess "Users/admin/folder test/script.p1" should have worked. There is a blank in the path. Therefore, "" are needed
Related
I have a long list of folders. Most of the folders follow the "name_#name" format. I have some that don't follow that structure. I want to move all the folders (and the sub-folders/files within) that DON'T have "_" in the folder name.
For example:
test_#12352
moose_#4532
horse_#84462
cow24
fish3
Moved:
cow24
fish3
I think Move files when they contain a specific word? could be modified to make it work...just not sure how. I'm used to just using GUI, this is my first time using PowerShell
When I tried using that code in that link it didn't work with my situation
What you want to do is just filter the list before you move any files
So you can use the following to pick up all the files you want
$Files = Get-childItem -Path $Path -File
You can then filter it down. My favourite way is to pipe the variable into Where-Object and play around with the individual properties and match types. Since you don't want to include the _ we can use a -notmatch "_" to exclude those values
$Files = Get-ChildItem -Path $Path -File | Where-object{$_.Name -notmatch "_"}
And finally, you can move the files
$Files | move-item -path $_.FullName -Destination $Destination
Or as a one liner
Get-ChildItem -Path $Path -File | Where-object{$_.Name -notmatch "_"} | move-item -path $_.FullName -Destination $Destination
*Please note I haven't really tested this code. So test it out yourself before you run it
I have a number of folders that I am trying to copy. The folders are all name 'yyyymmdd' i.e. 20190615, going back up to a year or more. I am trying to figure out a way to copy only the last 45 days of these folders. The biggest issue that I've run into is that the computers that I am running this on only have Powershell 2.0, which seems to have some limitations that 5 or greater does not have.
I have been able to get the list of all of the folders in the path with :
$datedsubs = Get-ChildItem -path $path | where-object { $_ -like "20*" }
From there though, I am a little stuck. I feel this would be easier with PS 5 or greater. I've tried Robocopy, even though that is not a PS solution, but that copies everything, and I just want the folders.
I've tried something like the following, but it doesn't seem to work in PS 2.0.
Get-ChildItem -Path $path | Where-Object { ($_ -like '20*') -and ($_.LastAccessTime -lt $datedlimit)} | Copy-Item -Destination $destination -Recurse
Any help would be appreciated here.
Thanks
Putting what Lee has said into some code.
Get-ChildItem -Path $Path -Filter "20*" | Where-Object {($_.PSIsContainer) `
-and ($_.LastAccessTime -gt ((Get-Date).AddDays(-45)))} | `
Copy-Item -Destination $destination -Recurse
This should get you what you are after.
I have put it to -gt 45 days ago because this will only show folders accessed within the last 45 days.
I am currently trying to run a script I wrote. It works great, but I need it to also search and remove from the hidden folders as well. It does not seem to have any effect on hidden folders... Here is my script.
Get-ChildItem C:\ -Include saplogon.ini -Recurse | foreach ($_) {Remove-Item $_.fullname}
$src_dir = "\\xxxxxxxxxx\xxxxxxxxxxxx\saplogon\saplogon.ini"
$dst_dir = "C:\Windows"
$file = Get-ChildItem $src_dir
Copy-Item $file -Destination $dst_dir
[System.Environment]::SetEnvironmentVariable('SAP_LOGON_INI', 'C:\Windows\saplogon.ini', 'Machine')
You are missing the the -Force parameter.
The code below is using alias so it won't require horizontal scrolling. Know that gci is Get-ChildItem.
Note that you will only be able to get access if you have permission.
gci c:\ -Include saplogon.ini -Recurse -Force | foreach ($_) {remove-item $_.fullname}
At this point, you probably already took care of the non-hidden files. If you want to run the script again, but only for hidden files (and not non-hidden files), you can do that with the -Hidden flag.
Again, you will only be able to get access if you have the permission.
gci c:\ -Include saplogon.ini -Recurse -Hidden | foreach ($_) {remove-item $_.fullname}
I'm trying to copy all *.csproj.user files recursively from C:\Code\Trunk to C:\Code\F2.
For example:
C:\Code\Trunk\SomeProject\Blah\Blah.csproj.user
Would get copied to:
C:\Code\F2\SomeProject\Blah\Blah.csproj.user
My current attempt is:
Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination
C:\Code\F2 -Recurse -WhatIf
However I get:
What if: Performing operation "Copy Directory" on Target "Item:
C:\Code\Trunk Destination: C:\Code\F2\Trunk".
First, it wants to put them all in a new folder called F2\Trunk which is wrong. Second, it doesn't list any of the files. There should be about 10 files to be copied over.
What's the correct syntax for the command? Thanks!
Update:
Okay, it seems to have something to do with the fact that C:\Code\F2 already exists. If I try copying the files over to a destination that does not exist, it works.
I want to overwrite any existing .csproj.user files in the destination.
You guys are making this hideously complicated, when it's really simple:
Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse
Will copy the Directory, creating a "Trunk" directory in F2. If you want to avoid creating the top-level Trunk folder, you have to stop telling PowerShell to copy it:
Get-ChildItem C:\Code\Trunk | Copy-Item -Destination C:\Code\F2 -Recurse -filter *.csproj.user
While the most voted answer is perfectly valid for single file types, if you need to copy multiple file types there is a more useful functionality called robocopy exactly for this purpose with simpler usage
robocopy C:\Code\Trunk C:\Code\F2 *.cs *.xaml *.csproj *.appxmanifest /s
Seen this before, and I don't know why PowerShell can't seem to get it right (IMHO). What I would do is more cumbersome but it works.
$Source = 'C:\Code\Trunk'
$Files = '*.csproj.user'
$Dest = 'C:\Code\F2'
Get-ChildItem $Source -Filter $Files -Recurse | ForEach{
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
Copy-Item $_.FullName -Destination $Path -Force
}
I tried Jaykul answer and it did not work for me. I had to change it as below to get it to work. I also created the C:\Code\F2 folder before it worked.
Get-ChildItem C:\Code\Trunk -Recurse -filter *.csproj.user | Copy -Destination C:\Code\F2
Answer 1 looked good, and I changed to Move-Item for my purposes. However I found that in each folder it recursively went through, it only moved the first file. Below is my complete script which also includes some conversion of doc files to pdf's:
$Source = 'C:\Users\sgrody\Desktop\NSPM-Vol1'
$MoveFiles = '*.PDF'
$Dest = 'C:\Users\sgrody\Desktop\MedPassPDF'
$Folders = Get-ChildItem $Source -Directory -Recurse
ForEach ($Folder in $Folders)
{
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$folderpath = "$($Folder.FullName)\*"
$fileTypes = "*.docx","*doc"
Get-ChildItem -path $folderpath -include $fileTypes |
foreach-object
{
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
"Converting $path to pdf ..."
$doc = $word.documents.open($_.fullname)
$doc.saveas([ref] $path, [ref]$wdFormatPDF)
$doc.close()
}
$word.Quit()
}
Get-ChildItem $Source -Filter $MoveFiles -Recurse | ForEach{
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
Move-Item $_.FullName -Destination $Path -Force
}
}
Recently I had to replace a file present in several sub folders, I did it as below.
foreach($file in (Get-ChildItem File_you_want_to_be_copied.txt -Recurse)) {$target=$file.directoryname; Copy-Item -path C:\Source_Path\File_you_want_to_be_copied.txt -Destination $target}
I have several programs (.exe) installed on my computer which create ".dat" files. One of them creates very large files.
I want to delete only the files created by this program.
Is there a way in PS to know which program has created a file?
I try to filter them in following code:
Get-ChildItem $path -Filter "*.dat" -Recurse -Force |'
Where-Object {$_.CreationTime -lt $limit -and $_.LastAccessTime -lt $limit2 -and $_.Attributes -notmatch "Offline" } |'
Remove-Item -Force
This is not possible unless your program somehow stamps a property onto .dat file which you would then read.
Use Process Explorer if you want to find out which executable creates the file in question.
One option is to execute the ".exe programms" under different credentials, one different user per exe. Then you can use get-acl to identify who created each file:
$OWNER = "xxxx"
Get-ChildItem $path -Filter "*.dat" -Recurse -Force |'
Where-Object {Get-Acl $_.FullName -eq $OWNER -and $_.CreationTime -lt $limit -and $_.LastAccessTime -lt $limit2 -and $_.Attributes -notmatch "Offline" } |'
Remove-Item -Force
I would suggest using ProcessMonitor ( http://technet.microsoft.com/en-gb/sysinternals/bb896645). This will show all file system activity and will quickly show you which processes are accessing which files.