classes/dry.module.ad.class.ou.ps1
Using Namespace System.Management.Automation.Runspaces # removed: # Using Module ActiveDirectory # dry.module.ad is an AD config module for use with DryDeploy, or by itself. # # Copyright (C) 2021 Bjørn Henrik Formo (bjornhenrikformo@gmail.com) # LICENSE: https://raw.githubusercontent.com/bjoernf73/dry.module.ad/main/LICENSE # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Class OU { [string] $OUDN [string] $ObjectType [string] $DomainFQDN [string] $DomainDN [PSSession] $PSSession [string] $DomainController [PSCredential] $Credential [string] $ExecutionType # Overload for CN or OU creation in a PSSession OU( [string] $OUDN, [string] $DomainFQDN, [PSSession] $PSSession ) { $This.OUDN = $OUDN if ($This.OUDN -match "^CN=*") { $This.ObjectType = 'container' } elseif ($This.OUDN -match "^OU=*") { $This.ObjectType = 'organizationalUnit' } elseif ($This.OUDN.Trim() -eq '') { $This.ObjectType = 'DomainRoot' } else { olad 1 "Unknown Object Type (not CN, OU or Domain Root): $($This.OUDN)" throw "Unknown Object Type (not CN, OU) or Domain Root: $($This.OUDN)" } $This.DomainFQDN = $DomainFQDN $This.DomainDN = "DC=" + $($This.DomainFQDN.replace(".",",DC=")) $This.PSSession = $PSSession $This.ExecutionType = 'Remote' $This.DomainController = 'localhost' } # Overload for CN or OU creation locally with PSCredential OU( [string] $OUDN, [string] $DomainFQDN, [string] $DomainController, [PSCredential] $Credential ) { $This.OUDN = $OUDN if ($This.OUDN -match "^CN=*") { $This.ObjectType = 'container' } elseif ($This.OUDN -match "^OU=*") { $This.ObjectType = 'organizationalUnit' } elseif ($This.OUDN.Trim() -eq '') { $This.ObjectType = 'DomainRoot' } else { olad w "Unknown Object Type (not CN or OU): $($This.OUDN)" throw "Unknown Object Type (not CN or OU): $($This.OUDN)" } $This.DomainFQDN = $DomainFQDN $This.DomainDN = "DC=" + $($This.DomainFQDN.replace(".",",DC=")) $This.Credential = $Credential $This.ExecutionType = 'Local' $This.DomainController = $DomainController } # Overload for CN or OU creation locally using privileges of the executing user OU( [string] $OUDN, [string] $DomainFQDN, [string] $DomainController ) { $This.OUDN = $OUDN if ($This.OUDN -match "^CN=*") { $This.ObjectType = 'container' } elseif ($This.OUDN -match "^OU=*") { $This.ObjectType = 'organizationalUnit' } elseif ($This.OUDN.Trim() -eq '') { $This.ObjectType = 'domainRoot' } else { olad 1 "Unknown Object Type (not CN or OU): $($This.OUDN)" throw "Unknown Object Type (not CN or OU): $($This.OUDN)" } $This.DomainFQDN = $DomainFQDN $This.DomainDN = "DC=" + $($This.DomainFQDN.replace(".",",DC=")) $This.Credential = $null $This.ExecutionType = 'Local' $This.DomainController = $DomainController } [void]CreateOU () { if ($This.ObjectType -eq 'domainRoot') { olad d "Trying to create root of domain - just return" } else { # Create an array of elements. Start with making sure # root level exist, looping out to the leaf $DNParts = $This.OUDN.Split(',') for ($c = ($DNParts.Count -1); $c -ge 0; $c--) { $CurrentDN = [string]::Join(',', ($DNParts[$c..($DNParts.Count -1)])) $CurrentDomainDN = ($CurrentDN + ',' + $This.DomainDN).TrimStart(',') $CurrentName = (($CurrentDN -split (",",2))[0]).SubString(3) $CurrentParent = ($currentDN -split (",",2))[1] $CurrentParentDomainDN = ($CurrentParent + ',' + $This.DomainDN).TrimStart(',') if ($CurrentParent -eq '') { olad d "'$CurrentName'. The parent domainDN is $CurrentParentDomainDN" } else { olad d 'LeafOU (CurrentName)',"'$CurrentName'" olad d 'Parent (CurrentParent)',"'$CurrentParent'" olad d 'Parent domainDN (CurrentParentDomainDN)',"'$CurrentParentDomainDN'" olad d 'CurrentDomainDN',"'$CurrentDomainDN'" } # Test if object exists try { [ScriptBlock] $GetResultScriptBlock = { param ( $ObjectDN, $Server, $Credential ) try { $GetADObjectParams = @{ Identity = $ObjectDN Server = $Server ErrorAction = 'Stop' } if ($Credential) { $GetADObjectParams += @{ Credential = $Credential } } Get-ADOBject @GetADObjectParams | Out-Null # The Object exists already $true } catch { if($_.CategoryInfo.Reason -eq 'ADIdentityNotFoundException') { # The Object does not exist $false } else { # The Object does not exist olad e "Error trying to get OU '$CurrentName' in parent '$CurrentParent'" olad e $_.Exception.Message olad e $_.InvocationInfo olad e $_.ScriptStackTrace olad e $_.ScriptName olad e $_.TargetObject olad e $_.FullyQualifiedErrorId olad e $_.ErrorRecord # Throw the error to the caller $PSCmdlet.ThrowTerminatingError($_) } } } $GetArgumentList = @($CurrentDomainDN,$This.DomainController,$This.Credential) $GetParams = @{ ScriptBlock = $GetResultScriptBlock ArgumentList = $GetArgumentList } if ($This.ExecutionType -eq 'Remote') { $GetParams += @{ Session = $This.PSSession } } $GetResult = Invoke-Command @GetParams switch ($GetResult) { $true { olad s "The OU exists already" olad d "The OU '$CurrentName' in parent '$CurrentParent' exists already." } $false { olad d "The OU '$CurrentName' in parent '$CurrentParent' does not exist, must be created" } default { olad e "Error trying to get OU '$CurrentName' in parent '$CurrentParent'" throw $GetResult } } } catch { olad e "Failed to test '$CurrentDomainDN'" throw $_ } if ($GetResult -eq $false) { [ScriptBlock] $SetResultScriptBlock = { param ( $Name, $Type, $Path, $Server, $Credential ) try { $NewADObjectParams = @{ Name = $Name Type = $Type Path = $Path Server = $Server ErrorAction = 'Stop' } if ($Credential) { $NewADObjectParams += @{ Credential = $Credential } } New-ADOBject @NewADObjectParams | Out-Null # The Object was created $true } catch { $_ } } $SetArgumentList = @($CurrentName,$This.ObjectType,$CurrentParentDomainDN,$This.DomainController,$This.Credential) $SetParams = @{ ScriptBlock = $SetResultScriptBlock ArgumentList = $SetArgumentList } if ($This.ExecutionType -eq 'Remote') { $SetParams += @{ Session = $This.PSSession } } $SetResult = Invoke-Command @SetParams switch ($SetResult) { $true { olad s "The OU was created" olad d "OU '$CurrentName' in parent '$CurrentParent' was created" $OUsWasCreated = $true } default { olad f "The OU was not created" olad e "Failed to create OU '$CurrentName' in parent '$CurrentParent'" throw $SetResult.ToString() } } } } } } } |