Scheduled Powershell Moves to Specific Folders - file

Thanks for viewing my question. I was unable to find any information online in regards to my question. I also have very basic experience in this area.
PowerShell Script:
-Query folder for files (list?)
-Move file based on filename to folder with same name. (Move with pipe to query?)
-Move will also parse second part of file name to include subsequent matching folder name for destination folder.
Files will contain many separate names so the move has to be on a loop.
Ex. File - "Name 1"
Scripts excutes moves file to folder with "name" then to subfolder "1".
Just to be clear there will be multiple names and numbers so multiple destination paths. Basically every file will have a different destination but the destination will correlate to the file name. If there is a language more accessible for this function please let me know.

Something like the following will get you started
$files = Get-ChildItem -File
foreach($f in $files) {
$dirname = $f -split " " -join "\"
New-Item -ItemType Directory -Path ".\$dirname"
Move-Item $f $dirname
}

Related

Batch replacing text within .xml files within a zip archive through powershell

I've posted this question before, yet was not able to find a suitable solution for my problem, hence I have been testing some more myself and have some new findings and theories as to why It might not work as intended. I hope a respectable time has passed for me to bump my question with new info attached.
I am for quite a while, in my free time, tackling a script that can batch replace external link addresses in multiple excel files within script folder. I have learned, that you can't change external links via usual powershell to excel interaction, as these values are forced to read-only. However, there is a clever way to bypass that by converting the Excel file to a .zip archive and read/change the files inside and then rename it back to excel format.
Through learning and digging around the web, I have compiled this script function that should create a backup, rename to archive and then replace desired text within, renaming the file backwards afterwards.
function Update-ExcelLinks($xlsxFile, $oldText, $newText) {
# Build BAK file name
$bakFile = $xlsxFile -ireplace [regex]::Escape(".xlsb"), ".bak"
# Build ZIP file name
$zipFile = $xlsxFile -ireplace [regex]::Escape(".xlsb"), ".zip"
# Create temporary folder
$parent = [System.IO.Path]::GetTempPath();
[string] $guid = [System.Guid]::NewGuid();
$tempFolder = Join-Path $parent $guid;
New-Item -ItemType Directory -Path $tempFolder;
# Uncomment the next line to create backup before processing XLSX file
# Copy-Item $xlsxFile $bakFile
# Rename file to ZIP
Rename-Item -Path $xlsxFile -NewName $zipFile
# Not using Expand-Archive because it changes the ZIP format
C:\7z\7za.exe x "$zipFile" -o"$tempFolder"
# Replace old text with new text
$fileNames = Get-ChildItem -Path $tempFolder -Recurse -Force -Include *.xml,*.bin.rels
foreach ($file in $fileNames)
{
(Get-Content -ErrorAction SilentlyContinue $file.PSPath) |
Foreach-Object { $_ -replace $oldText, $newText } |
Set-Content $file.PSPath
}
# Changing working folder because 7Zip option -w doesn't work
Set-Location -Path $tempFolder
# Not using Compress-Archive because it changes the ZIP format
C:\7z\7za.exe u -r "$zipFile" *.*
# Rename file back to XLSB
Rename-Item -Path $zipFile -NewName $xlsxFile
}
So far, I am able to find the desired file, rename it to .zip, extract it to a temporary folder, and according to the powershell window prompts, it updates the archive with new files. Afterwards I am left with the .zip file without any desired changes inside. The files that are responsible for external links data in the excel files are located at
wk33\Gross Qty_wk33.zip\xl\externalLinks\_rels
and are presented in the form of files named externalLink1.bin.rels and numbered onwards.
These files are essentially identical to a .xml file and are opened with either Notepad or Internet explorer through windows and contain the following:
The aim of my script is to rename the week number within "Target=" parameters from last week to current (For example wk32 to wk33). The thing is that no changes happen even though no errors are displayed, and 7zip indicates that files are packed into the zip successfully.
I have tested what happens, If I unpack the .bin.rels file and change the week number inside manually through notepad and repeat the intended script process and I can confirm that it works. When I open the file the link is correctly updated.
The last 4 steps seem to be not working as intended, even though they are correct as far as I am aware. The changes are not made and the file is not consecutively renamed back to its original .xlsb extension.
Here is the output of my powershell window upon trying to execute the function:
I've been trying for several weeks to make it work, but nothing substantial can be changed as it seems. I would appreciate any additional insights or alternatives to my code to achieve the same task.
EDIT: The function is intended to be called upon from within the working directory, so it is supposed to be used as Update-ExcelLinks 'Gross Qty_wk33.xlsb' 'wk32' 'wk33' Although I have tried calling the file via its full path as Update-ExcelLinks 'C:\Test\Gross Qty_wk33.xlsb' 'wk32' 'wk33'

