Created
April 28, 2024 19:28
-
-
Save supermarsx/7596cc6bb600db92b57c77f1e91287cc to your computer and use it in GitHub Desktop.
Windows Sandbox startup script example, several different functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param ( | |
[Parameter()] | |
[int]$BackupTaskBar | |
) | |
Add-Type -AssemblyName System.Windows.Forms | |
Add-Type @" | |
using System; | |
using System.Runtime.InteropServices; | |
public class Win32 { | |
[DllImport("user32.dll", SetLastError = true)] | |
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); | |
[DllImport("user32.dll", SetLastError = true)] | |
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); | |
[DllImport("user32.dll")] | |
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); | |
[DllImport("user32.dll")] | |
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); | |
[DllImport("user32.dll", SetLastError = true)] | |
public static extern bool EnumWindows(IntPtr lpEnumFunc, IntPtr lParam); | |
} | |
"@ | |
# Full startup routine, equivalent to main | |
function Startup-Routine { | |
If ($BackupTaskBar -gt 0) { | |
$startupFunctions = @( | |
"Startup-Gui-Start", | |
"Backup-Taskbar-State", | |
"Startup-Gui-Close" | |
) | |
} | |
Else { | |
$startupFunctions = @( | |
"Startup-Gui-Start", | |
"Kill-Explorer", | |
"Mute-Sound", | |
"Copy-Anydesk", | |
"FirstRun-Anydesk", | |
"Set-Search-Icon", | |
"Remove-WindowsCopilot", | |
"Hide-Desktop-Icons", | |
"Remove-Start-Menu-Recommended", | |
"Set-DarkTheme", | |
"Set-Black-Wallpaper", | |
"Disable-Transparency", | |
"Update-Anydesk-User", | |
"Update-Anydesk-System", | |
"Launch-Explorer", | |
"Launch-Anydesk", | |
"Startup-Gui-Close" | |
) | |
} | |
$totalFunctions = $startupFunctions.Length | |
$percentStep = [math]::Round(100 / $totalFunctions); | |
for ($functionIndex = 0; $functionIndex -lt $totalFunctions; $functionIndex++) { | |
If ($functionIndex -gt 1 ) { | |
Startup-Gui-SetProgress -Percent ($percentStep * $functionIndex) -Label $startupFunctions[$functionIndex] | |
} | |
$currentFunction = $startupFunctions[$functionIndex] | |
Invoke-Expression $currentFunction | |
} | |
} | |
# Kill explorer | |
function Kill-Explorer { | |
Start-Process -FilePath "cmd.exe" -ArgumentList "/c taskkill /f /im explorer.exe" -NoNewWindow -Wait | |
} | |
# Remove Windows Copilot | |
function Remove-WindowsCopilot { | |
$registryPath = "HKCU:\Software\Policies\Microsoft\Windows\WindowsCopilot" | |
If (-Not (Test-Path $registryPath)){ | |
New-Item -Path $registryPath -Force | Out-Null | |
} | |
New-ItemProperty -Path $registryPath -Name "TurnOffWindowsCopilot" -Value 1 -PropertyType "DWORD" -Force | Out-Null | |
$registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" | |
If (Get-ItemProperty -Path $registryPath -Name "ShowCopilotButton" -ErrorAction SilentlyContinue) { | |
Set-ItemProperty -Path $registryPath -Name "ShowCopilotButton" -Value 0 | |
} Else { | |
New-ItemProperty -Path $registryPath -Name "ShowCopilotButton" -Value 0 -PropertyType "DWORD" -Force | Out-Null | |
} | |
} | |
# Set dark theme | |
function Set-DarkTheme { | |
$registryPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" | |
Set-ItemProperty -Path $registryPath -Name "SystemUsesLightTheme" -Value 0 | |
Set-ItemProperty -Path $registryPath -Name "AppsUseLightTheme" -Value 0 | |
} | |
# Set solid black color wallpaper | |
function Set-Black-Wallpaper { | |
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "WallPaper" -Value "" | |
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers" -Name "BackgroundType" -Type DWORD -Value 1 | |
Set-ItemProperty -Path "HKCU:\Control Panel\Colors" -Name "Background" -Value "0 0 0" | |
} | |
# Disable transparency | |
function Disable-Transparency { | |
$registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize" | |
Set-ItemProperty -Path $registryPath -Name "EnableTransparency" -Value 0 | |
} | |
# Hide desktop icons | |
function Hide-Desktop-Icons { | |
$registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" | |
if (Test-Path $registryPath) { | |
if (Get-ItemProperty -Path $registryPath -Name "HideIcons" -ErrorAction "SilentlyContinue") { | |
Set-ItemProperty -Path $registryPath -Name "HideIcons" -Value 1 | |
} else { | |
New-ItemProperty -Path $registryPath -Name "HideIcons" -Value 1 -PropertyType "DWORD" -Force | Out-Null | |
} | |
} | |
} | |
# Set taskbar search as icon | |
function Set-Search-Icon { | |
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search" -Name "Searchboxtaskbarmode" -Type "DWORD" -Value 1 | |
} | |
# Remove recommended from start menu | |
function Remove-Start-Menu-Recommended { | |
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\" -Name "Explorer" -Force | |
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer" -Name "HideRecommendedSection" -PropertyType "DWORD" -Value 1 -Force | |
} | |
# Mute sound | |
function Mute-Sound { | |
Stop-Service -Name "audiosrv" -Force -NoWait | |
} | |
# Mute sound alternate method | |
function Mute-Sound-Alternate-Method { | |
Start-Sleep -Seconds 3.5 | |
(New-Object -com wscript.shell).SendKeys([char]173) | |
} | |
# Backup taskbar state (non-functional) | |
function Backup-Taskbar-State { | |
$registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" | |
$exportPath = "C:\StartupContents\Layouts\TaskbarCurrentState.reg" | |
Start-Process -FilePath "reg.exe" -ArgumentList "export `"$registryPath`" `"$exportPath`" /y" -NoNewWindow -Wait | |
} | |
# Restore start menu state (non-functional) | |
function Restore-StartMenu-State { | |
$registryDeletePath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" | |
$registryImportPath = "C:\StartupContents\Layouts\TaskbarCurrentState.reg" | |
Start-Process -FilePath "reg.exe" -ArgumentList "delete `"$registryDeletePath`" /f" -NoNewWindow -Wait | |
Start-Process -FilePath "reg.exe" -ArgumentList "import `"$registryImportPath`"" -NoNewWindow -Wait | |
} | |
# Copy Anydesk to Desktop | |
function Copy-Anydesk { | |
Copy-Item -Path "C:\StartupContents\AnyDesk.exe" -Destination "C:\Users\WDAGUtilityAccount\Desktop\" -Force | |
} | |
# Launch explorer | |
function Launch-Explorer { | |
Start-Process -FilePath "explorer.exe" | |
} | |
# Do a first run of AnyDesk | |
function FirstRun-Anydesk { | |
$anydeskInstance = Start-Process -FilePath "C:\Users\WDAGUtilityAccount\Desktop\AnyDesk.exe" -WindowStyle Minimized -PassThru | |
Hide-To-Tray -AppName "AnyDesk" | |
$userConfigurationPath = "C:\Users\WDAGUtilityAccount\AppData\Roaming\AnyDesk\user.conf" | |
while (-not (Test-Path -Path $userConfigurationPath)) { | |
#Start-Sleep -Milliseconds 50 | |
} | |
$anydeskInstance | Stop-Process -Force | |
} | |
# Hide application to tray | |
function Hide-To-Tray { | |
param( | |
[string]$AppName | |
) | |
$handles = Get-WindowHandleByProcessName -processName $AppName | |
foreach ($handle in $handles) { | |
[Win32]::ShowWindow($handle, 11) | |
} | |
} | |
# Get window handle by process name | |
function Get-WindowHandleByProcessName { | |
param ( | |
[string]$processName | |
) | |
$processes = Get-Process | Where-Object { $_.ProcessName -eq $processName } | Select-Object -ExpandProperty Id | |
$windowHandles = New-Object System.Collections.Generic.List[IntPtr] | |
Add-Type -AssemblyName System.Windows.Forms | |
[System.Windows.Forms.Application]::EnableVisualStyles() | |
foreach ($pid in $processes) { | |
[System.Windows.Forms.Application]::DoEvents() | |
$callback = { | |
param ( | |
[IntPtr]$hwnd, | |
[int]$lParam | |
) | |
$id = 0 | |
$thread = [Win32]::GetWindowThreadProcessId($hwnd, [ref]$id) | |
if ($id -eq $lParam) { | |
$windowHandles.Add($hwnd) | |
} | |
return $true | |
} | |
$gcHandle = [System.Runtime.InteropServices.GCHandle]::Alloc($callback) | |
$ptr = [System.Runtime.InteropServices.Marshal]::GetFunctionPointerForDelegate($callback) | |
[Win32]::EnumWindows($ptr, $pid) | |
$gcHandle.Free() | |
} | |
return $windowHandles | |
} | |
# Change Anydesk user configuration | |
function Update-Anydesk-User { | |
$userConfigurationPath = "C:\Users\WDAGUtilityAccount\AppData\Roaming\AnyDesk\user.conf" | |
Update-ConfigurationFile -FilePath $userConfigurationPath -KeyValuePairs @{ | |
"ad.print.mode" = "0" | |
"ad.privacy.bkgnd.show" = "3" | |
"ad.privacy.image.show" = "0" | |
"ad.privacy.name" = "User" | |
"ad.privacy.name.show" = "2" | |
"ad.privacy.screen_frame.color.watched" = "#00000080" | |
"ad.privacy.screen_frame.mode" = "0" | |
"ad.audio.playback_mode" = "1" | |
"ad.audio.transmit_mode" = "0" | |
"ad.ui.inst_info_count" = "2" | |
"ad.ui.lang" = "en" | |
"ad.ui.session_invitation_window" = "0" | |
"ad.roster.recent_out.view_type" = "2" | |
"ad.roster.recv_invitation.show_all" = "true" | |
"ad.roster.sent_invitation.show_all" = "true" | |
"ad.roster.sent_invitation.view_type" = "2" | |
} | |
} | |
# Change Anydesk system configuration | |
function Update-Anydesk-System { | |
$systemConfigurationPath = "C:\Users\WDAGUtilityAccount\AppData\Roaming\AnyDesk\system.conf" | |
Update-ConfigurationFile -FilePath $systemConfigurationPath -KeyValuePairs @{ | |
"ad.security.acl_enabled" = "true" | |
"ad.security.acl_list" = "X:true" | |
"ad.security.acl_trigger" = "true" | |
"ad.security.allow_logon_token" = "false" | |
"ad.security.block_input" = "false" | |
"ad.security.clipboard.files" = "true" | |
"ad.security.control_input" = "false" | |
"ad.security.file_manager" = "true" | |
"ad.security.frontend_clipboard" = "1" | |
"ad.security.frontend_clipboard_files" = "1" | |
"ad.security.frontend_clipboard_version" = "1" | |
"ad.security.hear_audio" = "true" | |
"ad.security.interactive_access" = "2" | |
"ad.security.lock_account" = "false" | |
"ad.anynet.direct" = "false" | |
"ad.discovery.hidden" = "true" | |
"ad.security.print" = "false" | |
"ad.security.privacy_feature" = "false" | |
"ad.security.record_session" = "false" | |
"ad.security.restart" = "false" | |
"ad.security.sync_clipbrd" = "true" | |
"ad.security.sysinfo" = "true" | |
"ad.security.tcp_tunnel" = "false" | |
"ad.security.update_version" = "1" | |
"ad.security.user_pointer" = "true" | |
"ad.security.vpn" = "true" | |
"ad.security.whiteboard" = "false" | |
"ad.wol.mode" = "0" | |
} | |
} | |
# Update a key-value type configuration file | |
function Update-ConfigurationFile { | |
param( | |
[string]$FilePath, | |
[hashtable]$KeyValuePairs | |
) | |
$lines = Get-Content $FilePath | |
Startup-Gui-SetProgress -Percent 0 -Label "Update-ConfigurationFile" | |
$totalKeys = [int]$KeyValuePairs.count | |
$percentStep = [math]::Round(100 / $totalKeys) | |
foreach ($key in $KeyValuePairs.Keys) { | |
$currentKey = [int][array]::IndexOf($KeyValuePairs.Keys, $key) | |
$currentPercent = [int]$(If ($currentKey * $percentStep -gt 100) { 100 } Else { ($currentKey * $percentStep) }) | |
Startup-Gui-SetProgress -Percent $currentPercent -Label "Update-ConfigurationFile::$key" | |
$found = $false | |
for ($i = 0; $i -lt $lines.Length; $i++) { | |
if ($lines[$i].StartsWith("$key=")) { | |
$lines[$i] = "$key=$($KeyValuePairs[$key])" | |
$found = $true | |
break | |
} | |
} | |
if (-not $found) { | |
$lines += "`n$key=$($KeyValuePairs[$key])`n" | |
} | |
} | |
$lines | Set-Content $FilePath -Force | |
} | |
# Disable keyboard and mouse (?) | |
function Disable-KeyboardAndMouse { | |
Get-PnpDevice | Where-Object { $_.Class -eq 'Keyboard' -or $_.Class -eq 'Mouse' } | ForEach-Object { | |
Disable-PnpDevice -InstanceId $_.InstanceId -Confirm:$false | |
} | |
} | |
# Enable keyboard and mouse (?) | |
function Enable-KeyboardAndMouse { | |
Get-PnpDevice | Where-Object { $_.Class -eq 'Keyboard' -or $_.Class -eq 'Mouse' } | ForEach-Object { | |
Enable-PnpDevice -InstanceId $_.InstanceId -Confirm:$false | |
} | |
} | |
# Launch Anydesk | |
function Launch-Anydesk { | |
Start-Process -FilePath "C:\Users\WDAGUtilityAccount\Desktop\AnyDesk.exe" -WindowStyle "Maximized" | |
} | |
# Startup GUI start, wrapper | |
function Startup-Gui-Start { | |
Startup-Gui-New-Form | |
Startup-Gui-New-ProgressBar | |
Startup-Gui-New-ProgressBarLabel | |
Startup-Gui-Show | |
} | |
# Create new startup GUI form | |
function Startup-Gui-New-Form { | |
$global:progressForm = New-Object System.Windows.Forms.Form | |
$global:progressForm.Width = 400 | |
$global:progressForm.Height = 150 | |
$global:progressForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle | |
$global:progressForm.Text = "Auto-Setup in progress" | |
} | |
# Create a new progress bar | |
function Startup-Gui-New-ProgressBar { | |
$global:progressBar = New-Object System.Windows.Forms.ProgressBar | |
$global:progressBar.Location = New-Object System.Drawing.Point(10, 50) | |
$global:progressBar.Size = New-Object System.Drawing.Size(350, 20) | |
$global:progressForm.Controls.Add($progressBar) | |
} | |
# Create a new progress bar label | |
function Startup-Gui-New-ProgressBarLabel { | |
$global:progressLabel = New-Object System.Windows.Forms.Label | |
$global:progressLabel.Location = New-Object System.Drawing.Point(10, 20) | |
$global:progressLabel.Size = New-Object System.Drawing.Size(350, 20) | |
$global:progressLabel.Text = "0% (Warming up...)" | |
$global:progressLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft | |
$global:progressForm.Controls.Add($global:progressLabel) | |
} | |
# Show new GUI | |
function Startup-Gui-Show { | |
$global:progressForm.Show() | |
} | |
# Set GUI progress | |
function Startup-Gui-SetProgress { | |
param ( | |
[Parameter()] | |
[int]$Percent, | |
[Parameter()] | |
[string]$Label | |
) | |
$global:progressBar.Value = $Percent | |
$global:progressLabel.Text = "$Percent% ($Label)" | |
$global:progressLabel.Refresh() | |
} | |
# Close GUI | |
function Startup-Gui-Close { | |
$global:progressForm.Close() | |
} | |
# Go | |
Startup-Routine |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment