„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:

Das hast du vielleicht verpasst

shibiadmin
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzererfahrung bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst, und hilft unserem Team zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.