Add Azure user roaming and reproducible Laboratorio wallpaper policy

This commit is contained in:
2026-09-17 16:40:44 -06:00
parent 7460f9316d
commit 7de6e2d867
18 changed files with 1258 additions and 6 deletions
+153
View File
@@ -0,0 +1,153 @@
$repositoryRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
$bicepPath = Join-Path $repositoryRoot 'infra\azure\main.bicep'
$deploymentPath = Join-Path $repositoryRoot 'scripts\Deploy-SguAzureInfrastructure.ps1'
$configurationPath = Join-Path $repositoryRoot 'scripts\Enable-SguAzureUserRoaming.ps1'
$installerPath = Join-Path $repositoryRoot 'scripts\Install-SguFsLogix.ps1'
$clientBootstrapPath = Join-Path $repositoryRoot 'scripts\Invoke-SguClientBootstrap.ps1'
$azureLauncherPath = Join-Path $repositoryRoot 'scripts\Start-SguAzureClientEnrollment.cmd'
$packagePath = Join-Path $repositoryRoot 'scripts\New-SguBootstrapPackages.ps1'
foreach ($scriptPath in @(
$deploymentPath,
$configurationPath,
$installerPath,
$clientBootstrapPath,
$packagePath)) {
$tokens = $null
$parseErrors = $null
[Management.Automation.Language.Parser]::ParseFile(
$scriptPath,
[ref]$tokens,
[ref]$parseErrors) | Out-Null
if ($parseErrors.Count -gt 0) {
throw "$scriptPath contains PowerShell parser errors: $($parseErrors -join '; ')"
}
}
$configurationTokens = $null
$configurationParseErrors = $null
$configurationAst = [Management.Automation.Language.Parser]::ParseFile(
$configurationPath,
[ref]$configurationTokens,
[ref]$configurationParseErrors)
$samFunction = $configurationAst.Find({
param($node)
$node -is [Management.Automation.Language.FunctionDefinitionAst] -and
$node.Name -eq 'Get-SguStorageSamAccountName'
}, $true)
Invoke-Expression $samFunction.Extent.Text
Describe 'SGU Azure user-roaming infrastructure' {
It 'deploys dedicated private Azure Files resources by default' {
$source = Get-Content -LiteralPath $bicepPath -Raw
$source | Should Match 'param deployUserRoaming bool = true'
$source | Should Match "purpose: 'SGU-user-roaming'"
$source | Should Match "publicNetworkAccess: 'Disabled'"
$source | Should Match "privateLinkServiceId: userRoamingStorageAccount.id"
$source | Should Match "'file'"
$source | Should Match "privatelink\.file\.\$\{storageEndpointSuffix\}"
$source | Should Match 'dhcpOptions:'
$source | Should Match 'dnsServers:'
$source | Should Match 'domainControllerPrivateIp'
$source | Should Match 'fsLogixProfilesShare'
$source | Should Match 'redirectedFoldersShare'
}
It 'does not repurpose the temporary bootstrap staging account' {
(Get-Content -LiteralPath $bicepPath -Raw) | Should Not Match 'sgustage|SGU-bootstrap-staging'
}
It 'requires a private P2S route when roaming is enabled' {
$source = Get-Content -LiteralPath $deploymentPath -Raw
$source | Should Match '\$DeployUserRoaming -and -not \$DeployVpnGateway'
$source | Should Match 'private Azure Files endpoint'
}
It 'returns every post-domain setup value from the Azure deployment' {
$source = Get-Content -LiteralPath $deploymentPath -Raw
foreach ($name in @(
'UserRoamingEnabled',
'UserRoamingStorageAccountName',
'FsLogixProfilesSharePath',
'RedirectedFoldersSharePath',
'UserRoamingSetupArguments')) {
$source | Should Match $name
}
}
}
Describe 'SGU role-specific roaming policies' {
It 'uses an AD computer identity with AES-256 Kerberos' {
$source = Get-Content -LiteralPath $configurationPath -Raw
$source | Should Match "DomainAccountType = 'ComputerAccount'"
$source | Should Match 'KerberosEncryptionType AES256'
$source | Should Match 'PasswordNeverExpires \$true'
$source | Should Match 'StorageFileDataSmbShareContributor'
}
It 'isolates per-user directories with CREATOR OWNER ACLs' {
$source = Get-Content -LiteralPath $configurationPath -Raw
$source | Should Match "SecurityIdentifier\]::new\('S-1-3-0'\)"
$source | Should Match 'PropagationFlags\]::InheritOnly'
$source | Should Match 'SetAccessRuleProtection\(\$true, \$false\)'
}
It 'redirects only the student Desktop and Documents folders' {
$source = Get-Content -LiteralPath $configurationPath -Raw
$source | Should Match "ValueName 'Desktop'"
$source | Should Match "ValueName 'Personal'"
$source | Should Match '%USERNAME%\\Desktop'
$source | Should Match '%USERNAME%\\Documents'
$source | Should Match "ValueName 'DisableFRAdminPin'"
}
It 'enables FSLogix only through the AD and DO group SIDs' {
$source = Get-Content -LiteralPath $configurationPath -Raw
$source | Should Match "\$fsLogixRoot = 'HKLM\\SOFTWARE\\FSLogix\\Profiles'"
$source | Should Match '\\ObjectSpecific\\\$\(\$staffGroup\.SID\.Value\)'
$source | Should Match '\$professorGroup, \$administrativeGroup'
$source | Should Match "ValueName 'Enabled' -Type DWord -Value 0"
$source | Should Match 'VHDLocations = @\{ Type = ''String''; Value = \$profilesSharePath \}'
}
It 'does not delete existing staff profiles unless explicitly requested' {
$source = Get-Content -LiteralPath $configurationPath -Raw
$source | Should Match '\[switch\]\$DeleteExistingStaffLocalProfiles'
$source | Should Match 'if \(\$DeleteExistingStaffLocalProfiles\) \{ 1 \} else \{ 0 \}'
}
It 'derives valid deterministic AD names for long storage account names' {
$name = Get-SguStorageSamAccountName -StorageName 'abcdefghijklmnopqrstuvwx'
$name.Length | Should Be 20
$name | Should Match '^sgufs[0-9a-f]{15}$'
(Get-SguStorageSamAccountName -StorageName 'abcdefghijklmnopqrstuvwx') | Should Be $name
(Get-SguStorageSamAccountName -StorageName 'sguroam1234567890123') |
Should Be 'sguroam1234567890123'
}
}
Describe 'SGU FSLogix image enrollment' {
It 'verifies the Microsoft signature and installs unattended' {
$source = Get-Content -LiteralPath $installerPath -Raw
$source | Should Match 'Get-AuthenticodeSignature'
$source | Should Match 'CN=Microsoft Corporation'
foreach ($argument in @('/install', '/quiet', '/norestart')) {
$source | Should Match ([regex]::Escape($argument))
}
$source | Should Match "Get-Service -Name frxsvc"
}
It 'exposes the optional installer through the unified Azure launcher' {
((Get-Command $clientBootstrapPath).Parameters.Keys -contains
'FsLogixInstallerPath') | Should Be $true
$launcher = Get-Content -LiteralPath $azureLauncherPath -Raw
$launcher | Should Match 'SGU_FSLOGIX_INSTALLER=%~5'
$launcher | Should Match '-FsLogixInstallerPath'
}
It 'packages both roaming setup scripts' {
$source = Get-Content -LiteralPath $packagePath -Raw
$source | Should Match "'Install-SguFsLogix\.ps1'"
$source | Should Match "'Enable-SguAzureUserRoaming\.ps1'"
}
}