PortValhalla/scripts/Windows/Scripts/Context.ps1

418 lines
14 KiB
PowerShell
Raw Normal View History

2023-07-12 20:37:31 +00:00
#!/bin/pwsh
2024-03-21 16:21:02 +00:00
. "$PSScriptRoot/Entrypoints.ps1";
2024-08-07 17:08:13 +00:00
. "$PSScriptRoot/../../Common/Software/PowerShell/profile.ps1";
class Context {
2023-06-21 20:04:18 +00:00
[string]$EntryPoint;
2023-06-16 18:24:37 +00:00
[string]$RootDir;
[string]$BackupName;
2024-03-23 14:38:06 +00:00
[string[]]$UserNames;
2023-06-22 21:04:13 +00:00
[string]$AdminName = "Admin";
[string]$ConfigRoot = "HKLM:\Software\PortValhalla";
[string]$RunOnceName = "PortValhalla";
[string]$StagePropertyName = "Stage";
Context() {
try {
$this.EntryPoint = Get-Entrypoint;
}
catch { }
}
[string] ProjectRoot() {
return Resolve-Path (Join-Path $PSScriptRoot ".." ".." "..");
}
[string] BackupRoot() {
2023-06-16 18:24:37 +00:00
if (-not $this.RootDir)
{
2023-07-29 19:19:57 +00:00
return Join-Path $this.ProjectRoot() "backup" $this.BackupName;
2023-06-16 18:24:37 +00:00
}
else
{
return $this.RootDir;
}
}
[void] RemoveDesktopIcon($pattern) {
Remove-Item "$env:PUBLIC/Desktop/$pattern";
Remove-Item "~/Desktop/$pattern";
}
2023-07-18 18:04:34 +00:00
[void] RemoveTaskbarItem($pattern) {
Import-Module -UseWindowsPowerShell PinnedItem;
Get-PinnedItem -Type TaskBar | Where-Object { $_.Name -like "$pattern" } | Remove-PinnedItem;
}
[void] AddPowerShellProfileStatement([string] $statement) {
$this.AddPowerShellProfileStatement($true, $statement);
}
[void] AddPowerShellProfileStatement([string] $category, [string] $statement) {
$this.AddPowerShellProfileStatement($true, $category, $statement);
}
[void] AddPowerShellProfileStatement([bool] $system, [string] $statement) {
$this.AddPowerShellProfileStatement($system, $null, $statement);
}
[void] AddPowerShellProfileStatement([bool] $system, [string] $category, [string] $statement) {
if ($category) {
$overwrite = $true;
} else {
$overwrite = $false;
}
$this.AddPowerShellProfileStatement($system, $category, $statement, $overwrite);
}
2023-07-27 00:28:37 +00:00
[void] AddPowerShellProfileStatement([bool] $system, [string] $category, [string] $statement, [bool] $overwrite) {
if ($system) {
Add-PowerShellProfileStatement -System -Category $category -Statement $statement -Overwrite $overwrite;
} else {
Add-PowerShellProfileStatement -Category $category -Statement $statement -Overwrite $overwrite;
}
}
[Microsoft.Win32.RegistryKey] EnsureConfigKey() {
if (-not (Test-Path $this.ConfigRoot)) {
2023-06-29 17:11:41 +00:00
$null = New-Item $this.ConfigRoot;
2023-06-29 18:02:12 +00:00
$acl = Get-Acl $this.ConfigRoot;
$acl.AddAccessRule(
[System.Security.AccessControl.RegistryAccessRule]::new(
2023-06-29 22:55:42 +00:00
[System.Security.Principal.SecurityIdentifier]::new([System.Security.Principal.WellKnownSidType]::BuiltinUsersSid, $null),
2023-06-29 18:02:12 +00:00
[System.Security.AccessControl.RegistryRights]::FullControl,
[System.Security.AccessControl.InheritanceFlags]::ObjectInherit -bor [System.Security.AccessControl.InheritanceFlags]::ContainerInherit,
[System.Security.AccessControl.PropagationFlags]::None,
[System.Security.AccessControl.AccessControlType]::Allow));
2023-06-29 23:57:45 +00:00
Set-Acl $this.ConfigRoot $acl;
}
return Get-Item $this.ConfigRoot;
}
[object] Get([string] $key) {
$configKey = $this.EnsureConfigKey();
if ($configKey.GetValueNames().Contains($key)) {
return $configKey.GetValue($key);
} else {
return $null;
}
}
[void] Set([string] $key, $value) {
$this.Set($key, $value, "ExpandString");
}
[void] Set([string] $key, $value, [Microsoft.Win32.RegistryValueKind] $type) {
$configKey = $this.EnsureConfigKey();
2023-06-30 00:40:15 +00:00
$null = Set-ItemProperty -Path $configKey.PSPath -Name $key -Value $value -Type $type;
}
[void] Remove([string] $key) {
$configKey = $this.EnsureConfigKey();
$null = Remove-ItemProperty -Path $configKey.PSPath -Name $key;
}
[void] SetStage([string] $name) {
2024-03-24 00:10:44 +00:00
$this.Set($this.StagePropertyName, $name);
}
[string] GetStage() {
return $this.Get($this.StagePropertyName);
}
[void] RemoveStage() {
$this.Remove($this.StagePropertyName);
}
[string] ArchivePath($name) {
return Join-Path $this.BackupRoot() "$name.7z";
}
[string] FileArchivePath($name) {
return $this.ArchivePath($(Join-Path "Files" $name));
}
[string] SoftwareArchive([string]$softwareName) {
return $this.ArchivePath($softwareName);
}
[void] Backup([string]$sourcePath, [string]$archivePath) {
$this.Backup($sourcePath, $archivePath, @());
}
[void] Backup([string]$sourcePath, [string]$archivePath, [string[]]$arguments) {
2023-08-01 10:48:27 +00:00
$this.Backup($sourcePath, $archivePath, $arguments, $true);
}
[void] Backup([string]$sourcePath, [string]$archivePath, [string[]]$arguments, [bool]$split) {
if (Test-Path $archivePath) {
Remove-Item -Recurse $archivePath;
}
2023-08-05 01:03:57 +00:00
if (Test-Path "$archivePath.*") {
Remove-Item -Recurse "$archivePath.*";
}
Start-Process -WorkingDirectory "$sourcePath" `
-FilePath "7z" `
-ArgumentList (
@(
"a",
"-xr!desktop.ini",
2023-06-09 16:21:26 +00:00
"-xr!thumbs.db",
"-xr!Thumbs.db",
2023-08-01 15:22:20 +00:00
"-slp",
2023-08-01 10:50:48 +00:00
$archivePath) + $arguments + $(
2023-08-01 10:48:27 +00:00
if ($split) {
2023-08-01 18:32:23 +00:00
@("-v2g");
2023-08-01 10:48:27 +00:00
} else {
@();
}
)) `
-Wait `
-NoNewWindow;
}
2023-06-16 18:24:22 +00:00
[void] Restore([string]$archivePath, [string]$destinationPath) {
$this.Restore($archivePath, $destinationPath, @());
}
[void] Restore([string]$archivePath, [string]$destinationPath, [string[]] $arguments) {
2023-08-01 10:48:27 +00:00
if (-not (Test-Path -PathType Leaf $archivePath)) {
$archivePath = "$archivePath.001";
}
2023-08-01 10:35:40 +00:00
if (-not (Test-Path -PathType Leaf $archivePath)) {
Write-Information (
[string]::Join(
"`n",
@(
"An archive at the specified path $archivePath does not exist.",
"No restoration will be performed.")));
}
else {
if (-not (Test-Path -PathType Container $destinationPath)) {
New-Item -ItemType Directory "$destinationPath";
}
Start-Process -WorkingDirectory "$destinationPath" `
2023-07-30 12:34:56 +00:00
-FilePath "7z" `
-ArgumentList @("x", "$archivePath") + $arguments `
-Wait `
-NoNewWindow;
2023-06-16 18:24:22 +00:00
}
}
[string] GetTempDirectory() {
$tempDir = Join-Path $([System.IO.Path]::GetTempPath()) $([System.IO.Path]::GetRandomFileName());
$null = New-Item -ItemType Directory $tempDir;
return $tempDir;
}
2023-06-22 20:58:54 +00:00
[void] ProcessDefaultUserKey([System.Action[Microsoft.Win32.RegistryKey]] $action) {
$rootPath = "HKLM:\DefaultUser";
$regRootPath = $rootPath.Replace(":", "");
2023-06-25 15:57:23 +00:00
$hivePath = "$env:SystemDrive\Users\Default\NTUSER.dat"
$null = & reg load $regRootPath $hivePath;
$root = Get-Item $rootPath;
$action.Invoke($root);
$root.Handle.Close();
[System.GC]::Collect();
& reg unload $regRootPath;
}
2023-06-25 16:25:52 +00:00
[void] ProcessLogonKey([System.Action[Microsoft.Win32.RegistryKey]] $action) {
$key = Get-Item "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon";
$action.Invoke($key);
}
2023-07-03 11:44:51 +00:00
[Microsoft.Win32.RegistryKey] GetSystemPolicyKey() {
$keyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
return Get-Item "$keyPath";
}
[Microsoft.Win32.RegistryKey] GetRunOnceKey() {
return $this.GetRunOnceKey($null);
}
[Microsoft.Win32.RegistryKey] GetRunOnceKey([Microsoft.Win32.RegistryKey] $userKey) {
if (-not $userKey) {
$userKey = Get-Item "HKCU:\";
}
2023-06-25 14:33:04 +00:00
Push-Location $userKey.PSPath;
2023-06-25 16:05:55 +00:00
$runOncePath = "Software\Microsoft\Windows\CurrentVersion\RunOnce";
if (-not (Test-Path $runOncePath)) {
New-Item $runOncePath;
}
$result = Get-Item $runOncePath;
2023-06-25 14:28:12 +00:00
Pop-Location;
2023-06-25 14:54:10 +00:00
return $result;
}
2023-07-03 11:44:51 +00:00
[bool] GetUACState() {
return [bool](Get-ItemPropertyValue -Path ($this.GetSystemPolicyKey().PSPath) -Name "EnableLUA");
}
[void] SetUACState([bool] $value) {
2023-07-10 19:22:31 +00:00
$null = Set-ItemProperty -Path ($this.GetSystemPolicyKey().PSPath) -Name "EnableLUA" -Value ([int]$value);
2023-07-03 11:44:51 +00:00
}
[void] RegisterReboot() {
$this.RegisterReboot($null);
}
[void] RegisterReboot([Microsoft.Win32.RegistryKey] $userKey) {
$runOnceKey = $this.GetRunOnceKey($userKey);
2023-06-28 11:43:20 +00:00
Set-ItemProperty -Path $runOnceKey.PSPath -Name $this.RunOnceName -Value "pwsh `"$($this.EntryPoint)`"" -Type "ExpandString";
$runOnceKey.Handle.Close();
}
[void] RegisterNewUserReboot() {
$this.ProcessDefaultUserKey({ param ($root) $this.RegisterReboot($root); });
}
[void] DeregisterNewUserReboot() {
2023-06-25 16:10:23 +00:00
$this.ProcessDefaultUserKey({ param ($root) Remove-Item -Path $this.GetRunOnceKey($root).PSPath });
}
2023-06-25 16:25:52 +00:00
[void] SetAutologin($user, $pw) {
$this.ProcessLogonKey(
{
param ($logon)
$path = $logon.PSPath;
Set-ItemProperty $path -Name "AutoAdminLogon" 1;
Set-ItemProperty $path -Name "DefaultUserName" $user;
2023-06-30 02:47:31 +00:00
if ($pw) {
Set-ItemProperty $path -Name "DefaultPassword" $pw;
2023-06-25 16:25:52 +00:00
} else {
Remove-ItemProperty $path -Name "DefaultPassword";
}
});
}
[void] RemoveAutologin() {
$this.ProcessLogonKey(
{
param ($logon)
$path = $logon.PSPath;
2023-06-25 16:48:13 +00:00
Set-ItemProperty $path -Name "AutoAdminLogon" 0;
2023-07-02 23:14:34 +00:00
Remove-ItemProperty $path -Name "DefaultDomainName" -ErrorAction SilentlyContinue;
Remove-ItemProperty $path -Name "DefaultUserName" -ErrorAction SilentlyContinue;
Remove-ItemProperty $path -Name "DefaultPassword" -ErrorAction SilentlyContinue;
2023-06-25 16:25:52 +00:00
});
}
2023-06-30 11:17:00 +00:00
[string] GetNextcloudConfigFile() {
return "$env:APPDATA/Nextcloud/nextcloud.cfg";
}
2023-07-02 13:44:47 +00:00
[void] AddNextcloudSync([string] $localPath, [string] $targetPath) {
$this.AddNextcloudSync($localPath, $targetPath, $false);
}
[void] AddNextcloudSync([string] $localPath, [string] $targetPath, [bool] $virtualFiles) {
2023-07-25 08:51:16 +00:00
Write-Host "Adding a Nextcloud sync";
Write-Information "$targetPath <=> $localPath";
2023-07-02 15:38:44 +00:00
$pattern = "^\d+\\Folders(?:WithPlaceholders)?\\(\d+)";
2023-07-02 13:44:47 +00:00
$folderID = (
Get-Content $($this.GetNextcloudConfigFile()) | `
Where-Object { $_ -match "$pattern" } | `
ForEach-Object { $_ -replace "$pattern.*$","`$1" } | `
Sort-Object -Unique | `
Measure-Object -Maximum).Maximum + 1;
2023-07-02 18:45:25 +00:00
$configName = "Folders";
2023-07-02 19:49:00 +00:00
$localPath = $localPath.Replace("\", "/");
$targetPath = $targetPath.Replace("\", "/");
2023-07-02 13:44:47 +00:00
2023-07-02 18:45:25 +00:00
if ($virtualFiles) {
$configName += "WithPlaceholders";
}
2023-07-25 08:51:16 +00:00
Write-Information "Stopping Nextcloud process";
$nextcloudProcess = Get-Process nextcloud;
$nextcloudPath = [string]$nextcloudProcess[0].Path;
$nextcloudProcess | Stop-Process -Force;
$accountSectionEntered = $false;
$accountSectionLeft = $false;
$newSettings = [string]::Join(
"`n",
@(
"0\$configName\$folderID\localPath=$localPath",
"0\$configName\$folderID\targetPath=$targetPath"));
$oldContent = Get-Content ($this.GetNextcloudConfigFile());
$(
2023-07-25 10:16:26 +00:00
for ($i = 0; $i -lt $oldContent.Count; $i++) {
2023-07-25 10:40:35 +00:00
$line = $oldContent[$i];
if ($line -eq "[Accounts]") {
$accountSectionEntered = $true;
}
if ($line -eq "" -and $accountSectionEntered) {
$accountSectionLeft = $true;
$newSettings;
}
2023-07-25 10:40:35 +00:00
$line;
if (
(-not $accountSectionLeft) -and
($i -eq ($oldContent.Count - 1)))
{
$newSettings;
}
}) | Set-Content ($this.GetNextcloudConfigFile());
2023-07-02 15:38:44 +00:00
2023-07-25 08:51:16 +00:00
Write-Information "New nextcloud config:";
Write-Information (Get-Content $($this.GetNextcloudConfigFile()) | Out-String);
2023-07-25 08:51:16 +00:00
Write-Information "Restarting Nextcloud";
2023-07-02 15:38:44 +00:00
Start-Process $nextcloudPath;
2023-07-02 13:44:47 +00:00
}
2023-06-22 20:58:54 +00:00
[void] Reboot() {
Write-Host "Restarting Computer...";
$this.RegisterReboot();
2023-07-16 09:30:20 +00:00
Restart-Computer -Force;
exit;
}
2023-07-29 00:58:00 +00:00
[void] PreventSleepMode() {
$performanceScheme = "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c";
2023-07-29 09:04:55 +00:00
$currentScheme = [regex]::Match((powercfg /GETACTIVESCHEME), "Power Scheme GUID: ([0-9a-f-]+) ").Groups[1].Value;
2023-07-29 00:58:00 +00:00
if ($currentScheme -ne $performanceScheme) {
2023-07-29 01:01:53 +00:00
Write-Information "Disabling Power Save mode";
2024-03-24 00:10:44 +00:00
$this.Set("Power Scheme", $currentScheme);
2023-07-29 00:58:00 +00:00
powercfg /S 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;
}
}
2023-07-03 11:24:36 +00:00
[void] Cleanup() {
$this.DeregisterNewUserReboot();
$this.RemoveAutologin();
2023-07-03 12:35:16 +00:00
$this.SetUACState($true);
2023-07-29 00:58:00 +00:00
$originalScheme = $this.Get("Power Scheme");
2023-07-29 01:25:47 +00:00
Remove-Item $($this.EnsureConfigKey().PSPath);
2023-07-29 00:58:00 +00:00
if ($originalScheme) {
2023-07-29 01:01:53 +00:00
Write-Information "Reset power plan to original state";
2023-07-29 00:58:00 +00:00
powercfg /S $originalScheme;
}
2023-07-03 11:24:36 +00:00
}
}