diff --git a/Combination_scripts/Win - Active Directory Group monitoring.ps1 b/Combination_scripts/Win - Active Directory Group monitoring.ps1 new file mode 100644 index 0000000..95f1c31 --- /dev/null +++ b/Combination_scripts/Win - Active Directory Group monitoring.ps1 @@ -0,0 +1,162 @@ +<# +.SYNOPSIS + This script monitors the membership of a specified Active Directory group. + It can log changes in group membership to a specified log file and update + a previous state file for future comparisons. + +.DESCRIPTION + The script retrieves the current members of a specified Active Directory group + and compares them to a previously saved state. It can output changes to the console + when run in monitor mode, and it can update the previous state file when requested. + The script supports the following parameters: + + -GroupName: The name of the Active Directory group to monitor. + -Monitor: Outputs changes in group membership without updating the previous state file. + -Update: Updates the previous state file with the current group members. + +.PARAMETER GroupName + The name of the Active Directory group to monitor. + +.PARAMETER Monitor + Switch parameter that, when specified, outputs changes in group membership + without updating the previous state file. + +.PARAMETER Update + Switch parameter that, when specified, updates the previous state file + with the current group members. + +.OUTPUTS + Exit codes: + 0: Successful execution (no errors). + 1: Error retrieving group members (e.g., the group does not exist or there is a permission issue). + 2: Changes detected in group membership when using the -Monitor parameter. + +.EXAMPLE + .\Win - Active Directory Group monitoring.ps1 -GroupName "YourGroupName" -Monitor + This command checks for changes in the specified group and outputs them to the console. + +.EXAMPLE + .\Win - Active Directory Group monitoring.ps1 -GroupName "YourGroupName" -Update + This command updates the previous state file with the current members of the specified group. + +.EXAMPLE + .\Win - Active Directory Group monitoring.ps1 -GroupName "YourGroupName" -Monitor -Update + This command checks for changes in the specified group and updates the previous state file. + +#> + +param ( + [Parameter(Mandatory=$true)] + [string]$GroupName, + [switch]$Monitor, + [switch]$Update +) + +# Check if either Monitor or Update is specified +if (-not $Monitor -and -not $Update) { + Write-Host "Error: You must specify either -Monitor or -Update." + exit 1 # Exit code 1: Neither Monitor nor Update specified +} + +# Define Toolbox path +$ToolboxPath = "C:\ProgramData\TacticalRMM\toolbox\Groupmonitoring" +if (!(test-path $ToolboxPath)) {mkdir $ToolboxPath} + +# Define the path to the log file +$logFilePath = "$ToolboxPath\Log-$GroupName-$(Get-Date -Format "yyyy-MM-dd-HHmmss").txt" + +# Define the path to the previous state file +$previousStateFilePath = "$ToolboxPath\$Groupname.json" + + +# Function to get group members +function Get-GroupMembers { + param ( + [string]$groupName + ) + try { + $group = Get-ADGroup -Identity $groupName -ErrorAction Stop + $members = Get-ADGroupMember -Identity $group -Recursive | Select-Object -ExpandProperty SamAccountName + return $members + } catch { + Write-Host "Error retrieving members for group: $groupName. $_" + return @() + } +} + +# Load previous state if it exists +$previousState = @{} +if (Test-Path $previousStateFilePath) { + $previousState = Get-Content $previousStateFilePath | ConvertFrom-Json +} + +# Initialize current state +$currentState = @{} + +# Get current members of the specified group +$currentMembers = Get-GroupMembers -groupName $GroupName +if (-not $currentMembers) { + Write-Host "Failed to retrieve members for group '$GroupName'." + exit 1 # Exit code 1: Error retrieving group members +} + +$currentState[$GroupName] = $currentMembers + +# Check if the group exists in the previous state +if ($previousState -and $previousState.$GroupName) { + $previousMembers = $previousState.$GroupName +} else { + $previousMembers = @() +} + +# Check for added members +$addedMembers = $currentState[$GroupName] | Where-Object { $_ -notin $previousMembers } +# Check for removed members +$removedMembers = $previousMembers | Where-Object { $_ -notin $currentState[$GroupName] } + +# Log changes if not in monitor mode +if (-not $Monitor) { + if ($addedMembers.Count -gt 0 -or $removedMembers.Count -gt 0) { + $logEntry = "Changes for group '$GroupName' on $(Get-Date):`n" + if ($addedMembers.Count -gt 0) { + $logEntry += "Added Members: $($addedMembers -join ', ')`n" + } + if ($removedMembers.Count -gt 0) { + $logEntry += "Removed Members: $($removedMembers -join ', ')`n" + } + $logEntry += "`n" + Add-Content -Path $logFilePath -Value $logEntry + } +} + +# Output changes if in monitor mode +if ($Monitor) { + if ($addedMembers.Count -gt 0 -or $removedMembers.Count -gt 0) { + Write-Host "Changes for group '$GroupName' on $(Get-Date):" + if ($addedMembers.Count -gt 0) { + Write-Host "Added Members: $($addedMembers -join ', ')" + } + if ($removedMembers.Count -gt 0) { + Write-Host "Removed Members: $($removedMembers -join ', ')" + } + } else { + Write-Host "No changes detected for group '$GroupName'." + } +} + +# Update the previous state file if -Update is specified +if ($Update) { + $currentState | ConvertTo-Json | Set-Content -Path $previousStateFilePath + Write-Host "Previous state file updated." +} + +# Exit codes +if ($Monitor -and ($addedMembers.Count -eq 0 -and $removedMembers.Count -eq 0)) { + exit 0 # Exit code 0: No changes detected +} elseif ($Monitor) { + exit 2 # Exit code 2: Changes detected +} elseif ($Update) { + exit 0 # Exit code 0: Update successful +} + +exit 0 # Exit code 0: Successful execution \ No newline at end of file