przejąłem projekt migracji – konsolidacja struktury domen do nowej, pojedynczej domeny. „wszystko już praktycznie zrobione, będziesz się nudził” – z taką optymistyczną informacją zaczynałem pracę nad zadaniem. z bardzo wielu krzaków, które wyszły, sqpię się nad jedną ciekawostką.
po przejrzeniu zmigrowanych grup okazało się, że część kont jest pokazywana jako konta external. listing członkostwa w grupie ujawniał wpisy typu:
CN=S-1-5-21-2096504233-xxxxxxxxx-944726268-2633,CN=ForeignSecurityPrincipals,DC=target,DC=domain
CN=S-1-5-21-2096504233-xxxxxxxxx-944726268-3498,CN=ForeignSecurityPrincipals,DC=target,DC=domain
Tak są właśnie przechowywane referencje do kont z lasów ztrustowanych. zacząłem więc szukać co to za domena. sprawa prosta, ponieważ zasada jest taka sama jak przy zwykłych SIDach – pierwsza część SID to domainSID. sprawdziłem więc ID wszystkich domen źródłowych [zwykły (Get-ADDomain).domainsid.value] … i okazało się, że takiej domeny nie ma /:
śledztwo. „taaaaakk…hmmm… była kiedyś migracja parę lat temu, tej domeny już nie ma”. tia. ostatnim etapem migracji jest cleanup SIDhistory, którego ktoś nie zrobił. sprawdzam grupy w domenie źródłowej – sweet, tam też członkowie pododawani są przez SIDHistory.
po dalszym przeglądzie okazało się, że w grupach były również konta z domen połączonych trustem nieprzechodnim z domeną źródłową, czyli nierozwiązywalne – kolejna grupa dziwnych FSP. tych niestety nie da się w żaden sposób przenieść chyba, że utworzy się trust z tymi externalami. poznajdywały się również konta CNF [w nowej domenie!] i inne wynalazki. i tak to właśnie się nudziłem…
po pierwsze wniosek/porada: migrację zaczyna się od czyszczenia. nawet jak klient mówi „przenosimy 1:1” – trzeba zweryfikować jak bardzo jest naśmiecone i poczyścić.
po drugie – skrypt, czyszczący FSP
z ciekawostek: do usunięcia usera z grupy korzystając z CN, musiałem użyć ADSI – nie potrafiłem zmusić koszernych cmdletów do obsłużenia CNa.
<#
.SYNOPSIS
skrypt czyszczący grupy lokalne w domenie z Foreign Security Principal
.DESCRIPTION
dla każdej grupy lokalnej sprawdzany jest membership. jeśli znalezione jest konto FSP, weryfikowany jest jego realny login. FSP jest wywalany a dodawane jest konto lokalne.
.NOTES
author: nExoR 2o14
.LINK
https://w-files.pl
#>
function isMember($uname,$gname){
$ouser=get-aduser $uname -Properties memberof
if ( ($ouser.memberOf | where { $_ -match $gname}) -eq $null) { return $false }
return $true
}
Function Convert-FspToUsername
{
Param($UserSID)
foreach ($Sid in $UserSID)
{
try
{
$SAM = (New-Object System.Security.Principal.SecurityIdentifier($Sid)).Translate([System.Security.Principal.NTAccount])
$Result = New-Object -TypeName PSObject -Property @{
Sid = $Sid
sAMAccountName = $SAM.Value
}
Return $Result
}
catch
{
$Result = New-Object -TypeName PSObject -Property @{
Sid = $Sid
sAMAccountName = $Error[0].Exception.InnerException.Message.ToString().Trim()
}
Return $Result
}
}
}
Get-ADGroup -Filter {groupscope -eq "DomainLocal"} -Properties members| %{
echo "sprawdzam $($_.name)..."
$gdn=$_.distinguishedname
$groupname=$_.name
$_.members|%{
if ($_.contains("ForeignSecurityPrincipals")) {
echo "`tznaleziony: $_"
$cu= convert-fsptousername $_.substring(3,$_.indexof(',')-3)#; echo $cu.sAMAccountName
if($cu.samaccountname -notlike "*invalid*") {
$cuname=$cu.samaccountname.substring($cu.sAMAccountName.indexof('\')+1)
echo "`t`todwzorowanie login:$cuname . usuwam FSP"
try {
([adsi]"LDAP://$gdn").remove("LDAP://$_")
if(!(isMember $cuname $groupname)) {
echo "`t`tpryncypał nie jest członkiem (; dodaję."
Add-ADGroupMember $groupname $cuname
} else {
echo "`t`tpryncypał już jest członkiem ^^"
}
} catch {
echo $_.Exception.Message
}
}
}
}
}
eN.

