Providers/AD/Public/New-ADTestGroupPolicy.ps1
|
function New-ADTestGroupPolicy { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the companion Group Policy object that denies logon to the test service accounts. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Colour-coded console progress is intentional; results are returned as objects.')] [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [switch]$PassThru ) begin { $correlationId = [System.Guid]::NewGuid() Write-Verbose "Starting New-ADTestGroupPolicy - CorrelationId: $correlationId" $domain = Get-ADTestDomain $policy = Get-ADTestPolicySetting -DomainDN $domain.DomainDN $result = [PSCustomObject]@{ CorrelationId = $correlationId Name = $policy.Name Created = $false Linked = $false AccountCount = 0 LinkTarget = $policy.LinkTarget Errors = @() Warnings = @() } } process { try { Write-TestMessage -Message 'Creating test deny-logon Group Policy' -Type Header try { Import-Module GroupPolicy -ErrorAction Stop -Verbose:$false } catch { $msg = 'GroupPolicy module not available - install RSAT-GPMC to create ' + 'the companion policy' Write-Warning $msg $result.Warnings += $msg return } # The policy is meaningless without machines to apply to, and linking it # somewhere else would widen its scope beyond the test data. $linkOU = Get-ADOrganizationalUnit -Identity $policy.LinkTarget -ErrorAction SilentlyContinue if (-not $linkOU) { $msg = "Link target not found: $($policy.LinkTarget). Create the OU " + 'structure before the policy.' Write-Warning $msg $result.Warnings += $msg return } $accounts = @(Get-ADUser -Filter * -SearchBase $policy.AccountOU -ErrorAction SilentlyContinue) $result.AccountCount = $accounts.Count if ($accounts.Count -eq 0) { $msg = 'No service accounts found; the policy would name nobody' Write-Warning $msg $result.Warnings += $msg return } Write-TestMessage -Message "Denying logon to $($accounts.Count) service accounts..." -Type Info $existing = Get-GPO -Name $policy.Name -ErrorAction SilentlyContinue if ($existing) { Write-Verbose "Policy '$($policy.Name)' already exists - reusing it" $gpo = $existing } elseif ($PSCmdlet.ShouldProcess($policy.Name, 'Create Group Policy object')) { $gpo = New-GPO -Name $policy.Name -Comment $policy.Comment -ErrorAction Stop $result.Created = $true Write-Verbose "Created GPO $($gpo.Id)" } else { # Under -WhatIf there is no object to configure, so stop here rather than # reporting work that did not happen. return } if ($PSCmdlet.ShouldProcess($policy.LinkTarget, "Link GPO '$($policy.Name)'")) { $alreadyLinked = $false $inheritance = Get-GPInheritance -Target $policy.LinkTarget -ErrorAction SilentlyContinue if ($inheritance) { $alreadyLinked = @($inheritance.GpoLinks | Where-Object { $_.DisplayName -eq $policy.Name }).Count -gt 0 } if (-not $alreadyLinked) { $null = New-GPLink -Guid $gpo.Id -Target $policy.LinkTarget -LinkEnabled Yes -ErrorAction Stop } $result.Linked = $true Write-Verbose "Linked to $($policy.LinkTarget)" } if ($PSCmdlet.ShouldProcess($policy.Name, 'Write deny-logon user rights')) { Set-ADTestPolicyUserRight -PolicyId $gpo.Id -Right $policy.Right -Account $accounts Write-Verbose "Wrote $($policy.Right.Count) deny-logon rights" } Write-Host " Policy: $($policy.Name)" -ForegroundColor Green Write-Host " Linked to: $($policy.LinkTarget)" -ForegroundColor Green Write-Host " Accounts denied logon: $($accounts.Count)" -ForegroundColor Green } catch { $errorMsg = "Failed to create test Group Policy: $($_.Exception.Message)" $result.Errors += $errorMsg Write-Error $errorMsg } } end { if ($PassThru) { return $result } } } |