Skip navigation

JSI Tip 1676. Do you have user/group corruption?

You probably don't have user/group corruption of the SAM, but I saw a user post that claimed to have the problem.

You probably don't have user/group corruption of the SAM, but I saw a user post that claimed to have the problem.

Primarily to demonstrate the technique, I have written a batch script to detect group corruption.

Orphaned_Groups.bat uses the public domain SHOWMBRS program, to improve performance, but could easily be replaced by parsing the standard net group and net localgroup commands (which are also used in this script), and uses the freeware FSORT, though the standard SORT command would work as well.

The syntax for using the batch, which should be run on your PDC (or workstation for local corruption) is:

Orphaned_Groups.bat <Drive:>\Folder\OutputReportFile.extension

where <Drive:>\Folder\OutputReportFile.extension is the full path to the file that will contain the report.

Orphaned_Groups works by parsing the groups from the net group and net localgroup command and using SHOWMBRS to output the membership. The NET USER command is them used to parse the user names and a NET USER <UserName> is used to output the users global and local group membership. Finally, the output file is sorted and inconsistencies are reported. The script also reports empty groups, primarly to have someting to report. The sorted temporary file is not deleted, in case you want to use it. It is stored at %TEMP%\orphaned_groups.tmp and has the following fields:

Postion Lenght  D e s c r i p t i o n                    
 000     25     Group Name
 025     25     Group member, either UserName or GroupName
 050      1     Record type, 1=Group Name from the NET command, 
                             2=Group Membership from the NET USER command
                             3=Group Membership from the SHOWMBRS program
 051      1     Group Type,  G=Global, L=Local
 052      1     Member Type, G=Group, U=User
 053     35     User Full Name or Domain Name (as in DomainName\UserName)

Here is a sample report, where I forced corruption:


Account Operators                                   1 L G                                     - Group has no members. 
Administrators            JERRY                     2 L U Jerold Schulman                     -  missing from group Administrators . 
Administrators            JSI_ADMINISTRATORS        3 L U JSI                                 - JSI_ADMINISTRATORS  missing Administrators  reference. 
Administrators            Opalis                    2 L U OpalisRobot                         -  missing from group Administrators . 
Backup Operators          JERRY                     2 L U Jerold Schulman                     - No group Backup Operators . 
Domain Admins             JERRY                     3 G U                                     - JERRY missing Domain Admins reference. 
Domain Admins             Opalis                    3 G U                                     - Opalis  missing Domain Admins reference. 
Domain Admins             ULTRABAC                  2 G U ULTRABAC                            -  missing from group Domain Admins. 
FastCon Users                                       1 L G                                     - Group has no members. 
Server Operators                                    1 L G                                     - Group has no members. 
Test Global                                         1 G G                                     - Group has no members. 

Orphaned_Groups.bat contains:

@echo off
if NOT "%1"

"" goto begin :syntax @echo Syntax: Orphaned_Groups File goto end :begin setlocal set utp=G set gt=G set file=%1 if exist %file% del /q %file% if exist %TEMP%\orphaned_groups.log del /q %TEMP%\orphaned_groups.log if exist %TEMP%\orphaned_groups.tmp del /q %TEMP%\orphaned_groups.tmp for /f "Skip=2 Tokens=*" %%i in ('net group') do call :prsgrp "%%i" set gt=L for /f "Skip=2 Tokens=*" %%i in ('net localgroup') do call :prsgrp "%%i" set utp=G for /f "Skip=4 Tokens=*" %%i in ('net users') do call :prsuser "%%i" @echo ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ0 >>%TEMP%\orphaned_groups.log fsort %TEMP%\orphaned_groups.log %TEMP%\orphaned_groups.tmp -cn @echo Begin report phase. del /q %TEMP%\orphaned_groups.log set pregrp=Z set preusr=Z set preunm=Z set pregt=Z set prert=0 set pret1=0 set preut=G for /f "Tokens=*" %%i in (%TEMP%\orphaned_groups.tmp) do call :report "%%i" endlocal goto end :report set substr=%1 set substr=%substr:"=% set grp=%substr:~0,25% set usr=%substr:~25,25% set rt=%substr:~50,1% set gt=%substr:~51,1% set ut=%substr:~52,1% set unm=%substr:~53,35% set grpe=%grp: =% set usre=%usr: =% if "%rt%"

