i want to create a .csv list of some folders in a giant directory (1400+ folders and subfolders, more than 6TB). I need to list the Fullname, creation date, last access time and last write time. Yesterday i have managed to extract some folders, but then it stopped (PC went to sleep...). The .csv that the script created got almost 1GB big, which isn't the problem. The real problem is that i don't want to list those files again.
Here is my script, that i used:
Get-ChildItem -Path P:\ -Recurse -Force -ErrorAction SilentlyContinue | Sort-Object -Property FullName,Name,CreationTime,LastAccessTime,LastWriteTime | Select-Object FullName,Name,CreationTime,LastAccessTime,LastWriteTime | Export-Csv -Path C:\...\*.csv -NoTypeInformation
I've tried some -Exclude-Parameters but that didnt work. The output file always is 0KB.
Is there a way to exclude the folders, that already got listet? The remaining 1300+ folders would be too much to insert them manually. I've tried to create a .txt list, merged them side-by-side (with Ubuntu) but that also didn't work, because of the missing backslash in the path name, like P:\folder\ (the last backslash is always missing).
The last option is to insert every path manually, which also could be automated, but i don't know how.
Related
I am an absolute noob when it comes to Powershell..
Currently I run a simple script to get a file listing across our server.
(gci -filter *.xl* -recurse).FullName > AllExcel.txt
It gives me exactly what I'm looking for, a directory path and the file name all on one line across all subdirectories.
X:\00\This file 1.xls
X:\00\This file 2.xls
X:\aaa\This file Too 1.xls
X:\aaa\This file Too 2.xls
Can I add The date/time the file was last modified for each item? {$_.LastWriteTime}?
If so, can the output be sorted by this date/time? Would prefer newest at the top if possible.
are there also options to get who last modified a file?
Instead of a simple text file, I would store the results in a structured CSV file.
Get-ChildItem -Path 'X:\' -Filter '*.xls*' -File -Recurse |
Select-Object FullName, LastWriteTime |
Sort-Object LastWriteTime -Descending |
Export-Csv -Path 'X:\Somewhere\AllExcel.csv' -NoTypeInformation -UseCulture
This will result in a structured CSV file you can open on a machine with the same regional settings as yours to open in Excel
As for who last modified the files:
You could use Get-Acl on each file and with that get the Owner, but whoever owns the file is not necessarily the one who created/modified it.
You cannot identify creator or user who made the last change in Windows unless have file and folder auditing enabled beforehand, so you can extract the information from the audit logs.
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 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.
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
in a particular folder I have files created with random name for example:
file1.xml
file2.xml
when these files are succesfully created, a .ack file is created.
So I will have
file1.xml
file1.ack
file2.xml
file2.ack
What I have to do:
Move a .xml file only if the corresponding .ack is created.
The difficult part: file names are random and I have no control over them.
Is there a way to create a .bat or a powershell to check and move with these requirements run at scheduled times?
Many thanks for your help
the ideal would be a powershell task, indeed. Now, you will want to leverage window's Scheduled Tasks in order to run it at a scheduled time.
In a nutshell, what you'll have to do with powershell is to
List the xml files in your folder with Get-ChildItem -filter "*.xml"
Pipe it to a Where-Object statement to make sure the .xml has a .ack counterpart, leveraging Test-Path
For each produced item, move the .xml file.
Move-Item -Path $source -Destination $target
Optionally, you could also clean the .ack files with Remove-Item.
Find every filename that appears with two extensions, and move them both.
gci | group basename |? Count -eq 2 | select -expand group | move -Dest c:\temp
Because it's fun not to use any loops. If you want loops, maybe: to move the XML and delete the .ack.
gci *.ack |% { move ($_.BaseName +'.xml') "c:\temp" ; rm $_ }