I am trying to use a .bat to get system info with WMIC. I want to create a folder in C:\ with the name of the computer, then have a few .txt files made within the folder with the info on I am seeking. This is what I have so far:
start cmd
cd C:\
md C:\%computername%_Software_Baseline
wmic
/output:C:\%computername%_Software_Baseline\Installed_Software.txt product get name,version
This is where my first roadblock is. I get the message that the file name is invalid. The next few are the other .txt files I want to create in that folder as well (Once I can do the first I should be able to apply it to these as well).
/output:C:\%computername%_Software_Baseline\Computer_System_Information.txt computersystem get domain,manufacturer,model,name,totalphysicalmemory
/output:C:\%computername%_Software_Baseline\Disk_Drive_Information.txt diskdrive get model,size,manufacturer
/output:C:\%computername%_Software_Baseline\CPU_Information.txt cpu get architecture,currentclockspeed,description,extclock,l2chachesize,manufacturer,name
/output:C:\%computername%_Software_Baseline\BIOS_Information.txt BIOS get serial number,name,smbiosbiosversion,manufacturer
/output:C:\%computername%_Software_Baseline\OS_Information.txt OS get name,cdsversion,manufacturer,freephysicalmemory,buildnumber
I also want this to save everything to a folder on my network as well, but that can wait until I get the script going.
I can't understand why not to perform the task within current cmd instance omitting start cmd:
#ECHO OFF
SETLOCAL enableextensions
md "C:\%computername%_Software_Baseline"
wmic /output:"C:\%computername%_Software_Baseline\Installed_Software.txt" product get name,version
or using pushd - popd command pair:
#ECHO OFF
SETLOCAL enableextensions
md "C:\%computername%_Software_Baseline" 2>NUL
pushd "C:\%computername%_Software_Baseline"
wmic /output:"Installed_Software.txt" product get name,version
rem further wmic commands here
popd
PUSHD: Change the current directory/folder and store the previous folder/path for use by the POPD command.
POPD: Change directory back to the path/folder most recently stored by the PUSHD command.
When a UNC path is specified, PUSHD will create a temporary drive
map and will then use that new drive. The temporary drive letters are
allocated in reverse alphabetical order, so if Z: is free it will be
used first.
POPD will also remove any temporary drive maps created by PUSHD.
Related
I created a .bat file with the following code in order to copy a random file from a directory A-POOL FOLDER into a directory B-FOLDER (with a fixed file name video.mp4). So, in the directory A there is a pool of .mp4 file, and in the directory B there is the the file video.mp4 (same name, but different video every time I execute my batch-file).
That's a code who do this. It perfectly works.
#echo off
setlocal EnableDelayedExpansion
cd C:\Users\aless\Desktop\example\A-POOL
set n=0
for %%f in (*.*) do (
set /A n+=1
set "file[!n!]=%%f"
)
for /L %%i in (1,1,%time:~-1%) do set "dummy=!random!"
set /A "rand=(n*%random%)/32768+1"
copy "!file[%rand%]!" C:\Users\aless\Desktop\example\B-FOLDER\video.mp4
FOR %%G IN ("!file[%rand%]!") DO >"C:\Users\aless\Desktop\example\B-FOLDER\title.txt" ECHO %%~nG
Now the question (different from last time):
In the directory A-POOL I have a lot of .mp4 files. I changed manually the .mp4 extension of every file with a code who rappresent a food.
For example: Filename.pizza, Filename2.pizza, Filename.pasta, Filename200.pasta, Filename.cheeseburger etc...
I created another folder named "FOOD-DATABASE" (in C:\Users\aless\Desktop\FOOD-DATABASE) who contains a big database of images in .jpg extension of the foods. The file NAMES of the food database are equal to the file EXTENSIONS of the files contained in A-POOL folder
Content of FOOD DATABASE folder:
(pasta.jpg, pizza,jpg, cheeseburger.jpg... etc..).
So I need to add to the code a string/conditional who execute e command who say:
If the picked random File have the extension .pizza COPY pizza.jpg from C:\Users\aless\Desktop\FOOD-DATABASE into C:\Users\aless\Desktop\B-FOLDER\FOOD.JPG (fixed name file)
Actually I don't want to add this strings for every food type... in few word the code strings have to read the extension of the picked random file and copy from C:\Users\aless\Desktop\FOOD-DATABASE to C:\Users\aless\Desktop...B FOLDER\FOOD.JPG (fixed name file) the file with the same name to the extension of the random file.
It's a mess... I know ;) Thanks for your help!
As mentioned in the comments, we know that the extension of the one file is the name of another file. so these variable expansions are important:
%%~nG
%%~xG
The last for loop sets a variable %food% from expanded %%~xG which is the extension of the file and using a random example would be .pizza We just need to get rid of the . and you have pizza. We do this by %food:~1.
#echo off
setlocal EnableDelayedExpansion
pushd "%userprofile%\Desktop\example\A-POOL"
set n=0
for %%f in (*.*) do (
set /A n+=1
set "file[!n!]=%%f"
)
for /L %%i in (1,1,%time:~-1%) do set "dummy=!random!"
set /A "rand=(n*%random%)/32768+1"
copy "!file[%rand%]!" "..\B-FOLDER\video.mp4" /Y
for %%G IN ("!file[%rand%]!") DO (
echo %%~nG > "..\B-FOLDER\title.txt"
set "food=%%~xG"
)
copy "..\FOOD-DATABASE\%food:~1%.jpg" "..\B-FOLDER\food.jpg" /Y
popd
Notes!
I am using pushd instead of cd and using relative path, not full paths as we are working in the same folder structure.
I can make out that you are running this on your own profile, so I replaced C:\users\<username> with %userprofile% in the event someone else wants to run it from a similar folder, their <username> will be different.
popd at the bottom of the script simply changes back to the previous working directory you were in before the last pushd. it is not needed for this particular script, but adding it so you can learn about it compared to pushd
All of the items I modified has some good help topics, you can find help topics on cmd by simply running the command name with an appended /? for instance for /?, set /? etc.
Morning all.
So I've been up hours trying to cobble together -a variety of replies to other posts- into my own code in order to see if I could get something usable. No-go. I'm sufficiently lost in the sauce that I've now got to ask for some help from you.
Background:
OS: Windows 10
I use the program text2folders.exe to create 20-30 new folders on a secondary drive every night.
Primarily, I have a base file "aGallery-dl.bat" that I populate each folder with using an xcopy batch file. Secondarily, from time to time I update the source file "aGallery-dl.bat" using the same xcopy and this overwrites the older target file, populating all folders with the newest "aGallery-dl.bat" (whether they need it or not). All is well.
#echo off
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy /y /d ".\aGallery-dl.bat" "%%a\"
I've recently decided I want to add two new files to each folder and have expanded my xcopy to include these. All is well.
#echo off
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy /y /d ".\aGallery-dl.bat" "%%a\"
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder.jpg" "%%a\"
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder2.jpg" "%%a\"
Folder.jpg
a big red X
Folder2.jpg
a big yellow ! mark
When I choose to run a "aGallery-dl.bat" in a given folder (again, one of 100's), it first deletes Folder.jpg then renames Folder2.jpg to Folder.jpg. This has the effect of the red X being replaced by the yellow ! when viewing the folder in File Explorer parent folder. Secondly, it calls "gallery-dl.exe." I use going from red to yellow to let me know I've run "aGallery-dl.bat" at least once. All is well.
rem #echo off
del .\Folder.jpg
ren .\Folder2.jpg Folder.jpg
FOR /F %%i IN ('cd') DO set FOLDER=%%~nxi
"C:\Program Files (x86)\gallery-dl\gallery-dl.exe" -d "U:\11Web\gallery-dl" --download-archive ".\aGDB.sqlite3" "https://www.deviantart.com/"%FOLDER%"/gallery/all"
del .\Folder.jpg
If "aGallery-dl.bat" completes successfully, it finally deletes the Folder.jpg (currently yellow !), and now the representative contents of the folder (usually DeviantArt .jpg's) are visible.
Problem:
When I have to re-run my original xcopy command to update "aGallery-dl.bat" in ALL FOLDERS, the Folder.jpg and Folder2.jpg will be re-copied to all folders, defeating the purpose of deleting them once via "aGallery-dl.bat." I don't want to have to go back and re-run "aGallery-dl.bat" intermittently across 100's of folders (again, only those that have had aGallery-dl.bat run at least once). I need some type of test, that if "aGallery-dl.bat" is already present in the target folder, DO NOT xcopy Folder.jpg and Folder2.jpg aka vague example, below.
*********************************Some sort of test statement here!!!***********************
:aGallery-dlPresent
GOTO eof
:aGallery-dlNotPresent
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder.jpg" "%%a\"
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder2.jpg" "%%a\"
GOTO eof
:eof
I had found a hopeful candidate test statement in the below (copied in its original form from what/where I read in other post), but am looking for ideas/replacements as I HAVE NO IDEA how to modify/inject/implement the below to work in the above.
If exist \\%DIR%\%Folder%\123456789.wav xcopy \\%DIR%\%Folder%\123456789.wav D:\%New Folder%\ /y
Having XCopy copy a file and not overwrite the previous one if it exists (without prompting)
Note: The below is a vague approximation of what it should all look like (barring having a correct -test statement-).
rem #echo off
*********************************Some sort of test statement here!!!***********************
:aGallery-dlPresent
GOTO eof
:aGallery-dlNotPresent
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder.jpg" "%%a\"
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy ".\Folder2.jpg" "%%a\"
GOTO eof
:eof
for /D %%a in ("U:\11Web\gallery-dl\deviantart\*.*") do xcopy /y /d ".\aGallery-dl.bat" "%%a\"
The command for copying a file is COPY. It is an internal command of Windows command processor cmd.exe. XCOPY is an eXtended file and directory copying executable in directory %SystemRoot%\System32 which is deprecated since Windows Vista as there is even more powerful ROBOCOPY which is with full qualified file name %SystemRoot%\System32\robocopy.exe.
There is no need to use XCOPY or ROBOCOPY for this simple file copying task. COPY is enough on source files aGallery-dl.bat, Folder.jpgand Folder2.jpg don't have hidden attribute set and the same files in the target directories don't have read-only attribute set.
.\ references the current directory which can be any directory. Windows Explorer sets the directory of the batch file as current directory on double clicking on a batch file. But this is nearly the only method to run a batch file on which the directory of the executed batch file is set automatically as current directory (except the batch file is stored on a network resource accessed using UNC path).
There is %~dp0 to reference the path of the batch file. This path always ends with a backslash which means that no additional backslash is needed on concatenating the batch file path with a file or folder name. The usage of %~dp0 makes it possible to reference files in same directory as the executed batch file independent on which directory is the current directory on execution of the batch file.
The batch file needed for your task is:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /D %%I in ("U:\11Web\gallery-dl\deviantart\*") do (
if not exist "%%I\aGallery-dl.bat" (
copy "%~dp0Folder.jpg" "%%I\"
copy "%~dp0Folder2.jpg" "%%I\"
)
copy /Y "%~dp0aGallery-dl.bat" "%%I\"
)
endlocal
A file/folder name must be enclosed in " if containing a space or one of these characters &()[]{}^=;!'+,`~. For that reason all file/folder names are enclosed in this batch file in double quotes although inside the batch files no file/folder name contains a space or one of the characters in the list. It is important to understand on batch file writing how a command line looks like after Windows command processor processed the command line. See following topics:
How does the Windows Command Interpreter (CMD.EXE) parse scripts?
How to debug a batch file?
Windows interprets *.* like just * which means any file or folder name. For that reason it is enough to just write * and omit .*.
Please note that for /D ignores directories with hidden attribute set.
The batch file checks first for each subfolder if it does not contain the batch file aGallery-dl.bat. In this case it copies the two files Folder.jpg and Folder2.jpg from directory of executed batch file to current subdirectory of U:\11Web\gallery-dl\deviantart.
Then the batch file aGallery-dl.bat is copied from directory of executed batch file to to current subdirectory of U:\11Web\gallery-dl\deviantart independent on its existence in the destination directory.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains %~dp0 ... drive and path of argument 0 ... full batch file path.
cmd /? ... outputs the help of Windows command processor executing a batch file.
copy /?
echo /?
endlocal /?
for /?
if /?
setlocal /?
See also the chapters Issue 6 and Issue 7 in this answer why using setlocal EnableExtensions DisableDelayedExpansion and endlocal although not necessary by default and why using I instead of a as loop variable although a would work here, too.
I have a .txt file with multiple lines. Each line contain a path to a folder on my network drive/computer:
[NetworkDrive_PathToFolder1]
[Computer_PathToFolder1]
[NetworkDrive_PathToFolder2]
[Computer_PathToFolder2]
[NetworkDrive_PathToFolder3]
[Computer_PathToFolder3]
etc...
The idea is to have a .bat file that will read line 1 and 2 and copy files in folder [NetworkDrive_PathToFolder1] into folder [Computer_PathToFolder1], then read line 3 and 4 and copy files in folder [NetworkDrive_PathToFolder2] into folder [Computer_PathToFolder2], etc.
This will enable me to add/remove paths without need of altering the code.
I'm not sure how the .txt file should look like. Maybe it's better to use a xml file?
This is for a Windows 10 computer with a network drive connected.
When I start my computer I want to automatically update some specific files from my network drive to a local folder on my computer.
To map the network drive I'll prefer to use PUSHD and POPD instead of NET USE since I don't want the network drive to be permanently mapped.
Today I have a .txt file with paths to the folders in the network drive:
[NetworkDrive_PathToFolder1]
[NetworkDrive_PathToFolder2]
[NetworkDrive_PathToFolder3]
etc...
And the path to the folder where the files are copied to are in the .bat file.
But then everything is just copied into the same folder at my computer.
FOR /F %%i IN (C:\UpdateFilesFromNetworkPaths.txt) DO (
NET USE L: /delete
NET USE L: %%i
xcopy L:\*.txt C:\FilesFromNetwork\ /d /y
)
Result from this code:
Every .txt files that doesn't exist in the folder [C:\FilesFromNetwork] will be copied from the paths in the textfile [UpdateFilesFromNetworkPaths.txt].
If a file exist, copy the file if it's a newer version.
So based on your post, it looks like you're trying to copy files based on paths in a text file. All groups of two (1-2, 3-4, 5-6) contain source and destination paths. This problem can be solved by a simple for loop and a simple counter.
Assuming your text file (.txt) is formatted in my example bellow:
C:\PathToNetworkDriveFolder1
C:\PathToComputerFolder1
C:\PathToNetworkDriveFolder2
C:\PathToComputerFolder2
C:\PathToNetworkDriveFolder3
C:\PathToComputerFolder3
Bellow will be the solution script:
#ECHO OFF
#Setlocal EnableDelayedExpansion
Set "Count=1"
Rem | Read The Text File Line By Line
FOR /F "tokens=*" %%A in ('Type "list.txt"') DO (
Rem | Grabbed First Line
IF "!Count!"=="1" (
Rem | Add One To Count
Set /a "Count=!Count!+1"
Rem | Save Current Variable
Set "NetworkDrivePath=%%A"
Rem | Grabbed Second Line
) else (
Rem | Subtract One To Count
Set /a "Count=!Count!-1"
Rem | Save Current Variable
Set "ComputerDrivePath=%%A"
Rem | Copy Files
Echo "!NetworkDrivePath!" "!ComputerDrivePath!"
)
)
Goto :EOF
Keep in mind my example uses list.txt. Feel free to change that to your example or your usage. If you have multiple text files you want to use your can simply add another for loop at the beginning to search for all *.txt file names.
For all my scripts, I put in rem comments to help you follow along in what each process is doing. For help on any of the commands do the following in a new window:
set /?
for /?
if /?
ren /?
So on.
this is my first question, so I apologize beforehand if I write not as you are used to...
fact:
I've a deep folder structure with tons of files (images,videos and so on) so I want to copy that files to a flat structure for a better overview.
I want to keep (at least) the original date attributes: creation-date and last-modified date.
Problem 1) there are files with same name 00001.jpg in different folders which I want to have in same folder, so I want to add creation date/time to filename on copy process.
00001.jpg becomes 2015-11-17_11-23-35_00001.jpg
So far so good. Or not good...
Copy and XCopy doesn't give me an option to do that, without loosing at least the creation date information (I didn`t find a solution with both).
Now I try to copy the files (file by file) with robocopy to new folder and use ren on the copied file to "pre-set" the date/time information before the filename.
Here is a simple test.bat example:
setlocal enableextensions enabledelayedexpansion
robocopy . ./zzz original.txt /copy:DATSO
pause
rem :: formatted creation date of original file will be here, in real life
set "myDate=2015-11-17-_11-23-35"
rem rename "./zzz/original.txt" "!myDate!_renamed.txt" ::doesnt work: why? relative path??
rem :: this will do what I want - original creation date is kept on copy file
FOR %%A IN (zzz/original.txt) DO REN "%%~fA" "!myDate!_%%~nxA"
[possibly] Problem2) Is there a better way to do this, or could I run into thread problems (asynchronous execution). Could it be, that I try to rename a file before the robocopy has finished the copy process (e.g. for large files)?
Sorry I'm a totally batch newbie (also as poster in SO ;).
ThanX in advance for each tip and also for critics on my solution approach. Maybe I have the horse-blinkers on my head and dont see the easy solution?!
[edit: formatting of post]
[edit: content of post -> date/time in front of filename for better sorting]
It is possible to use command DIR to get recursive listed all files in the specified folder and its subfolders with creation date/time.
The format of the date/time depends on Windows Region and Language settings.
Example output for F:\Temp\Test on my machine with English Windows 7 and region is configured to Germany on running the command line dir F:\Temp\Test\* /A-D /S /TC:
Volume in drive F is TEMP
Volume Serial Number is 1911-26A4
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
1 File(s) 465.950 bytes
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
1 File(s) 360.546 bytes
Total Files Listed:
2 File(s) 826.496 bytes
0 Dir(s) 58.279.460.864 bytes free
This output is filtered with findstr /R /C:"^ Directory of" /C:"^[0123][0123456789]" to get only lines starting with Directory of (note the space at begin) or with a number in range 00 to 39.
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
And this filtered output is processed by FOR loop and the commands executed by FOR.
#echo off
for /F "tokens=1-2*" %%A in ('dir "F:\Temp\Test\*" /A-D /S /TC ^| %SystemRoot%\System32\findstr.exe /R /C:"^ Directory of" /C:"^[0123][0123456789]" 2^>nul') do (
if "%%A %%B" == "Directory of" (
set "FilePath=%%C"
) else (
set "CreationDate=%%A"
set "CreationTime=%%B"
for /F "tokens=1*" %%I in ("%%C") do set "FileName=%%J"
call :RenameFile
)
)
goto :EOF
:RenameFile
set "NewName=%CreationDate:~-4%-%CreationDate:~3,2%-%CreationDate:~0,2%_%CreationTime:~0,2%-%CreationTime:~3,2%_%FileName%"
ren "%FilePath%\%FileName%" "%NewName%"
goto :EOF
It would be advisable to put command echo before command ren in last but one line to first verify the expected new file names.
ren "F:\Temp\Test\SimpleFile.ccl" "2017-09-25_17-26_SimpleFile.ccl"
ren "F:\Temp\Test\Test Folder\Test File.tmp" "2017-09-25_17-26_Test File.tmp"
Note: The batch file must be in a folder not processed by this batch file as otherwise the batch file itself would be renamed while running which breaks the processing of the batch file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
dir /?
echo /?
for /?
goto /?
if /?
ren /?
set /?
By the way: WinRAR can add files into a RAR archive with creation and last access time in addition to last modification time and extract the files to a different directory with restoring also creation and last access time using SetFileTime function of Windows kernel.
currently I use Locale independent date. I use tokens from that for currrent date/time.
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem :: format it to YYYY-MM-DD_hh-mm-ss
set myDateTime=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%_%datetime:~8,2%-%datetime:~10,2%-%datetime:~12,2%
Thats not the problem.
To clarify:
The listing is also not the problem.
I loop throw all related files without a prob (except batch files and output dir and its sub tree ;).
My problem is:
I call robocopy for each file, then I rename the file to save the original creation date. My fear is that it makes problems (Multi-Threading?) for large files and for the number of calls (many thousend times)
Is batch execution really serialized? Is the process waiting for robocopy, that it has finished, before I try to rename file. Could I run into dead-locks for vry large files? I'll test it with some fake gigabyte-files.
Your suggestion, to use winrar sounds interesting.
If I could add all that files to a big archive (with structure) and at the end extract it to target dir... I'll try it ;)
If it doesn't work I will program it in java!
There I know what to do, thats my playground :D
I thought it would be easy to write a simple batch file, to do this for me, but it seems it's not as easy as I thought!
ThanX anyway
I'm trying to build a batch file script, which will copy the outlook.pst file, from the user's My Documents folder and move it to the server, which I've mapped as a drive, "B:\"
This is the code I have so far:
#echo on
xcopy "c:\Documents and Settings\%username%\My Documents\outlook.pst" "B:\PST\%username%\" -c -d -i -y
exit
The script is designed for Windows XP.
However, when I run this code on the client machine, it doesn't copy the .pst file across, it just runs the command over and over again, until I Ctrl + C it...
Thanks
If I recall correctly, the default location for PST files is in %localappdata%\Microsoft\Outlook\. And if the user has PST files in multiple locations, it's possible that he has more than one with the same name, just in different folders. Good times.
If it's possible that your users might have PST files in locations other than My Documents, I recommend modifying your script with just a couple of very minor changes.
#echo off
setlocal enabledelayedexpansion
for /r "%userprofile%" %%I in (*.pst) do (
rem avoid overwriting in case "outlook.pst" exists in two locations, for instance
if exist "B:\PST\%username%\%%~nxI" (
set cnt=000
rem get count of files matching b:\pst\username\filename*.pst
for /f %%a in ('dir "B:\PST\%username%\%%~nI*%%~xI" 2^>NUL ^| find " File(s) "') do (
set "cnt=!cnt!%%a"
)
rem file of the same name will become filename001.pst, filename002.pst, etc.
set "dest=%%~nI!cnt:~-3!%%~xI"
rem otherwise leave the filename alone
) else set "dest=%%~nxI"
set /P "=Copying !dest!... "<NUL
copy "%%~fI" "B:\PST\%username%\!dest!"
echo Done.
)
I wished to copy outlook.pst from its Microsoft default location to a memory stick using a batch file in Windows XP
I found that xcopy failed to copy Outlook.pst to the memory stick or to My Documents
I now xcopy it in 2 steps, firstly to C:\ then to the Memory Stick
It has worked reliably