diff --git a/scripts/Common/Scripts/Config.ps1 b/scripts/Common/Scripts/Config.ps1 index a43c22b0..31e116ca 100644 --- a/scripts/Common/Scripts/Config.ps1 +++ b/scripts/Common/Scripts/Config.ps1 @@ -100,6 +100,30 @@ $null = New-Module { Invoke-ConfigScript "getConfig $Name --json $ArgumentList"; } + <# + .SYNOPSIS + Gets a user configuration. + + .PARAMETER UserName + The name of the user to get the configuration for. + + .PARAMETER Name + The name of the configuration to get. + #> + function Get-UserConfig { + param( + [string] $UserName = $env:UserName, + [Parameter(Mandatory, Position = 0)] + [string] $Name + ) + + if ((Get-Users) -contains $UserName) { + Get-Config "valhalla.windows.users.$UserName.$Name"; + } else { + return $null; + } + } + <# .SYNOPSIS Gets the attributes of a configuration object. diff --git a/scripts/Windows/OS/Install.ps1 b/scripts/Windows/OS/Install.ps1 index 315ca0dd..45a8eb5c 100644 --- a/scripts/Windows/OS/Install.ps1 +++ b/scripts/Windows/OS/Install.ps1 @@ -9,6 +9,7 @@ $null = New-Module { . "$PSScriptRoot/../Scripts/Hooks.ps1"; . "$PSScriptRoot/../Scripts/PowerManagement.ps1"; . "$PSScriptRoot/../Scripts/Update.ps1"; + . "$PSScriptRoot/../Scripts/Users.ps1"; . "$PSScriptRoot/../../Common/Scripts/Config.ps1"; . "$PSScriptRoot/../../Common/Scripts/Operations.ps1"; . "$PSScriptRoot/../../Common/Scripts/Software.ps1"; @@ -411,6 +412,7 @@ $null = New-Module { Set-Stage ([SetupStage]::CreateUser); } ([SetupStage]::CreateUser) { + Start-ValhallaUserSetup; Set-IsFinished $true; } } diff --git a/scripts/Windows/Scripts/Users.ps1 b/scripts/Windows/Scripts/Users.ps1 new file mode 100644 index 00000000..922c7e38 --- /dev/null +++ b/scripts/Windows/Scripts/Users.ps1 @@ -0,0 +1,107 @@ +using namespace System.Management.Automation.Host; + +$null = New-Module { + . "$PSScriptRoot/../../Common/Scripts/Config.ps1"; + [string] $userOption = "SetupUser"; + + <# + .SYNOPSIS + Creates the configured users. + #> + function Start-ValhallaUserSetup { + [int] $current = Get-SetupOption $userOption; + [string[]] $users = Get-Users; + + function Add-MicrosoftAccount { + param( + [string] $Name + ) + + $newUser = & { + while ($true) { + $currentUsers = Get-LocalUser | ForEach-Object { $_.Name }; + + Write-Host ( + @( + "So… Windows is too dumb to create users which are bound to a Microsoft Account.", + "Thus, you have to do it by yourself.", + "So sorry…") -join "`n"); + + Write-Host "Create a user for ``$Name`` manually (because Windows is too stupid)…"; + Read-Host "Hit enter once you're done"; + + $newUsers = @(Get-LocalUser | Where-Object { -not ($currentUsers -contains $_.Name) }); + + if ($newUsers.Count) { + if ($newUsers.Count -eq 1) { + $newUser = $newUsers[0]; + + Write-Host "Found new user ``$newUser``"; + + if ( + $Host.UI.PromptForChoice( + "Confirm", + "Is ``$newUser`` your user?", + [ChoiceDescription[]]@( + [ChoiceDescription]::new("&No", "``$newUser`` is not your user"), + [ChoiceDescription]::new("&Yes", "``$newUser`` is your user")), + 0) -eq 1) { + return $newUser; + } + } else { + $result = $Host.UI.PromptForChoice( + "Select your User", + "Which one is your user?", + [ChoiceDescription[]]( + & { + [ChoiceDescription]::new("&None", "None of these users is yours"); + + for ($i = 0; $i -lt $newUsers.Count; $i++) { + $name = "$($newUsers[$i])"; + + [ChoiceDescription]::new("&$($i + 1) - ``$name``", "Your user is ``$name``"); + } + }), 0); + + if ($result -gt 0) { + return $newUsers[$result - 1]; + } + } + + Write-Host "Unable to determine the new user"; + Write-Host "Retrying…"; + } + } + }; + + Write-Host "Renaming the new user to ``$Name``…"; + Rename-LocalUser $newUser $Name; + } + + for ($i = $current ?? 0; $i -lt $users.Count; $i++) { + Set-SetupOption $userOption $i; + $name = $users[$i]; + Write-Host "Creating personal user ``$name``…"; + + if (Get-UserConfig -UserName $name "microsoftAccount") { + Add-MicrosoftAccount $name; + } else { + $displayName = Get-UserConfig -UserName $name "displayName"; + + $userArguments = @{ + name = $name; + }; + + if ($displayName) { + $userArguments.fullName = $displayName; + } + + New-LocalUser -NoPassword @userArguments; + } + + foreach ($group in Get-UserConfig -UserName $name "groups") { + Add-LocalGroupMember -Group $group -Member $name; + } + } + } +};