insert header row from bat into csv file - batch-file

I have created a bat file that creates a csv file, please see below
#echo off
echo %date%,%time%,%computername%,%username% >> %random%.csv
This produces csv file which contains the following data:
29/05/2021,15:35:31.10,PC9083,fmartin
But I need the bat file to include these headers e.g Date,Time,Host,Name if possible e.g.
Date,Time,Host,Name
29/05/2021,15:35:31.10,PC9083,fmartin
Any ideas on how to accomplish this? any info would be greatly appreciated
Many Thanks
John

If you wanted to move ahead and use PowerShell, this would work. Using -UseQuotes AsNeeded requires PowerShell Core 7+. If you remove -UseQuotes AsNeeded it will work with Windows PowerShell 5.1, but every field will be quoted.
New-Object psobject -Property ([ordered]#{"Date"=(Get-Date).ToString('dd/MM/yyyy');
"Time"=(Get-Date).ToString('HH:mm:ss.ff');"Host"=$Env:COMPUTERNAME;"Name"=$Env:USERNAME}) |
Export-Csv -Path '.\so-createcsv.csv' -Encoding ascii -NoTypeInformation -UseQuotes AsNeeded
If you must keep the code in a cmd.exe batch file script, this could be used. Use pwsh.exe for PowerShell Core 6+. Use powershell.exe for Windows PowerShell 5 or earlier.
pwsh.exe -NoLogo -NoProfile -Command ^
"New-Object psobject -Property ([ordered]#{""Date""=(Get-Date).ToString('dd/MM/yyyy');""Time""=(Get-Date).ToString('HH:mm:ss.ff');""Host""=$Env:COMPUTERNAME;""Name""=$Env:USERNAME}) |" ^
"Export-Csv -Path '.\so-createcsv.csv' -Encoding ascii -NoTypeInformation -UseQuotes AsNeeded"

Related

create a file using windows CMD and fill it with a repeated line but different value

