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.
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'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
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 have about 700 .txt files scattered in 300 directories and sub-directories.
I would like to open each of them, convert all text inside to lowercase, including Unicode characters (such as É to é), then save and close them.
Can you advise how it could be done through PowerShell? It is my own computer and I have admin rights.
I have started with the below:
Get-ChildItem C:\tmp -Recurse -File | ForEach-Object {}
but I am not sure what to put between the brackets of ForEach-Object {}.
Simple script, with your requirements:
$path=".\test\*.txt"
#With Default system encoding
Get-ChildItem $path -Recurse | foreach{
(Get-Content $_.FullName).ToLower() | Out-File $_.FullName
}
#Or with specified encoding
Get-ChildItem $path -Recurse | foreach{
(Get-Content $_.FullName -Encoding Unicode).ToLower() |
Out-File $_.FullName -Encoding Unicode
}
#Test
Get-ChildItem $path -Recurse | foreach{
Write-Host "`n File ($_.FullName): `n" -ForegroundColor DarkGreen
Get-Content $_.FullName
}
You need to use :
# Reading the file content and converting it to lowercase and finally putting the content back to the file with the same filename.
(Get-Content C:\path\file.txt -Raw).ToLower() | Out-File C:\path\file.txt -Force
inside the foreach and then change the case to lower.
If you want to iterate all the files in the corresponding folder then you can use another foreach to get that job done.
Hope it helps.
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}