PowerShell Move Files with specific names - powershell

I need a PS script that can copy specific files from one directory to another.
Main Goal: I want to copy all files from Month folder (November) to DirectoryX. HOWEVER,I only want to move the files with specific names from an .xlsx file with the column named FileName. So say there are 3,000 filesnames in the .xlsx file with unique filenames. This is a monthly report that is generated from SSMS.
Process: .xlsx file is created with data. The column for the filenames is FileName. I want to cross reference those filenames with the November folder and copy those files to a new directory to upload to the client.
Folder Structure:
Year: 2022
Month: 11
Day: 09
File Naming Convention: CA09a37ce4c69f31997c8656df274749c4.mp3.
Not sure the best way to do this. I have looked around on here and nothing that really suits what I need.
I really hope this makes sense and someone can guide me in the right direction. Thank you so much in advance.
We use an in-house application. I can add a PS script to it. I am brand new to Powershell so this is more complex than what I can handle.

Install the ImportExcel module, then this should work if you update the paths:
# import the FileNames column from excel file
$FileNames = Import-Excel 'C:\folder\file.xlsx' | Select -ExpandProperty FileName | Sort
# specify folder(s) to search
$Month = '11'
$SearchFolder = "C:\SourceFiles\2022\$Month" # all days in month
# get the list of existing source files, filtered by the imported file names
$SourceFiles = Get-ChildItem -Path $SearchFolder -Recurse -File |
Where Name -In $FileNames
# optionally check for missing files
$MissingFiles = Compare-Object $SourceFiles.Name $FileNames
If ($MissingFiles) {
Write-Warning "Could not find $($MissingFiles.Count) source files in $SearchFolder"
$MissingFiles.InputObject
}
# copy files to separate folder
$SourceFiles | Copy-Item -Destination "C:\Uploads\"
It's not the most efficient thing, but it should be easy enough to modify as needed

Related

Copy latest files based on datestamp in filename from various directories

I am trying to write a Powershell script for a small problem I am having.
I have various log files in various directories. These log files are related to various other computers, and a new batch of these files are added every so often. These files have timestamps within the filename.
For example:
index\1\computer1_system_01122022.evtx
index\2\computer1_system_01122021.evtx
index\3\computer2_system_01122022.evtx
index\4\computer2_system_01122021.evtx
Note: date is ddMMyyyy
I am trying to write a script that can go into the 'Index' directory, look for all files containing "system", then only selecting the latest file based on the datestamp in the filename.
So for the above example, only copy the following to another directory (i.e. index\latest)
index\latest\computer1_system_01122022.evtx
index\latest\computer2_system_01122022.evtx
I hope I have described the problem clearly enough. I have tried various things, but can't figure this one out.
Any help would be much appreciated.
What I have tried so far:
I have not come up with any script for this so far, I am fairly new to powershell. I have to used .indexof to separate the datestamp, and then sort and select the newer one. But this results in the script selecting only the newest file, and discarding the files for other computers. I can't think of a way to make powershell only compare the datestamp of the two 'computer1' files and selecting the newer ones, and then two 'computer2' find and selecting the newer one, and so on.
So to clarify, the script should compare 'computer1' with all other files that contain 'computer1' and select the newer one based on the datestamp in the filename. Then, compare 'computer2' and select the newer one, then 'computer3' and so on.
Each of these selected files should be copied to a new directory.
Note: the latest datestamp on computer1 may be different from the latest datestamp on computer2. I.e. newest computer1 file may be named computer1_01122022.evtx and computer2 may be computer2_02022022.evtx. comparison of computer1 should only be with other files that contain computer1, and computer2 files should only be compared with other computer2 files.
This is part is a larger script that is being used to extract log data from files. I have written a script to extract the data, but cannot figure out what to do to get the latest log files out from the folders as described above.
Combine Group-Object with Sort-Object, using calculated properties:
# Simulate Get-ChildItem output.
[System.IO.FileInfo[]] $files =
'index\1\computer1_system_01122022.evtx ',
'index\2\computer1_system_01122021.evtx',
'index\3\computer2_system_01122022.evtx',
'index\4\computer2_system_01122021.evtx'
$files |
Group-Object { ($_.BaseName -split '_')[0] } | # group by computer name
ForEach-Object { # for each group of computer-specific files
# sort by timestamp embedded in the file name and output the most recent
$_.Group |
Sort-Object -Descending {
$dateStr = ($_.BaseName -split '_')[-1]
[datetime]::ParseExact($dateStr, 'ddMMyyyy', [cultureinfo] '')
} |
Select-Object -First 1
}

Powershell: How to copy files from one Directory to another

I am looking to copy a series of files from one directory to another. Essentially the files are a series of zip folders that are simply changed versions of programs. The files will be named something like: test_1_092.zip in the source directory and test_1_091.zip in the target directory. I don't want the script to look at the numeric portion of the folder, simply the name.
Please forgive my lack of knowledge as this is my first foray into powershell scripting. Any thoughts or need more info?
Something to start with
(Get-ChildItem -Filter "*.zip").Name | where {$_ -like 'test_1_*'} | Move-Item -Destination .\1 -Force -WhatIf
Please confirm the output from –whatif , then remove it to perform the action.
For the relation between the new and old name, please provide some more information.

Renaming files from a text list using powershell

I have seen many different postings here on how to approach this task. I have tried them all with minor variations of them to no avail. Every time I run the powershell code, I still get the same error message: "cannot rename because the file does not exist..."
I just simply want to rename a bunch of files in one folder from the list of filenames I have in a text file.
Here is one version of code:
$inputFile1=#()
$filesTochange=#()
$inputFile1 = get-content H:\dev\outputfile.txt
$filesToChange = Get-ChildItem H:\dev\extractedFiles1 | Foreach -Begin
{$i=0}
-process {Rename-Item $filesToChange[$i] -newName ($inputFile1[$i] -f $i++)
}
Here is another version:
$inputFile1=#()
$filesTochange=#()
$inputFile1 = get-content H:\dev\outputfile.txt
$filesToChange = Get-ChildItem H:\dev\extractedFiles1
$i=0
foreach ($fil in $filesToChange) {Rename-Item $fil -NewName
$inputFile1[$i++]}
Not entirely sure what's your setup or desired output is but give this a whirl bud. Not the most elegant looking solutions but hopefully this is what you are looking for? Do be mindful with the sorting of the filenames in your outputfile.txt and how the folders are listed when you get the childitem.
$BasePath = 'C:\Test'
$FilesToChangeFolderName = 'extractedFiles1'
$filestochange = Get-ChildItem -Path "$BasePath\$FilesToChangeFolderName"
$FileNames = Get-Content "$BasePath\outputfile.txt"
if($filestochange.FullName.Count -eq $FileNames.Count)
{
for($i=0; $i -lt $FileNames.Count; $i++)
{
write-host "Renaming file $($filestochange.Name[$i]) to $($FileNames[$i]+".txt")"
Rename-Item -Path $filestochange.FullName[$i] -NewName ($FileNames[$i]+".txt")
}
}
Setup -
outputfile.txt contains:
renametoA
renametoB
renametoC
renametoD
renametoE
renametoF
Folder structure:
Results:
Renaming file renameto1.txt to renametoA.txt
Renaming file renameto2.txt to renametoB.txt
Renaming file renameto3.txt to renametoC.txt
Renaming file renameto4.txt to renametoD.txt
Renaming file renameto5.txt to renametoE.txt
Renaming file renameto6.txt to renametoF.txt
Explanation [TLDR]:
The script below takes a text file input which contains the name that should be used to rename each text file you have.
Example:
outputfile.txt file contains the names below:
renametoA
renametoB
renametoC
renametoD
renametoE
renametoF
There are 6 text files inside the "extractedFiles1" folder which you can see in the image.
The script actually renames the files in the "extractedFiles1" folder according to the names from the output.txt file.
Thus it follows this logic:
Renaming file renameto1.txt to renametoA.txt
Renaming file renameto2.txt to renametoB.txt
Renaming file renameto3.txt to renametoC.txt
Renaming file renameto4.txt to renametoD.txt
Renaming file renameto5.txt to renametoE.txt
Renaming file renameto6.txt to renametoF.txt
So after all the script runs your "extractedFiles1" folder's gonna look something like this:
Despite this being an older thread, I wanted to offer another "brute force" option.
CodeNagi's reply works well in PowerShell, although it took me a bit to get working.
If you already have a list with file names (output.txt) consider using excel (or OpenOffice) and the command prompt cmd.
This video is a step by step guide for some of this solution:
https://youtu.be/znhqGrF4gVQ
Open cmd with administrator privileges.
Create a list of your current (old) file names:
cd H:\dev\extractedFiles1
dir > input.txt
Open the input.txt (e.g. in Notepad). It should look like this:
Volume in drive H is Windows
Volume Serial Number is C123-4567
Directory of H:\dev\extractedFiles1
05/12/2022 11.24 .
05/12/2022 11.24 ..
05/12/2022 09.34 5,255,248 Filename1.txt
05/12/2022 09.34 5,255,952 Filename2.txt
...
Copy the lines with filenames and timestamps into an Excel sheet
Use Data > Text to columns to split the filenames from the time stamps
Copy or import your target/new filenames from output.txt next to the old filenames
Make a new column with the formula
= "ren"&" "&A1&" "&B1
resulting in something like
ren Filename1.txt FilenameA.txt
Copy all formulas and paste them in cmd. Make sure you are in the right directory.
Notes: If you have spaces in the file names, you will need to wrap each file name first in apostrophes ". Since the concatenation formula in excel doesn't accept """ (triple apostropes), make yourself a column with only " (here C) and then refer to it in the concatenation: = "ren "&C1&A1&C1&" "&C1&B1&C1&.
Further, if you have duplicate files or want to make sure they are copied correclty, you can use the MOVE function instead of rename (ren).
Instead of point 6. above do the following:
Make a new column with the formula
= "MOVE"&" "&A1&" "&"H:\dev\extractedFiles1\Renamed"&B1
Copy the created command into cmd
It will move and rename the files according to the names in B1.
This example make a copy and rename file to a list csv
Import-CSV LISTA.csv -Header newFileName | % { Copy-Item -Path archivo_convert.pdf -Destination "$($_.newfilename).pdf" }

