Batch File looping until certain text is displayed - loops

Currently have a batch file for replacing NTFS permissions using the takeown and icacls commands, i have added these commands to a loop and it works great.
Is there a way to exit the loop when a certain response is displayed? like "Failed processing 0 files" or something like that? the code i am using is below, hopefully this will help some other people also.
#echo off
setlocal enabledelayedexpansion
for /l %%x in (1,1,1000) do (
echo Taking ownsership of Folders & Files - loop %%x
for /f "delims=" %%i in ('takeown.exe /R /A /F "F:\Shares\NetBackup Clients" /D N ^| findstr /i /C:"Failed processing 0 files"') do (
set "error=%%i"
if "!errorlevel!"=="0" goto :end
)
echo Applying permissions to filestore - loop %%x
icacls.exe "F:\Shares\NetBackup Clients" /grant "Domain\Group":F /grant "Domain\Group":R /T /C
echo Finished applying permissions to filestore - loop %%x >> C:\Loopy.txt
)
goto :eof
:end
echo %error%
Many Thanks

I think you might have the error the wrong way around, so you would need to adjust it accordingly, but we use findstr and if we meet the requirement (errorlevel is 0) we exit the loop.
#echo off
setlocal enabledelayedexpansion
for /l %%x in (1,1,1000) do (
echo %%x
for /f "delims=" %%i in ('takeown.exe /R /A /F "\\fileserver\share\" /D N ^| findstr /i "Failed processing 0 files"') do (
set "error=%%i"
if "!errorlevel!"=="0" goto :end
)
echo Finished takeown >> C:\Loopy.txt
icacls.exe "\\fileserver\share\" /grant "Domain\Group":F /grant "Domain\Group":R /T /C
echo Finished icacls >> C:\Loopy.txt
echo Loop %%x >> C:\Loopy.txt
)
goto :eof
:end
echo %error%

Related

Log contents of text file before deleting

My script isn't logging the contents of run.txt to log.txt
I've tried to remove the delete command to see if it was deleting it too quickly and therefore couldn't log. But that wasn't the case.
What should I change?
#ECHO OFF &setlocal
SET File=run.txt
type %File%
for /f "tokens=*" %%A in (%File%) do (echo >> log.txt)
del "%File%" /s /f /q > nul
pause
Here is a very simple way to do the task you are requiring.
#echo off
REM Will only grab the first line of the file
set /p file=<run.txt
REM For the last line use a for loop
for /f "tokens=*" %%a in (%file%) do set last_line=%%a
(
echo %file%
)>>log.txt
del /f %file% >nul
If not %errorlevel% equ 0 (
ECHO ERROR - %errorlevel%
pause
exit /b
)
ECHO Success!
timeout /t 003
exit /b %errorlevel%
EXPLANATION
set /p is for set prompt. For more information you can use set /? in your CMD window or check out this site.
I wish I could speak more on what < does, but what it is doing here is piping the content of run.txt to our variable.
Then we echo out our variable to our log file with (ECHO This is our %file%)>>destination
>> is to append where > is to overwrite the file.
(
echo %file%
echo.
)>>%file%
Checking for an error is probably unnecessary, but I believe it is a good habit to build on which is what I am trying to do with that If not %errorlevel% statement.
No error? We Success and timeout ourselves for xxx seconds.
Try:
#ECHO OFF &setlocal
SET "File=run.txt"
type "%File%" >> "log.txt" && (del "%File%" /f > nul)
pause

Test if process is running on remote units and output to log