"1" goto rt1 if "%rt%"

"2" goto rt2 if "%rt%"

"3" goto rt3 if "%rt%"

"0" goto rt1 echo %grp% %usr% %rt% %gt% %ut% %unm% - Unknown Record Type. >> %file% goto newgrp :rt1 if "%prert%"

"0" goto newgrp if "%grp%"

"%pregrp%" goto dupgrp if "%prert%"

"1" goto prenom if "%prert%"

"2" goto preno3x :newgrp set pret1=%rt% :samegrp set pregrp=%grp% set preusr=%usr% set prert=%rt% set pregt=%gt% set preunm=%unm% set preut=%ut% set pregrpe=%pregrp: =% set preusre=%preusr: =% goto end :dupgrp echo %grp% %usr% %rt% %gt% %ut% %unm% - Duplicate Group %grpe%. >> %file% goto newgrp :preno3x echo %pregrp% %preusr% %prert% %pregt% %preut% %preunm% - %preusere% missing from group %pregrpe%. >> %file% goto newgrp :prenom echo %pregrp% %preusr% %prert% %pregt% %preut% %preunm% - Group has no members. >> %file% goto newgrp :rt2 if "%grp%"

"%pregrp%" goto rt2c echo %grp% %usr% %rt% %gt% %ut% %unm% - No group %grpe%. >> %file% set prert1=1 set pregrp=%grp% set prert=1 :rt2c if "%usr%"

"%preusr%" goto dupusr if "%prert%"

"2" echo %pregrp% %preusr% %prert% %pregt% %preut% %preunm% - %preusere% missing from group %pregrpe%. >> %file% goto samegrp :dupusr echo %grp% %usr% %rt% %gt% %ut% %unm% - Duplicate user %usre%. >> %file% goto samegrp :rt3 if "%grp%"

"%pregrp%" goto rt3c echo %grp% %usr% %rt% %gt% %ut% %unm% - No group %grpe%. >> %file% set prert1=1 set pregrp=%grp% set prert=1 :rt3c if "%prert%"

"1" goto rt3p1 if "%prert%"

"2" goto rt3p2 if "%prert%"

"3" goto rt3p3 if "%ut%"

"G" echo %grp% %usr% %rt% %gt% %ut% %unm% - No group %grpe%. >> %file% if "%ut%"

"U" echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% missing %grpe% reference. >> %file% goto samegrp :rt3p1 if "%ut%"

"G" goto samegrp echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% missing %grpe% reference. >> %file% goto samegrp :rt3p2 if "%usr%"

"%preusr%" goto rt3p2u echo %pregrp% %preusr% %prert% %pregt% %preut% %preunm% - %preusere% missing from group %pregrpe%. >> %file% if "%ut%"

"G" goto samegrp echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% missing %grpe% reference. >> %file% goto samegrp :rt3p2u if not "%gt%"

"%pregt%" goto diffgt if not "%ut%"

"%preut%" goto diffut goto samegrp :rt3p3 if "%usr%"

"%preusr%" goto rt3p3u if "%ut%"

"G" goto samegrp echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% missing %grpe% reference. >> %file% goto samegrp :rt3p3u if "%ut%"

"G" goto rt3p3g echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% missing %grpe% reference. >> %file% goto samegrp :rt3p3g echo %grp% %usr% %rt% %gt% %ut% %unm% - %usre% duplicate in %grpe%. >> %file% goto samegrp :diffgt echo %grp% %usr% %rt% %gt% %ut% %unm% - Different group type from net user. >> %file% goto samegrp :diffut echo %grp% %usr% %rt% %gt% %ut% %unm% - Different user type %ut% vs %preut%. >> %file% goto samegrp :prsgrp set str=#%1# set str=%str:#"=% set str=%str:"#=% if "%str%"

"The command completed successfully." goto end set substr=%str:~0,26% if not "%substr:~0,1%"

