Skip to content

Instantly share code, notes, and snippets.

@supermarsx
Created April 28, 2024 19:28
Show Gist options
  • Save supermarsx/7596cc6bb600db92b57c77f1e91287cc to your computer and use it in GitHub Desktop.
Save supermarsx/7596cc6bb600db92b57c77f1e91287cc to your computer and use it in GitHub Desktop.
Windows Sandbox startup script example, several different functions
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