Providers/AD/Private/New-ADTestOU.ps1
|
function New-ADTestOU { <# .SYNOPSIS Creates an Active Directory OU with WhatIf support .DESCRIPTION Helper function to create OUs with consistent error handling and WhatIf support .PARAMETER Name Name of the OU to create .PARAMETER Path Parent path where the OU should be created .PARAMETER Description Description for the OU .PARAMETER Unprotected Creates the OU without accidental deletion protection. New-ADOrganizationalUnit turns that protection on by default, and a protected child blocks a recursive delete of its parent. Pass this for OUs that a teardown is expected to remove as part of a subtree - the edge case tree is the case that needs it. Left off, the behaviour is unchanged: the OU is protected. .EXAMPLE New-ADTestOU -Name "TestUsers" -Path "DC=contoso,DC=com" -Description "Test user accounts" DESCRIPTION: Creates a protected OU OUTPUT: Hashtable with Success, Action, Message and DistinguishedName .EXAMPLE New-ADTestOU -Name "EdgeCases" -Path $testDataOU -Description "Disposable" -Unprotected DESCRIPTION: Creates an OU a recursive teardown can remove OUTPUT: Hashtable with Success, Action, Message and DistinguishedName .OUTPUTS System.Collections.Hashtable Success, Action ('Created', 'Skipped', 'WhatIf' or 'Failed'), Message, and DistinguishedName. DistinguishedName is returned whatever the action, so a caller that needs the path does not have to rebuild it. .NOTES Author: Jeffrey Stuhr Version: 1.1.0 #> [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([hashtable])] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [string]$Description, [Parameter()] [switch]$Unprotected ) $fullPath = "OU=$Name,$Path" try { if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$fullPath'" -ErrorAction SilentlyContinue)) { if ($PSCmdlet.ShouldProcess($fullPath, "Create OU")) { $ouParam = @{ Name = $Name Path = $Path Description = $Description # Every object this module creates carries the seed tag here, including the # containers. adminDescription is base schema and on top, so one attribute # covers organisational units, users, computers and groups alike. OtherAttributes = @{ adminDescription = (Get-ADTestSeedMarker).Tag } } if ($Unprotected) { $ouParam['ProtectedFromAccidentalDeletion'] = $false } New-ADOrganizationalUnit @ouParam Write-Verbose "Created OU: $Name" return @{ Success = $true; Action = 'Created' Message = "OU created: $Name"; DistinguishedName = $fullPath } } else { return @{ Success = $true; Action = 'WhatIf' Message = "Would create OU: $Name"; DistinguishedName = $fullPath } } } else { Write-Verbose "OU already exists: $Name" return @{ Success = $true; Action = 'Skipped' Message = "OU already exists: $Name"; DistinguishedName = $fullPath } } } catch { Write-Error "Failed to create OU '$Name': $($_.Exception.Message)" return @{ Success = $false; Action = 'Failed' Message = "Failed to create OU '$Name': $($_.Exception.Message)" DistinguishedName = $fullPath } } } |