135 lines
5.5 KiB
PowerShell
135 lines
5.5 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess)]
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[string]$PublishPath,
|
|
|
|
[Parameter(Mandatory)]
|
|
[ValidatePattern('^https://')]
|
|
[string]$BrokerEndpoint,
|
|
|
|
[Parameter(Mandatory)]
|
|
[ValidatePattern('^[0-9A-Fa-f ]{40,59}$')]
|
|
[string]$ClientCertificateThumbprint,
|
|
|
|
[Parameter(Mandatory)]
|
|
[ValidatePattern('^[0-9A-Fa-f ]{40,59}$')]
|
|
[string]$ServerCertificateThumbprint,
|
|
|
|
[string]$DomainNetbios = 'LCI',
|
|
[ValidateRange(2, 90)]
|
|
[int]$TimeoutSeconds = 90,
|
|
[string]$RemoteDesktopPrincipal = 'LCI\SG-Laboratorio-Usuarios-RDP',
|
|
[string]$DotNetRuntimeInstallerPath
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$taskName = 'SGU-CredentialProvider-EnrollmentGuard'
|
|
$enrollmentRoot = Join-Path $env:ProgramData 'SGU\Enrollment'
|
|
$sourceScripts = @(
|
|
'Install-CredentialProvider.ps1',
|
|
'Enable-LabRemoteAccess.ps1',
|
|
'Test-SguClientEnrollment.ps1',
|
|
'Repair-SguClientEnrollment.ps1'
|
|
)
|
|
|
|
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
|
|
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
|
throw 'Run this script from an elevated Windows PowerShell session.'
|
|
}
|
|
|
|
foreach ($scriptName in $sourceScripts) {
|
|
if (-not (Test-Path -LiteralPath (Join-Path $PSScriptRoot $scriptName) -PathType Leaf)) {
|
|
throw "$scriptName must be beside Install-SguEnrollmentGuard.ps1."
|
|
}
|
|
}
|
|
|
|
$requiredProviderFile = Join-Path $PublishPath 'SGU.CredentialProvider.comhost.dll'
|
|
if (-not (Test-Path -LiteralPath $requiredProviderFile -PathType Leaf)) {
|
|
throw 'PublishPath does not contain the Credential Provider package.'
|
|
}
|
|
|
|
if ($DotNetRuntimeInstallerPath -and
|
|
-not (Test-Path -LiteralPath $DotNetRuntimeInstallerPath -PathType Leaf)) {
|
|
throw 'DotNetRuntimeInstallerPath does not exist.'
|
|
}
|
|
|
|
if ($PSCmdlet.ShouldProcess($enrollmentRoot, 'Install the SGU enrollment repair guard')) {
|
|
New-Item -ItemType Directory -Path $enrollmentRoot -Force | Out-Null
|
|
$packageId = '{0}-{1}' -f (Get-Date -Format 'yyyyMMddHHmmss'), ([Guid]::NewGuid().ToString('N').Substring(0, 8))
|
|
$guardPublishPath = Join-Path $enrollmentRoot "packages\$packageId"
|
|
New-Item -ItemType Directory -Path $guardPublishPath -Force | Out-Null
|
|
Copy-Item -Path (Join-Path $PublishPath '*') -Destination $guardPublishPath -Recurse -Force
|
|
|
|
foreach ($scriptName in $sourceScripts) {
|
|
Copy-Item -LiteralPath (Join-Path $PSScriptRoot $scriptName) `
|
|
-Destination (Join-Path $enrollmentRoot $scriptName) -Force
|
|
}
|
|
|
|
$guardRuntimeInstaller = $null
|
|
if ($DotNetRuntimeInstallerPath) {
|
|
$runtimeDirectory = Join-Path $enrollmentRoot 'prerequisites'
|
|
New-Item -ItemType Directory -Path $runtimeDirectory -Force | Out-Null
|
|
$guardRuntimeInstaller = Join-Path $runtimeDirectory (Split-Path $DotNetRuntimeInstallerPath -Leaf)
|
|
Copy-Item -LiteralPath $DotNetRuntimeInstallerPath -Destination $guardRuntimeInstaller -Force
|
|
}
|
|
|
|
$guardConfiguration = [ordered]@{
|
|
PublishPath = $guardPublishPath
|
|
BrokerEndpoint = $BrokerEndpoint
|
|
ClientCertificateThumbprint = ($ClientCertificateThumbprint -replace ' ', '')
|
|
ServerCertificateThumbprint = ($ServerCertificateThumbprint -replace ' ', '')
|
|
DomainNetbios = $DomainNetbios
|
|
TimeoutSeconds = $TimeoutSeconds
|
|
RemoteDesktopPrincipal = $RemoteDesktopPrincipal
|
|
DotNetRuntimeInstallerPath = $guardRuntimeInstaller
|
|
}
|
|
$configurationPath = Join-Path $enrollmentRoot 'enrollment.json'
|
|
[IO.File]::WriteAllText(
|
|
$configurationPath,
|
|
($guardConfiguration | ConvertTo-Json),
|
|
[Text.UTF8Encoding]::new($false))
|
|
|
|
$acl = Get-Acl -LiteralPath $enrollmentRoot
|
|
$acl.SetAccessRuleProtection($true, $false)
|
|
$acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new(
|
|
'SYSTEM', 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow'))
|
|
$acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new(
|
|
'BUILTIN\Administrators', 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow'))
|
|
Set-Acl -LiteralPath $enrollmentRoot -AclObject $acl
|
|
|
|
$repairScript = Join-Path $enrollmentRoot 'Repair-SguClientEnrollment.ps1'
|
|
$powerShell = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"
|
|
$action = New-ScheduledTaskAction -Execute $powerShell `
|
|
-Argument "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$repairScript`""
|
|
$startupTrigger = New-ScheduledTaskTrigger -AtStartup
|
|
# Give domain networking and Group Policy time to initialize before the
|
|
# repair script resolves domain principals and validates remote access.
|
|
$startupTrigger.Delay = 'PT1M'
|
|
$triggers = @(
|
|
$startupTrigger,
|
|
(New-ScheduledTaskTrigger -Daily -At '3:00 AM')
|
|
)
|
|
$settings = New-ScheduledTaskSettingsSet `
|
|
-StartWhenAvailable `
|
|
-ExecutionTimeLimit (New-TimeSpan -Minutes 5) `
|
|
-RestartCount 3 `
|
|
-RestartInterval (New-TimeSpan -Minutes 1)
|
|
Register-ScheduledTask -TaskName $taskName `
|
|
-Action $action `
|
|
-Trigger $triggers `
|
|
-Settings $settings `
|
|
-User 'SYSTEM' `
|
|
-RunLevel Highest `
|
|
-Force | Out-Null
|
|
|
|
& $repairScript -ConfigurationPath $configurationPath | Out-Null
|
|
}
|
|
|
|
[pscustomobject]@{
|
|
EnrollmentRoot = $enrollmentRoot
|
|
TaskName = $taskName
|
|
TaskState = (Get-ScheduledTask -TaskName $taskName).State
|
|
ConfigurationPath = Join-Path $enrollmentRoot 'enrollment.json'
|
|
}
|