private/createOrSetGPO.ps1
function CreateOrSetGPO { [CmdletBinding(SupportsShouldProcess=$true,DefaultParameterSetName='Default')] Param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({[bool](get-rbacOrg -org $_ -includeGlobal)})] [ArgumentCompleter( {(get-rbacOrg -includeGlobal).Org})] [String]$Org, [Parameter(Mandatory, ValueFromPipelineByPropertyName, ParameterSetName = 'SpecificComponent')] [ValidateScript({ $(get-rbacComponent).component.contains($_) })] [ArgumentCompleter( {(get-rbacComponent).Component})] [String]$Component, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Hashtable]$GPOTemplate ) Begin{ $Domain = get-ADDomain $DomainDNSRoot= $Domain.DNSRoot $DomainGPOPath="\\$DomainDNSRoot\sysvol\$DomainDNSRoot\Policies" $shouldProcess = @{ Confirm = [bool]($ConfirmPreference -eq "low") Whatif = [bool]($WhatIfPreference.IsPresent) verbose = [bool]($verbosePreference -eq "continue") } $GPOHeader_SecEdit_INF=@' [Unicode] Unicode=yes [Version] signature="$CHICAGO$" Revision=1 '@ $GPOHeader_GPT_INI_HEADER=@' [General] Version=1 displayName=New Group Policy Object '@ } PROCESS { if ($component) { $element = get-rbacComponent -org $org -component $Component -detailed } else { $element = get-rbacOrg -org $org -includeGlobal -detailed } if (-not $element) { throw "Invalid RBAC Element (maybe wrong org for component?)" } if ($org -eq $OrganizationConfig.GlobalOUName) { $element.distinguishedName = "OU=$($OrgsOUStruct.Name),$($OrgsOUStruct.Path)" } $GPOName = "{0}-{1}" -f $GPOTemplate.Metadata.NamePrefix, $Element.objectMidName write-Verbose "Working on GPO: $GPOName" $GPOObject = if ($PSCmdlet.ShouldProcess($GPOName, "Create / get GPO")) { try { new-gpo -name $GPOName -erroraction stop @shouldProcess $preExisting = $false Write-Host "Created GPO: $GPOName" } catch { write-warning "GPO already existed: $GPOName" $preExisting = $true get-gpo $GPOName } } else { get-gpo $GPOName } $GPOBaseFilePath = "{0}\{{{1}}}" -f $DomainGPOPath, $GPOObject.ID.GUID #region set GPLink if ($PSCmdlet.ShouldProcess($GPOName, "Create or Set GPLink")) { try { new-gplink -name $GPOName -target $Element.DistinguishedName -erroraction stop @shouldProcess| out-null } catch { write-Verbose "$($GPONname) GPLink already exists." } $GPLinkParams = @{ target = $Element.distinguishedname Order = $GPOTemplate.Metadata.LinkOrder LinkEnabled = "Yes" Enforced = "No" } $GPOObject | set-gplink @GPLinkParams | out-null Write-host ("Set GPLink: {0,-32} : #{1,-1} ; Enforced: {2,-5} ; Enabled: {3,-5} ; Path: {4}" -f $GPOObject.displayName, $GPLinkParams.Order, $GPLinkParams.Enforced, $GPLinkParams.LinkEnabled, $GPLinkParams.target) } #endregion #region Set permissions on GPO $GPPermissions = @{} foreach ($GPPermissionLevel in $GPOTemplate.metadata.gppermissions.getEnumerator()) { $entityList = resolveEntityReferences -rightsPrefix "Right-$($element.objectMidName)" -rightsAndPrincipals $GPPermissionLevel.value $GPPermissions.$($GPPermissionLevel.key) = $EntityList } write-host "Setting permissions for GPO..." foreach ($PermissionLevel in $GPPermissions.GetEnumerator()) { foreach ($entity in $PermissionLevel.value) { if ($PSCmdlet.ShouldProcess($GPOName, ("Set permissions: {0,-10}; on entityType: {1,-10}; entity: {2}" -f $permissionLevel.key, $entity.objectClass, $entity.name))) { try { $Params = @{ name = $GPOName TargetName = $entity.name TargetType = $entity.objectClass Permissionlevel = $permissionLevel.key Replace = $true } set-GPPermission @Params -ErrorAction stop | out-null } Catch { $_ | format-list * -force Write-warning "Error setting permissions for $GroupName on $GPOName" throw $_ } } } } #endregion if (-not $preExisting -or $GPOTemplate.Metadata.AlwaysRebuild) { $GPCExtensionList = "[{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90F574B}]" #region SecEdit.inf $SecEditPath ="{0}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf" -f $GPOBaseFilePath $SecEditContents = try { $GPOHeader_SecEdit_INF if ($GPOTemplate.SecEdit) { foreach ($Section in $GPOTemplate.secedit.getEnumerator()){ $SectionString = "[{0}]" -f $section.key $sectionString try { foreach ($setting in $Section.value.getEnumerator()) { write-verbose "Setting Secedit \ $($section.key)" $entityList = resolveEntityReferences -rightsPrefix "Right-$($element.objectMidName)" -rightsAndPrincipals $setting.value $NamesList = ($entityList | where-object {$null -ne $_.name -and $null -eq $_.GPOSIDRef} ).name -join "," $SIDList = ($entityList | where-object {$null -ne $_.GPOSIDRef} ).GPOSIDRef -join "," $EntityString = (@($NamesList, $SIDList) | where-object {$_ -ne $null -and $_ -ne ""}) -join "," "{0} = {1}" -f $setting.key, $entityString } } catch [System.Management.Automation.RuntimeException] { write-warning "Missing settings or bad format in GPO template (Section: secedit \ $($section.key))..." $_ | format-list * -force } } } } catch [System.Management.Automation.RuntimeException] { write-warning "Missing settings or bad format in GPO template under SECEDIT..." $_ | format-list * -force } if ($PSCmdlet.ShouldProcess($SecEditPath, ("Writing out SecEdit.inf"))) { new-item $SecEditPath -force | out-null $SecEditContents | out-file -append $SecEditPath -Encoding unicode } else { $secEditContents } #endRegion #region RegPol if ($GPOTemplate.RegPol) { $GPCExtensionList = "[{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{D02B1F72-3407-48AE-BA88-E8213C6761F1}]" + $GPCExtensionList $RegPolPath ="{0}\Machine\Registry.pol" -f $GPOBaseFilePath $PolicyDefs = foreach ($policyItem in $GPOTemplate.RegPol) { $Value = if ($PolicyItem.ValueCollection) { $entityList = resolveEntityReferences -rightsPrefix "Right-$($element.objectMidName)" -rightsAndPrincipals $PolicyItem.ValueCollection # Special Handling switch ($policyItem.ValueName) { "ADPasswordEncryptionPrincipal" { $EntityList[0].NetBIOS } default { ($($entityList.name + $entityList.SID.Value) | where-object {$_ -ne $null}) -join "," } } } else { $policyItem.valueData } $Policy = @{ keyName = $policyItem.keyName valueName = $policyItem.valueName ValueType = $Policyitem.valueType ValueData = $value } write-host ("Setting policy {2,-10}- {0}\{1} = {3}" -f $policy.keyName, $Policy.valueName, $policy.valueType, $policy.ValueData) New-GPRegistryPolicy @policy } Create-GPRegistryPolicyFile -path $RegPolPath append-RegistryPolicies -registryPolicies $PolicyDefs -path $RegPolPath } # endregion # region GPPrefRegistryValues if ($GPOTemplate.GPPrefRegistryValues) { $GPCExtensionList = $GPCExtensionList + "[{B087BE9D-ED37-454F-AF9C-04291E351182}{BEE07A6A-EC9F-4659-B8C9-0B1937907C83}]" foreach ($RegistryPref in $GPOTemplate.GPPrefRegistryValues) { set-GPPrefRegistryValue -GUID $GPOObject.ID @RegistryPref -verbose } } # endregion if ($PSCmdlet.ShouldProcess($GPOObject.Path,"Set GPCMachineExtensions on GPO and increment version")) { try { $oldVersion = (get-adobject -identity $GPOObject.Path -properties versionNumber).versionNumber $newVersion = [int]$oldVersion + 1 } catch { $newVersion = 1 } set-adobject -identity $GPOObject.Path -replace @{gPCMachineExtensionNames = $GPCExtensionList; versionNumber = $newVersion} | out-null $GPT_Ini_Contents=@" [General] Version=$NewVersion displayName=$GPOName "@ # Apparently encoding unicode is bad news for gpt.ini $GPT_Ini_Contents | out-file $GPOBaseFilePath\gpt.ini -Force } } } End { } } |