We help IT Professionals succeed at work.

Audit log for the script

Navdeep
Navdeep asked
on
Hi,

I would like to have real time audit logs for the following script. The script remove the users from the group. I would like to audit the log in such a way that it can be used as input in case of restoring the group membership.

#Remove user from part access group based on csv file.

#Clear-Host
cls

#Customise Vars
$ImportFile = "C:\Temp\Import.csv"

#Import data into $coldata
$coldata = Import-Csv $ImportFile

foreach ($colitem in $coldata)
{
        #Assign Username/Group Vars
        $UserName = $colitem.sAN
        $AccessGroup = $colitem.grp
       
        "{0,-6} {1} {2}" -f "User", ":", $UserName
        "{0,-6} {1} {2}" -f "Group", ":", $AccessGroup
       
        $Searcher = New-Object DirectoryServices.DirectorySearcher
        $Searcher.Filter = "(&(objectCategory=person)(objectClass=user)(samAccountName=$Username))"
        [array]$SearchResults = $Searcher.FindOne()
       
        #Check 1 result is returned
        if ($SearchResults.Count -eq 1)
        {
                #Bind to AD User
                $ADSIUser = [ADSI]$SearchResults[0].Path
               
                #Get DN of user
                [string]$ADSIUserDN = $ADSIUser.distinguishedName
               
                Write-Host $ADSIUser.Properties.sAmAccountName
               
                #Loop through group membership of user
                foreach ($GroupMembership in $ADSIUser.memberOf)
                {
                        #Bind to Group Membership
                        $ADSIGroup = [ADSI]"LDAP://$GroupMembership"
                       
                        #If group name matches
                        if ($ADSIGroup.Name -eq $AccessGroup)
                        {
                                Write-Host -ForeGroundColor "Yellow" "Match Found for $AccessGroup : LDAP://$GroupMembership"
                               
                                #Remove user from Group
                                $ADSIGroup.member.Remove($ADSIUserDN)
                                $ADSIGroup.SetInfo()
                        }
                }
        }
}

Please refer to the following post for more info
http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_27472343.html#a37231723

Thanks
Navdeep
Comment
Watch Question

For logging, I tend to find a solution that both logs to file and writes to host is best, this means that any times you want to write to host it's also going to go into the log file as well. Then it just becomes a question of what info you want to log.

Something like this function should do what you want, please bear in mind when calling the function, by default it takes the current foreground/background colors, I have overridden these in my example by declaring the foreground/background colors when calling the function.

Function Logging
{
	param
	(
		$LogFile,
		$ForeGroundColor = (Get-Host).UI.RawUI.ForeGroundColor,
		$BackGroundColor = (Get-Host).UI.RawUI.BackGroundColor
	)
	
	#Get pipeline input text
	[string]$PipelineText = $Input
	
	#Current date and time formatted to required date time values
	$CurrentDateTime = (Get-Date).ToString("HH:mm:ss dd/MM/yyyy")
	
	#Write to host and to logfile
	Write-Host -ForeGroundColor $ForeGroundColor -BackGroundColor $BackGroundColor "$CurrentDateTime : $PipelineText"
	"$CurrentDateTime : $PipelineText" | Out-File $LogFile -Append	
}

#LogFile
$LogFilePath = "C:\Temp\LogFile.txt"

[array]$Services = Get-Service

foreach ($Service in $Services)
{
	$Service.Name | Logging $LogFile "Yellow" "Black"
}

Open in new window

Thanks Chris for the code. So lets say if we want to capture the output of the removal of AD users from group referring to previous question, how we can use this function during the run time, how would i call it so that it writes the audit log.

Also i would like to check with you if you would be interested in working for paid projects on powershell. These are usually small projects, like writing automation scripts for windows/exchange/directory services. Let me know if you would be interested, just send me an email at v_2nas@hotmail.com. I tried to find how to contact you on experts-exchange but i think there wasn't a way to do so.
Regarding paid work, at the moment I would probably say no i'm afraid, I quite like being able to jump on and do stuff when I want to without it feeling like work too much or being obliged to do anything when I don't feel like it, keeps me sharp as well :)

Not tested, but this should be "integrated" into the code you posted above. With PowerShell functions they must be declared before the code itself in order to be called properly. Functions are both great and can be a pain to troubleshoot as they run independently of the main code but there is some crossover. I use them if i want to have repeatable code in a one liner instead of writing it out the same code many times.

#Remove user from part access group based on csv file.

#Function to log to file
Function Logging
{
	param
	(
		$LogFile,
		$ForeGroundColor = (Get-Host).UI.RawUI.ForeGroundColor,
		$BackGroundColor = (Get-Host).UI.RawUI.BackGroundColor
	)
	
	#Get pipeline input text
	[string]$PipelineText = $Input
	
	#Current date and time formatted to required date time values
	$CurrentDateTime = (Get-Date).ToString("HH:mm:ss dd/MM/yyyy")
	
	#Write to host and to logfile
	Write-Host -ForeGroundColor $ForeGroundColor -BackGroundColor $BackGroundColor "$CurrentDateTime : $PipelineText"
	"$CurrentDateTime : $PipelineText" | Out-File $LogFile -Append	
}

#Clear-Host
cls

#Customise Vars
$ImportFile = "C:\Temp\Import.csv"
$LogFilePath = "C:\Temp\LogFile.txt"

#Import data into $coldata
$coldata = Import-Csv $ImportFile

foreach ($colitem in $coldata)
{
        #Assign Username/Group Vars
        $UserName = $colitem.sAN
        $AccessGroup = $colitem.grp
       
        "User: $UserName" | Logging $LogFile
        "Group: $AccessGroup" | Logging $LogFile
       
        $Searcher = New-Object DirectoryServices.DirectorySearcher
        $Searcher.Filter = "(&(objectCategory=person)(objectClass=user)(samAccountName=$Username))"
        [array]$SearchResults = $Searcher.FindOne()
       
        #Check 1 result is returned
        if ($SearchResults.Count -eq 1)
        {
				"Bound to User: $($SearchResults[0].Path)" | Logging $LogFile
		
                #Bind to AD User
                $ADSIUser = [ADSI]$SearchResults[0].Path
               
                #Get DN of user
                [string]$ADSIUserDN = $ADSIUser.distinguishedName
               
                "SamAccountName: $($ADSIUser.Properties.sAmAccountName)" | Logging $LogFile
               
                #Loop through group membership of user
                foreach ($GroupMembership in $ADSIUser.memberOf)
                {
                        #Bind to Group Membership
                        $ADSIGroup = [ADSI]"LDAP://$GroupMembership"
						
						"Group Membership: $LDAP://$GroupMembership" | Logging $LogFile
                       
                        #If group name matches
                        if ($ADSIGroup.Name -eq $AccessGroup)
                        {
								"Match Found for $AccessGroup : LDAP://$GroupMembership" | Logging $LogFile "Yellow"
                               
								"Removing user $ADSIUserDN from group LDAP://$GroupMembership" | Logging $LogFile "Yellow"
							   
                                #Remove user from Group
                                $ADSIGroup.member.Remove($ADSIUserDN)
                                $ADSIGroup.SetInfo()
                        }
                }
        }
}

Open in new window

Thank you very much Chris, for answering my questions and really appreciate your straight forwardness.

I will run the code in my uat and post the results.

Regards,
Navdeep