How to parse / pass lines from a text file to a program to be run using that string

I use an old program that went out of business, it creates a folder and inside of that "root" folder it creates other folders inside of that folder it creates a rar file of the output from the program that ran.
Root
Folder
zipfile
Folder
zipfile
Note that inside of the Root is where there are over 400 folders and each has a zip file inside I need to unrar.
The folder is based on time it was run and this program runs anywhere from 2 times per minute to 6 times a minute so it creates a new folder in the "root" folder based on the time it ran.
To see the information, I need to unrar the file it made in that folder.
Problem, I have over 400 folders inside of a central folder, that has to have all the files unrared to the folder they are currently in.
I know WinRar has an unrar here function, and I have generated a text file that has the directory listing of each folder I need to unrar. One folder per line.
Basically I need a batch file that will go to each folder, do a unrar here and move on to the next folder.
Any help available? I am on a Win10 Home system and have my registered version 5.80 of WinRAR. I am not a Powershell user, I am learning it starting today, I did use PowerShell to generate the txt file with the directory listing though.
(Get-ChildItem -Recurse -Filter "zip").FullName | Out-File d:\pattern.txt
So I am not totally clueless.
Thank you.
Responding to Campo, I use WinRar to handle Zips as well as Rars, I do not find I need a zip extractor when I have WinRar installed.
The reason I asked about the extension in my comments is because you said that you'd already used powershell to create a filelist using Get-ChildItem, and wanting to start learning it.
As you said you were using PowerShell in Windows 10, I expect that you have, PowerShell v5.0+. This therefore, is a single line for a PowerShell script or to enter directly at the PowerShell Prompt, which should unzip each of your .zip files directly without introducing a third party utility, like WinRAR.
Please change the -Path string according to your specific location.
Get-ChildItem -Path "C:\Users\Frank\Root" -Filter "*.zip" -File -Recurse | ForEach-Object { Expand-Archive -Path $_.FullName -DestinationPath $_.DirectoryName -Force }
You didn't clarify whether you wanted to delete the zip file once you've unarchived it, so if you want that functionality, for the purpose of this exercise you could simply append a deletion command:
Get-ChildItem -Path "C:\Users\Frank\Root" -Filter "*.zip" -File -Recurse | ForEach-Object { Expand-Archive -Path $_.FullName -DestinationPath $_.DirectoryName -Force; Remove-Item $_.FullName }
Please note that the example is only a starting point for you. When you learn more, you can add robustness to it, to prevent for example, deleting a zip file if its extraction failed, and perhaps what to do in the event of errors etc.

Using RegEx to match characters between two symbols and copy it to a location

I have directory of files and my goal is matching a 5 digit zip code and copying it to another set of specific folders.
I know there are a number of ways to do this but sometimes the zip code shows up twice in the file name so I have to match the zip code in between ^ and % such that the entire filename is like: mjn22182aguygbc^12350%abc.pdf.
Another assumption is the destination location has preset folders named the zip code such as: d:\queries\12350.
My goal is to move mjn22182aguygbc^12350%abc.pdd to d:\queries\12350 if the zip code exists in some list i can read in and if it is not part of the zip codes, the file stays in the source folder.
So far I have the following but the all files are being copied into my root destination folder and not the folders that I've created eg 12350 and I'm having trouble :
$dstpath = "D:\queries"
$filterlist = #("12350","90182")
$fileList = Get-ChildItem -Path $srcpath -Force -Recurse
foreach ($currentfile in $fileList)
{
foreach($zip in $filterLists)
{
$currentzip = $currentfile.Name -match '(?<=\^)[0-9]+(?=%)';
if($currentzip -in $filterlist)
{
Move-Item -Path $($file.FullName) -Destination $dstpath
}
}
}
The regex is right, but all -match does is return true.
'mjn22182aguygbc^12350%abc.pdd' -match '(?<=\^)[0-9]+(?=%)'
True
The match would be contained in $matches.0 afterwards.
$matches.0
12350
You're moving to $dstpath. There's no reason it would go anywhere else.

PowerShell script to create folders and then modify creation date from csv