Zipping folders in powershell

Hope fellow scripters can help with this one :) Been breaking my head around the problem for few hours now.
I'm trying to zip up certain folders using powershell.
My folder structure is
Backups
BoxIntranet
Components
Content
Database
Exec
Files
Logs
Multibrowser
Multibrowser\Legacy\Customisation
Packages
ParentPortal
ParentPortal\customisation
StudentPortal
StudentPortal\customisation
Update
WebDav
There are a lot more files and folders in every one of the above but these are the ones I'm mainly interested in.
I am trying to zip it all up using either Write-Zip or Compress-Archive methods in PowerShell but my conditions are.
Only Content, Files, Database folders should be zipped from root
Multibrowser\Legacy\customisation, StudentPortal\Customisation and ParentPortal\customisation folders should also be backed up.
Folder structure should remain the same in the zip file meaning that Root of the zip file should have Content, Files, Database, Multibrowser, ParentPortal and StudentPortal folders. Whilst Content, Files and Database folders should have everything zipped up, Multibrowser, ParentPortal and StudentPortal folders should only have the specified sub directories and all files within them.
Code:
$FilesAndInclude = #("Content", "Files", "Database", "Multibrowser\Legacy\customisation",
"StudentPortal\customisation", "ParentPortal\customisation",
"BoxIntranet\customisation")
$FilesToExclude = #("connectionstrings.config", "inc_dbconn.asp")
Get-ChildItem -Path "C:\Folder" -Include $FilesAndInclude -Recurse -Exclude $FilesToExclude|
Compress-Archive -DestinationPath "Archive.zip"
I've tried the above and it doesn't do anything however if I remove the -Include parameter then it zips up everything however doesn't retain folder structure.
Is there any way to complete what I am after within powershell?
Ok, first things first, the reason that you are having a hard time using the -Include parameter is because it is designed to exclusively include only the things you specify. As such, it will look at the name of things (not their path), and check against the list and if it matches something in the list it will include that item. Since you only list folder names it is only including those folders (but not their contents). So you aren't getting any files passed down the pipe this way. To get around that you'll need to build your file list first, then pipe it to the cmdlet to zip things up.
Next issue is that Compress-Archive doesn't store path info, so you'll need to use Write-Zip. I have included what I think you would want for that cmdlet.
$FilesAndInclude = #("Content", "Files", "Database", "Multibrowser\Legacy\customisation",
"StudentPortal\customisation", "ParentPortal\customisation",
"BoxIntranet\customisation")
$FilesToExclude = #("connectionstrings.config", "inc_dbconn.asp")
[array]$FilesToZip = Get-ChildItem .\* -Exclude $FilesToExclude -File
$FilesToZip += $FilesAndInclude | ForEach{Get-ChildItem .\$_ -Exclude $FilesToExclude -File}
$FilesToZip | Write-Zip -EntryPathRoot $(Resolve-Path .\|Select -Expand Path) -OutputPath Archive.zip

Comparing File Names with different extensions using Powershell

I want to compare files with same name but with different extensions present in the same directory.
Example: There are 6 files at a location.
1234.pdf
1234.xml
abcd.pdf
abcd.xml
5678.pdf
efgh.xml
I want to compare all the .pdf/.xml files with the files with .xml/.pdf extension which have a same name and find out if any of the .pdf or .xml file is missing like here in the above example the 5678.xml file is missing and efgh.pdf file is missing.
I tried to copy all the .pdf files in a text file and all the .xml files in another text file and tried comparing the strings within them but it isn't working.
Can anyone please let me know how can i compare the file names with different extensions?
Push-Location "\\Cifintgfsfs001\gfs\MXPDFXML\Data\Test"
Get-childitem *.xml | ForEach {
if (!(test-path "$($_.BaseName).pdf")){
"$($_.BaseName).pdf missing"
}
}
Get-childitem *.pdf | ForEach {
if (!(test-path "$($_.BaseName).xml")){
"$($_.BaseName).xml missing"
}
}
Pop-Location