Streamline the creation of users

This commit is contained in:
Manuel Thalmann 2024-08-21 18:34:18 +02:00
parent 1c458f8004
commit 596bca0b4e
3 changed files with 227 additions and 98 deletions

View file

@ -9,12 +9,20 @@ enum SetupStage {
Configure
Install
CreateUser
ConfigureUser
}
enum UserStage {
Create
Configure
Completed
}
$null = New-Module {
[string] $configRoot = "HKLM:\Software\PortValhalla";
[string] $stageOption = "Stage";
[string] $userOption = "SetupUser";
[string] $userStageOption = "UserStage";
[string] $accountOption = "MSAccount";
[string] $finishedOption = "Finished";
[RegistryKey] $key = $null;
@ -273,6 +281,85 @@ $null = New-Module {
$null = Set-SetupOption $stageOption $Name;
}
<#
.SYNOPSIS
Gets the current user to set up.
#>
function Get-CurrentUser {
return (Get-SetupOption $userOption) ?? 0;
}
<#
.SYNOPSIS
Sets the index of the current user to set up.
.PARAMETER Value
The index of the user to set up.
#>
function Set-CurrentUser {
param(
[int] $Value
)
Set-SetupOption $userOption $value;
}
<#
.SYNOPSIS
Gets the name of the current stage of the user setup.
#>
function Get-UserStage {
$stage = Get-SetupOption $userStageOption;
if ($null -ne $stage) {
$stage = [UserStage]$stage;
}
return $stage;
}
<#
.SYNOPSIS
Sets the current stage of the user setup.
.PARAMETER Name
The name of the stage to set.
#>
function Set-UserStage {
param(
$Name
)
if (-not (($null -eq $Name) -or ($Name -is [string]))) {
$Name = ([UserStage]$Name).ToString();
}
$null = Set-SetupOption $userStageOption $Name;
}
<#
.SYNOPSIS
Gets the name of the microsoft account to create.
#>
function Get-MSAccountName {
return Get-SetupOption $accountOption;
}
<#
.SYNOPSIS
Sets the name of the microsoft account to create.
.PARAMETER Name
The name of the microsoft account to create.
#>
function Set-MSAccountName {
param(
[string] $Name
)
Set-SetupOption $accountOption $Name;
}
<#
.SYNOPSIS
Gets a value indicating whether the setup has finished.

View file

@ -196,6 +196,9 @@ $null = New-Module {
Start-OneShot {
switch (Get-OneShotTask) {
([OneShotTask]::InitializeMSAccount) {
Initialize-UserCreation;
}
([OneShotTask]::DisableUAC) {
Disable-UAC;
Register-Setup;
@ -536,87 +539,70 @@ $null = New-Module {
Set-Stage ([SetupStage]::CreateUser);
}
([SetupStage]::CreateUser) {
Start-ValhallaUserSetup;
Set-Stage ([SetupStage]::ConfigureUser);
}
([SetupStage]::ConfigureUser) {
$userOption = "CurrentUser";
$users = @(Get-Users);
$i = Get-CurrentUser;
function Get-CurrentUser {
(Get-SetupOption $userOption) ?? 0;
}
function Set-CurrentUser {
param([int] $Value)
Set-SetupOption $userOption $Value;
}
[string[]] $users = Get-Users;
$currentUser = Get-CurrentUser;
for (; $i -lt $users.Count; $i++) {
$name = $users[$i];
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
Set-CurrentUser $i;
if (Test-Admin) {
Disable-BootMessage;
}
if ($currentUser -lt $users.Count) {
$user = Get-LocalUser $users[$currentUser];
$msAccount = Get-UserConfig -UserName "$user" -Name "microsoftAccount";
while ((Get-UserStage) -ne ([UserStage]::Completed)) {
switch (Get-UserStage) {
($null) {
Set-UserStage ([UserStage]::Create);
continue;
}
([UserStage]::Create) {
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
Add-LocalGroupMember `
@adminGroup `
$user `
-ErrorAction SilentlyContinue;
if ($env:UserName -ne "$user") {
Disable-LocalUser $env:UserName;
Enable-LocalUser $user;
if ($env:UserName -ne $name) {
New-ValhallaUser $name;
if ($msAccount) {
Enable-UAC;
Disable-Autologin;
Enable-OneShotListener;
Set-BootMessage -Caption "Please Log In" -Message "Please log in using your new Microsoft Account ``$user``.";
Register-Setup -DefaultUser;
logoff;
} else {
Set-AutologinUser "$user";
Restart-Intermediate;
}
Restart-Intermediate -DefaultUser;
return;
exit;
} else {
$configure = {
Deploy-SoftwareAction -Action ([InstallerAction]::ConfigureUser);
Remove-LocalGroupMember -Member "$user" @adminGroup -ErrorAction SilentlyContinue;
foreach ($group in Get-UserConfig -UserName "$user" "groups") {
Add-LocalGroupMember -Member "$user" -Name "$group";
}
}
if ($msAccount) {
if (-not (Test-Admin)) {
Invoke-OneShot DisableUAC;
Restart-Computer;
return;
} else {
& $configure;
}
Clear-SetupRegistration;
Disable-OneShotListener;
}
} else {
& $configure;
Set-UserStage ([UserStage]::Configure);
}
}
(([UserStage]::Configure)) {
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
Deploy-SoftwareAction -Action ([InstallerAction]::ConfigureUser);
Remove-LocalGroupMember -Member $name @adminGroup -ErrorAction SilentlyContinue;
foreach ($group in Get-UserConfig -UserName $name "groups") {
Add-LocalGroupMember -Member $name -Name "$group";
}
}
}
}
if (-not $msAccount) {
net user "$user" /logonpasswordchg:yes;
net user $name /logonpasswordchg:yes;
}
Set-CurrentUser ($currentUser + 1);
continue;
}
Set-IsFinished $true;

View file

@ -1,15 +1,23 @@
using namespace System.Management.Automation.Host;
using namespace System.Security.Principal;
$null = New-Module {
. "$PSScriptRoot/../../Common/Scripts/Config.ps1";
[string] $userOption = "SetupUser";
. "$PSScriptRoot/../../Common/Scripts/Operations.ps1";
. "$PSScriptRoot/../../Common/Types/OneShotTask.ps1";
$loggedInUserOption = "LoggedInUser";
<#
.SYNOPSIS
Creates the configured users.
Creates a new user for the PortValhalla setup.
.PARAMETER Name
The name of the user to create.
#>
function Start-ValhallaUserSetup {
[string[]] $users = Get-Users;
function New-ValhallaUser {
param(
[string] $Name
)
function Add-MicrosoftAccount {
param(
@ -26,7 +34,7 @@ $null = New-Module {
"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)";
Write-Host "Create a user for ``$Name`` manually (because Windows is too stupid)";
$null = Read-Host "Hit enter once you're done";
$newUsers = @(Get-LocalUser | Where-Object { -not ($currentUsers -contains $_.Name) });
@ -57,7 +65,6 @@ $null = New-Module {
for ($i = 0; $i -lt $newUsers.Count; $i++) {
$name = "$($newUsers[$i])";
[ChoiceDescription]::new("&$($i + 1) - ``$name``", "Your user is ``$name``");
}
}), 0);
@ -74,15 +81,45 @@ $null = New-Module {
}
};
Write-Host "Renaming the new user to ``$Name``";
Rename-LocalUser $newUser $Name;
Set-MSAccountName ([string]$newUser);
}
for ($i = 0; $i -lt $users.Count; $i++) {
Set-SetupOption $userOption $i;
$name = $users[$i];
Write-Host "Creating personal user ``$name``";
$displayName = Get-UserConfig -UserName $name "displayName";
$msAccount = Get-UserConfig -UserName $Name "microsoftAccount";
if ($msAccount) {
if (Test-Admin) {
Write-Host "Preparing environment for creating MS Account";
Enable-OneShotListener;
Enable-UAC;
Restart-Intermediate -CurrentUser;
exit;
}
}
Write-Host "Creating personal user ``$Name``";
if ($msAccount) {
Add-MicrosoftAccount $Name;
Set-SetupOption $loggedInUserOption $env:UserName;
Invoke-OneShot ([OneShotTask]::InitializeMSAccount);
} else {
New-LocalUser -NoPassword $Name;
Set-LocalUser $Name -PasswordNeverExpires $true;
Set-LocalUser $Name -PasswordNeverExpires $false;
Initialize-UserCreation;
}
}
<#
.SYNOPSIS
Prepares the first login for initializing the current user under configuration.
#>
function Initialize-UserCreation {
$name = (@(Get-Users))[(Get-CurrentUser)];
$msAccount = Get-UserConfig -UserName $name "microsoftAccount";
$displayName = Get-UserConfig -UserName $Name "displayName";
Write-Host "Initializing user ``$name``";
$userArguments = @{
name = $name;
@ -92,15 +129,34 @@ $null = New-Module {
$userArguments.fullName = $displayName;
}
if (Get-UserConfig -UserName $name "microsoftAccount") {
Add-MicrosoftAccount $name;
} else {
New-LocalUser -Disabled -NoPassword @userArguments;
Set-LocalUser $name -PasswordNeverExpires $true;
Set-LocalUser $name -PasswordNeverExpires $false;
$adminGroup = @{
SID = [SecurityIdentifier]::new([WellKnownSidType]::BuiltinAdministratorsSid, $null);
};
if ($msAccount) {
$accountName = Get-MSAccountName;
Write-Host "Renaming ``$accountName`` to ``$name``"
Rename-LocalUser $accountName $name;
}
Set-LocalUser @userArguments;
if ($msAccount) {
Disable-LocalUser (Get-SetupOption $loggedInUserOption);
} else {
Disable-LocalUser $env:UserName;
}
Add-LocalGroupMember `
@adminGroup `
$name `
-ErrorAction SilentlyContinue;
if ($msAccount) {
Disable-Autologin;
Set-BootMessage -Caption "Please Log In" -Message "Please log in using your new Microsoft Account ``$name``.";
} else {
Set-AutologinUser "$name";
}
}
};