How to save Filename and Modified Date to .txt filein PowerShell v3.0 - batch-file

I am trying to convert my batch file syntax to PowerShell v3.0. I need to pull all the file names from a mapped network drive and save it to a folder on my root C:
Everything works except when it comes to saving the file names. If I do
dir /s > C:\2\filename.txt
In a batch file it will output the file's name (along with the extension) and the date modified to a .txt file. However I cannot get the PowerShell v3.0 equvalent to work. It just creates a txt file but nothing is saved within the file. Here is my PowerShell v3.0 code.
Get-ChildItem -Path K:\Transactions\Processed\Audit-Images\Lane` 12\$date\done > C:\2\$date-LaneServer12ImagesDONE.txt

In the examples below, you may want to add some parameters to Get-ChildItem depending on what you're looking for. "-Force" to have it list hidden files, "-Attributes !Directory" to exclude directory names.
I would find the output most useful in a csv.
Get-ChildItem -Path K:\Transactions\Processed\Audit-Images\Lane` 12\$date\done -Recurse | Select-Object Name,LastWriteTime | Export-CSV "C:\2\filename.csv"
Same line, in a text file:
Get-ChildItem -Path K:\Transactions\Processed\Audit-Images\Lane` 12\$date\done -Recurse | Select-Object #{n='File';e={$_.Name + " " + $_.LastWriteTime}} | Out-File "C:\2\filename.txt"

Related

Search multiple text files for string and copy line by appending it to summary_[date].log

I'm trying to search through a number of log files with different filenames. I want search for a hostname in each log and when a match is found have it copy that entire line to summary_[date].log and keep appending matching lines to it. So something I've started with is:
$captured = Get-ChildItem -recurse -Path \\nas1\share1 -Include *.log |
where { ($_.Name | Select-String -pattern ('PC1','PC2','PC3') -SimpleMatch) }
Now copy the line from each log file which contains the pattern and append it to a file with today's date stamp, so each week I'll have a file like \\nas1\share1\summary_03-07-2020.log
But this is not quite what I want as this will capture the filenames and append them to the $captured variable. It's also missing the code to copy any matching lines to a date stamped summary_[date].log
Each text file will contain, among other lines that start with a time stamp, something like this:
03-07-2020_14-36-17 - Backup of computer [PC1] is successfully
created.
So what I want is to search several text files on a share for several hostnames. If a text file contains the hostname have it append the line which contains the hostname to summary_[date].log. Lastly, since the matching lines will all start with a date/time stamp I need to keep the contents of summary_[date].log file sorted from newest date to oldest.
Essentially I should end up with a summary_[date].log every week that will look similar to this:
03-07-2020_14-36-17 - Backup of computer [PC1] is successfully created.
03-07-2020_13-21-12 - Backup of computer [PC3] is successfully created.
03-07-2020_11-36-29 - Backup of computer [PC2] is successfully created.
By doing this I get a summary of all log files from that day in a single file which I will then automatically email to a specific email address.
How do I accomplish this?
Your current code selects a string from the file name, not the content.
To do what you are after, you can use simething like this:
$logFolder = '\\nas1\share1'
$outFile = Join-Path -Path $logFolder -ChildPath ('summary_{0:dd-MM-yyyy}.log' -f (Get-Date))
$captured = Get-ChildItem -Recurse -Path $logFolder -Include *.log | ForEach-Object {
($_ | Select-String -Pattern 'PC1','PC2','PC3' -SimpleMatch).Line
} | Sort-Object # sorting is optional of course
#output on screen
$captured
# output to new log file
$captured | Set-Content -Path $outFile
Next send this file as attachment like:
# use splatting for cmdlets that take a lot of parameters
$params = #{
SmtpServer = 'yourmailserver'
From = 'logtester#yourcompany.com'
To = 'someone#yourcompany.com'
Subject = 'Summary'
Body = 'Hi, in the attachment a summary of the backup logs'
Attachments = $outFile
# etc.
}
Send-Mailmessage #params
How big are your log files?
This will work but it loads the entire content of all files into memory and maybe inefficient with large file and/or a large number of files.
If there is a large number of files or large files you could do some nested foreach loops and loop through each computer name for each file.
This also uses match rather than like in where-object, you can use. like if you get false positives.
$FileContent = Get-Content -Path "\\nas1\share1\*.log"
$ComputerArray = 'PC1','PC2','PC3'
$DateStamp = get-date -Format dd-MM-yyyy
$OutFile = 'summary_' + $DateStamp + '.log'
foreach ($ComputerName in $ComputerArray)
{
$FileContent | Where {$_ -match $ComputerName} | Add-Content -Path $OutFile
}

Search Directory for folders

I am trying to create a batch file that I can use to type in a name of a folder and search multiple directories, then display the results in a new window. Example: I want to search for "tcash" in 3 separate directories, ie; \vm-xa01\users, vm-xa02\users and vm-xa03\users. How can I do this?
The original question had Powershell tag, so the answer is Powershell. For cmd (batch) script, I'd strongly suggest you to move into Powershell anyway. It's 2018 and cmd scripts require lots of tweaking.
In Powershell, there's a built-in cmdlet Out-GridView that might be suitable. For example, to display all txt files in c:\some\path and its subdirectories requires just a few commands. Like so,
gci c:\some\path -Recurse | ? { $_.extension -eq ".txt" } | ogv
First off, get a recursive list of all files
gci c:\some\path -Recurse
Then select those that have extension .txt
| ? { $_.extension -eq ".txt" }
Finally, pass the results to out-gridview aka ogv
| ogv
I also think PowerShell is the better script language for your task.
You can do a dir/Get-ChildItem with ranges [1-3] similar to a Regular Expression, so:
Get-ChildItem "\vm-xa0[1-3]\users\tcash" -File -Recurse | Out-Gridview
should enumerate all matching files and display in a gui window.

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

How to judge certain type of files(suce as csv file) exist using powershell?

I need a function to delete all the csv files in a folder A, if there is csv files in folder A , then delete all the csv files(actually, I don't know the exact csv files' name in folder A);
if there is no csv file in folder A , then do nothing.
I have searched a topic about removing mp3 files:
Powershell - Delete all non mp3 files
then I take the example out and below is the cmdlet that delete my csv files in folder A :
Get-childitem -Recurse | Where-Object {$_.Extension -eq '.csv'} |
Remove-Item -whatIf
but there is a problem , when there is no csv files in folder A , when excuting above cmd will cause error. I just don't know how to judge if csv file exists, anyone else can help? thx very much.
You can simply add -ErrorAction to remove-item to skip the error:
Get-childitem -Recurse | Where-Object {$_.Extension -ne '.csv'} |
Remove-Item -ErrorAction SilentlyContinue
Use an if construct to test if a condition is true before executing the deletions:
if(gci c:\folderA -filter *.csv){do-something}
If the statement between the parentheses returns false, the code between the curly braces is not executed.

Resources