Showing posts with label Audit. Show all posts
Showing posts with label Audit. Show all posts

2013/06/10

Scripting Games 2013 - Advanced Event 4 - An Auditing Adventure

This is my solution for the Advanced Event 4 of the Scripting Games 2013.
This event was a bit challenging for me... In the past, I played with Quest Active Directory snap-in to create a bunch of Monitoring tools and some other small automation tasks, but that's about it. (Example Monitor Active Directory Groups membership change).

Let's see how I solved it.



2013/01/07

Get-LocalGroupAllMembers

In my previous post, I explain my PowerShell function to retrieve the local administrators group membership.
Today I will go a bit further and find the nested members from the Active Directory.

Get-LocalGroupAllMembers


The following scripts query a localgroup on the localhost or a remote computer, and gather all the local and domain members (direct and nested).

By Default, if you do not specify any parameter, the function will query the Localhost and the Localgroup "Administrators".

Dot Sourcing

Once your Powershell is launched you can load the function using the Dot Sourcing method:
. ./Get-LocalGroupAllMembers.ps1

Usage


Get-LocalGroupAllMembers -ComputerName SERVER01 -GroupName "Administrators"

2012/12/31

Get-LocalGroupMembership (Using ADSI/WinNT)

Updated (2013/06/03): I added some error handeling/verbose/testing. You are now able to pass multiple computers to the ComputerName parameter.

Intro

Recently I had to do an Audit at my work to find who was Local Administrators on a bunch of Servers.
That might sounds easy when you just have to check 2 or 3 servers... but what if you have to get the information for hundreds! Plus ... I know the Auditor would ask me this same question every few months to prove that the list did not change...Arghhh!

Once again PowerShell saved me so much time on that one!!

Get-LocalGroupMembership

Get the specified local group membership on a local or remote computer.
By default, if you don't specify any parameter, It will query the local group "Administrators" on the localhost.

For some reason WMI bug with some of my Windows Server 2003 and does not return some Domain Groups where Windows Server 2008/2012 work just fine.

Here is my ADSI/WinNT version, It fixed my problem.
In the next post I will go a bit further and get the membership from the domain groups ;-)

Running the Function


The Code

Function Get-LocalGroupMembership {
<#
.Synopsis
    Get the local group membership.
            
.Description
    Get the local group membership.
            
.Parameter ComputerName
    Name of the Computer to get group members. Default is "localhost".
            
.Parameter GroupName
    Name of the GroupName to get members from. Default is "Administrators".
            
.Example
    Get-LocalGroupMembership
    Description
    -----------
    Get the Administrators group membership for the localhost
            
.Example
    Get-LocalGroupMembership -ComputerName SERVER01 -GroupName "Remote Desktop Users"
    Description
    -----------
    Get the membership for the the group "Remote Desktop Users" on the computer SERVER01

.Example
    Get-LocalGroupMembership -ComputerName SERVER01,SERVER02 -GroupName "Administrators"
    Description
    -----------
    Get the membership for the the group "Administrators" on the computers SERVER01 and SERVER02

.OUTPUTS
    PSCustomObject
            
.INPUTS
    Array
            
.Link
    N/A
        
.Notes
    NAME:      Get-LocalGroupMembership
    AUTHOR:    Francois-Xavier Cat
    WEBSITE:   www.LazyWinAdmin.com
#>

 
 [Cmdletbinding()]

 PARAM (
        [alias('DnsHostName','__SERVER','Computer','IPAddress')]
  [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true)]
  [string[]]$ComputerName = $env:COMPUTERNAME,
  
  [string]$GroupName = "Administrators"

  )
    BEGIN{
    }#BEGIN BLOCK

    PROCESS{
        foreach ($Computer in $ComputerName){
            TRY{
                $Everything_is_OK = $true

                # Testing the connection
                Write-Verbose -Message "$Computer - Testing connection..."
                Test-Connection -ComputerName $Computer -Count 1 -ErrorAction Stop |Out-Null
                     
                # Get the members for the group and computer specified
                Write-Verbose -Message "$Computer - Querying..."
             $Group = [ADSI]"WinNT://$Computer/$GroupName,group"
             $Members = @($group.psbase.Invoke("Members"))
            }#TRY
            CATCH{
                $Everything_is_OK = $false
                Write-Warning -Message "Something went wrong on $Computer"
                Write-Verbose -Message "Error on $Computer"
                }#Catch
        
            IF($Everything_is_OK){
             # Format the Output
                Write-Verbose -Message "$Computer - Formatting Data"
             $members | ForEach-Object {
              $name = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
              $class = $_.GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null)
              $path = $_.GetType().InvokeMember("ADsPath", 'GetProperty', $null, $_, $null)
  
              # Find out if this is a local or domain object
              if ($path -like "*/$Computer/*"){
               $Type = "Local"
               }
              else {$Type = "Domain"
              }

              $Details = "" | Select-Object ComputerName,Account,Class,Group,Path,Type
              $Details.ComputerName = $Computer
              $Details.Account = $name
              $Details.Class = $class
                    $Details.Group = $GroupName
              $details.Path = $path
              $details.Type = $type
  
              # Show the Output
                    $Details
             }
            }#IF(Everything_is_OK)
        }#Foreach
    }#PROCESS BLOCK

    END{Write-Verbose -Message "Script Done"}#END BLOCK
}#Function Get-LocalGroupMembership


Thanks for Reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter: @lazywinadm

2012/04/04

Using PowerShell as a Starting Point for Comparing GPOs

source






Video Transcript

Comparing two Group Policy Objects can be pretty tricky with the native tools. Here in the Group Policy Management console or GPMC I have created two different GPO’s, test 1 and test 2. Now if we open one up each of these only setting a couple of settings. You will find it under Computer Configuration/Polices/Windows Settings/Security Settings/Event Log. What I have done is set the Retain security log in this one to 75 days and the other test GPO to 7 days. Then both of them set the retention method for security log to By days.
Right here in the GPMC there is nothing I can really do to compare these two things. What I have done is hop on Google, I punched in compare GPO and I found this script that was written by Ed Wilson, the scripting guy at Microsoft. He has helpfully posted this in the repository and what I have done is take the scripts default parameters to reflect my environment. I provided the domain name, the name of the controller, my two GPO’s, and then the folder where I want the comparison information to be written.
You do not have to set that information, it is possible to provide all of those perimeters when you run the script. For example, we will hop down here. There is the name of the script. Now because I have set all of those perimeters to what I want them to be by default I do not need to specify the GPO names, or the domain name, or the server names, or any of that. But I do need to specify either -computer or            -user, based on which side of the GPO, the computer settings or the user settings, I want to compare.
Running this, it is actually outputting both GPO’s test 2 and test 1 to an xml file and it is indicating that both of these GPO’s change the same settings. I see AuditLogRetentionPeriod and RetentionDays. Unfortunately because of the way this output is created I cannot really tell that it is the security audit log that was changed. I see both of them changed that setting, but I do not actually see what they changed it to just with that default output.
This is why some people will start looking at third party tools. If you hop into Google or your favorite search engine and type compare GPO tool, you will find plenty of different results. The key and one of the things I discuss in the article, Native Methods for Comparing Group Policy Objects, that accompanies this video is in deciding exactly what you are going to do with that comparison, because different tools provide you with that information in different ways. For example, if you just need a quick check of what settings two GPO’s do, well then this little script can do that for you. If you need to dive deeper and maybe get a color coded change management report that shows what values are different from GPO to GPO well, then you are going to have to either do more work with something like PowerShell or find some tools that implement that for you.