none
Guest status

    Domanda

  • Are there any scripts that can audit each workstation (not server) in the domain to see if guest is enabled? Or perhaps just list machines where guest is enabled. It's not practical to audit each manually... This strangely doesnt seem to be a domain level setting albeit you'd think by default it would be disabled.

    lunedì 20 febbraio 2012 12:05

Risposte

  • The code below should be what you want. As always test first.

    'This script uses Active Directory to find and connect to all Windows and check the status of the Guest account, Enabled or Disabled.
    'Will return "True" if the account is Disabled
    
    On Error Resume Next
    
    Const ForWriting = 2
    set objFSO = CreateObject("scripting.filesystemobject")
    set objFile = objFSO.createtextfile(".\AuditGuestAccountStatus.txt")
    objFile.WriteLine "Name;Disabled;sID;Error"
    
    domain = "DC=Domain,DC=Com" 
    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand = CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConnection
     
    objCommand.CommandText = _ 
    "SELECT distinguishedName, Name, Location, operatingSystem, operatingSystemservicepack FROM " _ 
    & "'LDAP://" & domain & "' WHERE objectClass='computer' " _ 
    & "and operatingSystem = '*server*'"
    
    objCommand.Properties("Timeout") = 30
    
    Set objRecordSet = objCommand.Execute()
    Do Until objRecordSet.EOF
        
        strComputer=objRecordSet.Fields("Name").Value
        'set objWMIDateTime = CreateObject("WbemScripting.SWbemDateTime")
        'set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
    
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    
     
    If Err.Number <> 0 Then  
     objFile.WriteLine strComputer & ";" & ";" & ";" & Err.Description
    Err.Clear
    Else
    
    
    Set colItems = objWMIService.ExecQuery _
    ( "Select * from Win32_UserAccount Where LocalAccount = True AND Name='Guest' " )
     
    'Set colGroups = GetObject("WinNT://" & strComputer & "")
    
    For Each objItem in colItems
        
    	objFile.WriteLine strComputer & ";" & objItem.Disabled & ";" & objItem.SID
    
        'Wscript.Echo "Account Type: " & objItem.AccountType
        'Wscript.Echo "Caption: " & objItem.Caption
        'Wscript.Echo "Description: " & objItem.Description
        'Wscript.Echo "Disabled: " & objItem.Disabled
        'Wscript.Echo "Domain: " & objItem.Domain
        'Wscript.Echo "Full Name: " & objItem.FullName
        'Wscript.Echo "Local Account: " & objItem.LocalAccount
        'Wscript.Echo "Lockout: " & objItem.Lockout
        'Wscript.Echo "Name: " & objItem.Name
        'Wscript.Echo "Password Changeable: " & objItem.PasswordChangeable
        'Wscript.Echo "Password Expires: " & objItem.PasswordExpires
        'Wscript.Echo "Password Required: " & objItem.PasswordRequired
        'Wscript.Echo "SID: " & objItem.SID
        'Wscript.Echo "SID Type: " & objItem.SIDType
        'Wscript.Echo "Status: " & objItem.Status
        'Wscript.Echo
    Next
    
    
    
    end if
    objRecordSet.MoveNext 
    Loop
    
    objFile.WriteLine "Complete"
    
    objFile.Close

    • Contrassegnato come risposta cf090 martedì 21 febbraio 2012 13:55
    lunedì 20 febbraio 2012 14:04

