Remove items in directory if filename matches words from CSV - powershell

I've been struggling with this all day now. I'm trying to delete any files in a given directory if the filenames match a word in a CSV list.
I have imported the CSV list as text then try to match words with the filenames in the target directory, however I'm not sure which operator to use or how to go about this. Obviously 'Match' is not a cmdlet.
#store csv file as variable
$CSVList = Get-content -Delimiter (',') -path "C:\Users\Leeds TX 11\Desktop\Test folder\Watchfolder\DAZN Production Numbers - purgelist.csv"
write-host $CSVList
#delete if word matches .csv entry
$targetdirectory = "C:\Users\Leeds TX 11\Desktop\Test folder\AVMedia"
$Files = Get-childItem $targetdirectory | Match ("\w") $CSVList | remove-item -whatif
write-host $Files

Just add a Where-Object to the pipe where you check whether the Name property is -In the $CSVList:
# ...
$Files = Get-ChildItem $targetdirectory | Where-Object Name -In $CSVList | Remove-Item -whatif
Note: I consider the filenames within your CSV contains a file extension. If not, you want to change Where-Object Name to Where-Object BaseName.
Edit. Since you are using PowerShell Version 2, you have to use -contains and swap the variables:
$Files = Get-ChildItem $targetdirectory | Where-Object {$CSVList -contains $_.BaseName} | Remove-Item -whatif

try Something like this
#store csv file as variable and take first column
$CSVList = (import-csv "c:\temp\missing.csv" -Header col1).col1
#delete if word matches .csv entry
$targetdirectory = "C:\temp2"
$Files = Get-childItem $targetdirectory -Recurse | Where-Object {$CSVList -contains $_.BaseName } | remove-item -whatif
write-host $Files

Related

Is there a way to pull a variable value into a select-object expression?

The purpose of this script is to find the Name, directory and last write time of files and output it to a csv file.
get-childitem D:\testing -recurse -filter *.txt | select-object Name,DirectoryName,LastWriteTime, #{Name="New_colimn";Expression={"copy-item \`"DirectoryName\`" To_Compile_directory"}} | where { $_.DirectoryName -ne $NULL } | Export-CSV D:\testing\rdf.csv
My problem is that there is 1 cell I want to fill with another script that takes values from the generated csv file. Is there a way to pull the value of each DirectoryName and paste it into the Expression of the same row? I only get an error that says DirectoryName is an invalid key.
when I try to pull using $.DirectoryName the script only reads the $ and the value it has is the Name.
Thank for helping.
Did you mean to collect the data from the files like this:
Get-ChildItem -Path 'D:\testing' -Filter '*.txt' -File -Recurse |
Select-Object Name,DirectoryName,LastWriteTime | Export-Csv -Path 'D:\testing\rdf.csv' -NoTypeInformation
and then have your other script read the DirectoryName's from it like this?
$directories = (Import-Csv -Path 'D:\testing\rdf.csv').DirectoryName | Select-Object -Unique
# maybe do something with these directories here?
foreach ($folderPath in $directories) {
# copy the directories including the files to an existing root destination folder
Copy-Item -Path $folderPath -Destination 'D:\SomeExistingDestinationPath' -Recurse -Force
}

Change content of a file based on a content of another file

I have this file structure
In PowerShell my location is set to Folder. SubSubFolders has a lot of xml files, and I want to add a line there only if content of version.txt file is a and that line doesn't exist there already.
I was able to figure out how to change an xml file in particular SubSubFolder, but I can't do it when I start in Folder folder and and taking into consideration version
#here I need to add: only if version.txt content of xml file in parent folder is "a"
$files = Get-ChildItem -Filter *blah.xml -Recurse | Where{!(Select-String -SimpleMatch "AdditionalLine" -Path $_.fullname -Quiet)} | Format-Table FullName
foreach($file in $files)
{
(Get-Content $file.FullName | Foreach-Object { $_
if ($_ -match "AdditionalLineAfterThisLine")
{
"AdditionalLine"
}
}) | Set-Content $file.FullName
}
If I understand you correctly, you're looking for the following:
$files = (
Get-ChildItem -Filter *blah.xml -Recurse |
Where-Object{
-not ($_ | Select-String -SimpleMatch "AdditionalLine" -Quiet) -and
(Get-Content -LiteralPath "$($_.DirectoryName)/../version.txt") -eq 'a'
}
).FullName
Note that the assumption is that the version.txt file contains just one line. If it contains multiple lines, the -eq 'a' operation would act as a filter and return all lines whose content is 'a', which in the implied Boolean context of -and would yield $true if one or more such lines, potentially among others, exist.

Get a list of all specific empty subfolders inside employee's folders

Could you please help me with a directory operation?
I have an employee directory and in that directory, there are about 200+ employees subdirectories named by their employee code. And within each employee's subdirectory, there are about 20 subfolders referring to various documents. For example, subfolder named 'Educational Documents'. This 'Educational Documents' subfolder exists in each of these 200+ employee's folders.
I want to output a text or csv file listing all such 'Educational Documents' subfolders out of those 200+ employees which are empty or in other words where scanned PDF files have not been copied as yet. By doing so, I will be able to use that output file as a task list for myself to populate all those empty folders by putting scanned PDF documents for the missing employee data.
I have tried to use DOS commands with /S switch but that does not precisely cater to my needs and therefore I am looking at some Powershell script which could get this done.
My code so far:
$Search = gci -Filter "Educational Documents" -Recurse -Path "D:\Employees" -Directory
Foreach ($path in $Search.fullname)
{
Write-Output $path | Out-File d:\Filelist.txt -append
$file = gci -path $path | select name
$file.name | Out-File d:\filelist.txt -append
Write-Output "------- Next Folder --------------" | Out-File d:\Filelist.txt -append
}
If I understand correctly, you want a file listing of all empty folders called 'Educational Documents'.
To do that, you could make use of the GetFileSystemInfos() method of the DirectoryInfo objects returned by Get-ChildItem like this:
$Search = Get-ChildItem -Path "D:\Employees" -Filter "Educational Documents" -Recurse -Directory |
Where-Object { $_.GetFileSystemInfos().Count -eq 0 } | Select-Object -ExpandProperty FullName
# add '-PassThru' to also output this list on screen
$Search | Set-Content -Path 'D:\Empty_EducationalDocuments_Folders.txt'
Hope that helps
As per your comment, you would like to list both empty folders and folders that do not have a file with the word Graduation in their name, you can edit the above to become
$Search = Get-ChildItem -Path "D:\Employees" -Filter "Educational Documents" -Recurse -Directory |
Where-Object { $_.GetFileSystemInfos().Count -eq 0 -or
$_.GetFiles("*Graduation*", "TopDirectoryOnly").Count -eq 0 } |
Select-Object -ExpandProperty FullName
# add '-PassThru' to also output this list on screen
$Search | Set-Content -Path 'D:\EducationalDocuments_Folders_without_Graduation_File.txt'
You can try this code:
$Search = Get-ChildItem -Recurse -Path "D:\Employees" -Directory
foreach ($path in $Search.fullname)
{
$directoryInfo = Get-ChildItem -Path $path | Measure-Object
if($directoryInfo.count -eq 0)
{
$path | Out-File "D:\Filelist.txt" -append
Write-Output "------- Next Folder --------------" | Out-File "D:\Filelist.txt" -append
}
}
I used some code from this question: Test if folder is empty

How to copy files using a txt list to define beginning of file names

