问题
My goal is to make a universal code which loops through all user account names in a computer and sends the output to a batch file. The "net user" command outputs a list of users but I want to assign each user name to an argument. So I should use the for /f
command to do it. This may look easy, but remember user names may include spaces at any place: at the beginning, at the end or in the middle, Also, it's possible to find 2 consecutive spaces
Hint 1: The maximum length of a user name is 20 characters
Hint 2: The loops needs to iterate through wrong user names so it needs to check if they're valid. The command net user "uName"
sets %ErrorLevel%
to 0 if the user name "uName" (for example) is valid.
If there's no way possible, maybe a VBScript could start the batch file with each of the user account names.
Edit: I finally made my own code, but it takes about 5 seconds for only 15 accounts.
I would like a better solution, maybe with another programming language.
setlocal EnableDelayedExpansion
For /f "skip=4 delims=" %%I in ('net user') do (
Set "Line=%%I"
If not "!Line:~-1,1!" == "." for %%I in (0,25,50) do (
Set "Name=!Line:~%%I,20!"
Call :setName
)
)
Set Name=
:setName
If not "!Name!" == "" (
Net user "!Name!" && %~dp0Test.bat "!Name!"
If not "!Name:~-1,1!" == " " goto:eof
Set "Name=!Name:~0,-1!"
Goto setName
)
endlocal
回答1:
A user account name with a space at beginning or end of name is according to my tests not possible. Spaces can be only between non whitespace characters in a user account name.
Here is my commented batch solution which is also not very fast.
@echo off
rem Process output of command 'net user' line by line with skipping
rem the first 4 lines and stopping processing when line with success
rem message is reached which of course depends on language of Windows.
for /F "usebackq skip=4 delims=" %%L in (`%SystemRoot%\System32\net.exe user`) do (
if "%%L"=="The command was successfully executed." goto :EOF
call :ProcessAccounts "%%L"
)
goto :EOF
rem Subrountine to process a line with user account names.
:ProcessAccounts
rem Get the line without the double quotes.
set "Line=%~1"
:NextUser
rem Get first 20 characters from line and next remove those 20 characters.
set "Name=%Line:~0,20%"
set "Line=%Line:~20%"
rem Remove all spaces at end of current user account name.
:TrimRight
if "%Name:~-1%"==" " (
set "Name=%Name:~0,-1%"
goto TrimRight
)
rem Check if this user account name is valid.
%SystemRoot%\System32\net.exe user "%Name%" 1>nul 2>nul
if not errorlevel 1 (
echo Valid user account name is: %Name%
rem Do here what should be done with this user account name.
)
rem Remove leading spaces from remaining line.
:TrimLeft
if "%Line:~0,1%"==" " (
set "Line=%Line:~1%"
goto TrimLeft
)
rem Is the shortened line now completely processed?
if not "%Line%"=="" goto NextUser
rem Exit the subroutine ProcessAccounts.
goto :EOF
There is perhaps a better solution for trimming spaces left and right, see How to remove trailing and leading whitespace for user-provided input in a batch file?
The reason for the slow execution speed of this batch file is:
%SystemRoot%\System32\net.exe user "%Name%" 1>nul 2>nul
if not errorlevel 1 (
echo Valid user account name is: %Name%
rem Do here what should be done with this user account name.
)
By changing this block to just
echo Valid user account name is: %Name%
rem Do here what should be done with this user account name.
makes the batch file much, much faster.
The validation of user account name with net user "%Name%"
makes the batch file so slow.
回答2:
Here is a one line powershell proposition :
foreach ($account in Get-WmiObject -Class Win32_UserAccount -Namespace "root\cimv2" -Filter "LocalAccount='$True'" -ComputerName . -ErrorAction Stop) { myscript.bat $account.Name}
you can store in a .ps1 file and execute with powershell myfile.ps1
If you need more than just local account you will have to mess with the -Filter
parameter.
Also, any account name with spaces will be passed with surrounding quotes, you need to cope with in the callee batch script.
来源:https://stackoverflow.com/questions/26935615/how-to-run-a-batch-file-for-every-user-returned-in-list-by-command-net-user