December, 2014

Posts
  • How to move whole OU subtree bringing GPO and GPO link from source forest to destination forest

    During a Forest and Domain consolidation project I had a challenge to migrate users e computers between Forests.

    I had the need to maintain the same GPO and the same structure of OU.

    I dug the net and could not find anything that I could meet, I had to assemble various scripts, but even so I would not have satisfied my need.

    I wrote a powershell script that apply to this scenario.

    I'm still working on it, but I decided to share and hope to get some feedback for improving it or correct some bugs.

    This script  on target forest, create same source OU subtree, copy and link same source GPO on relative copied OU.

    WMIFilter is not migrated in this script version.

    Prerequisite:

    • Tested with Windows 2012 R2 (target) and Windows 2008 R2 (source)
    • RSAT
    • GPMC console
    • Tested with bidirectional Trust

    These are the parameters:

    • BaseSourceDN: DN of source OU subtree you want move
    • BaseTargetDN: DN of targetOU where you want move in
    • SourceDomain: source domain name
    • TargetDomainController: target domain controller server name
    • prefix: (optional) prefix name for target GPO

    # Sample .\move_OU1.ps1 -BaseSourceDN "OU=users,DC=contoso,DC=local" -BaseTargetDN "OU=users,OU=home,DC=adatum,DC=local" -SourceDomain "contoso.local" -TargetDomainController dc01.adatum.local -prefix "Contoso-"

    Param(

    [string]$BaseSourceDN,

    [string]$BaseTargetDN,

    [string]$SourceDomain,

    [string]$TargetDomainController,

    [string]$Prefix=""

    )

    function CopyGPO

    {

    param([string]$SourceDomain,

    [string]$TargetDomainController,

    [string]$SourceDN,

    [string]$OUTargetUrl)

    $oSourceOU=[adsi]"LDAP://$SourceDN"

    $gPLinks=$oSourceOU.gPLink

    if(($gPLinks -ne $null) -or ($gPLinks -ne ''))

    {

    $gPlink=$gPlinks.split('][')

    for ($i=$gPlink.count-2;$i -gt 0;$i=$i-2)

    {

    $GPO_URI=$gPlink[$i].split(';')

    $GPO_DN=$GPO_URI[0].substring(7)

    switch($GPO_URI[1])

    {

    "1" {$EnableStatus = 'No'; $EnforceStatus = 'No'}

    "2" {$EnableStatus = 'Yes'; $EnforceStatus = 'Yes'}

    "3" {$EnableStatus = 'No'; $EnforceStatus = 'Yes'}

    "0" {$EnableStatus = 'Yes'; $EnforceStatus = 'No'}

    }

    $GPO_URI_wDomain="LDAP://$SourceDomain/$GPO_DN"

    $oGPO=[adsi]"$GPO_URI_wDomain"

    $GPO_Name=$oGPO.DisplayName

    try

    {

    Write-Host

    Write-Host "Try to copy GPO $GPO_Name" -ForegroundColor Green

    Copy-GPO -SourceName "$GPO_Name" -SourceDomain "$SourceDomain" -TargetName "$Prefix$GPO_Name" -TargetDomainController "$TargetDomainController" -ErrorAction Stop

    $cGPOApply=$oGPO.psbase.objectsecurity.access |?{$_.ActivedirectoryRights -eq 'ExtendedRight'}

    Set-GPPermission -Name "$Prefix$GPO_Name" -TargetName "Authenticated Users" -PermissionLevel None -TargetType Group -ErrorAction SilentlyContinue

    foreach($GPOApply in $cGPOApply)

    {

    $SecurityFiltering=$GPOApply.IdentityReference

    Set-GPPermission -Name "$Prefix$GPO_Name" -TargetName "$SecurityFiltering" -PermissionLevel GpoApply -Server "$TargetDomainController" -TargetType Group -ErrorAction SilentlyContinue

    }

    if ($Prefix -eq '')

    {

    Write-Host "$GPO_Name copied" -ForegroundColor Green

    }

    else

    {

    Write-Host "$GPO_Name copied and renamed in $Prefix$GPO_Name" -ForegroundColor Green

    }

    }

    catch [exception]

    {

    write-host $_.Exception.Message -ForegroundColor Red

    }

    try

    {

    Write-Host

    Write-Host "Try to create link for GPO:$Prefix$GPO_Name on OU:$OUTargetUrl" -ForegroundColor Green

    New-GPLink -Name "$Prefix$GPO_Name" -Target $OUTargetUrl -Server "$TargetDomainController" -LinkEnabled $EnableStatus -Enforced $EnforceStatus -ErrorAction Stop

    Write-Host "Link for GPO:$Prefix$GPO_Name on OU:$OUTargetUrl created" -ForegroundColor Green

    }

    catch [Exception]{

    write-host $_.Exception.Message -ForegroundColor Red

    }

    }

    return

    }

    }

     

     

    function CreateOU

    {

    param ([string]$SourceDN,

    [string]$TargetDN)

    $oSourceOU=[adsi]"LDAP://$SourceDN"

    $RDN=[string]$oSourceOU.Name

    try

    {

    Write-Host

    Write-Host "Try to create OU=$RDN,$TargetDN" -ForegroundColor Green

    New-ADOrganizationalUnit -Name $RDN -Path $TargetDN

    Write-Host "OU=$RDN,$TargetDN created" -ForegroundColor Green

    $gPOption=$oSourceOU.gPOptions

    # Check if Blocked Inheritance is true

    if($gPOption -eq 1){

    Write-Host

    Write-Host "Try to set Block Inheritance true" -ForegroundColor Green

    Set-GPInheritance -IsBlocked Yes -Target "OU=$RDN,$TargetDN" # Block Inheritance

    Write-Host "Block Inheritance is true" -ForegroundColor Green

    }

    }

    catch [Exception]{

    write-host $_.Exception.ServerErrorMessage -ForegroundColor Red

    }

    $NewTargetDN="OU=$RDN,$TargetDN"

    $NewSourceDN=$SourceDN

    CopyGPO $SourceDomain $TargetDomainController $SourceDN $NewTargetDN

    $cOUs=$oSourceOU.Children | Where-Object{$_.schemaclassname -eq "OrganizationalUnit"}

    if (($cOUs -ne '') -and ($cOUs.count -ne 0))

    {

    foreach($ChildOU in $cOUs)

    {

    $RDN=[string]$ChildOU.name

    $NewSourceDN="OU=$RDN,"+$SourceDN

    CreateOU $NewSourceDN $NewTargetDN

    }

    }

    return

    }

     

    if(($BaseSourceDN -eq '') -or (!$BaseSourceDN) -or ($BaseTargetDN -eq '') -or (!$BaseTargetDN) -or

    ($SourceDomain -eq '') -or (!$SourceDomain) -or ($TargetDomainController -eq '') -or (!$TargetDomainController))

    {

    Write-Host "Incomplete parameters" -ForegroundColor Blue

    Write-Host "Use this sintax:"-ForegroundColor Blue

    Write-Host ".\move-ou.ps1 -BaseSourceDN ""OU=users,DC=contoso,DC=local"" -BaseTargetDN ""OU=users,OU=home,DC=adatum,DC=local"" -SourceDomain ""contoso.local"" -TargetDomainController ""dc01.adatum.local""" -ForegroundColor Blue

    }

    else

    {

    CreateOU $BaseSourceDN $BaseTargetDN

    }

  • How to add second user to Windows User Local Profile

    ATTENTION: this procedure could be not supported, then If you modify registry entry, you are doing at your own risk.
    When I afford a domain consolidation and than a Windows migration, many times I got request from clients to allow new migrated user (second user) to allow access to previous Windows User Local Profile.
    Normally I get this gol by ADMT, when I do Security Translation I use ADD mode on User Profile, but some clients asked me to do it without ADMT and just use a script.
    I did reverse engineering about ADMT and I found these steps.
    Assume Windows Operating System is Windows 7 and source user is sourcedomain\j9999 and target user is targetdomain\j9999
    1. Logon on workstation with sourcedomain\j9999 user
    2. Browse c:\users directory and find user profile folder j9999 and click right click on Properties
    3. Then click on Security Tab and then on Advanced button
    4. Add full control to user targetdomain\j9999 and apply to Replace all child object permission…
    5. Open regedit and select HKEY_CURRENT_USER

    6. Right click on Permission and add full control to user targetdomain\j9999
    7. Logoff and logon with local administrator user, or runas regedit with different user
    8. Copy the follow Registry Key changing these parameters:

    a. Insert Registry Key name with targetdomain\j9999 SID (string format)

    b. Copy same old profile registry entry

    c. Change only Sid  entry with binary hex targetdomain\j9999 user

       

    Log off and logon with both users (source and target) to check u r accessing to same Windows Local User Profile.

    Next step I would like to script the previous steps.