I would like to update wireshark decode-as file with all RTP range using a CMD command or a Batch script.
The file must contain values like this:
decode_as_entry: udp.port,16384,(none),RTP
decode_as_entry: udp.port,16386,(none),RTP
decode_as_entry: udp.port,16388,(none),RTP
.
.
.
decode_as_entry: udp.port,32766,(none),RTP
As you can see, it is cumbersome to add the lines for all the RTP range manually.
So the batch script must create a text file, and add these lines one by one until value 32766 is reached.
I understand the logic of the code, that it should contain a FOR loop (for iteration), and an IF statement (to break the loop until 32766 is reached), but I am not able to build the batch file successfully as I lack the knowledge.
The comment by Compo using FOR /L works. Another way to do it using PowerShell from a cmd.exe .bat file script would be:
powershell.exe -NoLogo -NoProfile -Command ^
"(16384..32766).Where({$_ %% 2 -eq 0}) |" ^
" ForEach-Object { """decode_as_entry: udp.port,$($_.ToString()),(none),RTP""" } |" ^
" Out-File -FilePath '.\test.txt' -Encoding ASCII"
Of course, it is easier if you could run a PowerShell console or .ps1 script file.
(16384..32766).Where({$_ % 2 -eq 0}) |
ForEach-Object { "decode_as_entry: udp.port,$($_.ToString()),(none),RTP" } |
Out-File -FilePath '.\test.txt' -Encoding ASCII

How can I get a list with absolute paths, but with a specific name rule? (batch script)

i want to create a txt file, containing absolute paths for my robocopy backup. However, i only want to backup folders which have specific names in it.
This would be my source folder:
\\\fileserver\Projects
which contains folders like
20090-Miller-Georg
20094-Johnson-Susan
20097-Miller-Sarah
20125-Olston-John
20130-Johnson-Alex
....
Now here comes the tricky part: Let's say, i only want to list folders which contain e.g. Miller and Johnson, so my list would be something like this:
\\\fileserver\Projects\20090-Miller-Georg
\\\fileserver\Projects\20094-Johnson-Susan
\\\fileserver\Projects\20097-Miller-Sarah
\\\fileserver\Projects\20130-Johnson-Alex
...
In a batch script, dir does not enable this kind of sorting. Is there another way?
Here is something you can put in the .bat file script. It will produce UNC paths.
SET "BASEDIR=\\fileserver\Projects"
powershell -NoProfile -Command ^
"Get-ChildItem -Directory -Path "%BASEDIR%" |" ^
"ForEach-Object {" ^
"if ($_.Name -cmatch '-Miller-|-Johnson-') {" ^
"$_.FullName" ^
"}" ^
"}"
Of course, this is less cryptic when using PowerShell directly.
$basedir = '\\fileserver\Projects'
Get-ChildItem -Directory -Path $basedir |
ForEach-Object {
if ($_.Name -match '-Miller-|-Johnson-') {
$_.FullName
}
}

xCopy into the top folder of a directory

I running an xcopy command to transfer from one file to the other.
xcopy /s "c:\users\documents\thisfile.txt" "d:\otherfiles\1.2.1"
I'd like to be able to just copy the file into the most recent folder in the otherfiles directory rather than hard coding it every time a new version folder is created. These are versions numbers and these tend to just increase.
Is this entirely possible?
If you wanted to do this in PowerShell, it is possible. This would require PowerShell 3.0 or higher. It can be done with 2.0, but would require changes. Hopefully, you are on or can upgrade to a modern-day version of PowerShell.
When you are confident that the file will be copied correctly, remove the -WhatIf from the Copy-Item cmdlet.
$fn = 'C:/src/t/xxx.txt'
$destbasedir = 'C:/src/t/lastdir'
Get-ChildItem -Directory -Path $destbasedir |
Sort-Object -Property Name |
Select-Object -Last 1 |
ForEach-Object { Copy-Item -Path $fn -Destination $_.FullName -Whatif }
This could be put into a .bat file script.
SET "FN=C:\src\t\xxx.txt"
SET "DESTBASEDIR=C:\src\t\lastdir"
powershell -NoProfile -Command ^
"Get-ChildItem -Directory -Path %DESTBASEDIR% |" ^
"Sort-Object -Property Name |" ^
"Select-Object -Last 1 |" ^
"ForEach-Object { Copy-Item -Path "%FN%" -Destination "$_.FullName" -Whatif }"
Ok, it is possible to check the versions of the directories, but that will take a bit more code as we cannot simply remove the dots to get a numeric value and compare to the next. The reason being, considering versions 1.2.3 and 1.23 if we remove the dots to make it a matchable numeric value, both these will end up being being 123 therefore each version section would need to be tested.
However, based on your comments to my questions, you create new versions as folders, and therefor it ia sortable by date, so simply run a dir command and sort by created date. It will set the latest folder as the variable you need:
#echo off
for /f "delims=" %%i in ('dir /b /ad /o:d D:\otherfiles') do set "myvar=%%i"
xcopy /s "c:\users\documents\thisfile.txt" "d:\otherfiles\%myvar%"

PowerShell Get-Content on multiple unknow files from multiple directories and sub directories

I did the following script in PowerShell:
(Get-Content text\text.txt).replace('ABC', 'abc') | Set-Content text\text.txt
it works as expected...
it reads the contents of a file and replaces a particular character sequence by another seguency...
but, I need that script identify multiple files with different names in others possibles subdirectories of the same initial directory.
dir01\file_name.abc
dir01\filename.def
dir01\dir02\fi-le_na-me.ghi
dir01\dor02\fi_le-na_me.jkl
dir01\dir02\dir03\f-i-l-e_n-a-m-e.mno
etc...
I do not know which will be the names of the files nor the directories too!
In msdos I use the following expression to go from file to file:
for %%F in (*.*) do ("winRAR.exe" "%%F")
this batch, compresses file by file... its only a sample!
I do not know how to identifying file by file in PowerShel... Could someone help me with that?!
Just use Get-ChildItem and pipe the output into your command. You can tell Get-ChildItem to recurse directories using -recurse and only return files with -File:
Get-ChildItem dir01 -recurse -file |
foreach{(Get-Content $_.FullName).replace('ABC', 'abc') | Set-Content $_.FullName}

Powershell help, how can I combine text files in a directory to one file?

I'm new to powershell. I'm trying to convert some of our database scripts to powershell scripts. One thing we do in our script currently (DOS BATCH FILE) is use the Type command...
#ECHO OFF
DEL *.sql 1>NUL 2>&1
TYPE ..\db\database\TuscanyProfileDB.sql > CreateDB.sql
TYPE ..\db\tbls\*.sql > CreateTables.sql
TYPE ..\db\foreignKeys\*.sql > CreateForeignKeys.sql
TYPE ..\db\indexes\*.sql > CreateIndexes.sql
TYPE ..\db\sprocs\*.sql > CreateSprocs.sql
It basically goes into the specified folder, and concatenates all the files with the .sql file extension and combines them into a new file.
My question is how can I do this in powershell?
Remove-Item *.sql
Get-Content ..\db\database\TuscanyProfileDB.sql | Add-Content CreateDB.sql
Get-Content ..\db\tbls\*.sql | Add-Content CreateTables.sql
Get-Content ..\db\foreignKeys\*.sql | Add-Content CreateForeignKeys.sql
Get-Content ..\db\indexes\*.sql | Add-Content CreateIndexes.sql
Get-Content ..\db\sprocs\*.sql | Add-Content CreateSprocs.sql
Here's what I use, adapted from here.
In my case I tend to have many directories, each one has many SQL files and I want to create a separate merged SQL file for each directory. I only want to merge the files that are prefixed with a number (e.g. 001_blah.sql) and my merged file gets named upgrade_{DIRECTORY}.sql (e.g. merged_1370_to_1380.sql).
I put my merge_sql_files.ps1 file in the parent directory and I put a merge.bat file in each of the directories with the SQL files.
merge.bat file looks like this
#ECHO OFF
SET PsFile=merge_sql_files.ps1
SET ThisScriptsDirectory=%~dp0
SET PowerShellScriptPath=%ThisScriptsDirectory%..\%PsFile%
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%PowerShellScriptPath%'";
merge_sql_files.ps1 looks like this:
# Script to merge SQL files together.
# Takes all the SQL files that start with a number and concats
# them together, putting a line with "GO" in betweeen each one.
# The output is saved as upgrade_[DirectoryName].sql, e.g.
# 'upgrade_1370_to_1380.sql'.
#
# This script should be run from the folder with the sql files,
# e.g. put a merge.bat file in the folder that runs this ps1 script.
$path = (Resolve-Path .\).Path
$dirName = (get-item $path).Name
$outFile = "${path}\upgrade_${dirName}.sql"
if((Test-Path $outFile) -eq $true) {Remove-Item -Path $outFile -Force}
# Get all the SQL files that start with a number. Sort them
$files = Get-ChildItem -LiteralPath $path -Include "*.sql" | where {$_.Name -match "^[0-9]" } | Sort-Object -Property Name
New-Item -ItemType file -Path $outFile -Force | Out-Null
foreach($file in $files)
{
Write-Host "Appending file $file..." -ForegroundColor Gray
$content = Get-Content -Path $file.FullName
Add-Content -Path $outFile "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
Add-Content -Path $outFile "-- $File"
Add-Content -Path $outFile "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
Add-Content -Path $outFile $content
Add-Content -Path $outFile "GO`r`n"
}
Write-Host "Completed file $outFile" -ForegroundColor DarkGreen
# If running in the console, wait for input before closing.
if ($Host.Name -eq "ConsoleHost")
{
Write-Host "Press any key to continue..."
$Host.UI.RawUI.FlushInputBuffer() # Make sure buffered input doesn't "press a key" and skip the ReadKey().
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}

Resources