Windows Desktop Control
Control the Windows desktop via PowerShell. All file and directory operations are STRICTLY READ-ONLY.
Safety Rules — ABSOLUTE CONSTRAINTS
READ-ONLY File Policy
You MUST NOT modify, create, move, rename, or delete any file or directory on the user's system.
The ONLY exception is screenshot capture, which creates a new image file.
PROHIBITED Commands — NEVER Execute These
| Category |
Prohibited Commands |
Reason |
| File Write/Delete |
Remove-Item, Delete, Move-Item, Rename-Item, Set-Content, Add-Content, Out-File, New-Item, Copy-Item (to new location), rm, del, ren, move, rd, rmdir, mkdir (use New-Item only for screenshots) |
Files are READ-ONLY |
| Process Kill |
Stop-Process, Kill, taskkill, End-Process |
No process killing |
| Shutdown/Restart |
Restart-Computer, Stop-Computer, shutdown, shutdown.exe |
No shutdown/restart |
| Registry Write |
Set-ItemProperty on HKLM/HKCU, New-ItemProperty, Remove-ItemProperty, New-Item on Registry |
No registry writes |
| Service Control |
Start-Service, Stop-Service, Set-Service, Restart-Service |
No service control |
| Network Changes |
Set-NetAdapter, Disable-NetAdapter, Enable-NetAdapter, Set-DnsClientServerAddress, netsh (write ops) |
No network changes |
| User/Security |
Set-LocalUser, New-LocalUser, Remove-LocalUser, Add-LocalGroupMember, Remove-LocalGroupMember, icacls (write), takeown |
No user/security changes |
| Execution Policy |
Set-ExecutionPolicy |
No policy changes |
| Firewall |
Set-NetFirewallRule, New-NetFirewallRule, Remove-NetFirewallRule |
No firewall changes |
| Scheduled Tasks |
Register-ScheduledTask, Unregister-ScheduledTask, Set-ScheduledTask |
No task scheduling |
Additional Safety Rules
- Never pipe output to files — No
> file, >> file, | Out-File, | Set-Content
- Never use
Invoke-Expression on untrusted input
- Never download or execute remote scripts — No
Invoke-WebRequest to download executables
- Never modify environment variables — No
[Environment]::SetEnvironmentVariable, no $env:VAR = ... persistently
- Always prefer
-WhatIf when unsure about a command's side effects
- Screenshot exception: You MAY use
[System.Drawing.Bitmap]::new() or similar to save a screenshot file. State the save path to the user first.
Operation Categories
| # |
Category |
Read-Only? |
Key Operations |
| 1 |
Window Management |
No |
List, minimize, maximize, restore, move, resize, snap, close |
| 2 |
Application Management |
Mixed |
List processes (read), launch/switch apps (allowed) |
| 3 |
Clipboard |
No |
Read clipboard, copy text to clipboard |
| 4 |
Display Info |
READ-ONLY |
Resolution, monitors, brightness, DPI |
| 5 |
Audio/Volume |
No |
Get/set volume, mute/unmute, list devices |
| 6 |
System Info |
READ-ONLY |
CPU, RAM, disk, battery, OS, uptime |
| 7 |
Network Info |
READ-ONLY |
WiFi, IP, adapters, DNS, gateway |
| 8 |
File/Directory |
STRICTLY READ-ONLY |
List, search, read, properties, size |
| 9 |
Virtual Desktops |
No |
List, create, switch |
| 10 |
Screenshot |
No |
Full screen, active window, region (creates file) |
| 11 |
Power Management |
No |
Lock screen, sleep (NOT shutdown/restart) |
| 12 |
Notifications |
No |
Send toast notification |
| 13 |
Services |
READ-ONLY |
List services, get status |
| 14 |
Installed Software |
READ-ONLY |
List installed programs |
| 15 |
Environment Variables |
READ-ONLY |
List all, get specific |
| 16 |
Keyboard/Mouse |
No |
Send keystrokes, move mouse, click |
Quick Reference
Window Management
# List all visible windows
powershell.exe -Command "Get-Process | Where-Object {$_.MainWindowTitle -ne ''} | Select-Object Id, ProcessName, MainWindowTitle | Format-Table -AutoSize"
# Get active window title
powershell.exe -Command "Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class Win32 { [DllImport(\"user32.dll\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\"user32.dll\", CharSet=CharSet.Auto)] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count); }'; $sb = New-Object System.Text.StringBuilder 256; [Win32]::GetWindowText([Win32]::GetForegroundWindow(), $sb, 256); $sb.ToString()"
Application Management
# Launch an application
powershell.exe -Command "Start-Process 'notepad.exe'"
# List running processes (top 20 by CPU)
powershell.exe -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 20 Id, ProcessName, CPU, WorkingSet64 | Format-Table -AutoSize"
System Info
# CPU, RAM, OS summary
powershell.exe -Command "$os = Get-CimInstance Win32_OperatingSystem; $cpu = Get-CimInstance Win32_Processor; Write-Output \"OS: $($os.Caption) $($os.Version)\"; Write-Output \"CPU: $($cpu.Name)\"; Write-Output \"RAM: $([math]::Round($os.TotalVisibleMemorySize/1MB, 2)) GB total, $([math]::Round($os.FreePhysicalMemory/1MB, 2)) GB free\"; Write-Output \"Uptime: $((Get-Date) - $os.LastBootUpTime)\""
File/Directory (READ-ONLY)
# List directory contents
powershell.exe -Command "Get-ChildItem -Path 'C:\Users' | Format-Table Name, LastWriteTime, Length, Mode -AutoSize"
# Search for files by name
powershell.exe -Command "Get-ChildItem -Path 'C:\Users' -Recurse -Filter '*.txt' -ErrorAction SilentlyContinue | Select-Object FullName, Length, LastWriteTime | Format-Table -AutoSize"
# Get file properties
powershell.exe -Command "Get-ItemProperty -Path 'C:\path\to\file' | Select-Object FullName, Length, CreationTime, LastWriteTime, LastAccessTime"
# Get directory size
powershell.exe -Command "(Get-ChildItem -Path 'C:\path' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB"
Audio/Volume
# Get current volume (requires AudioDeviceCmdlets or nircmd approach)
powershell.exe -Command "Add-Type -TypeDefinition 'using System.Runtime.InteropServices; [Guid(\"5CDF2C82-841E-4546-9722-0CF74078229A\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { int _0(); int _1(); int _2(); int _3(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int _5(); int GetMasterVolumeLevelScalar(out float pfLevel); int SetMute(bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid(\"D666063F-1587-4E43-81F1-B948E807363F\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); } [Guid(\"A95664D2-9614-4F35-A746-DE8DB63617E6\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice); } [ComImport, Guid(\"BCDE0395-E52F-467C-8E3D-C4579291692E\")] class MMDeviceEnumerator {} '; $enumerator = New-Object MMDeviceEnumerator; $device = $null; $enumerator.GetDefaultAudioEndpoint(0, 1, [ref]$device); $iid = [Guid]'5CDF2C82-841E-4546-9722-0CF74078229A'; $volume = $null; $device.Activate([ref]$iid, 1, [IntPtr]::Zero, [ref]$volume); $level = 0.0; $volume.GetMasterVolumeLevelScalar([ref]$level); [math]::Round($level * 100)"
Screenshot
# Full screen screenshot
powershell.exe -Command "Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bmp = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height); $g = [System.Drawing.Graphics]::FromImage($bmp); $g.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size); $path = \"$env:TEMP\screenshot_$(Get-Date -Format 'yyyyMMdd_HHmmss').png\"; $bmp.Save($path); $g.Dispose(); $bmp.Dispose(); Write-Output \"Screenshot saved: $path\""
Network Info
# IP addresses and network info
powershell.exe -Command "Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -ne '127.0.0.1'} | Select-Object InterfaceAlias, IPAddress, PrefixLength | Format-Table -AutoSize"
Common Mistakes to Avoid
- DO NOT use
> or Out-File to redirect output to files — display output in terminal only
- DO NOT use
Remove-Item even if the user asks — explain the read-only policy
- DO NOT use
Stop-Process to close apps — use graceful window close via SendMessage(WM_CLOSE) instead
- DO NOT use
shutdown or Restart-Computer — only Lock-Workstation and sleep are allowed
- DO NOT modify registry, services, or firewall rules
- DO NOT use
Set-ExecutionPolicy — work within current policy using -Command parameter
- ALWAYS use
powershell.exe -Command "..." syntax for Bash tool compatibility
- ALWAYS use
-ErrorAction SilentlyContinue for recursive file searches to avoid permission errors flooding output
Full Command Reference
See powershell-reference.md for detailed commands for all 16 operation categories.
1---2name: windows-desktop3description: Use when performing Windows Desktop operations like window management, launching apps, taking screenshots, controlling volume, reading system info, or listing files. Enforces READ-ONLY for all file and directory operations.4---56# Windows Desktop Control78Control the Windows desktop via PowerShell. **All file and directory operations are STRICTLY READ-ONLY.**910## Safety Rules — ABSOLUTE CONSTRAINTS1112### READ-ONLY File Policy1314**You MUST NOT modify, create, move, rename, or delete any file or directory on the user's system.**15The ONLY exception is screenshot capture, which creates a new image file.1617### PROHIBITED Commands — NEVER Execute These1819| Category | Prohibited Commands | Reason |20|----------|-------------------|--------|21| **File Write/Delete** | `Remove-Item`, `Delete`, `Move-Item`, `Rename-Item`, `Set-Content`, `Add-Content`, `Out-File`, `New-Item`, `Copy-Item` (to new location), `rm`, `del`, `ren`, `move`, `rd`, `rmdir`, `mkdir` (use `New-Item` only for screenshots) | Files are READ-ONLY |22| **Process Kill** | `Stop-Process`, `Kill`, `taskkill`, `End-Process` | No process killing |23| **Shutdown/Restart** | `Restart-Computer`, `Stop-Computer`, `shutdown`, `shutdown.exe` | No shutdown/restart |24| **Registry Write** | `Set-ItemProperty` on HKLM/HKCU, `New-ItemProperty`, `Remove-ItemProperty`, `New-Item` on Registry | No registry writes |25| **Service Control** | `Start-Service`, `Stop-Service`, `Set-Service`, `Restart-Service` | No service control |26| **Network Changes** | `Set-NetAdapter`, `Disable-NetAdapter`, `Enable-NetAdapter`, `Set-DnsClientServerAddress`, `netsh` (write ops) | No network changes |27| **User/Security** | `Set-LocalUser`, `New-LocalUser`, `Remove-LocalUser`, `Add-LocalGroupMember`, `Remove-LocalGroupMember`, `icacls` (write), `takeown` | No user/security changes |28| **Execution Policy** | `Set-ExecutionPolicy` | No policy changes |29| **Firewall** | `Set-NetFirewallRule`, `New-NetFirewallRule`, `Remove-NetFirewallRule` | No firewall changes |30| **Scheduled Tasks** | `Register-ScheduledTask`, `Unregister-ScheduledTask`, `Set-ScheduledTask` | No task scheduling |3132### Additional Safety Rules3334- **Never pipe output to files** — No `> file`, `>> file`, `| Out-File`, `| Set-Content`35- **Never use `Invoke-Expression`** on untrusted input36- **Never download or execute remote scripts** — No `Invoke-WebRequest` to download executables37- **Never modify environment variables** — No `[Environment]::SetEnvironmentVariable`, no `$env:VAR = ...` persistently38- **Always prefer `-WhatIf`** when unsure about a command's side effects39- **Screenshot exception**: You MAY use `[System.Drawing.Bitmap]::new()` or similar to save a screenshot file. State the save path to the user first.4041## Operation Categories4243| # | Category | Read-Only? | Key Operations |44|---|----------|-----------|----------------|45| 1 | Window Management | No | List, minimize, maximize, restore, move, resize, snap, close |46| 2 | Application Management | Mixed | List processes (read), launch/switch apps (allowed) |47| 3 | Clipboard | No | Read clipboard, copy text to clipboard |48| 4 | Display Info | **READ-ONLY** | Resolution, monitors, brightness, DPI |49| 5 | Audio/Volume | No | Get/set volume, mute/unmute, list devices |50| 6 | System Info | **READ-ONLY** | CPU, RAM, disk, battery, OS, uptime |51| 7 | Network Info | **READ-ONLY** | WiFi, IP, adapters, DNS, gateway |52| 8 | File/Directory | **STRICTLY READ-ONLY** | List, search, read, properties, size |53| 9 | Virtual Desktops | No | List, create, switch |54| 10 | Screenshot | No | Full screen, active window, region (creates file) |55| 11 | Power Management | No | Lock screen, sleep (NOT shutdown/restart) |56| 12 | Notifications | No | Send toast notification |57| 13 | Services | **READ-ONLY** | List services, get status |58| 14 | Installed Software | **READ-ONLY** | List installed programs |59| 15 | Environment Variables | **READ-ONLY** | List all, get specific |60| 16 | Keyboard/Mouse | No | Send keystrokes, move mouse, click |6162## Quick Reference6364### Window Management65```powershell66# List all visible windows67powershell.exe -Command "Get-Process | Where-Object {$_.MainWindowTitle -ne ''} | Select-Object Id, ProcessName, MainWindowTitle | Format-Table -AutoSize"6869# Get active window title70powershell.exe -Command "Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class Win32 { [DllImport(\"user32.dll\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\"user32.dll\", CharSet=CharSet.Auto)] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count); }'; $sb = New-Object System.Text.StringBuilder 256; [Win32]::GetWindowText([Win32]::GetForegroundWindow(), $sb, 256); $sb.ToString()"71```7273### Application Management74```powershell75# Launch an application76powershell.exe -Command "Start-Process 'notepad.exe'"7778# List running processes (top 20 by CPU)79powershell.exe -Command "Get-Process | Sort-Object CPU -Descending | Select-Object -First 20 Id, ProcessName, CPU, WorkingSet64 | Format-Table -AutoSize"80```8182### System Info83```powershell84# CPU, RAM, OS summary85powershell.exe -Command "$os = Get-CimInstance Win32_OperatingSystem; $cpu = Get-CimInstance Win32_Processor; Write-Output \"OS: $($os.Caption) $($os.Version)\"; Write-Output \"CPU: $($cpu.Name)\"; Write-Output \"RAM: $([math]::Round($os.TotalVisibleMemorySize/1MB, 2)) GB total, $([math]::Round($os.FreePhysicalMemory/1MB, 2)) GB free\"; Write-Output \"Uptime: $((Get-Date) - $os.LastBootUpTime)\""86```8788### File/Directory (READ-ONLY)89```powershell90# List directory contents91powershell.exe -Command "Get-ChildItem -Path 'C:\Users' | Format-Table Name, LastWriteTime, Length, Mode -AutoSize"9293# Search for files by name94powershell.exe -Command "Get-ChildItem -Path 'C:\Users' -Recurse -Filter '*.txt' -ErrorAction SilentlyContinue | Select-Object FullName, Length, LastWriteTime | Format-Table -AutoSize"9596# Get file properties97powershell.exe -Command "Get-ItemProperty -Path 'C:\path\to\file' | Select-Object FullName, Length, CreationTime, LastWriteTime, LastAccessTime"9899# Get directory size100powershell.exe -Command "(Get-ChildItem -Path 'C:\path' -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB"101```102103### Audio/Volume104```powershell105# Get current volume (requires AudioDeviceCmdlets or nircmd approach)106powershell.exe -Command "Add-Type -TypeDefinition 'using System.Runtime.InteropServices; [Guid(\"5CDF2C82-841E-4546-9722-0CF74078229A\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { int _0(); int _1(); int _2(); int _3(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int _5(); int GetMasterVolumeLevelScalar(out float pfLevel); int SetMute(bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid(\"D666063F-1587-4E43-81F1-B948E807363F\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); } [Guid(\"A95664D2-9614-4F35-A746-DE8DB63617E6\"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice); } [ComImport, Guid(\"BCDE0395-E52F-467C-8E3D-C4579291692E\")] class MMDeviceEnumerator {} '; $enumerator = New-Object MMDeviceEnumerator; $device = $null; $enumerator.GetDefaultAudioEndpoint(0, 1, [ref]$device); $iid = [Guid]'5CDF2C82-841E-4546-9722-0CF74078229A'; $volume = $null; $device.Activate([ref]$iid, 1, [IntPtr]::Zero, [ref]$volume); $level = 0.0; $volume.GetMasterVolumeLevelScalar([ref]$level); [math]::Round($level * 100)"107```108109### Screenshot110```powershell111# Full screen screenshot112powershell.exe -Command "Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; $bmp = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height); $g = [System.Drawing.Graphics]::FromImage($bmp); $g.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size); $path = \"$env:TEMP\screenshot_$(Get-Date -Format 'yyyyMMdd_HHmmss').png\"; $bmp.Save($path); $g.Dispose(); $bmp.Dispose(); Write-Output \"Screenshot saved: $path\""113```114115### Network Info116```powershell117# IP addresses and network info118powershell.exe -Command "Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -ne '127.0.0.1'} | Select-Object InterfaceAlias, IPAddress, PrefixLength | Format-Table -AutoSize"119```120121## Common Mistakes to Avoid1221231. **DO NOT** use `>` or `Out-File` to redirect output to files — display output in terminal only1242. **DO NOT** use `Remove-Item` even if the user asks — explain the read-only policy1253. **DO NOT** use `Stop-Process` to close apps — use graceful window close via `SendMessage(WM_CLOSE)` instead1264. **DO NOT** use `shutdown` or `Restart-Computer` — only `Lock-Workstation` and sleep are allowed1275. **DO NOT** modify registry, services, or firewall rules1286. **DO NOT** use `Set-ExecutionPolicy` — work within current policy using `-Command` parameter1297. **ALWAYS** use `powershell.exe -Command "..."` syntax for Bash tool compatibility1308. **ALWAYS** use `-ErrorAction SilentlyContinue` for recursive file searches to avoid permission errors flooding output131132## Full Command Reference133134See [powershell-reference.md](./powershell-reference.md) for detailed commands for all 16 operation categories.