1

I'm writing a batch script that will use a WMIC command to get a list of all groups on a Windows machine, get the group info by using net localgroup <groupname>, and then write the info to an output file. Here is what I have:

for /f "skip=1" %%a in ('"wmic group get name"') do net localgroup %%a  >> "%OUTPUTFILEPATH%" 2> nul && echo.  >> "%OUTPUTFILEPATH%" && echo ^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=^=  >> "%OUTPUTFILEPATH%" && echo. >> "%OUTPUTFILEPATH%"

The issue I am having seems to be with getting quotes around the %%a variable in do net localgroup %%a because it outputs the info for groups like Administrators just fine but when it gets to a group name like Remote Desktop Users, it fails to return the info for the group.

In other words, this is what seems to be happening in the FOR loop:

net localgroup Administrators
net localgroup Remote Desktop Administrators

The first operation is successful. The second is not. Obviously, there need to be quotes around Remote Desktop Administrators in order for it to be seen as a single argument but I can't quite figure out how to get this to happen for my %%a FOR loop variable.

I have tried putting quotes around "%%a" and '%%a'. This doesn't help.

Any input would be greatly appreciated.

3 Answers3

2

You need to use either tokens=* as suggested by Carlos Gutiérrez or even better delims= on FOR to avoid splitting up the line into tokens based on spaces and tabs.

It is of course additionally necessary to enclose the group name in double quotes when any group name contains 1 or more spaces.

But the main problem here is that wmic outputs information in Unicode with UTF-16 Little Endian encoding which command FOR cannot parse right directly. A workaround for this issue is redirecting output of wmic into a temporary text file and using command type to get contents in ASCII/ANSI/OEM, i.e. one byte per character. See the answers on How to correct variable overwriting misbehavior when parsing output for details.

But there is one more problem here as wmic outputs the group names with trailing spaces. Those trailing spaces must be additionally removed before group name is passed as parameter to console application net enclosed in double quotes.

@echo off
setlocal EnableDelayedExpansion
set "OutputFile=%USERPROFILE%\Desktop\LocalGroupInfo.txt"
del "%OutputFile%" 2>nul
%SystemRoot%\System32\wbem\wmic.exe group get name >"%Temp%\%~n0.tmp"
for /f "skip=1 delims=" %%a in ('type "%Temp%\%~n0.tmp"') do (
    set "GroupName=%%a"
    call :RemoveTrailingSpaces
    %SystemRoot%\System32\net.exe localgroup "!GroupName!" >>"%OutputFile%" 2>nul
    if not errorlevel 1 (
        echo.>>"%OutputFile%"
        echo ==========================================>>"%OutputFile%"
        echo.>>"%OutputFile%"
    )
)
del "%Temp%\%~n0.tmp"
endlocal

:RemoveTrailingSpaces
if not "%GroupName:~-1%" == " " exit /B
set "GroupName=%GroupName:~0,-1%"
goto RemoveTrailingSpaces

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • del /?
  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • goto /?
  • if /?
  • net localgroup /?
  • set /?
  • setlocal /?
  • type /?
  • wmic group get /?
Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
2

REM

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "OUTPUTFILEPATH=u:\ofp.txt"
DEL  /F /Q "%outputfilepath%"
for /f "skip=1delims=" %%a in ('wmic group get name') do (
 SET "group=%%a"
 CALL :loptrail
 IF DEFINED group (
  net localgroup "!group!"  >> "%OUTPUTFILEPATH%" 2> NUL
  echo.>> "%OUTPUTFILEPATH%"
  echo ==========================================>> "%OUTPUTFILEPATH%"
  echo.>> "%OUTPUTFILEPATH%"
 )
)

GOTO :EOF

:loptrail
SET "group=%group:~0,-1%"
IF "%group:~-1%"==" " GOTO loptrail
GOTO :eof

The issue is that wmic output is unicode and %%a requires delims= else it returns the first [implicit-space]-delimited token.

Unfortunately, this means that %%a contains trailing spaces, which net appears to disapprove of.

Since batch does not allow a metavariable to be substringed, you need to put it into a common environment variable and invoke enabledelayedexpansion.

The value in group appears to be terminated by an extra NULL, so the :loptrail routine first arbitrarily removes that last character, then any remaining trailing spaces.

The very last line of wmic output will generate a forlorn empty group so the net processing proceeds only if group is non-empty.

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

Try:

for /f "tokens=*" %%a in ('"wmic group get name"') do ....
Carlos Gutiérrez
  • 13,972
  • 5
  • 37
  • 47
  • 1
    Thanks for the input! This does not appear to have done the trick. When using 'for /f "tokens=*" %%a in ('"wmic group get name"') do net localgroup %%a' instead of `for /f "skip=1" %%a in ('"wmic group get name"') do net localgroup %%a` I am still receiving a lot of `The syntax of this command is: NET LOCALGROUP [groupname [/COMMENT:"text"]] [/DOMAIN] groupname {/ADD [/COMMENT:"text"] | /DELETE} [/DOMAIN] groupname name [...] {/ADD | /DELETE} [/DOMAIN]` over and over again in STDERR and now it is no longer even logging the single-spaced groups names – Austin Eyler Feb 08 '16 at 06:18