Hello awesome community :)
I have a list containing a bunch of SKU's. All the filenames of the files, that I need to copy to a new location, starts with the corresponding SKU like so
B6BC004-022_10_300_f.jpg
In this case "B6BC004" is the SKU and my txt list contains "B6BC004" along with many other SKU's.
Somewhere in the code below I know I have to define that it should search for files beginning with the SKU's from the txt file but I have no idea how to define it.
Get-Content .\photostocopy.txt | Foreach-Object { copy-item -Path $_ -Destination "Z:\Photosdestination\"}
Thanks in advance :)
If all files start with one of the SKU's, followed by a dash like in your example, this should work:
$sourceFolder = 'ENTER THE PATH WHERE THE FILES TO COPY ARE'
$destination = 'Z:\Photosdestination'
# get an array of all SKU's
$sku = Get-Content .\photostocopy.txt | Select-Object -Unique
# loop through the list of files in the source folder and copy all that have a name beginning with one of the SKU's
Get-ChildItem -Path $sourceFolder -File -Recurse |
Where-Object { $sku -contains ($_.Name -split '\s*-')[0] } |
ForEach-Object { $_ | Copy-Item -Destination $destination }
I haven't tested this so please proceed with caution!
What is does it loops through all the items in your photostocopy.txt file, searches the $source location for a file(s) with a name like the current item from your file. It then checks if any were found before outputting something to the console and possibly moving the file(s).
$source = '#PATH_TO_SOURCE'
$destination = '#PATH_TO_DESTINATION'
$photosToCopy = Get-Content -Path '#PATH_TO_TXT_FILE'
$photosToCopy | ForEach-Object{
$filesToCopy = Get-ChildItem -Path $source -File | Where-Object {$_.Name -like "$_*"}
if ($fileToCopy.Count -le 0){
Write-Host "No files could be found for: " $_
}else{
$filesToCopy | ForEach-Object{
Write-Host "Moving: " $_.Name
Copy-Item -Path $_.FullName -Destination $destination
}
}
}
Let me know how if this helps you :)

How to find more than one string in list of file?

I am trying to search strings in files and display the file name which contains the strings
I have written a script like below.
Function GetFileContainsData ([string] $Folderpath,[string] $filename, [string] $Data) {
$Files=Get-ChildItem $Folderpath -include $filename -recurse | Select-String -pattern $Data | group path | select name
return,$Files
}
$configFiles= GetFileContainsData "C:\MyApplication" "web.config" "localhost"
Foreach ($file in $configFiles) { Add-Content -Path "Filelist.txt" -Value $file.Name}
This script writes all the filename which contains the string "localhost" into Filelist.txt.
I would like to find more than one string. If i pass an array
$stringstofind=("localhost","$env:ComputerName")
Foreach ($strings in $stringsToFind) {
$configFiles= GetFileContainsData $Installpath "web.config" $strings
Foreach ($file in $configFiles) { Add-Content -Path "Filelist.txt" -Value $file.Name}
}
It will look for each string in array with the list of files and update it. If the same file has both the strings , it will have 2 entries of that file in Filelist.txt.
Is it possible to find more than one string in a file and list out the name of the file? [so that redundant entry of file name may eliminated]
Actually, Select-String accepts a string[] as parameter for -Pattern, so you do not need the loop.
You could then use Get-Unique to remove duplicates.
In fact, Select-String also accepts a list of files as path, so you could do something like this:
Get-ChildItem $FolderPath -Include $Filenames -Recurse | Select-String -Pattern $StringsToFind | Select-Object path | Sort-Object | Get-Unique -AsString
Replacing the function and the loops in one line
EDIT: The final working version is
$Files=Get-ChildItem $Folderpath -include $filename -recurse | Select-String -pattern $Data | group path | select name |Get-Unique -AsString
The following script will solve the problem i had. Thanks for carlpett's useful inputs
<#
.NAME
Get-FilenameHasString
.SYNOPSIS
To search strings in file and return the filenames.
.DESCRIPTION
This script will be useful to find strings in list of files.
It will eliminate the duplicate filenames
.PARAMETER Filenames
This parameter will be having filenames where the string needs to be searched.
.PARAMETER FolderPath
This parameter will be having folder where it will look for the filenames
.PARAMETER StringsToFind
This parameter will be having the strings to be searched
.EXAMPLE
.\Get-FilenameHasString -Filenames "Web.config" -FolderPath "C:\Program Files (x86)\MyProj" -$StringsToFind ("$env:ComputerName","localhost")
To get the list of web.config files which is there in Folder path having StringsTofind. The result will be saved in Filelist.log by default.
#>
Param (
$Filenames="web.config",
$FolderPath="C:\Program Files (x86)\MyProj",
$StringsToFind=("$env:ComputerName","localhost"),
$Logfile="FileList.log"
)
$configFiles= Get-ChildItem $FolderPath -Include $Filenames -Recurse | Select-String -Pattern $StringsToFind | Group path | select name | Get-Unique -AsString
Foreach ($file in $configFiles) { Add-Content -Path $Logfile -Value $file.Name}