functions/Invoke-AdmfDomain.ps1
function Invoke-AdmfDomain { <# .SYNOPSIS Brings a domain into compliance with the desired state. .DESCRIPTION Brings a domain into compliance with the desired state. It implements a wide variety of settings against the targeed domain, whether it be OUs, groups, users, gpos, acls or many more items. Note on order: - OU Creation and Updating should be done first, but DELETING ous (OUHard) should be one of the last operations performed. - Acl & Access operations should be performed last - Managing group policy yields best results in this order: 1. Create new GPO 2. Create Links, only disabling undesired links 3. Delete unneeded GPO 4. Delete undesired links This is due to the fact that "unneeded GPO" are detected by being linked into managed GPOs. .PARAMETER Server The server / domain to work with. .PARAMETER Credential The credentials to use for this operation. .PARAMETER Options The various operations that are supported. By default "default" operations are executed against the targeted domain. - Acl : The basic permission behavior of an object (e.g.: Owner, Inheritance) - GPLink : Manages the linking of group policies. - GPPermission : Managing permissions on group policy objects. - GroupPolicy : Deploying and updating GPOs. - GroupMembership : Assigning group membership - Group : Creating groups - OUSoft : Creating & modifying OUs, but not deleting them - OUHard : Creating, Modifying & Deleting OUs. This exists in order to be able to create new OUs, then move all objects over and only when done deleting undesired OUs. Will NOT delete OUs that contain objects.! - PSO : Implementing Finegrained Password Policies - Object : Custom AD object - User : Managing User objects - GPLinkDisable : Creating GP Links, but only disabling undesired links. This is needed in order to detect undesired GPOs to delete: Those linked when they shouldn't be! - GroupPolicyDelete : Deploy, update and delete Group Policy objects. .PARAMETER CredentialProvider The credential provider to use to resolve the input credentials. See help on Register-AdmfCredentialProvider for details. .PARAMETER ContextPrompt Force displaying the Context selection User Interface. .PARAMETER Confirm If this switch is enabled, you will be prompted for confirmation before executing any operations that change state. .PARAMETER WhatIf If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run. .EXAMPLE PS C:\> Invoke-AdmfDomain Brings the current domain into compliance with the desired state. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingPlainTextForPassword', '')] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] Param ( [PSFComputer] $Server, [PSCredential] $Credential, [ADMF.UpdateDomainOptions[]] $Options = 'Default', [string] $CredentialProvider = 'default', [Alias('Ctx')] [switch] $ContextPrompt ) begin { Reset-DomainControllerCache $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential $originalArgument = Invoke-PreCredentialProvider @parameters -ProviderName $CredentialProvider -Parameter $parameters -Cmdlet $PSCmdlet try { $dcServer = Resolve-DomainController @parameters -Confirm:$false } catch { Invoke-PostCredentialProvider -ProviderName $CredentialProvider -Server $originalArgument.Server -Credential $originalArgument.Credential -Cmdlet $PSCmdlet throw } $parameters.Server = $dcServer Invoke-PSFCallback -Data $parameters -EnableException $true -PSCmdlet $PSCmdlet Set-AdmfContext @parameters -Interactive -ReUse:$(-not $ContextPrompt) -EnableException $parameters += $PSBoundParameters | ConvertTo-PSFHashtable -Include WhatIf, Confirm, Verbose, Debug $parameters.Server = $dcServer [ADMF.UpdateDomainOptions]$newOptions = $Options } process { try { if ($newOptions -band [UpdateDomainOptions]::OUSoft) { if (Get-DMOrganizationalUnit) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'OrganizationalUnits - Create & Modify', $parameters.Server Invoke-DMOrganizationalUnit @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'OrganizationalUnits - Create & Modify' } } if ($newOptions -band [UpdateDomainOptions]::Group) { if (Get-DMGroup) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'Groups', $parameters.Server Invoke-DMGroup @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'Groups' } } if ($newOptions -band [UpdateDomainOptions]::User) { if (Get-DMUser) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'Users', $parameters.Server Invoke-DMUser @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'Users' } } if ($newOptions -band [UpdateDomainOptions]::ServiceAccount) { if (Get-DMServiceAccount) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'ServiceAccounts', $parameters.Server Invoke-DMServiceAccount @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'ServiceAccounts' } } if ($newOptions -band [UpdateDomainOptions]::GroupMembership) { if (Get-DMGroupMembership) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupMembership', $parameters.Server Invoke-DMGroupMembership @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupMembership' } } if ($newOptions -band [UpdateDomainOptions]::PSO) { if (Get-DMPasswordPolicy) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'PasswordPolicies', $parameters.Server Invoke-DMPasswordPolicy @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'PasswordPolicies' } } if ($newOptions -band [UpdateDomainOptions]::GroupPolicy) { if (Get-DMGroupPolicy) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupPolicies - Create & Modify', $parameters.Server Invoke-DMGroupPolicy @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupPolicies - Create & Modify' } } if ($newOptions -band [UpdateDomainOptions]::GPPermission) { if (Get-DMGPPermission) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupPolicyPermissions', $parameters.Server Invoke-DMGPPermission @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupPolicyPermissions' } } if ($newOptions -band [UpdateDomainOptions]::GPLinkDisable) { if (Get-DMGPLink) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupPolicyLinks - Create, Update & Disable unwanted Links', $parameters.Server Invoke-DMGPLink @parameters -Disable } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupPolicyLinks - Create, Update & Disable unwanted Links' } } if ($newOptions -band [UpdateDomainOptions]::GroupPolicyDelete) { if (Get-DMGroupPolicy) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupPolicies - Delete', $parameters.Server Invoke-DMGroupPolicy @parameters -Delete } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupPolicies - Delete' } } if ($newOptions -band [UpdateDomainOptions]::GPLink) { if (Get-DMGPLink) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'GroupPolicyLinks - Delete unwanted Links', $parameters.Server Invoke-DMGPLink @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'GroupPolicyLinks - Delete unwanted Links' } } if ($newOptions -band [UpdateDomainOptions]::OUHard) { if (Get-DMOrganizationalUnit) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'OrganizationalUnits - Delete', $parameters.Server Invoke-DMOrganizationalUnit @parameters -Delete } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'OrganizationalUnits - Delete' } } if ($newOptions -band [UpdateDomainOptions]::Object) { if (Get-DMObject) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'Objects', $parameters.Server Invoke-DMObject @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'Objects' } } if ($newOptions -band [UpdateDomainOptions]::Acl) { if (Get-DMAcl | Remove-PSFNull) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'Acls', $parameters.Server Invoke-DMAcl @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'Acls' } } if ($newOptions -band [UpdateDomainOptions]::AccessRule) { if (Get-DMAccessRule) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'AccessRules', $parameters.Server Invoke-DMAccessRule @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'AccessRules' } } if ($newOptions -band [UpdateDomainOptions]::DomainLevel) { if (Get-DMDomainLevel) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'DomainLevel', $parameters.Server Invoke-DMDomainLevel @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'DomainLevel' } } if ($newOptions -band [UpdateDomainOptions]::Exchange) { if (Get-DMExchange) { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Executing.Invoke' -StringValues 'Exchange System Objects', $parameters.Server Invoke-DMExchange @parameters } else { Write-PSFMessage -Level Host -String 'Invoke-AdmfDomain.Skipping.Test.NoConfiguration' -StringValues 'Exchange System Objects' } } } catch { throw } finally { Invoke-PostCredentialProvider -ProviderName $CredentialProvider -Server $originalArgument.Server -Credential $originalArgument.Credential -Cmdlet $PSCmdlet } } } |