„Dynamische“ Gruppen via PowerShell Skript
Mal wieder ein Active Directory Thema nach langem:
Szenario: Lizenzen werden mit einer globalen Gruppe verteilt, damit man diese Personen erreichen kann, wird eine Verteilergruppe erstellt. Jetzt sollen alle Leute von der globalen Gruppe automatisch in die Verteilergruppe hinzugefügt werden. Achso und natürlich auch entfernt, wenn die nicht mehr in der globalen Gruppe enthalten sind. Macht Sinn:
Mit diesem PowerShell Skript recht gut machbar:
Ausführen mit ./skriptname -UserGroup GlobaleGruppeName -TargetUserGroup Verteilergruppe
Einfach jeden morgen um 01:00 laufen lassen oder mal Manuell ausführen. (Natürlich mit PowerShell 7)
<#
.SYNOPSIS
PUT SHORT SCRIPT DESCRIPTION HERE AND ADD ANY ADDITIONAL KEYWORD SECTIONS AS NEEDED (.PARAMETER, .EXAMPLE, ETC.).
.DESCRIPTION
Provide a more detailed description of what the script does here.
.PARAMETER ExportPath
Path to export the CSV file.
.PARAMETER ExportDelimiter
Delimiter to use in the CSV file.
.PARAMETER ExportEncoding
Encoding to use for the CSV file.
.PARAMETER OperationName
Name of the operation being performed, used for log file naming.
.PARAMETER LogDirectory
Directory where log files will be stored.
.EXAMPLE
Example of how to use this script.
.NOTES
Author: Jan Hupperten
Date: 2024-10-02
Version: 1.1
#>
[CmdletBinding()]
param (
# Path to export CSV or similar outputs
[Parameter(Mandatory = $false)]
[string]$ExportPath = "",
[Parameter(Mandatory = $false)]
[string]$ExportDelimiter = ";",
[Parameter(Mandatory = $false)]
[string]$ExportEncoding = "UTF8",
# Name of the operation, used in log file naming
[Parameter(Mandatory = $false)]
[string]$OperationName = "DefaultOperation",
# Directory where log files will be stored
[Parameter(Mandatory = $false)]
[string]$LogDirectory = "",
# Group where the user is
[string]$UserGroup = "",
# Group where the user is going to if he is not in this group
[string]$TargetUserGroup = ""
)
begin {
$InformationPreference = 'Continue'
# $VerbosePreference = 'Continue' # Uncomment this line if you want to see verbose messages.
# Generate a unique log file name
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$scriptName = [IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
if (-not $ExportPath) {
$ExportPath = (Join-Path -Path $PSScriptRoot -ChildPath "Output.csv")
}
if (-not $LogDirectory) {
$LogDirectory = (Join-Path -Path $PSScriptRoot -ChildPath "Logs")
}
[string]$lastRunLogFilePath = Join-Path -Path $LogDirectory -ChildPath "$($scriptName)_$($OperationName)_$($timestamp)_$($pid).log"
# Start transcript logging
Start-Transcript -Path $lastRunLogFilePath
# Display the time that this script started running.
[DateTime]$startTime = Get-Date
Write-Information "Starting script at '$($startTime.ToString('u'))'."
# Function to handle errors
function Handle-Error {
param (
[string]$Message
)
Write-Error $Message
Stop-Transcript
throw $Message
}
# Function to log information
function Log-Information {
param (
[string]$Message
)
Write-Information $Message
}
# check if all required parameters are set
if (-not $ExportPath) {
Handle-Error "ExportPath is required."
}
if (-not $ExportDelimiter) {
Handle-Error "ExportDelimiter is required."
}
if (-not $ExportEncoding) {
Handle-Error "ExportEncoding is required."
}
if (-not $OperationName) {
Handle-Error "OperationName is required."
}
}
process {
try {
Log-Information "Processing..."
$userGroupMembers = Get-ADGroupMember -Identity $UserGroup -Recursive
$targetUserGroupMembers = Get-ADGroupMember -Identity $TargetUserGroup -Recursive
foreach ($user in $userGroupMembers) {
if (-not ($targetUserGroupMembers | Where-Object { $_.DistinguishedName -eq $user.DistinguishedName })) {
Add-ADGroupMember -Identity $TargetUserGroup -Members $user -ErrorAction Stop
Log-Information "Added user '$($user.SamAccountName)' to target group '$TargetUserGroup'."
}
}
foreach ($user in $targetUserGroupMembers) {
if (-not ($userGroupMembers | Where-Object { $_.DistinguishedName -eq $user.DistinguishedName })) {
Remove-ADGroupMember -Identity $TargetUserGroup -Members $user -ErrorAction Stop
Log-Information "Removed user '$($user.SamAccountName)' from target group '$TargetUserGroup'."
}
}
}
catch {
Handle-Error $_.Exception.Message
}
}
end {
# Display the time that this script finished running, and how long it took to run.
[DateTime]$finishTime = Get-Date
[TimeSpan]$elapsedTime = $finishTime - $startTime
Write-Information "Finished script at '$($finishTime.ToString('u'))'. Took '$elapsedTime' to run."
Write-Host "Memory used beforce collecting: $([System.GC]::GetTotalMemory($false))"
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
Write-Host "Memory used after collecting: $([System.GC]::GetTotalMemory($false))"
Stop-Transcript
}
Share this content:
Kommentar abschicken