"*" goto end set substr=%substr:**=% set substr=%substr:~0,25% set Usernm= # set Usernm=%Usernm:~0,35% @echo %substr% 1%gt%G%Usernm% >>%TEMP%\orphaned_groups.log call :group "%substr%" set substr=%str:~26,26% if not "%substr:~0,1%"

"*" goto end set substr=%substr:**=% set substr=%substr:~0,25% set Usernm= # set Usernm=%Usernm:~0,35% @echo %substr% 1%gt%G%Usernm% >>%TEMP%\orphaned_groups.log call :group "%substr%" set substr=%str:~52,26% if not "%substr:~0,1%"

"*" goto end set substr=%substr:**=% set substr=%substr:~0,25% set Usernm= # set Usernm=%Usernm:~0,35% @echo %substr% 1%gt%G%Usernm% >>%TEMP%\orphaned_groups.log call :group "%substr%" goto end :group set gid=%1 set gid=%gid:"=%# set gid=%gid: =% set gid=%gid: #=% set gid=%gid:#=% for /f "Skip=2 Tokens=*" %%i in ('showmbrs "%gid%"') do call :prsusr "%%i" goto end :prsusr set utp=G set users=%1 set wrk=%users% set users=%users:"=%# if /i "%users:~0,24%"

"Could not find any users" goto end set work=%users:$#=% if not "%work%"

"%users%" goto end for /f "Tokens=1* Delims=\" %%i in ('@echo %users%') do set u1=%%i&set u2=%%j set Usernm= # if not "%u2%"

"" set Usernm=%u1% #&set users=%u2% set work=%users:#=% set users=%users:#= #% set users=%users:~0,25% set Usernm=%Usernm% # set Usernm=%Usernm:~0,35% if "%gt%"

"G" set utp=U&goto prsusro for /f "Tokens=*" %%i in ('showmbrs "%wrk%"') do call :uorg "%%i" :prsusro @echo %substr%%users%3%gt%%utp%%Usernm% >>%TEMP%\orphaned_groups.log goto end :uorg set uorgok=%1 if %uorgok%

"Error, Group name not found." set utp=U goto end :prsuser set str=#%1# set str=%str:#"=% set str=%str:"#=% if "%str%"

"The command completed successfully." goto end set substr=%str:~0,25%# set substr=%substr: =% set substr=%substr: #=% set substr=%substr:#=% if "%substr%"

"" goto end for /f "Tokens=*" %%i in ('net user "%substr%"') do call :prsuser1 "%%i" set substr=%str:~25,25%# set substr=%substr: =% set substr=%substr: #=% set substr=%substr:#=% if "%substr%"

"" goto end for /f "Tokens=*" %%i in ('net user "%substr%"') do call :prsuser1 "%%i" set substr=%str:~50,25%# set substr=%substr: =% set substr=%substr: #=% set substr=%substr:#=% if "%substr%"

"" goto end for /f "Tokens=*" %%i in ('net user "%substr%"') do call :prsuser1 "%%i" goto end :prsuser1 set ustr=%1 if %ustr%

"The command completed successfully." goto end set ustr=%ustr:"=% if "%ustr%"

"" goto end set ustr=%ustr% # set ln="%ustr:~0,8%" if %ln%

"User nam" set Userid=%ustr:~29,25%&goto end if %ln%

"Full Nam" set Usernm=%ustr:~29,35%&goto end if %ln%

"Local Gr" set gt=L&goto grp if %ln%

"Global G" set gt=G&goto grp if "%ustr:~0,1%"

"*" goto grp1 goto end :grp set ustr=%ustr:~29,99% if not "%ustr:~0,1%"

"*" goto end :grp1 set substr=%ustr:~1,21% # set substr=%substr:~0,25% @echo %substr%%Userid%2%gt%U%Usernm% >>%TEMP%\orphaned_groups.log if not "%ustr:~22,1%"

 

"*" goto end set substr=%ustr:~23,21% # set substr=%substr:~0,25% @echo %substr%%Userid%2%gt%U%Usernm% >>%TEMP%\orphaned_groups.log :end

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish