I need to print the full name of the current user in the console, I have this code that does what I need but only partially
NET USER %username% /DOMAIN | FIND /I "Full name" >tmp.txt
set /p VAR=<tmp.txt
echo %VAR%
del tmp.txt
Because the result of the print is for example "Full Name Juan Perez"
And the only thing I need is "Juan Perez"
Is there a way to do what I need?
Theoretically,
#ECHO OFF
SETLOCAL
FOR /f "tokens=2*delims= " %%b IN ('NET USER %username% /DOMAIN 2^>nul ^|find /I "Full name"') DO SET "var=%%c"
ECHO Full name : "%var%"
GOTO :EOF
but NET USER %username% /DOMAIN returns an error for me.
The 2^>nul redirects errors. the ^ before > and | tells cmd the character is part of the '-enclosed command to be executed, not of the for itself.
Documentation for for can be found by executing for /? from the prompt, or reading thousands of examples on SO
This is my first question on this site so let me get right into it.
I am in Cyber Patriots, a cyber security competition run by the air force. I am the main person for Windows on my team. For the past few years I have been struggling to make a script that will automatize setting the password for users from a list. I am doing this in batch [Windows] and currently have a script that works but its not automatic.
Here is the code I currently have
:A
net user
timeout /t 5
echo Change User Password
set /p UER=Which User Password Would You Like To Change?
echo Please Paste Password:
net user %UER% *
goto A
What this does, is it lists all the users on the network, then asks for the user you want to choose and takes your input and changes their password.
The method that I listed does work, but it isn't automatic like I want it to be. Is there a way I can make this automatic? I would prefer to stick with batch however if there's a way to do it from some other language that would be great too.
Last thing. My other thought was to somehow read from a file that has all the usernames and passwords. However unlike in Ubuntu there isn't a file that lists the users that I can read from so I don't know how I would go about this.
Anyway, thank you for your help!
I simply wrote this to show it can be done, even though I would never do such a thing in a working environment.
#echo off
set list=KLMNOPQRST2345UVWXYZabcdefghiABCDEFGHIJjklmnopqrstuvwxyz016789
setlocal enabledelayedexpansion
:start
cls
set /a num=0
for /f "delims=" %%i in ('dir /b c:\users') do (
set /a num+=1
set "user[!num!]=%%i"
)
for /l %%c in (1,1,%num%) do echo !user[%%c]!
set /p "to_change=Select user to change Password: "
call :passwd
net user %to_change% !pw! >nul 2>&1
echo(
echo New password for '%to_change%' is: !pw!
pause
goto :start
:passwd
set pw=
for /l %%a IN (0,1,8) DO (
set /a rand=!random! * 62 / 32768 + 1
for /f %%b in ('echo %%list:~!rand!^,1%%') do set pw=!pw!%%b
)
This simply lists all the users as received by dir /b c:\users If the user directory is located anywhere else, you would need to update that in the script.
We then prompt to type one of the users as listed, when typed and enter is pressed, it will generate a random password, do the change and then echo the new password which you need to save.
You can amend it to automatically change all of the passwords and just show you what the new passwords are per user, obviously excluding administrator
#echo off
set list=KLMNOPQRST2345UVWXYZabcdefghiABCDEFGHIJjklmnopqrstuvwxyz016789
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('dir /b c:\users') do (
if /i not "%%i"=="administrator" (
call :passwd
net user "%%i" !pw! >nul 2>&1
echo(
echo Password for '%%i' is !pw!
)
)
echo(
pause
goto :eof
:passwd
set pw=
for /l %%a IN (0,1,8) DO (
set /a rand=!random! * 62 / 32768 + 1
for /f %%b in ('echo %%list:~!rand!^,1%%') do set pw=!pw!%%b
)
If you win anything in the "Cyber Security Competition", remember, sharing is caring :D
I'm running automation testing on Windows (windows 10 and 2012), and one of the requirements of the automation is that ALL users need to be logged off. I have a chance to do this after deployment. I kind of see this page give an answer, but after I tried query session, I see it gives even services and rdp-tcp sessions... but I don't want to stop any service...
Any suggestion?
This solution is based on the previous answer but this one will close all sessions (even disconnected sessions). Unfortunately, the text format of each line returned by the 'query session' command can be difficult to parse. As you can see in the next screenshot, the username may be empty and in this example, if you use tokens=3, you will get the username instead of the ID for the user compil.
The problem is that you cant logoff a disconnected user with his username. To circumvent this problem, we use 2 for loops to get the session name and id (depending on the line format), and then we keep only the numeric values to send the logoff command and logoff also the disconnected sessions.
#echo off
for /f "skip=2 tokens=2,3 delims= " %%a in ('query session') DO (
echo %%a|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%a
)
echo %%b|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%b
)
)
The page you linked has the correct answer. Except that in Windows 2012 / 10 you should use skip=2 instead of 1. This way you will skip the 'services' line.
So your batch file will look like this:
query session >session.txt
for /f "skip=2 tokens=3," %%i in (session.txt) DO logoff %%i
del session.txt
We use this to log off all rdp sessions with the exception of the administrator. Could be tweaked as needed.
#echo off
:: Log off Active Users
query session | findstr "rdp, Active" | findstr /V "dministrator" >sessionActive.txt
for /f "tokens=3" %%i in (sessionActive.txt) DO logoff %%i
del sessionActive.txt
:: Log off Disconnected Users
query session | findstr "Disc" | findstr /V "dministrator, services" >sessionDisc.txt
for /f "tokens=2" %%i in (sessionDisc.txt) DO logoff %%i
del sessionDisc.txt
Note: "file.txt" contain computer name for each line.
for /f "tokens=*" %%i in ("*\file.txt") do (
psexec \\%%i -u domain\user -p password logoff console
)
Before using this code, you must download PsTools by this link:
https://download.sysinternals.com/files/PSTools.zip
https://learn.microsoft.com/vi-vn/sysinternals/downloads/psexec
Then extract PsTools archive => Copy all file => Paste to "*:\Windows\System32" => Installation Complete
use eol=> to skip active user
#echo off
query session > session.txt
::quser > session.txt
for /f "skip=2 eol=> tokens=2,3 delims= " %%G in (session.txt) DO (
echo %%G|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%G & echo logoff disconnect user %%G
)
echo %%H|findstr /xr "[1-9][0-9]* 0" >nul && (
logoff %%H & echo logoff active user %%H
)
)
del session.txt
I think I may struggle to explain the how I want my batch script to behave so here goes. My script is meant to act as a menu system requiring user input. What I have managed so far is to send a list of datestamps to output to a user. However I am attempting to arrange the script so any timestamp can be selected such as 1,2,3 and based on a prompt for user input. Later I want to save that to a variable in which I can do another operation with afterwards.
So this is what an example of what I can see:
FOR /f "tokens=3 delims= " %%G IN ('%history% ^| findstr /C:"Start Time:"') DO (call :subroutine %%G)
:subroutine
echo %1
GOTO :EOF
My output now looks like this:
20150706232400
20150706232707
20150706232757
20150706233058
20150706233144
Any pointers appreciated. Thanks.
#echo off
setlocal EnableDelayedExpansion
rem Show menu and store options in an array
echo Available datestamps:
echo/
set i=0
FOR /f "tokens=3" %%G IN ('%history% ^| findstr /C:"Start Time:"') DO (
set /A i+=1
echo !i!. %%G
set "option[!i!]=%%G"
)
echo/
:getChoice
set /P "choice=Enter desired option: "
if "!option[%choice%]!" equ "" echo ERROR: no such option & goto getChoice
set "variable=!option[%choice%]!"
ECHO/
ECHO Selected datestamp: %variable%
I want to count the no of lines in a text file and then the value has to be stored into a environment variable. The command to count the no of lines is
findstr /R /N "^" file.txt | find /C ":"
I refered the question How to store the result of a command expression in a variable using bat scripts?
Then I tried,
set cmd="findstr /R /N "^" file.txt | find /C ":" "
I am getting the error message,
FIND: Parameter format not correct
How could i get rid of this error.
There is a much simpler way than all of these other methods.
find /v /c "" filename.ext
Holdover from the legacy MS-DOS days, apparently. More info here: https://devblogs.microsoft.com/oldnewthing/20110825-00/?p=9803
Example use:
adb shell pm list packages | find /v /c ""
If your android device is connected to your PC and you have the android SDK on your path, this prints out the number of apps installed on your device.
You could use the FOR /F loop, to assign the output to a variable.
I use the cmd-variable, so it's not neccessary to escape the pipe or other characters in the cmd-string, as the delayed expansion passes the string "unchanged" to the FOR-Loop.
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" file.txt | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
echo %number%
Inspired by the previous posts,
a shorter way of doing so:
CMD.exe
C:\>FINDSTR /R /N "^.*$" file.txt | FIND /C ":"
The number of lines
Try it. It works in my console.
EDITED:
(the "$" sign removed)
FINDSTR /R /N "^.*" file.txt | FIND /C ":"
$ reduces the number by 1 because it is accepting the first row as Field name and then counting the number of rows.
Try this:
#Echo off
Set _File=file.txt
Set /a _Lines=0
For /f %%j in ('Find "" /v /c ^< %_File%') Do Set /a _Lines=%%j
Echo %_File% has %_Lines% lines.
It eliminates the extra FindStr and doesn't need expansion.
- edited to use ChrisJJ's redirect suggestion. Removal of the TYPE command makes it three times faster.
#Tony: You can even get rid of the type %file% command.
for /f "tokens=2 delims=:" %%a in ('find /c /v "" %_file%') do set /a _Lines=%%a
For long files this should be even quicker.
I usually use something more like this
for /f %%a in (%_file%) do (set /a Lines+=1)
for /f "usebackq" %A in (`TYPE c:\temp\file.txt ^| find /v /c "" `) do set numlines=%A
in a batch file, use %%A instead of %A
The perfect solution is:
FOR /F %%i IN ('TYPE "Text file.txt" ^| FIND /C /V ""') DO SET Lines=%%i
I found this solution to work best for creating a log file that maintains itself:
setlocal enabledelayedexpansion
SET /A maxlines= 10
set "cmd=findstr /R /N "^^" "filename.txt" | find /C ":""
for /f %%a in ('!cmd!') do set linecount=%%a
GOTO NEXT
:NEXT
FOR /F %%A IN ("filename.txt") DO (
IF %linecount% GEQ %maxlines% GOTO ExitLoop
echo %clientname% %Date% %Time% >> "filename.txt")
EXIT
:ExitLoop
echo %clientname% %Date% %Time% > "filename.txt"
EXIT
Environmental variables included are %clientname% the computername of the remote client %Date% is the current date and %Time% the current time. :NEXT is called after getting the number of lines in the file. If the file line count is greater than the %maxlines% variable it goes to the :EXITLOOP where it overwrites the file, creating a new one with the first line of information. if it is less than the %maxlines% variable it simply adds the line to the current file.
You don't need to use find.
#echo off
set /a counter=0
for /f %%a in (filename) do set /a counter+=1
echo Number of lines: %counter%
This iterates all lines in the file and increases the counter variable by 1 for each line.
The :countLines subroutine below accepts two parameters: a variable name; and a filename. The number of lines in the file are counted, the result is stored in the variable, and the result is passed back to the main program.
The code has the following features:
Reads files with Windows or Unix line endings.
Handles Unicode as well as ANSI/ASCII text files.
Copes with extremely long lines.
Isn’t fazed by the null character.
Raises an error on reading an empty file.
Counts beyond the Batch max int limit of (31^2)-1.
#echo off & setLocal enableExtensions disableDelayedExpansion
call :countLines noOfLines "%~1" || (
>&2 echo(file "%~nx1" is empty & goto end
) %= cond exec =%
echo(file "%~nx1" has %noOfLines% line(s)
:end - exit program with appropriate errorLevel
endLocal & goto :EOF
:countLines result= "%file%"
:: counts the number of lines in a file
setLocal disableDelayedExpansion
(set "lc=0" & call)
for /f "delims=:" %%N in ('
cmd /d /a /c type "%~2" ^^^& ^<nul set /p "=#" ^| (^
2^>nul findStr /n "^" ^&^& echo(^) ^| ^
findStr /blv 1: ^| 2^>nul findStr /lnxc:" "
') do (set "lc=%%N" & call;) %= for /f =%
endlocal & set "%1=%lc%"
exit /b %errorLevel% %= countLines =%
I know it looks hideous, but it covers most edge-cases and is surprisingly fast.
Just:
c:\>(for /r %f in (*.java) do #type %f ) | find /c /v ""
Font: https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l
One nice surprise is for one who has git bash on his windows: just plain old linux wc -l <filename> will works for you there
In the below code, the variable name are SalaryCount and TaxCount
#ECHO OFF
echo Process started, please wait...
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set SalaryCount=%%C
echo Salary,%SalaryCount%
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set TaxCount=%%C
echo Tax,%TaxCount%
Now if you need to output these values to a csv file, you could use the below code.
#ECHO OFF
cd "D:\CSVOutputPath\"
echo Process started, please wait...
echo FILENAME,FILECOUNT> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set Count=%%C
echo Salary,%Count%>> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set Count=%%C
echo Tax,%Count%>> SUMMARY.csv
The > will overwrite the existing content of the file and the >> will append the new data to existing data. The CSV will be generated in D:\CSVOutputPath
You can pipe the output of type into find inside the in(…) clause of a for /f loop:
for /f %%A in ('
type "%~dpf1" ^| find /c /v ""
') do set "lineCount=%%A"
But the pipe starts a subshell, which slows things down.
Or, you could redirect input from the file into find like so:
for /f %%A in ('
find /c /v "" ^< "%~dpf1"
') do set "lineCount=%%A"
But this approach will give you an answer 1 less than the actual number of lines if the file ends with one or more blank lines, as teased out by the late foxidrive in counting lines in a file.
And then again, you could always try:
find /c /v "" example.txt
The trouble is, the output from the above command looks like this:
---------- EXAMPLE.TXT: 511
You could split the string on the colon to get the count, but there might be more than one colon if the filename had a full path.
Here’s my take on that problem:
for /f "delims=" %%A in ('
find /c /v "" "%~1"
') do for %%B in (%%A) do set "lineCount=%%B"
This will always store the count in the variable.
Just one last little problem… find treats null characters as newlines. So if sneaky nulls crept into your text file, or if you want to count the lines in a Unicode file, this answer isn’t for you.
You can also try
set n=0 & for /f "tokens=*" %a in (text.txt) do set/a n=!n!+1
echo !n!
You can also mark with a wildcard symbol * to facilitate group files to count.
Z:\SQLData>find /c /v "" FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_*.txt
Result
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS01_V1.TXT: 2041
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIOST00_V1.TXT: 315938
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS00_V1.TXT: 0
---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_CNTPTF00_V1.TXT: 277