I would like to create a PowerShell script that can import a CSV file (details.csv) with two headers (FileName and FileCreationTime). Ideally, the script would look for details.csv in the current location the script is saved.
It would create folders in the script's current location with the same name as FileName, and the creation date of said folder would then be changed to match FileCreationTime.
Example chunk of my CSV [made in A & B columns of Excel then saved as CSV (comma delimited)(*.csv)]:
FileName FileCreationTime
Alpha 5/17/2017
Bravo 12/23/2013
Charlie 11/8/2015
I have been searching for a solution, but nothing I do seems to be quite right. I currently have this:
Import-Csv -Path 'K:\Users\eschlitz\Thesis\details.csv' -Delimiter "," |
ForEach-Object {
$path = 'K:\Users\eschlitz\Thesis'
# Again, didn't want a definite path here, but I was trying different
# tweaks to see if I could get at least one instance to work correctly.
New-Item -Path $path -Name $$_.Filename -Type Directory
(Get-Item $_.Filename).CreationTime = (Get-Date $_.FileCreationTime)
}
My current error message:
Get-Item : Cannot find path 'K:\Users\eschlitz\Thesis\Alpha' because it does not exist.
I do not care about whether or not the hh:mm:ss part of the creation time is edited for the new folders, but it would be a bonus if I could standardize them all to 12:00:00 AM.
~~~~~~~~~~~~~~~~~~~~~~~Question Duplication Edit~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suggested edit to show how my question is different from PowerShell: Change the timestamp (Date created) of a folder or file
Everything that I was able to find related to this did either only A)create folders from a CSV, or was B)script to edit the creation date of a single folder / or batch edit the creation date of multiple folders but only with a single new creation time. I wanted the script to hopefully fail if it would be unable to correctly find the new creation time unique to each new folder, thereby eliminating the need for me to manually delete wrong folders or edit the creation time manually.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Edit~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Just wanted to post the complete, working versions in case anyone needs them in the future.
#Adds folders to specified directory and modifies their creation date
Import-Csv -Path 'K:\Users\eschlitz\Thesis\details.csv' -Delimiter "," |
ForEach-Object {
$path = ' K:\Users\eschlitz\Thesis'
$dir = New-Item -Path $path -Name $_.Filename -Type Directory
$dir.CreationTime = [DateTime]::ParseExact($_.FileCreationTime,
'M\/d\/yyyy', [Globalization.CultureInfo]::InvariantCulture)
}
And a slightly different version depending on needs:
#Adds folders and then modifies their creation date where script+csv
#currently are
Set-Location -Path "$PSScriptRoot"
Import-Csv -Path ".\details.csv" -Delimiter ',' |
ForEach-Object {
New-Item -Path "$PSScriptRoot" -Name $_.FileName -Type Directory
(Get-Item $_.Filename).CreationTime =
([DateTime]::ParseExact($_.FileCreationTime, 'M\/d\/yyyy',
[Globalization.CultureInfo]::InvariantCulture))
}
The folder is not created b/c you have a typo in the New-Item statement ($$_.Filename → $_.Filename), and even if it were created Get-Item most likely wouldn't be able to find it, because it's looking in the current working directory, whereas you create the folder in $path. You can avoid the latter issue by capturing the DirectoryInfo object that New-Item returns in a variable:
$dir = New-Item -Path $path -Name $_.Filename -Type Directory
$dir.CreationTime = (Get-Date $_.FileCreationTime)
You may also need to actually parse the date string into a DateTime value (depending on your locale):
[DateTime]::ParseExact($_.FileCreationTime, 'M\/d\/yyyy', [Globalization.CultureInfo]::InvariantCulture)
If you defined the date in ISO format (yyyy-MM-dd) Get-Date should be able to digest it regardless of the system's locale.

How to batch rename files to new name listed in Excel using Windows commands?

I have a lot of files that I need to rename.
The current filename is typical like 10002414892.PDF.
The new name is a document number typical 170668-R-UP011-VA01-0205.
No number sequence just a lot of different titles.
I have a two column list in Excel with the current file name and the new file name.
I need a command to rename the file from the current file name to the new file name.
I would use powershell but save the excel file as a CSV, the command for rename is
Rename-Item test.txt new_name.txt
then the load cmd is something like
$FilePath = "C:\Files\NewFileList.csv"
$serverList = Import-Csv $FilePath
-Header "OldName","NewName"
$serverList | where {$_.OldName -like ".PDF" } | Rename-Item OldName NewName

Resources