Add Azure user roaming and reproducible Laboratorio wallpaper policy
This commit is contained in:
@@ -0,0 +1,430 @@
|
||||
#Requires -Version 5.1
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory)][guid]$SubscriptionId,
|
||||
[Parameter(Mandatory)][string]$ResourceGroupName,
|
||||
[Parameter(Mandatory)]
|
||||
[ValidatePattern('^[a-z0-9]{3,24}$')]
|
||||
[string]$StorageAccountName,
|
||||
[ValidatePattern('^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])$')]
|
||||
[string]$FsLogixProfilesShareName = 'profiles',
|
||||
[ValidatePattern('^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])$')]
|
||||
[string]$RedirectedFoldersShareName = 'redirected',
|
||||
[string]$DomainController = $env:COMPUTERNAME,
|
||||
[string]$AzureFilesOuName = 'AzureFilesConfig',
|
||||
[string]$StudentOuName = 'Alumnos',
|
||||
[string]$ProfessorOuName = 'Docentes',
|
||||
[string]$AdministrativeOuName = 'Administrativos',
|
||||
[string]$LaboratoryOuName = 'Laboratorio',
|
||||
[string]$StudentGroupName = 'SGU-Alumnos',
|
||||
[string]$ProfessorGroupName = 'SGU-Docentes',
|
||||
[string]$AdministrativeGroupName = 'SGU-Administrativos',
|
||||
[string]$StudentGpoName = 'SGU - AL redirected folders',
|
||||
[string]$StaffGpoName = 'SGU - AD-DO FSLogix profiles',
|
||||
[ValidateRange(1024, 1048576)]
|
||||
[int]$FsLogixProfileSizeMiB = 30000,
|
||||
[string]$AzFilesHybridModulePath,
|
||||
[switch]$UseDeviceAuthentication,
|
||||
[switch]$DeleteExistingStaffLocalProfiles
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Assert-Administrator {
|
||||
$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 5.1 session on the SGU domain controller.'
|
||||
}
|
||||
}
|
||||
|
||||
function Import-SguAzFilesHybrid {
|
||||
param([string]$ModulePath)
|
||||
|
||||
if ($ModulePath) {
|
||||
if (-not (Test-Path -LiteralPath $ModulePath)) {
|
||||
throw "AzFilesHybridModulePath does not exist: $ModulePath"
|
||||
}
|
||||
$resolvedModule = if (Test-Path -LiteralPath $ModulePath -PathType Container) {
|
||||
Get-ChildItem -LiteralPath $ModulePath -Recurse -File |
|
||||
Where-Object Name -in @('AzFilesHybrid.psd1', 'AzFilesHybrid.psm1') |
|
||||
Sort-Object @{ Expression = { $_.Extension -eq '.psd1' }; Descending = $true }, FullName |
|
||||
Select-Object -First 1
|
||||
}
|
||||
else {
|
||||
Get-Item -LiteralPath $ModulePath
|
||||
}
|
||||
if (-not $resolvedModule) {
|
||||
throw "AzFilesHybrid.psd1 or AzFilesHybrid.psm1 was not found beneath $ModulePath."
|
||||
}
|
||||
Import-Module -Name $resolvedModule.FullName -Force -ErrorAction Stop
|
||||
}
|
||||
else {
|
||||
Import-Module -Name AzFilesHybrid -Force -ErrorAction Stop
|
||||
}
|
||||
|
||||
$joinCommand = Get-Command Join-AzStorageAccount -ErrorAction SilentlyContinue
|
||||
if (-not $joinCommand) {
|
||||
$joinCommand = Get-Command Join-AzStorageAccountForAuth -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (-not $joinCommand) {
|
||||
throw 'AzFilesHybrid did not expose Join-AzStorageAccount. Install the current Microsoft AzFilesHybrid module and retry.'
|
||||
}
|
||||
return $joinCommand
|
||||
}
|
||||
|
||||
function Get-SguStorageSamAccountName {
|
||||
param([Parameter(Mandatory)][string]$StorageName)
|
||||
|
||||
if ($StorageName.Length -le 20) {
|
||||
return $StorageName
|
||||
}
|
||||
$sha256 = [Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
$hash = $sha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($StorageName))
|
||||
$suffix = ([BitConverter]::ToString($hash) -replace '-', '').Substring(0, 15).ToLowerInvariant()
|
||||
return "sgufs$suffix"
|
||||
}
|
||||
finally {
|
||||
$sha256.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
function Ensure-SguOrganizationalUnit {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Name,
|
||||
[Parameter(Mandatory)][string]$Path,
|
||||
[Parameter(Mandatory)][string]$Server
|
||||
)
|
||||
|
||||
$escapedName = $Name.Replace('\', '\5c').Replace('*', '\2a').Replace('(', '\28').Replace(')', '\29')
|
||||
$ou = Get-ADOrganizationalUnit -LDAPFilter "(ou=$escapedName)" -SearchBase $Path `
|
||||
-SearchScope OneLevel -Server $Server -ErrorAction Stop | Select-Object -First 1
|
||||
if (-not $ou -and $PSCmdlet.ShouldProcess("OU=$Name,$Path", 'Create Azure Files identity OU')) {
|
||||
New-ADOrganizationalUnit -Name $Name -Path $Path -ProtectedFromAccidentalDeletion $true `
|
||||
-Server $Server | Out-Null
|
||||
$ou = Get-ADOrganizationalUnit -Identity "OU=$Name,$Path" -Server $Server
|
||||
}
|
||||
if (-not $ou) {
|
||||
throw "The organizational unit OU=$Name,$Path does not exist."
|
||||
}
|
||||
return $ou
|
||||
}
|
||||
|
||||
function Ensure-SguGpoLink {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Name,
|
||||
[Parameter(Mandatory)][string]$TargetOuDn,
|
||||
[Parameter(Mandatory)][string]$DomainName,
|
||||
[Parameter(Mandatory)][string]$Server
|
||||
)
|
||||
|
||||
$gpo = Get-GPO -Name $Name -Domain $DomainName -Server $Server -ErrorAction SilentlyContinue
|
||||
if (-not $gpo -and $PSCmdlet.ShouldProcess($Name, 'Create user-roaming GPO')) {
|
||||
$gpo = New-GPO -Name $Name -Domain $DomainName -Server $Server
|
||||
}
|
||||
if (-not $gpo) {
|
||||
throw "The GPO '$Name' does not exist and was not created."
|
||||
}
|
||||
|
||||
$link = @(Get-GPInheritance -Target $TargetOuDn -Domain $DomainName -Server $Server).GpoLinks |
|
||||
Where-Object DisplayName -eq $Name | Select-Object -First 1
|
||||
$linkEnabled = $link -and ($link.Enabled -eq $true -or [string]$link.Enabled -eq 'Yes')
|
||||
if (-not $link -and $PSCmdlet.ShouldProcess($TargetOuDn, "Link and enable '$Name'")) {
|
||||
New-GPLink -Name $Name -Target $TargetOuDn -Domain $DomainName -Server $Server `
|
||||
-LinkEnabled Yes | Out-Null
|
||||
}
|
||||
elseif ($link -and -not $linkEnabled -and
|
||||
$PSCmdlet.ShouldProcess($TargetOuDn, "Enable the '$Name' link")) {
|
||||
Set-GPLink -Name $Name -Target $TargetOuDn -Domain $DomainName -Server $Server `
|
||||
-LinkEnabled Yes | Out-Null
|
||||
}
|
||||
return $gpo
|
||||
}
|
||||
|
||||
function Set-SguGpoRegistryValue {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$GpoName,
|
||||
[Parameter(Mandatory)][string]$DomainName,
|
||||
[Parameter(Mandatory)][string]$Server,
|
||||
[Parameter(Mandatory)][string]$Key,
|
||||
[Parameter(Mandatory)][string]$ValueName,
|
||||
[Parameter(Mandatory)][ValidateSet('DWord', 'String', 'ExpandString')][string]$Type,
|
||||
[Parameter(Mandatory)]$Value
|
||||
)
|
||||
|
||||
if ($PSCmdlet.ShouldProcess("$GpoName :: $Key\\$ValueName", "Set $Type policy value")) {
|
||||
Set-GPRegistryValue -Name $GpoName -Domain $DomainName -Server $Server `
|
||||
-Key $Key -ValueName $ValueName -Type $Type -Value $Value | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
function Get-SguUnusedDriveName {
|
||||
$used = @(Get-PSDrive -PSProvider FileSystem | Select-Object -ExpandProperty Name)
|
||||
foreach ($name in @('Z', 'Y', 'X', 'W', 'V')) {
|
||||
if ($used -notcontains $name) {
|
||||
return $name
|
||||
}
|
||||
}
|
||||
throw 'No temporary drive letter is available for configuring Azure Files ACLs.'
|
||||
}
|
||||
|
||||
function Set-SguAzureFileRootAcl {
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$UncPath,
|
||||
[Parameter(Mandatory)][PSCredential]$Credential,
|
||||
[Parameter(Mandatory)][Security.Principal.SecurityIdentifier]$DomainAdminsSid,
|
||||
[Parameter(Mandatory)][Security.Principal.SecurityIdentifier[]]$ContributorSids,
|
||||
[Security.AccessControl.FileSystemRights]$ContributorRights =
|
||||
[Security.AccessControl.FileSystemRights]::Modify
|
||||
)
|
||||
|
||||
$driveName = Get-SguUnusedDriveName
|
||||
try {
|
||||
New-PSDrive -Name $driveName -PSProvider FileSystem -Root $UncPath `
|
||||
-Credential $Credential -Scope Script -ErrorAction Stop | Out-Null
|
||||
$rootPath = "${driveName}:\"
|
||||
$acl = [Security.AccessControl.DirectorySecurity]::new()
|
||||
$acl.SetAccessRuleProtection($true, $false)
|
||||
$acl.SetOwner($DomainAdminsSid)
|
||||
$allow = [Security.AccessControl.AccessControlType]::Allow
|
||||
$containerAndObject = [Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit'
|
||||
$noneInheritance = [Security.AccessControl.InheritanceFlags]::None
|
||||
$nonePropagation = [Security.AccessControl.PropagationFlags]::None
|
||||
$inheritOnly = [Security.AccessControl.PropagationFlags]::InheritOnly
|
||||
$systemSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-18')
|
||||
$creatorOwnerSid = [Security.Principal.SecurityIdentifier]::new('S-1-3-0')
|
||||
foreach ($administratorSid in @($systemSid, $DomainAdminsSid)) {
|
||||
$acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new(
|
||||
$administratorSid,
|
||||
[Security.AccessControl.FileSystemRights]::FullControl,
|
||||
$containerAndObject,
|
||||
$nonePropagation,
|
||||
$allow))
|
||||
}
|
||||
$acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new(
|
||||
$creatorOwnerSid,
|
||||
[Security.AccessControl.FileSystemRights]::Modify,
|
||||
$containerAndObject,
|
||||
$inheritOnly,
|
||||
$allow))
|
||||
foreach ($contributorSid in $ContributorSids) {
|
||||
$acl.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new(
|
||||
$contributorSid,
|
||||
$ContributorRights,
|
||||
$noneInheritance,
|
||||
$nonePropagation,
|
||||
$allow))
|
||||
}
|
||||
Set-Acl -LiteralPath $rootPath -AclObject $acl -ErrorAction Stop
|
||||
}
|
||||
finally {
|
||||
Remove-PSDrive -Name $driveName -Scope Script -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
Assert-Administrator
|
||||
if ($FsLogixProfilesShareName.Contains('--') -or $RedirectedFoldersShareName.Contains('--')) {
|
||||
throw 'Azure Files share names cannot contain consecutive hyphens.'
|
||||
}
|
||||
if ($FsLogixProfilesShareName -eq $RedirectedFoldersShareName) {
|
||||
throw 'The profile-container and redirected-folder shares must have different names.'
|
||||
}
|
||||
|
||||
Import-Module ActiveDirectory -ErrorAction Stop
|
||||
Import-Module GroupPolicy -ErrorAction Stop
|
||||
foreach ($azureModule in @('Az.Accounts', 'Az.Storage')) {
|
||||
try {
|
||||
Import-Module $azureModule -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
throw "The current $azureModule module is required on the domain controller. Install Azure PowerShell and retry. $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
$joinStorageCommand = Import-SguAzFilesHybrid -ModulePath $AzFilesHybridModulePath
|
||||
|
||||
$domain = Get-ADDomain -Server $DomainController
|
||||
$baseDn = $domain.DistinguishedName
|
||||
$domainName = $domain.DNSRoot
|
||||
$usersOuDn = "OU=Usuarios-SGU,$baseDn"
|
||||
$studentOuDn = "OU=$StudentOuName,$usersOuDn"
|
||||
$professorOuDn = "OU=$ProfessorOuName,$usersOuDn"
|
||||
$administrativeOuDn = "OU=$AdministrativeOuName,$usersOuDn"
|
||||
$laboratoryOuDn = "OU=$LaboratoryOuName,$baseDn"
|
||||
foreach ($requiredOu in @($studentOuDn, $professorOuDn, $administrativeOuDn, $laboratoryOuDn)) {
|
||||
Get-ADOrganizationalUnit -Identity $requiredOu -Server $DomainController -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
$studentGroup = Get-ADGroup -Identity "CN=$StudentGroupName,$studentOuDn" -Server $DomainController
|
||||
$professorGroup = Get-ADGroup -Identity "CN=$ProfessorGroupName,$professorOuDn" -Server $DomainController
|
||||
$administrativeGroup = Get-ADGroup -Identity "CN=$AdministrativeGroupName,$administrativeOuDn" `
|
||||
-Server $DomainController
|
||||
$domainAdminsSid = [Security.Principal.SecurityIdentifier]::new("$($domain.DomainSID.Value)-512")
|
||||
$azureFilesOu = Ensure-SguOrganizationalUnit -Name $AzureFilesOuName -Path $baseDn -Server $DomainController
|
||||
|
||||
$azureContext = Get-AzContext -ErrorAction SilentlyContinue
|
||||
if (-not $azureContext -or $azureContext.Subscription.Id -ne $SubscriptionId.Guid) {
|
||||
$connectParameters = @{}
|
||||
if ($UseDeviceAuthentication) {
|
||||
$connectParameters.UseDeviceAuthentication = $true
|
||||
}
|
||||
Connect-AzAccount @connectParameters | Out-Null
|
||||
}
|
||||
Set-AzContext -SubscriptionId $SubscriptionId.Guid | Out-Null
|
||||
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName `
|
||||
-Name $StorageAccountName -ErrorAction Stop
|
||||
$fileEndpointHost = ([uri]$storageAccount.PrimaryEndpoints.File).Host
|
||||
if (-not $fileEndpointHost) {
|
||||
throw "Azure did not return a file endpoint for $StorageAccountName."
|
||||
}
|
||||
|
||||
$directoryService = [string]$storageAccount.AzureFilesIdentityBasedAuth.DirectoryServiceOptions
|
||||
if ($directoryService -and $directoryService -ne 'None' -and $directoryService -ne 'AD') {
|
||||
throw "Storage account $StorageAccountName already uses the incompatible Azure Files identity source '$directoryService'."
|
||||
}
|
||||
if ($directoryService -ne 'AD') {
|
||||
if ($PSCmdlet.ShouldProcess($StorageAccountName, "Join Azure Files to $domainName with AES-256 Kerberos")) {
|
||||
$requestedSamAccountName = Get-SguStorageSamAccountName -StorageName $StorageAccountName
|
||||
$joinParameters = @{
|
||||
ResourceGroupName = $ResourceGroupName
|
||||
StorageAccountName = $StorageAccountName
|
||||
SamAccountName = $requestedSamAccountName
|
||||
DomainAccountType = 'ComputerAccount'
|
||||
OrganizationalUnitDistinguishedName = $azureFilesOu.DistinguishedName
|
||||
}
|
||||
& $joinStorageCommand @joinParameters
|
||||
$storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName `
|
||||
-Name $StorageAccountName -ErrorAction Stop
|
||||
}
|
||||
}
|
||||
|
||||
$directoryService = [string]$storageAccount.AzureFilesIdentityBasedAuth.DirectoryServiceOptions
|
||||
if ($directoryService -ne 'AD') {
|
||||
throw "Azure Files identity authentication is '$directoryService', not AD. The domain join did not complete."
|
||||
}
|
||||
$activeDirectoryProperties = $storageAccount.AzureFilesIdentityBasedAuth.ActiveDirectoryProperties
|
||||
if ([string]$activeDirectoryProperties.DomainName -ne $domainName) {
|
||||
throw "Storage account $StorageAccountName is joined to $($activeDirectoryProperties.DomainName), not $domainName."
|
||||
}
|
||||
$storageSamAccountName = [string]$activeDirectoryProperties.SamAccountName
|
||||
if (-not $storageSamAccountName) {
|
||||
$storageSamAccountName = $StorageAccountName
|
||||
}
|
||||
$storageComputer = Get-ADComputer -Identity "${storageSamAccountName}$" `
|
||||
-Server $DomainController -ErrorAction Stop
|
||||
if ($PSCmdlet.ShouldProcess($storageComputer.DistinguishedName, 'Require AES-256 Kerberos and prevent an unattended storage identity password expiry')) {
|
||||
Set-ADComputer -Identity $storageComputer -Server $DomainController `
|
||||
-KerberosEncryptionType AES256 -PasswordNeverExpires $true
|
||||
}
|
||||
if ($PSCmdlet.ShouldProcess($StorageAccountName, 'Grant authenticated AD identities the Azure Files SMB contributor default share permission')) {
|
||||
$storageAccount = Set-AzStorageAccount -ResourceGroupName $ResourceGroupName `
|
||||
-Name $StorageAccountName `
|
||||
-DefaultSharePermission StorageFileDataSmbShareContributor
|
||||
}
|
||||
|
||||
$privateAddresses = @(Resolve-DnsName -Name $fileEndpointHost -Type A -ErrorAction Stop |
|
||||
Where-Object IPAddress | Select-Object -ExpandProperty IPAddress)
|
||||
if ($privateAddresses.Count -eq 0 -or @($privateAddresses | Where-Object {
|
||||
$_ -match '^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)'
|
||||
}).Count -eq 0) {
|
||||
throw "$fileEndpointHost did not resolve to a private endpoint. Verify the privatelink.file.core.windows.net VNet link and the DC Azure DNS forwarder."
|
||||
}
|
||||
if (-not (Test-NetConnection -ComputerName $fileEndpointHost -Port 445 -InformationLevel Quiet)) {
|
||||
throw "The domain controller cannot reach $fileEndpointHost on TCP 445 through the private endpoint."
|
||||
}
|
||||
|
||||
$storageKey = @(Get-AzStorageAccountKey -ResourceGroupName $ResourceGroupName `
|
||||
-Name $StorageAccountName -ErrorAction Stop | Where-Object KeyName -eq 'key1' |
|
||||
Select-Object -First 1).Value
|
||||
if (-not $storageKey) {
|
||||
throw "Azure did not return key1 for $StorageAccountName; it is required only to set the initial root ACLs."
|
||||
}
|
||||
$storageCredential = [PSCredential]::new(
|
||||
"Azure\$StorageAccountName",
|
||||
(ConvertTo-SecureString -String $storageKey -AsPlainText -Force))
|
||||
$profilesSharePath = "\\$fileEndpointHost\$FsLogixProfilesShareName"
|
||||
$redirectedFoldersSharePath = "\\$fileEndpointHost\$RedirectedFoldersShareName"
|
||||
try {
|
||||
if ($PSCmdlet.ShouldProcess($profilesSharePath, 'Apply isolated FSLogix root ACLs')) {
|
||||
Set-SguAzureFileRootAcl -UncPath $profilesSharePath -Credential $storageCredential `
|
||||
-DomainAdminsSid $domainAdminsSid `
|
||||
-ContributorSids @($professorGroup.SID, $administrativeGroup.SID)
|
||||
}
|
||||
if ($PSCmdlet.ShouldProcess($redirectedFoldersSharePath, 'Apply isolated student-folder root ACLs')) {
|
||||
$studentRootRights = [Security.AccessControl.FileSystemRights]::CreateDirectories -bor
|
||||
[Security.AccessControl.FileSystemRights]::ListDirectory -bor
|
||||
[Security.AccessControl.FileSystemRights]::ReadAttributes -bor
|
||||
[Security.AccessControl.FileSystemRights]::ReadExtendedAttributes -bor
|
||||
[Security.AccessControl.FileSystemRights]::ReadPermissions -bor
|
||||
[Security.AccessControl.FileSystemRights]::Traverse -bor
|
||||
[Security.AccessControl.FileSystemRights]::Synchronize
|
||||
Set-SguAzureFileRootAcl -UncPath $redirectedFoldersSharePath -Credential $storageCredential `
|
||||
-DomainAdminsSid $domainAdminsSid -ContributorSids @($studentGroup.SID) `
|
||||
-ContributorRights $studentRootRights
|
||||
}
|
||||
}
|
||||
finally {
|
||||
$storageKey = $null
|
||||
$storageCredential = $null
|
||||
}
|
||||
|
||||
$studentGpo = Ensure-SguGpoLink -Name $StudentGpoName -TargetOuDn $studentOuDn `
|
||||
-DomainName $domainName -Server $DomainController
|
||||
$userShellFoldersKey = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
|
||||
Set-SguGpoRegistryValue -GpoName $studentGpo.DisplayName -DomainName $domainName `
|
||||
-Server $DomainController -Key $userShellFoldersKey -ValueName 'Desktop' `
|
||||
-Type ExpandString -Value "$redirectedFoldersSharePath\%USERNAME%\Desktop"
|
||||
Set-SguGpoRegistryValue -GpoName $studentGpo.DisplayName -DomainName $domainName `
|
||||
-Server $DomainController -Key $userShellFoldersKey -ValueName 'Personal' `
|
||||
-Type ExpandString -Value "$redirectedFoldersSharePath\%USERNAME%\Documents"
|
||||
Set-SguGpoRegistryValue -GpoName $studentGpo.DisplayName -DomainName $domainName `
|
||||
-Server $DomainController -Key 'HKCU\Software\Policies\Microsoft\Windows\NetCache' `
|
||||
-ValueName 'DisableFRAdminPin' -Type DWord -Value 1
|
||||
|
||||
$staffGpo = Ensure-SguGpoLink -Name $StaffGpoName -TargetOuDn $laboratoryOuDn `
|
||||
-DomainName $domainName -Server $DomainController
|
||||
$fsLogixRoot = 'HKLM\SOFTWARE\FSLogix\Profiles'
|
||||
Set-SguGpoRegistryValue -GpoName $staffGpo.DisplayName -DomainName $domainName `
|
||||
-Server $DomainController -Key $fsLogixRoot -ValueName 'Enabled' -Type DWord -Value 0
|
||||
$fsLogixValues = [ordered]@{
|
||||
Enabled = @{ Type = 'DWord'; Value = 1 }
|
||||
DeleteLocalProfileWhenVHDShouldApply = @{
|
||||
Type = 'DWord'
|
||||
Value = if ($DeleteExistingStaffLocalProfiles) { 1 } else { 0 }
|
||||
}
|
||||
FlipFlopProfileDirectoryName = @{ Type = 'DWord'; Value = 1 }
|
||||
IsDynamic = @{ Type = 'DWord'; Value = 1 }
|
||||
LockedRetryCount = @{ Type = 'DWord'; Value = 3 }
|
||||
LockedRetryInterval = @{ Type = 'DWord'; Value = 15 }
|
||||
ProfileType = @{ Type = 'DWord'; Value = 0 }
|
||||
ReAttachIntervalSeconds = @{ Type = 'DWord'; Value = 15 }
|
||||
ReAttachRetryCount = @{ Type = 'DWord'; Value = 3 }
|
||||
SizeInMBs = @{ Type = 'DWord'; Value = $FsLogixProfileSizeMiB }
|
||||
VHDLocations = @{ Type = 'String'; Value = $profilesSharePath }
|
||||
VolumeType = @{ Type = 'String'; Value = 'VHDX' }
|
||||
}
|
||||
foreach ($staffGroup in @($professorGroup, $administrativeGroup)) {
|
||||
$objectSpecificKey = "$fsLogixRoot\ObjectSpecific\$($staffGroup.SID.Value)"
|
||||
foreach ($setting in $fsLogixValues.GetEnumerator()) {
|
||||
Set-SguGpoRegistryValue -GpoName $staffGpo.DisplayName -DomainName $domainName `
|
||||
-Server $DomainController -Key $objectSpecificKey -ValueName $setting.Key `
|
||||
-Type $setting.Value.Type -Value $setting.Value.Value
|
||||
}
|
||||
}
|
||||
|
||||
[pscustomobject]@{
|
||||
StorageAccountName = $StorageAccountName
|
||||
FileEndpoint = $fileEndpointHost
|
||||
PrivateEndpointAddresses = $privateAddresses
|
||||
DirectoryService = $directoryService
|
||||
KerberosEncryption = 'AES256'
|
||||
StorageIdentity = $storageComputer.DistinguishedName
|
||||
StorageIdentityPasswordNeverExpires = $true
|
||||
ProfilesSharePath = $profilesSharePath
|
||||
RedirectedFoldersSharePath = $redirectedFoldersSharePath
|
||||
StudentPolicy = $studentGpo.DisplayName
|
||||
StaffPolicy = $staffGpo.DisplayName
|
||||
StudentBehavior = 'Local non-authoritative profile; Documents and Desktop redirected without Offline Files pinning.'
|
||||
StaffBehavior = 'FSLogix VHDX profile container for SGU-Docentes and SGU-Administrativos only.'
|
||||
ExistingStaffLocalProfilesDeleted = [bool]$DeleteExistingStaffLocalProfiles
|
||||
}
|
||||
Reference in New Issue
Block a user