initial commit
This commit is contained in:
commit
87f047f909
54 changed files with 1113120 additions and 0 deletions
377
Process-ADObjects-Base.ps1
Normal file
377
Process-ADObjects-Base.ps1
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
|
||||
function writeHeaders
|
||||
{
|
||||
|
||||
################################################################
|
||||
# --------------------------------------------------------------
|
||||
# Header für $DAWGruppenAnlegenOutFilePath anlegen
|
||||
# --------------------------------------------------------------
|
||||
"Basket.Import.ADGroup.Create" | Out-File $DAWGruppenAnlegenOutFilePath -Encoding "utf8NoBOM"
|
||||
"GUIMandator" + ";" + "GUIADGroup.Name" + ";" + "GUIADGroup.Description" + ";" + "GUIMandatorADGroupType" + ";" + "GUIADGroup.DisplayName" + ";" + "GUIProcessingNote" + ";" + "OldName" | Out-File $DAWGruppenAnlegenOutFilePath -Append -Encoding "utf8NoBom"
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Header für $DAWGruppenverwaltungOutFilePath anlegen
|
||||
# --------------------------------------------------------------
|
||||
"Basket.Import.ADGroup.ManageMembers" | Out-File "$DAWGruppenverwaltungOutFilePath" -Encoding "utf8NoBom"
|
||||
"GUIMandator" + ";" + "GUIMandatorADGroupType" + ";" + "GUIADGroup.LDAP" + ";" + "GUIADGroup.ADGroups.Add.LDAPs" + ";" + "GUIADGroup.ADGroups.Rem.LDAPs" + ";" + "GUIADGroup.Accounts.Add.LDAPs" + ";" + "GUIADGroup.Accounts.Rem.LDAPs" + ";" + "GUIProcessingNote" + ";" + "ADObjectType" + ";" + "Quellgruppe" | Out-File $DAWGruppenverwaltungOutFilePath -Encoding "utf8NoBom" -Append
|
||||
|
||||
"Basket.Import.ADGroup.ManageMembers" | Out-File "$DAWGruppenverwaltungNeuOutFilePath" -Encoding "utf8NoBom"
|
||||
"GUIMandator" + ";" + "GUIMandatorADGroupType" + ";" + "GUIADGroup.LDAP" + ";" + "GUIADGroup.ADGroups.Add.LDAPs" + ";" + "GUIADGroup.ADGroups.Rem.LDAPs" + ";" + "GUIADGroup.Accounts.Add.LDAPs" + ";" + "GUIADGroup.Accounts.Rem.LDAPs" + ";" + "GUIProcessingNote" + ";" + "ADObjectType" + ";" + "Quellgruppe" | Out-File $DAWGruppenverwaltungNeuOutFilePath -Encoding "utf8NoBom" -Append
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Header für $KURSSollProfile anlegen
|
||||
# --------------------------------------------------------------
|
||||
"Profilnummer;Name;Beschreibung;Profilverantwortliche OE/Stelle;Info;InfoKurs" | Out-File $KURSSollProfileOutFilePath -Encoding "utf8NoBom"
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Header für $IstMitarbeiterProfile anlegen
|
||||
# --------------------------------------------------------------
|
||||
"Personalnummer;;Profilnummer;Name Berechtigungsprofil" | Out-File "$KURSIstMitarbeiterProfileOutFilePath" -Encoding "utf8NoBom"
|
||||
################################################################
|
||||
}
|
||||
|
||||
function getObjectMemberships
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string] $adObjectEntryName,
|
||||
[Parameter(Mandatory = $true, Position = 1)]
|
||||
[string] $memberShipType,
|
||||
[Parameter(Mandatory = $true, Position = 2)]
|
||||
[string] $memberShipOriginalType
|
||||
)
|
||||
|
||||
$key = getMembershipIndexKey $adObjectEntryName $memberShipType
|
||||
|
||||
$bucket = $ADObjectMembershipsIndexed[$key]
|
||||
$objectMemberships = if ($null -eq $bucket)
|
||||
{
|
||||
@()
|
||||
}
|
||||
else
|
||||
{
|
||||
@($bucket)
|
||||
}
|
||||
|
||||
$objectMemberships | Add-Member -Force "Origin" $memberShipOriginalType
|
||||
$objectMemberships | Add-Member -Force "OriginName" $adObjectEntryName
|
||||
return $objectMemberships
|
||||
}
|
||||
|
||||
function getAllUserMemberships
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
$adObjectEntry
|
||||
)
|
||||
|
||||
$result = [System.Collections.Generic.List[object]]::new()
|
||||
$result.AddRange(@(getObjectMemberships $adObjectEntry.ObjectName "user" "user"))
|
||||
|
||||
$groupMemberships = @(getObjectMemberships $adObjectEntry.ObjectName "group" "group")
|
||||
foreach ($groupMembership in $groupMemberships)
|
||||
{
|
||||
$result.AddRange(@(getObjectMemberships $groupMembership.MemberName "user" "group"))
|
||||
}
|
||||
# it's the same, bad odd syntax
|
||||
# return ,$result.ToArray()
|
||||
return @($result)
|
||||
}
|
||||
|
||||
function getUsersByMemberGroup
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieves the user membership entries for a given group via the
|
||||
prebuilt membership index (O(1) lookup, exact class match).
|
||||
.PARAMETER GroupName
|
||||
The group whose user members are requested (matched against GroupName).
|
||||
.OUTPUTS
|
||||
Array of matching membership entries (empty array if none).
|
||||
Object references are preserved from the index.
|
||||
#>
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string] $GroupName
|
||||
)
|
||||
|
||||
# BUGFIX 2026-07-02: was indexing the flat array $ADObjectMemberships with a string
|
||||
# key, which fails silently (non-terminating Int32 conversion error -> $null) and
|
||||
# dropped ALL indirect (group-inherited) user memberships. Must use the hashtable.
|
||||
$bucket = $ADObjectMembershipsIndexed[(getMembershipIndexKey $GroupName "user")]
|
||||
$result = if ($null -eq $bucket)
|
||||
{
|
||||
@()
|
||||
}
|
||||
else
|
||||
{
|
||||
@($bucket)
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
# function getAllUserMemberships
|
||||
# {
|
||||
# param([Parameter(Mandatory, Position = 0)] $adObjectEntry)
|
||||
|
||||
# $result = [System.Collections.Generic.List[object]]::new()
|
||||
# $result.AddRange(@(getObjectMemberships $adObjectEntry.ObjectName "user" "user"))
|
||||
|
||||
# $groupMemberships = @(getObjectMemberships $adObjectEntry.ObjectName "group" "group")
|
||||
# foreach ($groupMembership in $groupMemberships)
|
||||
# {
|
||||
# $result.AddRange(@(getObjectMemberships $groupMembership.MemberName "user" "group"))
|
||||
# }
|
||||
|
||||
# # ist beides gleich
|
||||
# # return ,$result.ToArray()
|
||||
# return @($result)
|
||||
# }
|
||||
|
||||
# function getObjectMemberships
|
||||
# {
|
||||
# param
|
||||
# (
|
||||
# [Parameter(Mandatory = $true, Position = 0)]
|
||||
# [String] $adObjectEntryName,
|
||||
# [Parameter(Mandatory = $true, Position = 1)]
|
||||
# [string] $memberShipType,
|
||||
# [Parameter(Mandatory = $true, Position = 2)]
|
||||
# [string] $memberShipOriginalType
|
||||
# )
|
||||
|
||||
# $objectMemberships = @($ADObjectMemberships | Where-Object {($_.GroupName -ieq $adObjectEntryName) -and ($_.MemberClass -ieq $memberShipType)})
|
||||
# # this is not very nice - we should only add members if they don´t exist - not just to set the values
|
||||
# $objectMemberships | Add-Member -Force "Origin" $memberShipOriginalType
|
||||
# $objectMemberships | Add-Member -Force "OriginName" $adObjectEntryName
|
||||
# return $objectMemberships
|
||||
# }
|
||||
|
||||
function getMembershipIndexKey
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string] $GroupName,
|
||||
[Parameter(Mandatory = $true, Position = 1)]
|
||||
[string] $MemberClass
|
||||
)
|
||||
return "$GroupName`0$MemberClass".ToLowerInvariant()
|
||||
}
|
||||
|
||||
function newObjectMembershipsIndex
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Builds a lookup index over membership entries for O(1) retrieval by
|
||||
GroupName + MemberClass, replacing repeated linear Where-Object scans.
|
||||
.PARAMETER ADObjectMemberships
|
||||
The flat collection of membership entries to index.
|
||||
.OUTPUTS
|
||||
Hashtable mapping "<groupname>\0<memberclass>" (lowercased) to a
|
||||
List[object] of the matching entries. Object references are preserved.
|
||||
#>
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[AllowEmptyCollection()]
|
||||
$ADObjectMemberships
|
||||
)
|
||||
|
||||
$index = @{}
|
||||
|
||||
foreach ($entry in $ADObjectMemberships)
|
||||
{
|
||||
# NUL separator avoids key collisions between e.g. "ab"+"c" and "a"+"bc"
|
||||
$key = getMembershipIndexKey $($entry.GroupName) $($entry.MemberClass)
|
||||
$key0 = "$($entry.GroupName)`0$($entry.MemberClass)".ToLowerInvariant()
|
||||
if (-not($key -eq $key0))
|
||||
{
|
||||
throw "this is BAAAD"
|
||||
}
|
||||
$bucket = $index[$key]
|
||||
if ($null -eq $bucket)
|
||||
{
|
||||
$bucket = [System.Collections.Generic.List[object]]::new()
|
||||
$index[$key] = $bucket
|
||||
}
|
||||
$bucket.Add($entry)
|
||||
}
|
||||
|
||||
return $index
|
||||
}
|
||||
|
||||
function getRoleType
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
$adObjectEntry,
|
||||
[Parameter(Mandatory = $true, Position = 1)]
|
||||
[String] $typeTag
|
||||
)
|
||||
# $FileSystemAccessEntriesNew = @()
|
||||
$roleType = "unknown"
|
||||
# BUGFIX 2026-07-02: 'Sort-Object -Property "Order"' does not resolve hashtable keys on
|
||||
# Windows PowerShell 5.1 (silent no-op, declaration order preserved). The scriptblock
|
||||
# form works identically on 5.1 and 7, making rule evaluation order engine-independent.
|
||||
$relevantRoleTypes = $SPK.GroupManagementMappings | Where-Object {$_.OU -ieq $typeTag} | Sort-Object { [int]$_.Order }
|
||||
foreach ($relevantRoleType in $relevantRoleTypes)
|
||||
{
|
||||
if ($adObjectEntry.OldName -cmatch $relevantRoleType.TagRegExp)
|
||||
{
|
||||
$roleType = $relevantRoleType.TypeName
|
||||
break
|
||||
}
|
||||
}
|
||||
# Ausnahmebehandlungen in Absprache mit N.Zimmer am 21.01.2019
|
||||
#--------------------------------------------------------------
|
||||
if (($typeTag -ieq $FI.TypeTagSecurity) -and ($roleType -ieq "unknown"))
|
||||
{
|
||||
$roleType = "GPO"
|
||||
}
|
||||
#--------------------------------------------------------------
|
||||
return $roletype
|
||||
}
|
||||
|
||||
function buildPrefixMatcher
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string]$CsvPath
|
||||
)
|
||||
|
||||
if (-not (Test-Path $CsvPath))
|
||||
{
|
||||
throw "Prefix CSV not found: $CsvPath"
|
||||
}
|
||||
|
||||
# length -> HashSet[string] of prefixes with exactly that length
|
||||
$byLength = [System.Collections.Generic.Dictionary[int, System.Collections.Generic.HashSet[string]]]::new()
|
||||
|
||||
# foreach ($row in (Import-Csv -Path $CsvPath))
|
||||
foreach ($row in $SPK.ProfilPrefixes)
|
||||
{
|
||||
$prefix = $row.Prefix
|
||||
if ([string]::IsNullOrEmpty($prefix))
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
$len = $prefix.Length
|
||||
$bucket = $null
|
||||
if (-not $byLength.TryGetValue($len, [ref] $bucket))
|
||||
{
|
||||
$bucket = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::Ordinal)
|
||||
$byLength[$len] = $bucket
|
||||
}
|
||||
[void]$bucket.Add($prefix)
|
||||
}
|
||||
|
||||
# Pre-compute the distinct lengths once, sorted descending so the most specific
|
||||
# (longest) prefix wins first - mirrors the "specific before generic" ordering
|
||||
# of a well-formed elseif cascade.
|
||||
$lengths = $byLength.Keys | Sort-Object -Descending
|
||||
|
||||
# Return a small state object carrying both structures.
|
||||
return [pscustomobject]@{
|
||||
ByLength = $byLength
|
||||
Lengths = $lengths
|
||||
}
|
||||
}
|
||||
|
||||
function testKnownPrefixes
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string]$Value,
|
||||
[Parameter(Mandatory = $true, Position = 1)]
|
||||
$Matcher
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrEmpty($Value))
|
||||
{
|
||||
return $false
|
||||
}
|
||||
|
||||
$valueLen = $Value.Length
|
||||
foreach ($len in $Matcher.Lengths)
|
||||
{
|
||||
if ($len -gt $valueLen)
|
||||
{
|
||||
continue
|
||||
} # prefix longer than value -> can't match
|
||||
$candidate = $Value.Substring(0, $len)
|
||||
$bucket = $Matcher.ByLength[$len]
|
||||
if ($bucket.Contains($candidate))
|
||||
{
|
||||
return $true # found a known prefix
|
||||
}
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
# function getNormalizedDirectoryPaths
|
||||
# {
|
||||
# $analyzedDirectoryEntries = @()
|
||||
# # $header = "Verzeichnisname", "Endpunktname", "Gruppe Lesen", "Gruppe Aendern", "Benutzer mit Leserecht", "Benutzer mit Aenderungsrecht", "Rollen mit Leserecht", "Rollen mit Aenderungsrecht", "Verzeichnisart", "normierter Pfad"
|
||||
# # $directoriesFilePathEntries = Get-Content -Path $DirectoriesFilePath | Select-Object -Skip 1 | ConvertFrom-Csv -Delimiter ";" -Header $header
|
||||
# # $directoriesFilePathEntries = Get-Content -Path $DirectoriesInFilePath | Select-Object -Skip 1 | ConvertFrom-Csv -Delimiter ";"
|
||||
# $directoriesFilePathEntries = Get-Content -Path $DirectoriesInFilePath | ConvertFrom-Csv -Delimiter ";"
|
||||
# # $headers = ($directoriesFilePathEntries | Get-Member -MemberType NoteProperty)
|
||||
# # $interstingHeader = $headers.Name -match "Gruppe .ndern"
|
||||
# foreach ($FilePathEntry in $directoriesFilePathEntries)
|
||||
# {
|
||||
# $analyzedDirectoryEntries += $FilePathEntry.Name
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
function postProcess
|
||||
{
|
||||
param (
|
||||
[Parameter(Mandatory = $false, Position = 0)]
|
||||
[bool]$convertToAscii = $false
|
||||
)
|
||||
|
||||
#########################################################
|
||||
# just to be sure that nothing happens: comment it out until you know what`s happening here !
|
||||
#########################################################
|
||||
|
||||
# $tmpFilePath = moveToInstituteTmpPath $DAWGruppenAnlegenOutFilePath $true
|
||||
# $firstlines = Get-Content -Path $tmpFilePath -TotalCount 2
|
||||
# Get-Content -Path $tmpFilePath -TotalCount 1 | Out-File -Force $DAWGruppenAnlegenOutFilePath
|
||||
# Get-Content -Path $tmpFilePath | Select-Object -Skip 2 | ConvertFrom-Csv -Delimiter ";" | select 'GUIMandator', 'GUIADGroup.Name', 'GUIADGroup.Description', 'GUIMandatorADGroupType', 'GUIADGroup.DisplayName', 'GUIProcessingNote' | ConvertTo-Csv -Delimiter ';' -NoTypeInformation | Out-File -FilePath $DAWGruppenAnlegenOutFilePath -Encoding UTF8 -Append
|
||||
# # Import-Csv $tmpFilePath | select 'GUIMandator','GUIADGroup.Name','GUIADGroup.Description','GUIMandatorADGroupType','GUIADGroup.DisplayName','GUIProcessingNote' | Export-Csv -Path $DAWGruppenAnlegenOutFilePath -Delimiter ";" -Encoding UTF8
|
||||
|
||||
# $tmpFilePath = moveToInstituteTmpPath $DAWGruppenverwaltungOutFilePath $true
|
||||
# $firstlines = Get-Content -Path $tmpFilePath -TotalCount 2
|
||||
# Get-Content -Path $tmpFilePath -TotalCount 1 | Out-File -Force $DAWGruppenverwaltungOutFilePath
|
||||
# Get-Content -Path $tmpFilePath | Select-Object -Skip 2 | ConvertFrom-Csv -Delimiter ";" | select "GUIMandator", "GUIMandatorADGroupType", "GUIADGroup.LDAP", "GUIADGroup.ADGroups.Add.LDAPs", "GUIADGroup.ADGroups.Rem.LDAPs", "GUIADGroup.Accounts.Add.LDAPs", "GUIADGroup.Accounts.Rem.LDAPs", "GUIProcessingNote" | ConvertTo-Csv -Delimiter ';' -NoTypeInformation | Out-File -FilePath $DAWGruppenverwaltungOutFilePath -Encoding UTF8 -Append
|
||||
|
||||
# # Import-Csv $tmpFilePath | select "GUIMandator","GUIMandatorADGroupType","GUIADGroup.LDAP","GUIADGroup.ADGroups.Add.LDAPs","GUIADGroup.ADGroups.Rem.LDAPs","GUIADGroup.Accounts.Add.LDAPs","GUIADGroup.Accounts.Rem.LDAPs","GUIProcessingNote" | Export-Csv -Path $DAWGruppenverwaltungOutFilePath -Delimiter ";" -Encoding UTF8 -NoTypeInformation
|
||||
# $tmpFilePath = moveToInstituteTmpPath $DAWGruppenverwaltungNeuOutFilePath $true
|
||||
# $firstlines = Get-Content -Path $tmpFilePath -TotalCount 2
|
||||
# Get-Content -Path $tmpFilePath -TotalCount 1 | Out-File -Force $DAWGruppenverwaltungNeuOutFilePath
|
||||
# Get-Content -Path $tmpFilePath | Select-Object -Skip 2 | ConvertFrom-Csv -Delimiter ";" | select "GUIMandator", "GUIMandatorADGroupType", "GUIADGroup.LDAP", "GUIADGroup.ADGroups.Add.LDAPs", "GUIADGroup.ADGroups.Rem.LDAPs", "GUIADGroup.Accounts.Add.LDAPs", "GUIADGroup.Accounts.Rem.LDAPs", "GUIProcessingNote" | ConvertTo-Csv -Delimiter ';' -NoTypeInformation | Out-File -FilePath $DAWGruppenverwaltungNeuOutFilePath -Encoding UTF8 -Append
|
||||
|
||||
####################################################### todo ?
|
||||
# $KURSIstProfileOutFilePath
|
||||
# $KURSIstProfileBerechtigungenOutFilePath
|
||||
# $KURSIstStellenBerechtigungenOutFilePath
|
||||
# $KURSIstStellenProfileOutFilePath
|
||||
# $KURSIstOEsBerechtigungenOutFilePath
|
||||
# $KURSIstOEsProfileOutFilePath
|
||||
# $KURSIstMitarbeiterProfileOutFilePath
|
||||
# $KURSSollStellenfunktionenOutFilePath
|
||||
# $KURSSollProfileOutFilePath
|
||||
# $KURSSollProfileBerechtigungenOutFilePath
|
||||
# $KURSSollStellenfunktionenBerechtigungenOutFilePath
|
||||
# $KURSSollStellenfunktionenProfileOutFilePath
|
||||
####################################################### todo ?
|
||||
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue