batch: ignore last line of an output - windows

I have a pretty basic script that echos local administrator accounts. My goal is to get rid of all of the header/footer information.
So far I have:
FOR /F "skip=6" %%G IN ('net localgroup administrators') DO echo %%G
Which echos:
Administrator
MyName
The
"The" being the first word in the footer: "The command completed successfully."
So I'd like to get rid of "The" but I understand that I may have to restructure the entire script, which is fine. I have tried saving to a variable %str% but you can't set multi-line variables. Also, using a txt file as a buffer is not an option.
Any input?

I can think of two simple solutions:
FOR /F "skip=6" %%G IN ('net localgroup administrators') DO if %%G neq The echo %%G
or
FOR /F "skip=6" %%G IN ('net localgroup administrators ^| findstr /vb The') DO echo %%G
I suppose one could argue a user name could be "The", in which case you can be more precise with the filter:
FOR /F "skip=6" %%G IN ('net localgroup administrators ^| findstr /vc:"The command completed successfully."') DO echo %%G

Related

How do you set a specific part of the output of a CMD batch command as a variable? or alternatively, just echo it?

I'm writing a simple little batch file that gets the password of a saved Wi-Fi network, but I want to grab the Key Content, then paste it on its own. Here's the current code:
#echo off
set /p name=Enter Wi-Fi Name:
cls
echo %name%
netsh wlan show profile name="%name%" key=clear
cmd /k
This gives me a long list of data, but the line I'm looking for is the "Key Content" line. What I essentially want to do is grab the "Key Content" line, clear all the lines, then echo the "Key Content" line. Is this possible without any plugins on Windows 11?
I'm new to the site and coding as a whole, by the way, so what may seem like something completely obvious to you is something I have a 95 percent chance not to know. Thank you!
Here's a batch-file snippet, based upon you having received and properly validated the end users input:
#For /F "Tokens=1,* Delims=:" %%H In ('
%SystemRoot%\System32\netsh.exe WLAN Show Profiles Name^="%name%" Key^=Clear
2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"^[ ][ ]*Key Content[ ][ ]*: "
') Do #(Set "}=%%I" & SetLocal EnableDelayedExpansion
For %%J In ("!}:~1!") Do #EndLocal & Echo(%%J)
You should always perform robust validation of any end users input, especially when using the Set /P command, which can accept nothing or absolutely anything, (including malicious content). If the target systems are Windows 8 / Server 2012 or above, then I wouldn't waste time asking the end user to self-determine the wireless profile name, and then type it correctly at a prompt. I'd just output all of the profile names, along side their returned keys.
The following examples are untested, and assume that your 'passwords' do not include double-quote characters. They should provide the output in a CSV-like format, ("ProfileName","Password"):
#For /F Tokens^=6^ Delims^=^" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe
/NameSpace:\\Root\StandardCimv2 Path MSFT_NetConnectionProfile Get Name
/Format:MOF 2^>NUL') Do #For /F "Tokens=1,* Delims=:" %%H In ('
%SystemRoot%\System32\netsh.exe WLAN Show Profiles Name^="%%G" Key^=Clear
2^>NUL ^| %SystemRoot%\System32\findstr.exe /RIC:"^[ ][ ]*Key Content[ ][ ]*: "
') Do #(Set "}=%%I" & SetLocal EnableDelayedExpansion
For %%J In ("!}:~1!") Do #EndLocal & Echo("%%G",%%J)
#Pause
As you appear to have used the cmd tag, despite your question being about a batch-file, you could probably do similarly, directly in the Command Prompt, (cmd.exe) too:
For /F Tokens^=6^ Delims^=^" %G In ('%SystemRoot%\System32\wbem\WMIC.exe /NameSpace:\\Root\StandardCimv2 Path MSFT_NetConnectionProfile Get Name /Format:MOF 2^>NUL') Do #For /F "Tokens=1,* Delims=:" %H In ('"%SystemRoot%\System32\netsh.exe WLAN Show Profiles Name="%G" Key=Clear 2>NUL | %SystemRoot%\System32\findstr.exe /RIC:"^[ ][ ]*Key Content[ ][ ]*: ""') Do #Set "}=%I" & For /F Delims^=^ EOL^= %J In ('%SystemRoot%\System32\cmd.exe /V /D /C "Echo "%G","!}:~1!""') Do #(Set /P ="%J") 0<NUL & Echo(

Issues when getting a list of user profiles using WMIC

