DSCResources/MSFT_ADOrganizationalUnit/MSFT_ADOrganizationalUnit.psm1
$script:resourceModulePath = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent $script:modulesFolderPath = Join-Path -Path $script:resourceModulePath -ChildPath 'Modules' $script:localizationModulePath = Join-Path -Path $script:modulesFolderPath -ChildPath 'ActiveDirectoryDsc.Common' Import-Module -Name (Join-Path -Path $script:localizationModulePath -ChildPath 'ActiveDirectoryDsc.Common.psm1') $script:localizedData = Get-LocalizedData -ResourceName 'MSFT_ADOrganizationalUnit' <# .SYNOPSIS Gets the Organization Unit (OU) from Active Directory .PARAMETER Name The name of Organization Unit (OU). .PARAMETER Path Specifies the X.500 path of the Organization Unit (OU) or container where the new object is created. #> function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter(Mandatory = $true)] [System.String] $Path ) Assert-Module -ModuleName 'ActiveDirectory' Write-Verbose ($script:localizedData.RetrievingOU -f $Name, $Path) try { $ou = Get-ADOrganizationalUnit -Filter { Name -eq $Name } -SearchBase $Path ` -SearchScope OneLevel -Properties ProtectedFromAccidentalDeletion, Description } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { Write-Verbose -Message ($script:localizedData.OUPathIsAbsent -f $Path) } catch { throw $_ } if ($null -eq $ou) { Write-Verbose -Message ($script:localizedData.OUIsAbsent -f $Name) $ensureState = 'Absent' } else { Write-Verbose -Message ($script:localizedData.OUIsPresent -f $Name) $ensureState = 'Present' } return @{ Name = $Name Path = $Path Ensure = $ensureState ProtectedFromAccidentalDeletion = $ou.ProtectedFromAccidentalDeletion Description = $ou.Description } } # end function Get-TargetResource <# .SYNOPSIS Tests the state of the specified Organization Unit (OU). .PARAMETER Name The name of Organization Unit (OU). .PARAMETER Path Specifies the X.500 path of the Organization Unit (OU) or container where the new object is created. .PARAMETER Ensure Specifies whether the Organization Unit (OU) is present or absent. Default value is 'Present'. .PARAMETER Credential The credential to be used to perform the operation on Active Directory. .PARAMETER ProtectedFromAccidentalDeletion Specifies if the Organization Unit (OU) container should be protected from deletion. Default value is $true. .PARAMETER Description The description of the Organization Unit (OU). Default value is empty ('') description. .PARAMETER RestoreFromRecycleBin Try to restore the Organization Unit (OU) from the recycle bin before creating a new one. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential, [Parameter()] [ValidateNotNull()] [System.Boolean] $ProtectedFromAccidentalDeletion = $true, [Parameter()] [ValidateNotNull()] [System.String] $Description = '', [Parameter()] [ValidateNotNull()] [System.Boolean] $RestoreFromRecycleBin ) $targetResource = Get-TargetResource -Name $Name -Path $Path if ($targetResource.Ensure -eq 'Present') { if ($Ensure -eq 'Present') { # Organizational unit exists if ([System.String]::IsNullOrEmpty($Description)) { $isCompliant = (($targetResource.Name -eq $Name) -and ($targetResource.Path -eq $Path) -and ($targetResource.ProtectedFromAccidentalDeletion -eq $ProtectedFromAccidentalDeletion)) } else { $isCompliant = (($targetResource.Name -eq $Name) -and ($targetResource.Path -eq $Path) -and ($targetResource.ProtectedFromAccidentalDeletion -eq $ProtectedFromAccidentalDeletion) -and ($targetResource.Description -eq $Description)) } if ($isCompliant) { Write-Verbose ($script:localizedData.OUInDesiredState -f $targetResource.Name) } else { Write-Verbose ($script:localizedData.OUNotInDesiredState -f $targetResource.Name) } } else { $isCompliant = $false Write-Verbose ($script:localizedData.OUExistsButShouldNot -f $targetResource.Name) } } else { # Organizational unit does not exist if ($Ensure -eq 'Present') { $isCompliant = $false Write-Verbose ($script:localizedData.OUDoesNotExistButShould -f $targetResource.Name) } else { $isCompliant = $true Write-Verbose ($script:localizedData.OUDoesNotExistAndShouldNot -f $targetResource.Name) } } return $isCompliant } #end function Test-TargetResource <# .SYNOPSIS Sets the state of the Organization Unit (OU) in Active Directory. .PARAMETER Name The name of Organization Unit (OU). .PARAMETER Path Specifies the X.500 path of the Organization Unit (OU) or container where the new object is created. .PARAMETER Ensure Specifies whether the Organization Unit (OU) is present or absent. Default value is 'Present'. .PARAMETER Credential The credential to be used to perform the operation on Active Directory. .PARAMETER ProtectedFromAccidentalDeletion Specifies if the Organization Unit (OU) container should be protected from deletion. Default value is $true. .PARAMETER Description The description of the Organization Unit (OU). Default value is empty ('') description. .PARAMETER RestoreFromRecycleBin Try to restore the Organization Unit (OU) from the recycle bin before creating a new one. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', [Parameter()] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential, [Parameter()] [ValidateNotNull()] [System.Boolean] $ProtectedFromAccidentalDeletion = $true, [Parameter()] [ValidateNotNull()] [System.String] $Description = '', [Parameter()] [ValidateNotNull()] [System.Boolean] $RestoreFromRecycleBin ) Assert-Module -ModuleName 'ActiveDirectory' $targetResource = Get-TargetResource -Name $Name -Path $Path if ($targetResource.Ensure -eq 'Present') { $ou = Get-ADOrganizationalUnit -Filter { Name -eq $Name } -SearchBase $Path -SearchScope OneLevel if ($Ensure -eq 'Present') { Write-Verbose ($script:localizedData.UpdatingOU -f $targetResource.Name) $setADOrganizationalUnitParams = @{ Identity = $ou Description = $Description ProtectedFromAccidentalDeletion = $ProtectedFromAccidentalDeletion } if ($Credential) { $setADOrganizationalUnitParams['Credential'] = $Credential } Set-ADOrganizationalUnit @setADOrganizationalUnitParams } else { Write-Verbose ($script:localizedData.DeletingOU -f $targetResource.Name) if ($targetResource.ProtectedFromAccidentalDeletion) { $setADOrganizationalUnitParams = @{ Identity = $ou ProtectedFromAccidentalDeletion = $ProtectedFromAccidentalDeletion } if ($Credential) { $setADOrganizationalUnitParams['Credential'] = $Credential } Set-ADOrganizationalUnit @setADOrganizationalUnitParams } $removeADOrganizationalUnitParams = @{ Identity = $ou } if ($Credential) { $removeADOrganizationalUnitParams['Credential'] = $Credential } Remove-ADOrganizationalUnit @removeADOrganizationalUnitParams } return # return from Set method to make it easier to test for a successful restore } else { if ($RestoreFromRecycleBin) { Write-Verbose -Message ($script:localizedData.RestoringOu -f $Name) $restoreParams = @{ Identity = $Name ObjectClass = 'OrganizationalUnit' ErrorAction = 'Stop' } if ($Credential) { $restoreParams['Credential'] = $Credential } $restoreSuccessful = Restore-ADCommonObject @restoreParams } if (-not $RestoreFromRecycleBin -or ($RestoreFromRecycleBin -and -not $restoreSuccessful)) { Write-Verbose ($script:localizedData.CreatingOU -f $targetResource.Name) $newADOrganizationalUnitParams = @{ Name = $Name Path = $Path Description = $Description ProtectedFromAccidentalDeletion = $ProtectedFromAccidentalDeletion } if ($Credential) { $newADOrganizationalUnitParams['Credential'] = $Credential } try { New-ADOrganizationalUnit @newADOrganizationalUnitParams } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { $errorMessage = $script:localizedData.PathNotFoundError -f $Path New-ObjectNotFoundException -Message $errorMessage } catch { throw $_ } } } } #end function Set-TargetResource Export-ModuleMember -Function *-TargetResource |