We would like to check if a certain process is running on any of our listed servers, outputting the result to a log file like this:
SERVERNAME Process is running
SERVERNAME Process is not running
I'm new to batch but this is how far I got:
FOR /F "TOKENS=*" %%A IN (LIST.TXT) DO TASKLIST /S %%A /FI "IMAGENAME EQ IEXPLORE.EXE" >> ECHO %%A D:\SEARCH.LOG
This should pretty much do what you want.
#echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (list.txt) do (
tasklist /s %%a | find /I "iexplore.exe" >nul
if !errorlevel! equ 0 (echo %%a Process is Running) else (echo %%a Process is Not Running)
) >> d:\search.log
As for your requirement on RPC errors, perhaps consider rpcping and echo to file if not available.
#echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (list.txt) do (
rpcping -s %%a |find /i "Completed" >nul
if not !errorlevel! equ 0 echo %%a RPC Server not available
tasklist /s %%a | find /I "iexplore.exe" >nul
if !errorlevel! equ 0 (echo %%a Process is Running) else (echo %%a Process is Not Running)
) >> d:\search.log
What you have, isn't far away, to get the output you asked for however, you could change your script more like this:
#ECHO OFF
(FOR /F "TOKENS=*" %%A IN (LIST.TXT
) DO TASKLIST /S %%A|FIND /I "IEXPLORE.EXE">NUL&&(Echo %%A Process is running
)||Echo %%A Process is not running)>D:\SEARCH.LOG

Batch file for installed software

