How to run a batch file for every user returned in list by command net user?

我只是一个虾纸丫 提交于 2020-01-05 06:59:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!