This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)] [string] $GpoName,
|
||||
[Parameter(Mandatory)] [string] $PolicyName,
|
||||
[string] $PolicyName = '',
|
||||
[Parameter(Mandatory)] [string] $ServerUrl,
|
||||
[Parameter(Mandatory)] [string] $AdminToken,
|
||||
[Parameter(Mandatory)] [string] $GpoCtl,
|
||||
@@ -10,11 +10,82 @@ param(
|
||||
[string] $Domain,
|
||||
[string] $DomainController,
|
||||
[switch] $InsecureSkipVerify,
|
||||
[switch] $ForceVersion
|
||||
[switch] $ForceVersion,
|
||||
[switch] $StrictPolicyName
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if (-not (Test-Path -LiteralPath $GpoCtl -PathType Leaf)) { throw "gpoctl not found: $GpoCtl" }
|
||||
$policyNamePattern = '^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$'
|
||||
|
||||
function ConvertTo-RepositoryPolicyName {
|
||||
[CmdletBinding()]
|
||||
param([Parameter(Mandatory)] [string] $Value)
|
||||
|
||||
$valueToConvert = $Value.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($valueToConvert)) {
|
||||
throw 'PolicyName must not be empty.'
|
||||
}
|
||||
|
||||
# Remove diacritics where possible and replace every sequence of characters
|
||||
# that is unsafe for a repository identifier with a single hyphen.
|
||||
$decomposed = $valueToConvert.Normalize([Text.NormalizationForm]::FormD)
|
||||
$builder = [Text.StringBuilder]::new()
|
||||
$separatorPending = $false
|
||||
|
||||
foreach ($character in $decomposed.ToCharArray()) {
|
||||
$category = [Globalization.CharUnicodeInfo]::GetUnicodeCategory($character)
|
||||
if ($category -eq [Globalization.UnicodeCategory]::NonSpacingMark) {
|
||||
continue
|
||||
}
|
||||
|
||||
$text = [string] $character
|
||||
if ($text -match '^[A-Za-z0-9._-]$') {
|
||||
[void] $builder.Append($character)
|
||||
$separatorPending = $false
|
||||
}
|
||||
elseif (-not $separatorPending -and $builder.Length -gt 0) {
|
||||
[void] $builder.Append('-')
|
||||
$separatorPending = $true
|
||||
}
|
||||
}
|
||||
|
||||
$converted = $builder.ToString()
|
||||
$converted = $converted -replace '-{2,}', '-'
|
||||
$converted = $converted.Trim([char[]]'.-_')
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($converted)) {
|
||||
throw "PolicyName '$Value' cannot be converted to a valid repository name."
|
||||
}
|
||||
if ($converted[0] -notmatch '[A-Za-z0-9]') {
|
||||
$converted = 'gpo-' + $converted
|
||||
}
|
||||
if ($converted.Length -gt 64) {
|
||||
$converted = $converted.Substring(0, 64).TrimEnd([char[]]'.-_')
|
||||
}
|
||||
if ($converted -notmatch $policyNamePattern) {
|
||||
throw "PolicyName '$Value' cannot be converted to a name matching $policyNamePattern."
|
||||
}
|
||||
return $converted
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $GpoCtl -PathType Leaf)) {
|
||||
throw "gpoctl not found: $GpoCtl"
|
||||
}
|
||||
|
||||
$requestedPolicyName = if ([string]::IsNullOrWhiteSpace($PolicyName)) { $GpoName } else { $PolicyName.Trim() }
|
||||
if ($requestedPolicyName -match $policyNamePattern) {
|
||||
$resolvedPolicyName = $requestedPolicyName
|
||||
}
|
||||
elseif ($StrictPolicyName) {
|
||||
throw "PolicyName '$requestedPolicyName' is invalid. It must match $policyNamePattern (maximum 64 characters; no spaces or umlauts)."
|
||||
}
|
||||
else {
|
||||
$resolvedPolicyName = ConvertTo-RepositoryPolicyName -Value $requestedPolicyName
|
||||
Write-Warning "PolicyName '$requestedPolicyName' was normalized to '$resolvedPolicyName'."
|
||||
}
|
||||
|
||||
Write-Host "Publishing AD GPO '$GpoName' as repository policy '$resolvedPolicyName'."
|
||||
|
||||
$work = Join-Path ([IO.Path]::GetTempPath()) ("gpo-publish-" + [guid]::NewGuid().ToString('N'))
|
||||
$backup = Join-Path $work 'backup'
|
||||
$zip = Join-Path $work 'gpo-backup.zip'
|
||||
@@ -36,12 +107,21 @@ try {
|
||||
$false
|
||||
)
|
||||
|
||||
$args = @('upload', '-server', $ServerUrl, '-token', $AdminToken, '-policy', $PolicyName, '-file', $zip)
|
||||
if ($Note) { $args += @('-note', $Note) }
|
||||
if ($InsecureSkipVerify) { $args += '-insecure-skip-verify' }
|
||||
if ($ForceVersion) { $args += '-force' }
|
||||
& $GpoCtl @args
|
||||
if ($LASTEXITCODE -ne 0) { throw "gpoctl exited with code $LASTEXITCODE" }
|
||||
$arguments = @(
|
||||
'upload',
|
||||
'-server', $ServerUrl,
|
||||
'-token', $AdminToken,
|
||||
'-policy', $resolvedPolicyName,
|
||||
'-file', $zip
|
||||
)
|
||||
if ($Note) { $arguments += @('-note', $Note) }
|
||||
if ($InsecureSkipVerify) { $arguments += '-insecure-skip-verify' }
|
||||
if ($ForceVersion) { $arguments += '-force' }
|
||||
|
||||
& $GpoCtl @arguments
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "gpoctl exited with code $LASTEXITCODE"
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Remove-Item -LiteralPath $work -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Reference in New Issue
Block a user