I was using the following batch command to retrieve all local user profiles (including domain users too) :
for /f "delims=" %%I in ('dir /a:d-h /b "%SystemDrive%\Users\*" 2^>nul ^| %SystemRoot%\System32\findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"') do (
The problem is that this command has its limits: it doesn't really check if the users in question do actually have an account.
The user Compo provided me a methodology for retrieving the profile names, using WMIC.
So I ended up writing the following command:
#For /F "tokens=* skip=1" %%I In ('%__AppDir__%wbem\WMIC.exe UserAccount Get Name ^|%__AppDir__%findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"') do (
The problem is: it ignores my exclusion file (which contains one user per line) and it ends up a profile without any name.
Any idea How I can solve these issues ?
#echo off
setlocal
set "bin=%~dp0"
for /f "tokens=* skip=1" %%I in ('
%__AppDir__%wbem\WMIC.exe UserAccount where Disabled^="FALSE" get Name ^|
%__AppDir__%WindowsPowerShell\v1.0\powershell -noprofile -command "$input.trim()" ^|
%__AppDir__%findstr.exe /i /l /x /v /g:"%bin%\exclude_users.txt"
') do echo "%%~I"
The wmic output is piped to powershell to be trimmed and then piped to findstr.
The wmic command will exclude disabled accounts by use of the where clause.
Change the setting of bin as needed.
If you want a solution which still uses WMIC, and your exclusion list, then the following should do as you require.
#For /F Tokens^=4Delims^=^" %%G In ('%__AppDir__%wbem\WMIC.exe UserAccount Where "LocalAccount='TRUE'" Assoc:List /ResultRole:Name 2^>NUL')Do #Echo %%G|%__AppDir__%findstr.exe /VXLIG:"%~dp0exclude_users.txt"
You can split that over multiple lines for easier reading too:
#For /F Tokens^=4Delims^=^" %%G In ('%__AppDir__%wbem\WMIC.exe UserAccount^
Where "LocalAccount='TRUE'" Assoc:List /ResultRole:Name 2^>NUL'
)Do #Echo %%G|%__AppDir__%findstr.exe /VXLIG:"%~dp0exclude_users.txt"

Collect each service's display name and status

I want to get list of services with their display name and their status.
This is what I have tried:
for /f "tokens=2" %s in ('SC query state^= all ^| find "DISPLAY_NAME"') do #(for /f "tokens=4" %t in ('SC query %s ^| find "STATE"') do #echo %s is %t)
But this returns only limited services such as disk, etc.
This is a perfect task for the built-in WMI command line executable, WMIC.exe.
From the cmd.exe prompt:
For /F "Skip=1 Delims=" %A In ('"WMIC Service Get DisplayName, Name, State"') Do #For /F "Delims=" %B In ("%A") Do #Echo(%B
From a batch file:
#For /F "Skip=1 Delims=" %%A In ('"WMIC Service Get DisplayName, Name, State"'
) Do #For /F "Delims=" %%B In ("%%A") Do #Echo(%%B
#Pause
Try getting help from powershell directly in your batch file, like this for example (save as .bat and run it). In the example i type it to the screen and give you ALL services, RUNNING ONLY, and STOPPED ONLY but you could do basically what you want with the content of that txt file (search it with a loop, save a part to a variable, etc.).
#echo off&cls
pushd %~dp0
echo.
echo List ALL services
pause
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "powershell Get-Service | Out-File services.txt"
type services.txt
echo.
echo List services that are RUNNING only
pause
find "Running" services.txt
echo.
echo List services that are STOPPED only
pause
find "Stopped" services.txt
pause
:cleanup
del /f services.txt

FOR /F error not reading .csv {BATCH FILE}

i am currently getting these errors when running my batch file:
System error 1379 has occurred.
The specified local group already exists.
Press any key to continue . . .
The system cannot find the file users.csv. {This is where my problem lies}
Press any key to continue . . .
There is no such global user or group: users.csv
My Batch File
#echo off
REM Adding a local group
net localgroup NEWDOSGROUP /Comment:"New Group Assignment" /add
pause
REM Add all the users from a .csv file
FOR /F "tokens=1,2 delims=," %%G IN (users.csv) DO (
net adduser
pause
REM Adding users to a local group
FOR /F "tokens=1,2 delims=," %%a IN ("users.csv") Do (
net localgroup NEWDOSGROUP %%a /add
)
pause
any help would be amazing thanks.
Put users.csv in the same folder as the batch file.
This loop is also missing a closing parenthesis by the look of it, and the net adduser should probably have an argument of %%G or %%H or similar
FOR /F "tokens=1,2 delims=," %%G IN (users.csv) DO (
net adduser
REM Add all the users from a .csv file
FOR /F "tokens=1,2 delims=," %%G IN (users.csv) DO (
net adduser
REM ARE YOU MISSING A CLOSE-PARENTHESIS HERE?
REM WHAT IS NET ADDUSER?
REM WHY ARE YOU NOT USING %%G,%%H?
REM HERE YOU'VE OPENED USERS.CSV... ARE YOU THEN TRYING TO RE-OPEN IT?
REM IS AN OPEN USERS.CSV CAUSING THE PROBLEM?
REM IS THE SYNTAX OF THE FOR...%%a CORRECT? USEBACKQ PERHAPS?
REM NOT SHOUTING - JUST EMPHASISING
pause
REM Adding users to a local group
FOR /F "tokens=1,2 delims=," %%a IN ("users.csv") Do (
net localgroup NEWDOSGROUP %%a /add
)
pause

pass the output of a batch file into a for loop

I am trying to pass the output of a process into a for loop by using pipes
type %1% | findstr /R /V "Test" | for /F "tokens=*" %%i IN ('more') DO #echo %%i
but I do not know what to put in place of ('more') so that it reads the output from the findstr command. Is this even possible? Or do I have to save the output to a file and then read in the file in an entirely different batch program? Please help.
for /f "delims=" %%a in ('findstr /rv "Test" "%1%" ^| more') do echo %%a
for loops cannot read from STDIN, so you need to put the command whose output you want to process into the parantheses:
for /F "tokens=*" %%i IN ('type %1% ^| findstr /R /V "Test"') DO #echo %%i
Note that pipes must be escaped in the subshell (^|).

Resources