Tutte le risposte

  • This script should get you started:

    http://gallery.technet.microsoft.com/scriptcenter/827623f5-eb55-4035-8f57-25c4afb444cd

    Just add a filter for an account named guest and only extract the Disabled value. That would do the trick, set up this query to run on all your computer and write the output to a text file and you will be all set.


    lunedì 20 febbraio 2012 12:25
    Moderatore
  • This script should get you started:

    http://gallery.technet.microsoft.com/scriptcenter/827623f5-eb55-4035-8f57-25c4afb444cd

    Just add a filter for an account named guest and only extract the Disabled value. That would do the trick, set up this query to run on all your computer and write the output to a text file and you will be all set.


    Thanks for the reply.

    Excuse my ignorance, but is this script geared to report on just one machine? Or is the paramter the domain? Or the OU? And subsequently would it then list them for all machines in that domain?

    lunedì 20 febbraio 2012 13:25
  • This line states the computer on which it is executed:

    strComputer = "." 


    If you would replace that line with this:

    ' If no argument is supplied then script is executed on local computer
    set args = Wscript.Arguments
    If Wscript.Arguments.Count = 0 Then
    	strComputer = "." 
    Else
    	strComputer = args.item(0)
    end if

    What this does is it makes the script execute locally if no parameter is given, but if you call the script with a parameter it will use that as the computer name eg:

    cscript guestaccount.vbs computer1
    cscript guestaccount.vbs computer2
    cscript guestaccount.vbs computer3

    This way you could batch it to run on all computer you wish to target. An alternative method might be to read the computer names from a file (plaintext/csv) and have the script action on that or even to query AD and target computers based on the AD query.

    lunedì 20 febbraio 2012 13:36
    Moderatore
  • The code below should be what you want. As always test first.

    'This script uses Active Directory to find and connect to all Windows and check the status of the Guest account, Enabled or Disabled.
    'Will return "True" if the account is Disabled
    
    On Error Resume Next
    
    Const ForWriting = 2
    set objFSO = CreateObject("scripting.filesystemobject")
    set objFile = objFSO.createtextfile(".\AuditGuestAccountStatus.txt")
    objFile.WriteLine "Name;Disabled;sID;Error"
    
    domain = "DC=Domain,DC=Com" 
    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand = CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConnection
     
    objCommand.CommandText = _ 
    "SELECT distinguishedName, Name, Location, operatingSystem, operatingSystemservicepack FROM " _ 
    & "'LDAP://" & domain & "' WHERE objectClass='computer' " _ 
    & "and operatingSystem = '*server*'"
    
    objCommand.Properties("Timeout") = 30
    
    Set objRecordSet = objCommand.Execute()
    Do Until objRecordSet.EOF
        
        strComputer=objRecordSet.Fields("Name").Value
        'set objWMIDateTime = CreateObject("WbemScripting.SWbemDateTime")
        'set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
    
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    
     
    If Err.Number <> 0 Then  
     objFile.WriteLine strComputer & ";" & ";" & ";" & Err.Description
    Err.Clear
    Else
    
    
    Set colItems = objWMIService.ExecQuery _
    ( "Select * from Win32_UserAccount Where LocalAccount = True AND Name='Guest' " )
     
    'Set colGroups = GetObject("WinNT://" & strComputer & "")
    
    For Each objItem in colItems
        
    	objFile.WriteLine strComputer & ";" & objItem.Disabled & ";" & objItem.SID
    
        'Wscript.Echo "Account Type: " & objItem.AccountType
        'Wscript.Echo "Caption: " & objItem.Caption
        'Wscript.Echo "Description: " & objItem.Description
        'Wscript.Echo "Disabled: " & objItem.Disabled
        'Wscript.Echo "Domain: " & objItem.Domain
        'Wscript.Echo "Full Name: " & objItem.FullName
        'Wscript.Echo "Local Account: " & objItem.LocalAccount
        'Wscript.Echo "Lockout: " & objItem.Lockout
        'Wscript.Echo "Name: " & objItem.Name
        'Wscript.Echo "Password Changeable: " & objItem.PasswordChangeable
        'Wscript.Echo "Password Expires: " & objItem.PasswordExpires
        'Wscript.Echo "Password Required: " & objItem.PasswordRequired
        'Wscript.Echo "SID: " & objItem.SID
        'Wscript.Echo "SID Type: " & objItem.SIDType
        'Wscript.Echo "Status: " & objItem.Status
        'Wscript.Echo
    Next
    
    
    
    end if
    objRecordSet.MoveNext 
    Loop
    
    objFile.WriteLine "Complete"
    
    objFile.Close

    • Contrassegnato come risposta cf090 martedì 21 febbraio 2012 13:55
    lunedì 20 febbraio 2012 14:04
  • you can use PoSh as well if it's available to you.  this should get you started in PoSh if you'd rather go that route:

    import-module ac* Get-ADComputer -Filter * | % { gwmi -ComputerName $_.Name Win32_UserAccount -Filter "LocalAccount = 'True'" | Select Name,Disabled,Description,SID,PasswordRequired,PasswordChangeable,PasswordExpires} 

    and if you want that output in a file, just make a final pipe (|) to Export-CSV.  you could also work in a test to connect to the host before attempting the wmi query but i'm just trying to give you the basics.



    • Modificato thepip3r lunedì 20 febbraio 2012 17:42
    lunedì 20 febbraio 2012 14:10
  • I would change the WMI query to either:


    -filter "localaccount = 'true' and name = 'guest'"


    or 


    -filter "sid = 'S-1-5-21-<insertyourdomainsidhere>-501'"


    For more information about standard SIDs: http://support.microsoft.com/kb/243330
    lunedì 20 febbraio 2012 14:46
    Moderatore
  • If you wanted to filter it just to the guest account sure.  However, I simply made it all local accounts as there really shouldn't be all that many and it might point out a security hole in his environment.  And, in my environment, we disable the local administrator as well so pulling all user accounts was beneficial to know from my perspective. 
    lunedì 20 febbraio 2012 14:53
  • Yes I was not trying to say your example was wrong, I just realized that by rephrasing the query we could have a query closer to what the original poster requested. By filtering on SID he could even be querying for Guest accounts that have been renamed. 
    lunedì 20 febbraio 2012 14:59
    Moderatore
  • GP should be used to rename and disable the guest accuont.  The GP policy would then automatically alter any new machine when it is joined to the domain.  GP policy reporting would detect any machines that the policy has failed to apply to.

    This is more reliable, more secure and more automatic that using sneaker-net technology to enforce security.


    ¯\_(ツ)_/¯

    lunedì 20 febbraio 2012 18:29
  • Thank you ever so much.

    How would this script "react" if it say found 200/500 machines were powered off? Has anyone run it over a larger domain? How long did it take? Was their any performance issues? Is there any way it could be configured in terms of "chunks" (i.e. text files with a list of PC hostnames) so we can split it to a list of known "On" machines.

    martedì 21 febbraio 2012 09:01
  • GP should be used to rename and disable the guest accuont.  The GP policy would then automatically alter any new machine when it is joined to the domain.  GP policy reporting would detect any machines that the policy has failed to apply to.

    This is more reliable, more secure and more automatic that using sneaker-net technology to enforce security.


    ¯\_(ツ)_/¯


    I agree -- but in the first instance it was more fact finding than addressing the problem.
    martedì 21 febbraio 2012 09:10
  • Thank you ever so much.

    How would this script "react" if it say found 200/500 machines were powered off? Has anyone run it over a larger domain? How long did it take? Was their any performance issues? Is there any way it could be configured in terms of "chunks" (i.e. text files with a list of PC hostnames) so we can split it to a list of known "On" machines.

    Which script are you referring to? the vbscript or PowerShell one?  It all depends on how you handle offline machines. In PowerShell, I would wrap the command around the following code to handle offline systems:

    ForEach ($Computer in $Computername) [
        If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) {
            #Run code to query for guest account
        } Else {
            Write-Warning ("{0}: Offline!" -f $Computer)
        }
    }


    Boe Prox

    Please remember to mark the best solution as the answer using Mark as Answer. If you find a solution to be helpful, please use Vote as Helpful.

    Looking for a script? Check out the Script Repository
    Need a script written for you? Submit a request at the Script Request Page

    martedì 21 febbraio 2012 12:06
    Moderatore
  • The script would terminate the moment it notices it can't query WMI, you can easily test this by running it against 20 non-existant computernames and your own workstation. For me the script terminates in about 5 seconds, you can make this faster by adding in a check in the script that pings the host before querying WMI.

    There should be plenty of examples in the scripting repository, I found one here in this script:

    http://gallery.technet.microsoft.com/scriptcenter/ecc1a47e-82f4-4f44-a1f7-42cec5e802de

    martedì 21 febbraio 2012 12:14
    Moderatore
  • Are there any scripts that can audit each workstation (not server) in the domain to see if guest is enabled? Or perhaps just list machines where guest is enabled. It's not practical to audit each manually... This strangely doesnt seem to be a domain level setting albeit you'd think by default it would be disabled.

    It is a domain leverl setting.  That is what Group Policy is for.  Just set a GP for that one item. I call it 'REname Accounts Policy' and it is set to rename both admin and guest accounts= as well as disabling the guest account.  This always works.

    The Guest account on all systems post-XP are disabled by default.


    ¯\_(ツ)_/¯

    martedì 21 febbraio 2012 13:54