I am very new to batch just learnt a few. I agree to having shamelessly lifted this code from a website. This is the code I want for displaying list of installed software, however there is just one problem, the version and the softwares are being displayed in different lines. How can I have both in the same line?
Ex: If you run the batch you will see the versions at the beginning and then the softwares.
Any help would be greatly appreciated. Thanks in advance.
#echo off
If Exist C:\Final.txt Del C:\Final.txt
regedit /e C:\regexport.txt "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport2.txt "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall"
regedit /e C:\regexport3.txt "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
find "DisplayName" C:\regexport.txt > C:\regprogs.txt
find "DisplayName" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayName" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
find "DisplayVersion" C:\regexport.txt > C:\regprogs.txt
find "DisplayVersion" C:\regexport2.txt >> C:\regprogs.txt
find "DisplayVersion" C:\regexport3.txt >> C:\regprogs.txt
for /f "tokens=2 delims==" %%a in (C:\regprogs.txt) do echo %%~a >> C:\installedprogs.txt
del C:\regexport.txt
del C:\regexport2.txt
del C:\regexport3.txt
del C:\regprogs.txt
sort C:\installedprogs.txt > C:\alles.txt
del C:\installedprogs.txt
:: script om alle dubbele lijnen eruit te gooien
REM -- Prepare the Command Processor --
SETLOCAL ENABLEEXTENSIONS
SETLOCAL EnABLEDELAYEDEXPANSION
REM -- Prepare the Prompt for easy debugging -- restore with prompt=$p$g
prompt=$g
rem The finished program will remove duplicates lines
:START
set "_duplicates=TRUE"
set "_infile=C:\alles.txt"
set "_oldstr=the"
set "_newstr=and"
call :BATCHSUBSTITUTE %_infile% %_oldstr% %_newstr%
pause
goto :SHOWINTELL
goto :eof
:BATCHSUBSTITUTE
type nul> %TEMP%.\TEMP.DAT
if "%~2"=="" findstr "^::" "%~f0"&GOTO:EOF
for /f "tokens=1,* delims=]" %%A in ('"type %1|find /n /v """') do (
set "_line=%%B"
if defined _line (
if "%_duplicates%"=="TRUE" (
set "_unconverted=!_line!"
set "_converted=!_line:"=""!"
FIND "!_converted!" %TEMP%.\TEMP.DAT > nul
if errorlevel==1 (
>> %TEMP%.\TEMP.DAT echo !_unconverted!
)
)
) ELSE (
echo(>> %TEMP%.\TEMP.DAT
)
)
goto :eof
:SHOWINTELL
#echo A|move %TEMP%.\TEMP.DAT C:\allesnietdubbel.txt
del C:\alles.txt
::Alle lijnen weggooien waar 'KB' in voor komt
type C:\allesnietdubbel.txt | findstr /V KB > C:\drivers\Final.txt
goto :eof
exit
Try next approach. Edited - saves output to a csv file (rfc4180 compliant):
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_csvfile=%TEMP%\%COMPUTERNAME%_39082171.csv" change to match your needs
> "%_csvfile%" (
rem (facultative, optional) CSV header
echo "version","displayname","comment"
call :getsw "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
call :getsw "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
ENDLOCAL
goto :eof
:getsw
for /F "delims=" %%g in ('reg query "%~1" 2^>NUL') do (
set "_swRegKey=%%~g"
set "_swName="
set "_swVers="
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayName 2^>NUL ^| findstr /I "DisplayName"
') do set "_swName=%%~I"
for /F "tokens=1,2,*" %%G in ('
reg query "%%~g" /V DisplayVersion 2^>NUL ^| findstr /I "DisplayVersion"
') do set "_swVers=%%~I"
call :echosw
)
goto :eof
:echosw
SETLOCAL EnableDelayedExpansion
if "%_swName%%_swVers%"=="" (
rem comment up next ECHO command if you don't require such information
ECHO "","","unknown !_swRegKey:HKEY_LOCAL_MACHINE=HKLM!"
) else (
echo "!_swVers!","!_swName!",""
)
ENDLOCAL
goto :eof
Sample output (largely narrowed down for demonstration here):
==> D:\bat\SO\39082171.bat
==> type "%TEMP%\%COMPUTERNAME%_39082171.csv"|findstr /I "comment KB unknown"
"version","displayname","comment"
"","","unknown HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\Connection Manager"
"12.0.31101","Visual Studio 2013 Update 4 (KB2829760)",""
"12.0.30112","Update for Microsoft Visual Studio 2013 (KB2932965)",""
"1","Update for (KB2504637)",""
==>
Resources (required reading):
(command reference) An A-Z Index of the Windows CMD command line
(helpful particularities) Windows CMD Shell Command Line Syntax
(%~G, %~1 etc. special page) Command Line arguments (Parameters)
(special page) EnableDelayedExpansion
(2>NUL, 2>&1, | etc. special page) Redirection
(2^>NUL, ^| etc.) Escape Characters, Delimiters and Quotes

Exclude certain file extensions from random file selection - batch script

I'm in the process of making a script that selects 25 random tracks from a user specified folder and adds them into an .m3u playlist. The trouble I have is that my music folders include various other files as well (eg: .txt, .jpg, .png, .nfo, etc...)
So I'm looking for a way of excluding the extensions listed above, limiting the script to just work with audio files. Any help would be much appreciated!
Here is the code so far... It has been stitched together from various sources so accept my apologies if it is a little crude:
#echo off
title Multiple Choice Menu
:home
cls
echo.
echo Select a genre:
echo =============
echo.
echo 1) Jungle
echo 2) D'n'B
echo 3) Reggae
echo 4) Hip-Hop
echo 5) Exit
echo.
set /p genre=Type option:
if "%genre%"=="1" cd /D "D:\NL Safe 2.0\High Quality\Jungle"
if "%genre%"=="2" cd /D "D:\NL Safe 2.0\High Quality\DnB\Standard DnB"
if "%genre%"=="3" cd /D "D:\NL Safe 2.0\High Quality\Reggae
if "%genre%"=="4" cd /D "D:\NL Safe 2.0\High Quality\Hip-Hop"
if "%genre%"=="5" exit
:: Clear existing Playlist
#echo. > C:\Users\Brew\Desktop\random.m3u
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
:: Open 25 random files
for /l %%N in (1 1 25) do call :openRandomFile
:: Delete the temp file
del "%tempFile%"
:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
setlocal EnableDelayedExpansion
set tune=%%B
#echo !tune! >> C:\Users\Brew\Desktop\random.m3u
)
Assuming your song's folder is on %1.
The dir command supports wildcards in the idea that
dir *.txt *.xml
will only list .txt and .xml files.
So you can try doing this instead:
...
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
pushd %1
dir /b /s /a-d *.mp3 *.EXT1 *.EXT2 | findstr /n "^" >"%tempFile%"
popd
...
Where EXT will be the extensions you want to match.
This will create your %tempFile% with only the files you want. Since the code that selects a file ramdomly works, as I see, over this file, it won't need to change at all.
I couldn't get dir to work with both target directory and wildcards.
Hope it helps.
This is why i used pushd and popd.
Thanks Daniel,
I had another go at it an finally got something working on my own. I used a series of If statements to put the random file through an extension validation check
This is the working script
#echo off
title Multiple Choice Menu
:home
cls
echo.
echo Select a task:
echo =============
echo.
echo 1) Jungle
echo 2) D'n'B
echo 3) Reggae
echo 4) Hip-Hop
echo 5) Exit
echo.
set /p genre=Type option:
if "%genre%"=="1" cd /D "D:\NL Safe 2.0\High Quality\Jungle"
if "%genre%"=="2" cd /D "D:\NL Safe 2.0\High Quality\DnB\Standard DnB"
if "%genre%"=="3" cd /D "D:\NL Safe 2.0\High Quality\Reggae
if "%genre%"=="4" cd /D "D:\NL Safe 2.0\High Quality\Hip-Hop"
if "%genre%"=="5" exit
:: Clear existing Playlist
#echo. > C:\Users\Brew\Desktop\random.m3u
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
:openRandomFile
echo opening random file.....
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
setlocal EnableDelayedExpansion
set tune=%%B
FOR %%i IN ("!tune!") do call :CheckifMusic
)
:CheckifMusic
echo checking now
FOR %%i IN ("!tune!") DO (
SET fileextension=%%~xi
IF !fileextension!==.aif goto ResultTrue
IF !fileextension!==.flac goto ResultTrue
IF !fileextension!==.m4a goto ResultTrue
IF !fileextension!==.mp3 goto ResultTrue
IF !fileextension!==.wav goto ResultTrue
IF !fileextension!==.wma goto ResultTrue
echo fail
echo !fileextension!
goto openRandomFile
:ResultTrue
echo pass
echo !fileextension!
#echo !tune! >> C:\Users\Brew\Desktop\random.m3u
set /A COUNTER=COUNTER+1
IF !COUNTER!==25 (
echo finished
pause
goto Done
) ELSE (
goto openRandomFile
)
:Done
echo.
:: Delete the temp file
del "%tempFile%"
exit
)
pause
Probably not the cleanest way to do it, but hey - It works!
replace
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
with
dir /b /s /a-d %1 | findstr /n /L /E /I /c:".mp3" /c:".wav">"%tempFile%"
Where the /c:".mp3"... can be extended as many times as you desire to select your target filetypes.
or
with
dir /b /s /a-d %1 | findstr /n /V /L /E /I /c:".jpg" /c:".txt">"%tempFile%"
Again repeating the /c:".jpg"... as many times as you desire to select your target exclude-me filetypes.
The /i means "case-insensitive", /e means "at the end of the line" /L means "literal match, not regex" and /v means "output non-matching"

How to remove all folders with a same name within the folder where is located and subfolders using cmd/batch file

I used a tip on how to do what I want, but I have a difficulty, the folders that begin with "!" ex.: c:\!test and in the middle is "." ex.: c:\test.test are not erased. You can help me?
#Echo OFF
echo.
setlocal enabledelayedexpansion
echo Search...
FOR /R %root% %%A IN (.) DO (
if '%%A'=='' goto end
set dir="%%A"
set dir=!dir:.=!
set directory=%%A
set directory=!directory:.=!
set directory=!directory::=!
set directory=!directory:\=;!
for /f "tokens=* delims=;" %%P in ("!directory!") do call :loop %%P
)
:end
echo.
echo Finished.
echo Press any key to exit...
pause >nul
endlocal
exit
:loop
if '%1'=='' goto endloop
if '%1'=='history' (
rd /S /Q !dir!
echo !dir! was deleted.
)
SHIFT
goto :loop
:endloop
I think your code checks every folder and if it finds ones called history then they are all deleted.
If that is the task then this should do the same thing.
#echo off
FOR /D /R %root% %%A IN (*) DO if /i "%%~nxA"=="history" if exist "%%A\" rd /s /q "%%A" & echo "%%A" has been deleted

Resources