I am building out a batch file that takes a zip archive which is uploaded nightly and unzips the contents and puts it in a specific folder.
Currently, I am generating a temporary folder named "tmpExtract". Once the files are extracted, I want to rename "tmpExtract" with yesterday's date. Preferably in MM-DD-YYYY format.
I was able to locate a PowerShell command to get yesterdays date, however, I am stuck at the part where I can rename the directory to yesterdays date.
PowerShell $date = Get-Date; $date=$date.AddDays(-1); $date.ToString('yyyy-MM-dd')
The full directory that I am using:
Y:\\Archive\TestFolder\Recordings\tmpExtract\
The full directory that I am looking for once the rename has completed: Y:\\Archive\TestFolder\Recordings\06-09-2021
I am open to either PowerShell or Batch/CMD. Whichever works best!
Based on Theo's response I found the following code to work best
powershell Get-Item -Path 'Y:\Archive\TestFolder\Recordings\tmpExtract' | powershell Rename-Item -path 'Y:\Archive\TestFolder\Recordings\tmpExtract' -NewName ('{0:dd-MM-yyyy}' -f (Get-Date).AddDays(-1))
I needed to add powershell and -Path 'Y:\Archive\TestFolder\Recordings\tmpExtract' to the second part of the string. After testing it works as intended.
Also, I was unaware that the second '' was not needed for a mapped network path.
Related
I’m trying to extract html files that automatically update from one folder to another. I am searching them by a auto generated code for every file. The files are named like : Diagnostics (2022'12'02 #1403'01''918''').html
Where the code after the # changes on every app start and close. Sometimes there a more than one file and they have the extension “p1” , “p2” ,”p3” , … “pn” and I want all the files with the # code to be taken and moved to another folder. This is what I came up with as my strategy was to take the most recent file created (which is most of the time Diagnostics (xxxxxx)pn.html and wanted to an script to copy the part from Diagnostics - xxx) and then find the other files.
$a = Get-ChildItem -Path 'C:\User\something\Temporary Files\'|Sort-Object -Descending -Property LastWriteTime | select -First 1
$b = Get-Content "C:\Users\something\Desktop\test.txt"
Echo $a
Out-File -FilePath .\test.txt|
Get-Content -Path .\test.txt
This creates a new file with the name of the file but I don’t know how to extract the useful part as a string and then search it in the directory and copy it to another folder on the desktop. This is done with Powershell as I want to make it a Bat file tha when executed does the whole process but coudnt do it with bat files only.
Thanks for the help in advance and I’m happy to join the community :)
Note: this is what the file test.txt has
Directory: C:\Users\something\Temporary Files
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---l 12/2/2022 2:09 PM 706568 Diagnostics (2022'12'02 #1403'01''918''').html
This is what I came up with
Note: this is my first time playing with .bat files and with Powershell so I understand it’s not really much but… :D
Need help with command like, one-liner, powershell to remove folders
I'm trying to find an elegant way to remove folders by folder name which reflects the date but I cannot rely on the file/folder date meta-data attributes.
Here's the problem I'm trying to solve:
I have a folder in which there are archived call recordings for each day the recording system creates folders and fills them with call recordings, a folder for each day named like format MM_dd_yyyy.
I need to remove all but the last 7 folders. But, I cannot rely on the creation/modified date on the file. That would be much easier with just powershell. So I MUST, unfortunately, remove the folders by testing the file name against the dates of the folders that I need to retain with same format (MM_dd_yyyy).
I can get the list of folder names that are to be retained base on the previous 6 days with the following Windows command line:
c:\>powershell $d0=(Get-Date).ToString('MM-dd-yyyy'); $d1=(Get-Date).AddDays(-1).ToString('MM-dd-yyyy'); $d2=(Get-Date).AddDays(-2).ToString('MM-dd-yyyy'); $d3=(Get-Date).AddDays(-3).ToString('MM-dd-yyyy'); $d4=(Get-Date).AddDays(-4).ToString('MM-dd-yyyy'); $d5=(Get-Date).AddDays(-5).ToString('MM-dd-yyyy'); $d6=(Get-Date).AddDays(-6).ToString('MM-dd-yyyy'); $d0; $d1; $d2; $d3; $d4; $d5; $d6
NOTE: I need to keep this in a command one-liner and cannot use PS1 power shell script because of corporate and domain enforced security limitations
This produces the folder names to be retained as listed below (ran on 20 NOV 2021 to retain last 7 days).
11_20_2021
11_19_2021
11_18_2021
11_17_2021
11_16_2021
11_15_2021
11_14_2021
The intention would be to remove any folder names that were like 11_13_2021, 11_12_2021... etc.
I can get away with running nested FOR loops in a Windows bat file to try and hack this together but I'm trying to find a more simple, readable and elegant one-liner that will let me do something like the following:
powershell $d=(Get-Date).AddDays(-7).ToString('MM-dd-yyyy'); and then some magic powershell stuff to remove any folder that doesn't match any of those that are to be retained.
If I had a way to provide the folder name (MM_dd_yyyy) to the (get-date).AddDays(-6) powershell command and have it return a boolean yes or no, that would be something closer to what I'm looking for.
I've been reading and you tubing and pulling hairs out but so far I'm learning but mostly making a mess of it. Any ideas are most welcome.
I'm likely approaching this all wrong. The constraints are:
Given a list of folders with naming format MM_dd_yyyy, I need to remove/delete all that are not within the last week of days.
I cannot run powershell scripts .ps1
I can run windows bat or cmd files with for loops and such
I cannot rely on the folder of files date/time meta attributes, some data in the folders may have create/write/modified dates that are not in line with the folder name. I must rely on the folder name (MM_dd_yyyy) to remove the folders.
UPDATED with resolution:
powershell "($f=Get-ChildItem -Path 'D:\PosConvSav' -Filter '*_*_*' -Directory | Where-Object { $_.Name -match '\d{2}_\d{2}_\d{4}' } | sort-object -desc)[14..($_.count)] | remove-item -recurse"
The PowerShell code for this would be:
Get-ChildItem -Path 'RootPath\Where\The\Folders\To\Delete\Are\Found' -Filter '*_*_*' -Directory |
Where-Object { $_.Name -match '\d{2}_\d{2}_\d{4}' } | # filter some more using regex -match
Sort-Object { [datetime]::ParseExact($_.Name, 'MM_dd_yyyy', $null) } | # sort by date
Select-Object -SkipLast 7 | # skip the newest 7 folders
Remove-Item -Recurse -Force # remove the rest
To play it safe, add -WhatIf to the final Remove-Item command. By doing that, the code does not actually delete anything, but show in the console what would be deleted. If you are satisfied that is correct, then remove -WhatIf to actually remove those folders.
As Olaf already commented, don't think using one-line code would be best, because what you'll end up with is code that isn't readable anymore and where mistakes are extremely hard to find.
There is no penalty whatsoever for multiline code, in fact it is THE way to go!
I am using a PowerShell script to zip up files that are older than 60 days. Some of these files have really long filenames so I get the filename or extension is too long error.
I would rather not go into each file and change the names so I need a way to be able to apply something to all the files at the same time or have my script bypass the error somehow. This script is also going to be run on several computers so I would prefer not to download something on to each one.
This is the script:
#Set source and target
$Source = "D:\Testing\"
$Target = "$ENV:USERPROFILE\Desktop\TEST.zip"
#Set time parameters
$Days = 60
$LastWrite = (Get-Date).Date.AddDays(-$Days)
#Invoke 7-zip
if (-not (test-path "$env:ProgramFiles\7-Zip\7z.exe")) {throw
"$env:ProgramFiles\7-Zip\7z.exe needed"}
set-alias zip "$env:ProgramFiles\7-Zip\7z.exe"
$Target = Get-Childitem $Source -Recurse | Where-Object -FilterScript
{($_.LastWriteTime -ge $LastWrite)}
zip a -mx=9 $Target $Source
I am using 7-zip to zip up the files and I have PS version 5.1.
As mentioned in the comments, one way around long file names is to store relative paths. 7Zip will store relative paths if you specify an input file with the relative paths and they resolve to the files you want to archive, as described in this answer.
Intermediate files can be messy, so I've written a script that uses the ZipFileExtensions' CreateEntryFromFile method to store a relative path in a zip file.
You can specify -ParentFolder on the command line to store paths relative to the parent, including a UNC path if you want to archive files on another computer. If -ParentFolder is not specified it will choose the script's folder as the parent and store paths relative to the script.
Copy the code to a new script named ArchiveOldLogs.ps1 and run it with this command line:
.\ArchiveOldLogs.ps1 -ParentFolder "D:\Testing\" -FileSpecs #("*.*") -Filter { $_.LastWriteTime -lt (Get-Date).AddDays(-60)} -DeleteAfterArchiving:$false
That will get you 11 more characters at the end of the path to store, which should be enough to get around the 10 character difference between Windows and Zip path length limits. Try a deeper folder if you still get errors. The files that can't be archived, or are already archived will be skipped.
Remove -DeleteAfterArchiving:$false from the command line when you're comfortable that it's archiving only what you want.
PowerShell File Rename Date/Time asked how to append the datetime stamp and I can see that it worked. However when I run this I end up prepending the file name with contents of $BackupFolder. I set $BackupFolder = "C:\Data1" and my files move to the C:\ with Data1 prepended to the name. I thought that $BackupFolder was the destination for the Move-Item cmdlet. What am I missing?
I was asked to write a PowerShell script that they can package in with their build updates. They will complete a build that gets dropped to a folder (say \server\build\release1.1.2). We need a script that takes all the files/folders from that folder and copies them to the appropriately named locations.
I need the script to also read the # of the current build from the folder title and create that same # build folder when it copies. Easy enough to that however I need the references to be all dynamic, so when that Release1.1.3 comes out wecan drop the same script into there and it will copy all the files to the appropriate directories (and create them if they don't exist).
This script should get you started. Run it to see an example of the values it produces.
# variable name chosen based on the automatic variable available to PowerShell Modules
$PSScriptRoot = ($MyInvocation.MyCommand.Path | Split-Path | Resolve-Path).ProviderPath
$BuildName = $PSScriptRoot | Split-Path -Leaf
#"
This script file is located at:
$($MyInvocation.MyCommand.Path)
The folder this script file is in is:
$PSScriptRoot
The name of the folder this script file is in is:
$BuildName
To copy files you might do this:
Copy-Item -Path `$PSScriptRoot\* -Destination C:\Install\`$BuildName -Recurse
"#